Event Schema Registry#
This registry defines canonical names and payload fields for EventBus records emitted by PLR. It is the shared semantic contract between instrument frontends and event consumers.
The registry describes operation families, not required capabilities. A frontend implements only the operations that its hardware and public API support. When it does implement an operation that already appears here, it should use the canonical operation name and field meanings below.
For guidance on operation boundaries, instrumentation style, and testing, see the EventBus contributor guide. For the exact frontend classes that currently emit these operations, see Current event coverage.
Extending the registry#
When adding an event for a device or operation family that is not represented here:
Prefer a device-independent semantic name over a vendor-specific name when the operation has a clear cross-device meaning.
Reuse canonical fields from this registry when their meaning matches. Do not introduce a second name for an existing concept.
Add new fields only when they describe information the PLR operation actually knows.
Document the proposed operation and fields in this registry in the same contribution as the implementation.
Treat maintainer review of the new schema as establishing the convention for future frontends that implement that operation family.
Do not distort resource semantics or add presentation-only fields for a particular logger, dashboard, or notification service.
Record classes#
Semantic operation lifecycle#
A semantic operation uses this lifecycle:
<component>.<operation>.started
<component>.<operation>.completed
or, when it raises:
<component>.<operation>.started
<component>.<operation>.failed
Lifecycle records share context.operation and context.operation_id. A failed record preserves
the operation’s invocation data and adds:
Field |
Type |
Meaning |
|---|---|---|
|
|
Exception class name. |
|
|
String representation of the original exception. |
Tables in this guide describe fields in event.data. A field marked completed only is added
only after successful execution. All other listed fields describe invocation state and remain
stable across the lifecycle unless an operation-specific note says otherwise.
State-transition records#
State records describe an instantaneous PLR model transition and do not use the
started/completed/failed lifecycle. Current examples are resource.assigned and
resource.unassigned.
Diagnostic records#
Diagnostic events describe controller or transport activity. They may use a lifecycle when the underlying command has a meaningful request and response, but they are not semantic frontend operations. When emitted inside a semantic operation, they inherit its event context.
Canonical common fields#
Field |
Type |
Meaning |
|---|---|---|
|
|
Device or controller issuing the operation. |
|
|
Direct PLR resources acted on by the operation. Omit or use an empty list when none are known. |
|
|
Physical origin of a resource transfer. |
|
|
Physical destination of a resource transfer. |
|
|
Requested duration in PLR’s default time unit. |
|
|
Requested timeout in PLR’s default time unit. |
|
|
Configured or requested controller target temperature. |
|
|
Controller sensor reading observed by the operation. It is not a resource-temperature measurement unless explicitly documented otherwise. |
|
|
Requested relative-humidity setpoint as a fraction from 0 to 1. |
|
|
Requested CO2 concentration as a fraction from 0 to 1. |
|
|
Requested O2 concentration as a fraction from 0 to 1. |
|
|
Allowed temperature difference in PLR’s default temperature unit. |
|
|
Requested liquid volume in PLR’s default volume unit. |
Use resource_reference() for direct resources and resource endpoints. Its ancestors provide
structural context without replacing a Well, TipSpot, plate, or holder with a more convenient
display resource. Use coordinate_reference() for geometric endpoints and targets.
Quantitative fields use PLR’s default units. Add a suffix
only when the value deliberately uses a different representation, such as speed_rpm or
speed_pct.
Canonical vocabulary#
Use these names consistently across operation families:
Concept |
Canonical field |
Do not introduce aliases such as |
|---|---|---|
Requested elapsed time |
|
|
Maximum wait |
|
|
Requested thermal setpoint |
|
|
Requested relative humidity |
|
|
Requested CO2 concentration |
|
|
Requested O2 concentration |
|
|
Observed controller temperature |
|
|
Temperature acceptance range |
|
|
Relative centrifugal force |
|
|
Direct operated resources |
|
|
Transfer endpoints |
|
|
Liquid volume |
|
|
Successful command result |
|
|
This vocabulary is semantic, not merely stylistic. For example, target_temperature is a
controller setpoint, while current_temperature is an observed controller reading. Do not use one
as an alias for the other.
Machine lifecycle#
Operation |
Fields |
Notes |
|---|---|---|
|
|
Initializes a generic machine frontend. |
|
|
Stops a generic machine frontend. |
Vendor frontends may use their own component name, such as precise_flex.setup, while preserving
the same lifecycle meaning.
Resource-model state#
These are state-transition records rather than semantic operation lifecycles.
Event |
Fields |
Notes |
|---|---|---|
|
|
Emitted after assignment. |
|
|
Emitted after unassignment while preserving the former parent and relative location. |
Resource transfer#
Incubators#
Operation |
Fields |
Notes |
|---|---|---|
|
|
|
|
|
Moves the loading-tray plate into storage. A requested selector such as |
|
|
Moves a plate directly between two transfer nests or other incubator endpoints. |
Stackers#
Operation |
Fields |
Notes |
|---|---|---|
|
|
Moves the accessible plate from a stack to the loading tray. |
|
|
Moves the loading-tray plate onto a stack. |
|
|
Moves the accessible plate between two stacks. |
Centrifuge loaders#
Operation |
Fields |
Notes |
|---|---|---|
|
|
Transfers the staging plate into the selected centrifuge bucket. |
|
|
Transfers the selected bucket plate onto the staging holder. |
Liquid-handler resource movement#
Operation |
Fields |
Notes |
|---|---|---|
|
|
|
|
|
Moves the currently held resource without assigning it to a destination. |
|
|
Drops the currently held resource at a resource or geometric destination. |
Manual operator actions#
Manual actions use the semantic lifecycle manual_operator.<action>.*, where <action> is a
stable, developer-defined action identifier such as centrifuge.spin, plate_reader.read, or
quality_control.inspect.
Operation |
Fields |
Notes |
|---|---|---|
|
|
|
|
|
|
Manual action providers decide how an operator acknowledges the request. Cancellation,
provider-reported failure, invalid provider results, and provider exceptions produce the normal
failed lifecycle record with error_type and error_message.
Liquid handling#
Channelized liquid operations#
Operation |
Fields |
|---|---|
|
|
|
|
resources contains the unique direct containers operated on. liquid_operations contains one
record per channel:
Field |
Type |
Meaning |
|---|---|---|
|
|
Liquid-handler channel index. |
|
|
Direct operated container, normally a well or trough. |
|
|
Owning plate when one exists; otherwise the direct container. |
|
|
Requested channel volume. |
Channelized tip operations#
Operation |
Fields |
|---|---|
|
|
|
|
resources contains unique direct TipSpot or Trash resources. tip_operations contains one
record per channel with channel and direct resource fields.
96-head tip operations#
Operation |
Fields |
Notes |
|---|---|---|
|
|
Direct resource is the operated |
|
|
Direct resource is the destination |
Shaking and environmental control#
Controllers that are ResourceHolders include their directly loaded resource in resources when
one is assigned at operation start.
Operation |
Fields |
Notes |
|---|---|---|
|
|
Omitted |
|
|
Explicitly stops an indefinite shake. |
|
|
Records the requested target and cooling policy. |
|
|
Starts active temperature control at the configured setpoint. |
|
|
|
|
|
Records a requested dwell without reissuing a setpoint or asserting that a resource reached temperature. |
|
|
Stops active temperature control. |
|
|
Records the requested relative-humidity fraction. |
|
|
Starts active humidity control at the configured setpoint. |
|
|
Stops active humidity control. |
|
|
Records the requested CO2 fraction. |
|
|
Starts active CO2 control at the configured setpoint. |
|
|
Stops active CO2 control. |
|
|
Records the requested O2 fraction. |
|
|
Starts active O2 control at the configured setpoint. |
|
|
Stops active O2 control. |
Centrifugation#
Operation |
Fields |
Notes |
|---|---|---|
|
|
Describes one requested spin cycle. |
resources contains directly loaded resources only. Empty buckets are not represented.
bucket_resources preserves the association between each loaded resource and its holder:
{
"holder": resource_reference(bucket),
"resource": resource_reference(plate),
}
relative_centrifugal_force is the dimensionless multiple of standard gravity conventionally
written as x g. Acceleration and deceleration are fractions of the device maximum.
Brooks PreciseFlex#
PreciseFlex currently exposes vendor-specific controller operations. These records describe the controller command and geometric or joint target; a higher-level resource-aware integration should emit separate resource-transfer operations when it knows the moved PLR resource.
Lifecycle and controller state#
Operation |
Fields |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Motion#
Operation |
Fields |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
target_joint_position maps axis names to positions. A Cartesian target contains a serialized
location, approach direction, optional elbow orientation, optional wrist, and optional
rail_position. Lengths use PLR’s default unit, grasp_force uses the default force unit, and
percentage values use the _pct suffix.
Diagnostic transports and firmware#
Serial, USB, and FTDI#
io.read and io.write are instantaneous diagnostic records:
Field |
Meaning |
|---|---|
|
|
|
Human-readable transport device name. |
|
Port, serial number, or transport-specific identifier. |
|
Decoded or hexadecimal transport payload. |
Hamilton firmware commands#
firmware.command.started, firmware.command.completed, and firmware.command.failed use:
Field |
Lifecycle |
Meaning |
|---|---|---|
|
all |
|
|
all |
Hamilton driver class name. |
|
all |
Firmware module identifier. |
|
all |
Firmware command identifier. |
|
all |
Correlation identifier assigned by the driver. |
|
all |
Full assembled command. |
|
completed |
Raw firmware response, if any. |
|
failed |
Original exception details. |
PreciseFlex firmware commands#
precise_flex.firmware_command.started, precise_flex.firmware_command.completed, and
precise_flex.firmware_command.failed use device and command in the full lifecycle, response
on completion, and error_type plus error_message on failure.
Schema compatibility#
Treat operation names and documented field meanings as public integration contracts:
Adding an optional field is normally backward compatible.
Adding completion-only information is normally backward compatible when invocation fields stay stable.
Renaming a field, changing its units, replacing a direct resource with an ancestor, or changing the meaning of an existing field is a compatibility change and requires explicit review.
Vendor-specific extensions should not silently redefine a canonical cross-device field.
When implementation and this registry diverge, update them together and add tests that assert the canonical operation name, lifecycle, and payload fields.