UniteLabs
Concepts

Module

How a connector groups related actions into logical modules you can discover and call.

A module groups related actions on a connector. If a connector represents an entire instrument, a module represents one functional aspect of that instrument — the temperature controller, the door controller, the weighing service. A balance connector typically has a weighing module and a lock module; a thermocycler has a temperature controller, a lid controller, and a block controller.

The module layer is where most of your code targets. You rarely call actions directly on the connector itself — you find the right module first, then call actions on it.

In the platform UI modules appear as their own column — click one to reveal its actions, grouped by type into Properties, Sensors, and Controls. See the Terminology table for the cross-surface mapping.

Structure

Every module has:

  • An identifier — the name you use to reach it from code (temperature_controller, weighing_service)
  • A set of actions — things you can call (read temperature, tare balance, set target)
  • A reference to its parent service (the connector instance it belongs to)

Discovering modules on a connector

From the Python SDK, modules are attributes of a connector instance and also addressable through the .modules mapping:

from unitelabs.sdk import AsyncApiClient

async with AsyncApiClient() as client:
    balance = await client.get_service_by_name("Balance")

    # Iterate
    print(balance.modules.keys())
    # dict_keys(['weighing_service', 'lock_controller', 'simulation_controller'])

    # Attribute access
    weight = await balance.weighing_service.get_stable_weight()

From the REST API:

# All modules across all connected services
curl "$BASE_URL/v1/modules" \
  -H "Authorization: Bearer $TOKEN"

# Modules on a specific service
curl "$BASE_URL/v1/services/$SERVICE_ID/modules" \
  -H "Authorization: Bearer $TOKEN"

# Detail for one module
curl "$BASE_URL/v1/modules/$MODULE_ID" \
  -H "Authorization: Bearer $TOKEN"

The SDK uses attribute access; the REST API returns JSON you can filter server-side. Both return the same set of modules for a given connector.

Built-in modules on every connector

Three modules ship on every connector regardless of instrument — service metadata for introspection, LockController for exclusive access, and SimulationController for offline testing. See Connector: Built-in modules for detail.

What's inside a module

Everything callable inside a module is an action. Some actions return a single value and complete; others stream updates over time (see Subscription). Both are actions — the distinction is how long they live and how you consume them, not how you reach them in code.