Skip to main content

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

Dependencies

Below are the direct dependencies of this API:

  • influxdb-client
  • matplotlib (optional)

Coming Soon

  • Timezone support.
  • Dynamic fridge configurations.
  • Live plotting.
  • User-defined data injection.
  • Panda support.

Quick Start for the Impatient

First off you'll need two things from Maybell Quantum:

  1. An API Token (e.g. 'EDECC12...THISouWIS_0oZ_A_P-yFAKE8...ITOKENO...A==')
  2. InfluxDB bucket associated with the API Token. (e.g. "Acme Quantum Computers")

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

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

maybell_quantum-1.0.1-py3-none-any.whl (16.2 kB view details)

Uploaded Python 3

File details

Details for the file maybell_quantum-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: maybell_quantum-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 16.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.11.0rc1

File hashes

Hashes for maybell_quantum-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b56530bc0c10fea28ea6d7a0dd2231cfe502c6d0add23a8b325107e36b66e29a
MD5 cdd029d8815ac190b7af73744a01ba82
BLAKE2b-256 534f5a5062f27f75daed5fc989254b7268d3ef6ad7af6b77f8593e9000e1c478

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page