API for pulling data from Maybell Quantum dilution refrigerators.
Project description
Maybell Quantum API
Public Python API to Maybell Quantum dilution refrigerators.
Getting Started
pip install maybell_quantum
https://pypi.org/project/maybell-quantum/
Dependencies
Below are the direct dependencies of this API:
- influxdb-client
- matplotlib (optional)
Latest Additions
- pymongo support - MongoTimeSeries
- Pandas support - MongoTimeSeries.fetch_pandas returns a pandas.DataFrame
Coming Soon
- Live plotting.
- User-defined data injection.
Quick Start for the Impatient
Cloud Access:
First off you'll need two things from Maybell Quantum:
- An API Token (e.g. 'EDECC12...THISouWIS_0oZ_A_P-yFAKE8...ITOKENO...A==')
- InfluxDB bucket associated with the API Token. (e.g. "Acme Quantum Computers")
Local Access:
Jump to the Local Access Guide and then come back here.
Copy and paste the following snippet and save it to a file called plot_temperature_data.py:
NB: The default values for url and org should work fine for all customers.
from datetime import datetime
from datetime import timedelta
from datetime import timezone
import logging
import os
import matplotlib.pyplot
from maybell_quantum.fridgedb import FridgeDB
from maybell_quantum.fridgedb import TimeRange
from maybell_quantum.helpers import plot
from maybell_quantum.helpers import pretty_print_result
if "INFLUXDB_TOKEN" not in os.environ:
logging.fatal(
"INFLUXDB_TOKEN environment variable is not set. Can't connect without it."
)
exit(1)
token = os.environ["INFLUXDB_TOKEN"]
# TODO: edit the following line with your bucket name
bucket = "<maybell-assigned-bucket-name>"
url = "https://us-east-1-1.aws.cloud2.influxdata.com"
org = "Maybell Quantum"
fdb = FridgeDB(org=org, url=url, token=token, bucket=bucket)
stop_time = datetime.now(timezone.utc)
start_time = stop_time - timedelta(hours=10)
time_range = TimeRange(start_time, stop_time)
matplotlib.pyplot.figure()
thermometers = ["mxp"]
temperatures = fdb.fetch(time_range, thermometers)
plot(thermometers, "temperature", temperatures, saveas="temperatures.png")
pretty_print_result(temperatures)
export INFLUXDB_TOKEN=<your-company-token>
python3 plot_temperature_data.py
Using Local Timezone
We recommend users manage queries using Coordinated Universal Time (UTC). The frigdedb TimeRange dataclass must be in UTC. Daylight savings rollovers or rollbacks can result in queries for more or less data than you may expect. However, for small sessions where it may be convenient, you can provide time ranges in local time using Timezone-Aware datetime. Use zoneinfo.available_timezones() to see a list of supported regions.
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
tz = ZoneInfo("America/Los_Angeles")
# create a Timezone-Aware `datetime` object using the tzinfo parameter
start_time_local = datetime(year=2024, month=12, day=4, hour=6, tzinfo=tz)
start_time_utc = start_time_local.astimezone(ZoneInfo("UTC")) # UTC conversion
stop_time_utc = start_time_local + timedelta(8)
time_range = TimeRange(start_time_utc, stop_time_utc)
In More Detail (Optional)
from fridgedb import FridgeDB
org = 'Maybell Quantum'
url = 'https://us-east-1-1.aws.cloud2.influxdata.com'
token = 'EDECC12GXgRO8grdiLPD7tXUVY7QL36THISouWIIS_0oZ_4SAfP-yFAKE8I3ZFBg0TOKENOko1fZikpEmq43gA=='
bucket = 'Acme Quantum Computing'
fdb = FridgeDB(org=org, url=url, token=token, bucket=bucket)
Get Temperature Data
You'll need to know the names of the thermometers for your specific system. Typical values are currently hard-coded as static class variables in FridgeDB.
from fridgedb import FridgeDB, TimeRange
from helpers import pretty_print_result, plot
from datetime import datetime, timedelta, timezone
print(f"{FridgeDB.sensor_names}")
print(f"{FridgeDB.device_names}")
org = 'Maybell Quantum'
url = 'https://us-east-1-1.aws.cloud2.influxdata.com'
token = '<your_api_token>'
bucket = '<your_maybell_assigned_bucket>'
fdb = FridgeDB(org=org, url=url, token=token, bucket=bucket)
time_range = TimeRange(start_time=datetime.now(timezone.utc) - timedelta(minutes=45), stop_time=datetime.now(timezone.utc))
thermometers = ["mxp", "prp", "rgp", "stp"]
temperatures = fdb.fetch(time_range, thermometers)
plot(thermometers, 'temperature', temperatures, saveas="temperatures.png")
pretty_print_result(temperatures)
Step by Step Explanation
Start with importing the necessary classes and some helper functions, like pretty_print_result and plot.
Next set the variable needed to create, and pull data from, an InfluxDB client. NB: you'll need
to get a unique API token from Maybell, as well as the name of the bucket(s) for your fridge(s).
In [1]: from fridgedb import FridgeDB, TimeRange
...: from helpers import pretty_print_result, plot
...: from datetime import datetime, timedelta
In [2]: org = 'Maybell Quantum'
...: url = 'https://us-east-1-1.aws.cloud2.influxdata.com'
...: token = '<your_api_token>'
...: bucket = '<your_maybell_assigned_bucket>'
Now that we have an instance of FridgeDB we can fetch data. The TimeRange dataclass has just two members:
start_time and stop_time (both Python datetime objects). Below is an example of how to fetch
data for the last 45 minutes.
In [3]: fdb = FridgeDB(org=org, url=url, token=token, bucket=bucket)
...: time_range = TimeRange(start_time=datetime.utcnow() - timedelta(minutes=45), stop_time=datetime.utcnow())
...: temperatures = fdb.fetch(time_range, ["mxp", "prp", "rgp", "stp"])
...: print(f"{fdb.sensor_names}")
...: print(f"{fdb.device_names}")
['p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8', 'cfp', 'f1', 'icp', 'mxp', 'prp', 'rgp', 'stp']
['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'v8', 'v9', 'v10', 'v11', 'v12', 'v13', 'v14', 'v15', 'v16', 'v17', 'v18', 'v19', 'v20', 'v21', 'v22', 'v23', 'v24', 'v25', 'v26', 'pm1', 'pm2', 'pm3', 'pm4', 'pm5', 'warmup', 'still', 'sample', 'cp1', 'cp2', 'inv1']
The result that's returned is a dictionary of dictionaries, where the first key is the name of the device or sensor, and the second key is the field of interest (e.g. "temperature"). Below shows the structure in more detail for clarity.
In [4]: pretty_print_result(temperatures)
{ 'mxp' :
{
'power' = [46.73, 49.89,..., 2.12, 57.52]
'quadrature' = [37.34, 68.39,..., 10.02, 40.96]
'resistance' = [62.17, 19.55,..., 25.76, 26.95]
'temperature' = [77.86, 4.62,..., 58.08, 39.46]
}
}
{ 'prp' :
{
'power' = [57.88, 35.83,..., 84.21, 20.50]
'quadrature' = [2.24, 52.69,..., 66.20, 94.42]
'resistance' = [92.64, 11.34,..., 59.66, 80.26]
'temperature' = [74.98, 6.59,..., 4.66, 24.80]
}
}
{ 'rgp' :
{
'power' = [93.86, 96.91,..., 53.15, 49.18]
'quadrature' = [61.12, 98.45,..., 66.95, 98.52]
'resistance' = [58.18, 30.39,..., 66.84, 41.51]
'temperature' = [5.97, 15.57,..., 37.27, 38.87]
}
}
{ 'stp' :
{
'power' = [1.99, 65.45,..., 49.96, 85.84]
'quadrature' = [58.32, 6.96,..., 18.05, 69.87]
'resistance' = [55.72, 30.75,..., 68.62, 15.45]
'temperature' = [17.65, 39.26,..., 58.94, 28.07]
}
}
Get All Sensor Data
For convenience, a thin wrapper around fetch is provided that gets all the sensor and device data for a given time range.
machine_state = fdb.fetch_all(time_range)
Get All Sensor Data Since a Given Time
For convenience, another thin wrapper around fetch is provided that gets all the sensor and device data from now until <timedelta>.
The following snippets pulls the entire machine state (all devices and sensors) for the last hour.
since = datetime.timedelta(hours=1)
machine_state = fdb.last(since)
Details - Sensor and Device Data Model
Snapshots of the fridge state are stored in an InfluxDB database at set intervals (default is every 10s).
Each system consists of sensors and devices. Sensors are read-only (e.g. pressure gauges and thermometers) and devices can be issued commands (e.g. valves can be opened and closed).
Sensors
All sensors below have their _tag set to "sensor"
(see InfluxDB Tags).
Thermometer
{
"_type" : "thermometer",
"_tag": "sensor",
"temperature": float,
"resistance": float,
"quadrature": float,
"power": float,
}
Pressure
{
"_type" : "pressure",
"_tag": "sensor",
"pressure": float,
}
BGA - Binary Gas Analyzer
{
"_type" : "bga",
"_tag": "sensor",
"percent": float
}
Flow
{
"_type" : "flow",
"_tag": "sensor",
"pressure": float,
"temperature": float,
"volumetric_flow": float,
"mass_flow": float,
}
Devices
All devices below have their _tag set to "device"
(see InfluxDB Tags).
Valve
{
"_type" : "valve",
"_tag": "device",
"open": bool,
}
Trap
{
"_type" : "trap",
"_tag": "device",
"output": float,
}
Pump
{
"_type" : "pump",
"_tag": "device",
"active": bool,
}
Heater
{
"_type" : "",
"_tag": "device",
"power": float,
"current": float,
"voltage": float,
"native": float,
}
Loop
{
"_type" : "loop",
"_tag": "device",
"setpoint": float,
"gain": float,
"integral": float,
"derivative": float,
"ramp_rate": float,
"state": bool,
}
Turbo
{
"_type" : "turbo",
"_tag": "device",
"state": bool,
"speed": int,
"converter": int,
"motor": int,
"bearing": int,
"setpoint": int,
"voltage": int,
"error": bool,
}
Ecodry
{
"_type" : "ecodry",
"_tag": "device",
"setpoint": float,
"frequency": float,
"current": float,
"voltage": float,
"bus_voltage": float,
"power": float,
"state": bool,
}
Inverter
{
"_type" : "inverter",
"_tag": "device",
"state": bool,
"frequency": float,
"current": float,
"voltage": float,
"alarm": Alarm,
}
class Alarm(enum.Enum):
"""Enumerate the toshiba alarm flags."""
NO_ALARM = 0
ALARM_OVER_CURRENT = 1 << 0
ALARM_INVERTER_OVERLOAD = 1 << 1
ALARM_MOTOR_OVERLOAD = 1 << 2
ALARM_OVERHEAT = 1 << 3
ALARM_OVER_VOLTAGE = 1 << 4
ALARM_UNDER_VOLTAGE = 1 << 5
ALARM_MAIN_OVERLOAD = 1 << 6
ALARM_LOW_CURRENT = 1 << 7
ALARM_OVER_TORQUE = 1 << 8
ALARM_BRAKE_OVERLOAD = 1 << 9
ALARM_OPERATION_HOURS = 1 << 10
ALARM_OPTION_COMMUNICATION = 1 << 11
ALARM_SERIAL_COMMUNICATION = 1 << 12
ALARM_MAIN_VOLTAGE = 1 << 13
Compressor
{
"_type" : "compressor",
"_tag": "device",
"state": bool,
"discharge_temperature": float,
"outlet_tempertaure": float,
"inlet_temperature": float,
"return_pressure": float,
}
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file maybell_quantum-1.1.0.tar.gz.
File metadata
- Download URL: maybell_quantum-1.1.0.tar.gz
- Upload date:
- Size: 21.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3abc91fb5cfda8975c941cb5cf82b6ccd6a26dd98fac525917c9f04efc8dd28a
|
|
| MD5 |
6f1bf817e6a6b7fabc15a99b192b635b
|
|
| BLAKE2b-256 |
846061efd4d9735cf84466785518cda6f6a047d2e98b6ae80af180d65a6b2fd9
|
File details
Details for the file maybell_quantum-1.1.0-py3-none-any.whl.
File metadata
- Download URL: maybell_quantum-1.1.0-py3-none-any.whl
- Upload date:
- Size: 18.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
28706f63e855c491374e2de16bc780e8c52af4f5d2d72e0a77d8689f1cee1819
|
|
| MD5 |
96f29ca850709f1a94111140367fef8e
|
|
| BLAKE2b-256 |
765b65e8ed7f40eefa86403a1cb4885ece9316417858018062fe23b38b33d75b
|