UniteLabs
Tutorial

Control a device with Python

One script that finds a connected QInstruments BioShake, lists what it can do, reads a value, starts heating and streams the temperature.

Every connector works the same way, whatever instrument it runs. You find the device by name, ask what it can do, then call it. The script below does all of that on a QInstruments BioShake plate shaker. For another instrument, only the module and action names change.

You need the SDK installed and a BioShake connector running in GroundControl. The script heats, so it needs a heated model (the -T variants). No shaker on the bench? Set simulated to true in the connector's configuration and the script runs against its built-in simulator.

control_a_device.py
import asyncio

from unitelabs.sdk import AsyncApiClient


async def main():
    # Connect to your tenant (reads the credentials from .env)
    client = AsyncApiClient()

    # Find the device by its connector's name in GroundControl
    shaker = await client.get_service_by_name(name="QINSTRUMENTS BioShake")
    shaking = shaker.shake_controller
    temperature = shaker.temperature_controller  # heated -T models only

    # Ask what it can do: its modules, then the actions of one
    print(shaker.modules.keys())
    for name, action in shaking.actions.items():
        print(name, action.type)

    # PROPERTY: read one value
    print(await shaking.get_device_specific_maximum_shaking_speed())
    print(await shaking.get_shaker_state_with_description())

    # CONTROL: make it do something, here heat to 37 °C
    await temperature.set_target_temperature(target_temp=37.0)
    await temperature.turn_temperature_control_on()
    try:
        # SENSOR: stream a live value, one reading per second
        subscription = await temperature.subscribe_current_temperature()
        async with subscription:
            for _ in range(5):
                print(await anext(subscription))
    finally:
        # Safe state: switch the heater off even if a reading failed
        await temperature.turn_temperature_control_off()


asyncio.run(main())

Run it with uv run control_a_device.py. It prints the modules, the shake controller's actions with their types, the maximum speed and the shaker's state, then five temperature readings as the plate starts to heat.

Every action is one of the three types the comments name:

TypeWhat it doesHow you call it
PROPERTYReads one valueawait it. The name usually starts with get_
SENSORStreams values as they comeSubscribe. The name starts with subscribe_
CONTROLMakes the device do somethingawait it with its parameters

To see what a control expects before you call it, print its schema: print(await temperature.set_target_temperature.parameters). The platform's web interface shows the same modules and actions as a form, so you can try one there without code.

Next steps

Last updated