Keywords and addressing#
The instrument’s entire control surface is a namespace of typed keywords. A keyword is a named, typed value with metadata, served by exactly one daemon. Reading instrument state, commanding a mechanism, and triggering an action are all keyword operations.
This is what lets one CLI, one GUI framework, and one sequencer work against every daemon without per-daemon client code.
Addressing#
<group>.<scope>.<name>
│ │ └── keyword served by that daemon
│ └────────── daemon scope: the hardware ownership boundary
└────────────────── group: the instrument subsystem
The Libby peer identity is <group>_<scope>; the keyword address is
<group>.<scope>.<name>. Examples:
zsvis.motion.slitwidth
zsvis.motion.kmirrorangle
zsvis.motion.adcangle
zsnir.motion.focusposition
zsfe.selector.position
zsfe.cal.arclampstate
zscam.vis.exposurestate
zshouse.thermal.detectortemperature
zshouse.vacuum.dewarpressure
zsseq.obs.sequencestate
Naming rules#
Lowercase throughout. No underscores inside a name segment: Libby’s
%wildcard matches within a segment, and consistent unbroken names make wildcard queries predictable (libby show zsvis.motion.is%).Groups are the subsystem prefixes fixed in Daemon inventory:
zsfe,zsimg,zsvis,zsnir,zscam,zshouse,zskeck,zsseq.Names are stable. A keyword name is an interface; renaming one breaks the GUI, the sequencer, scripts, and the night log.
Names carry no routing information.
groupandscopealready say where the keyword lives.Where a daemon owns several mechanisms, the mechanism is part of the name:
zsimg.motion.rotuposition,zsimg.motion.rotvposition.
Keyword types#
Libby provides five keyword types. Every ZShooter keyword is one of them:
Type |
Use |
|---|---|
|
Binary state and predicates: |
|
Counts and discrete indices: |
|
Physical quantities: positions, temperatures, pressures, times.
Always carries |
|
Names and enumerated states: |
|
Actions with no value: |
Access mode is inferred from what is supplied: a getter alone makes the keyword read-only, a setter alone write-only, both read-write.
Required metadata#
Every ZShooter keyword must declare:
description: one line, written for a support astronomer at 3 a.m.units: mandatory on everyFloatKeyword. A dimensioned number without units on the bus is a defect.timeout_s: on any keyword whose modify is slow. The CLI and GUIs read this fromkeys.describeto size their own timeouts, so a stage move that takes 40 seconds must advertise it or clients will time out prematurely.validator: wherever a value range or discrete set is known. This is the first line of the safety chain described in Safety.
Standard keywords#
Every ZShooter daemon serves this set, so that generic clients (the status panel, the watchdog, the night-log recorder) work against any daemon without special-casing.
Keyword |
Type |
Meaning |
|---|---|---|
|
string |
Daemon lifecycle state (see State models). |
|
string |
Active operating mode, including |
|
bool |
Driver is connected to its hardware. |
|
bool |
Daemon is ready for nominal observing operations. |
|
bool |
A fault is active. |
|
string |
Human-readable description of the active fault; empty when healthy. |
|
float |
Timestamp of the last liveness publication. |
|
string |
Key of the most recent command. |
|
string |
Outcome of the most recent command. |
|
trigger |
Stop activity and hold safely. Always accepted, in every state. |
|
trigger |
Enter the daemon’s defined safe state. |
|
trigger |
Explicit recovery from fault state. |
halt is special: it must be accepted unconditionally, including while the
daemon is busy, faulted, or owned by another client. It is the one command that
never fails validation.
Motion daemons additionally serve, per mechanism: <mech>position,
<mech>target, <mech>softmin, <mech>softmax, <mech>hardmin,
<mech>hardmax, <mech>ismoving, <mech>isreferenced,
<mech>home.
Discovery#
Libby auto-registers two meta-services on every peer:
keys.list: enumerate keyword names, with%wildcards.keys.describe: full metadata for one keyword.
These make the instrument self-describing. The hard hat GUI builds its
engineering panels from keys.describe rather than from hand-maintained
per-daemon layouts, and the FITS header writer can be driven from the same
metadata.
Note
TBC: keyword catalogue
The complete per-daemon keyword catalogue is not yet written. It should be generated from the daemon configuration schemas rather than maintained by hand, and it depends on the mechanism list being finalised against the L1/L2/L3 requirements.