Designing Data Types
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, andMinimalLength, reject invalid input before the command runs. - Informational constraints, such as
UnitandContentType, 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