UniteLabs
Reference

Designing Data Types

Why connectors use typed structures, enums, binary data, and device-native units.

The types on a connector's signatures are the contract a client relies on. A well-typed endpoint tells the client what a value means, what range it can take, and what unit it is in, without reading any prose.

For how to declare the types themselves, see the SiLA Data Types tutorial. For how to add constraints and units, see Constraints and Units.

Constrain every value

Add constraints wherever they apply, to return values as well as parameters, and base them on what the device actually accepts and reports.

There are two kinds:

  • Validation constraints, such as MinimalInclusive, MaximalInclusive, Set, and MinimalLength, reject invalid input before the command runs.
  • Informational constraints, such as Unit and ContentType, tell the client what a value means without validating anything.

Structured data

When a response bundles several related values, define a dataclass. A loose tuple or a formatted string makes the client parse your output.

Don't pass raw XML or JSON as a string. If the payload is small and has a structure, model it as a dataclass. If it has to stay serialized, send it as bytes with a ContentType constraint, and a Schema constraint when a schema exists.

Lists can't be nested in SiLA: a list holds basic types, structures, constrained types, or custom types, never another list. Wrap the inner list in a structure.

Status values

Use an Enum for a status or state, not an integer or a bare string. An integer forces the client to look up what 3 means; an enum member carries its meaning in its name. The CDK converts enums into constrained strings based on the member names.

class DeviceStatus(enum.Enum):
    IDLE = enum.auto()
    RUNNING = enum.auto()
    ERROR = enum.auto()

Binary data

Use bytes, not str, for raw payloads: file contents, images, or any data without a fixed text encoding. A SiLA string is limited to 2²¹ characters (about 2 MB) and assumes an encoding that may not match the data.

When the binary format is known, say so with a ContentType constraint, such as image/png or application/pdf.

Units

Expose the unit the device uses. If the device reports Kelvin, annotate the interface with Kelvin rather than subtracting 273.15 and exposing Celsius. A silent conversion hides a transformation that no client can see or verify, and it becomes a maintenance trap if it is ever wrong. The Unit constraint already tells the client exactly what it is getting.

Fractional units have two cases. Some devices genuinely operate in a fractional unit, and their documentation defines the resolution that way, such as 1/10 mm. Expose that as-is, with the scaling documented or a custom unit label. Other devices only use integers because their firmware lacks float support. In that case, convert on the connector side and expose the standard unit. Either way, document the choice.

Units never go in identifiers (timeout, not timeout_ms) or docstrings. They belong on the signature, where the client can read them.

Coordinate systems

On a liquid handler, report and accept positions in a coordinate system whose origin is the bottom of the tip. Every liquid handler UniteLabs supports uses this origin, so a client moving between two of them doesn't have to work out a new reference frame.

Last updated