Data & Metadata Schemas
plesty-lib defines one schema contract per data domain so that every HUB
module acquires, stores, and exchanges data in the same shape. Three domains
are covered (issue lib#4):
Domain |
Schema |
Module |
|---|---|---|
Device configuration |
|
|
Operational telemetry |
|
|
Experimental output |
|
|
Device configuration
Structured representation of device parameters and settings — see
Parameter System. Every parameter is a
ConfigParameter (name, dtype, unit, constraints, command binding) organised
into ConfigGroups and managed by the ConfigSystem that every device model
composes. Device modules declare their parameters in a YAML/JSON schema which
ConfigSystem materialises at init.
Operational telemetry
Real-time status, state, and diagnostic data, defined in
plesty.lib.device.telemetry. Two shapes cover pull and push:
DeviceStatus— a point-in-time snapshot. Every device inheritsstatus()via theTelemetrySystemmixin; the default implementation is assembled from the connection check and the cached configuration values (no device I/O), so it is always cheap to call:status = device.status() status.connection # "connected" | "disconnected" | "connecting" | "error" status.state # "ready", "busy", ... (override device_state() to refine) status.parameters # last-known parameter values status.last_error # most recent error message, if any
TelemetryEvent— a timestamped record of kindreading,state_change,error, orwarning. Consumers register a hook; the base device emitsstate_change/readingevents automatically on every successfulwrite/query, and devices can emit custom events withemit_telemetry():events = [] device.register_telemetry_hook(events.append) device.write("wavelength", 850.0) # emits a state_change event from plesty.lib.device.telemetry import append_events append_events(run_dir / "telemetry.jsonl", events)
Hooks run synchronously and never disturb device operation (a failing hook is
logged and skipped). When no hook is registered, no event is constructed.
append_events/read_events persist events in the same crash-tolerant
append-only JSONL format as the experiment journal. Polling loops, threads,
and transports are deliberately out of scope — they belong to monitors and
services, not to the schema.
Experimental output
Acquired data plus its metadata, defined in plesty.lib.data.io. The storage
contract keeps blobs in their original raw format (.npy for
PlestyArray, native encoding for image bytes) described by a JSON metadata
document — the typed ResultDocument model — holding the Plesty meta (name,
unit, range, description), timestamps, provenance, and a reference link to
the blob:
from plesty.lib.data import save_result, load_result, load_document
path = save_result(array, run_dir / "step_0001", provenance={"step_id": "s1"})
document = load_document(path) # metadata only — no blob I/O
result = load_result(path) # reconstructed PlestyArray
The JSON document is the commit record: a result exists once its .json
file does, and writes are crash-safe (blob first, document last, both
atomic). convert_to_hdf5 optionally packs a set of documents into a single
HDF5 archive for exchange; it needs the hdf5 extra
(uv add "plesty-lib[hdf5]") and raises an ImportError naming it otherwise.