A measurement is several programs, often on several PCs. This is how they are wired together — for a run started from PLESTY Bench, in three steps:
- The bench starts the instruments, each on the PC it is plugged into — its own directly, another bench's through that bench's agent (port 5550, guarded by a token).
- It hands the run their addresses —
HWP_ADDRESS,SPEC_ADDRESS. - The experiment connects to them directly. The agents are not in the measurement's path; they only start and stop things.
One server per instrument
A device module is never imported into an experiment. It runs as a device server that holds the instrument open and listens on one TCP port; anything that needs the instrument is a client. So an instrument has exactly one owner, it is reached by an address wherever it is plugged in, and a vendor driver that only exists for Windows never has to be installed where the experiment runs.
A client needs only the address. When it connects, it asks the server to describe the device, and from then on:
| every call is checked | against the device's schemas, on the server — a value out of range never reaches the instrument |
| every call has a budget | the client waits as long as the operation declared, not a global timeout |
| shared instruments are locked per resource | one experiment can hold two channels of a DAQ while another holds a third |
The transport is ZMQ with JSON messages: a ROUTER socket in the server, a DEALER in each client, so one server answers many clients at once.
The experiment's rig
An experiment reaches its instruments through its rig: one client per
instrument, each under a name, each at the address in <NAME>_ADDRESS.
Before the first step, the rig's preflight checks that every server
answers and offers every operation the experiment will call — a missing
server stops the run by name, not at step 40.
Where the wiring is written
An experiment module names its devices and their benches in setup.yaml,
committed with the module. It holds variable names only; the addresses and
tokens are in the .env beside it, on that PC:
benches:
bench-local: {data: ${LOCAL_DATA}}
spec-pc: {address: ${SPEC_PC_ADDRESS}, token: ${SPEC_PC_TOKEN}, data: ${SPEC_PC_DATA}}
devices:
hwp: {package: plesty-k10cr1, host_name: bench-local}
spec: {package: plesty-lightfield-spectrometer, host_name: spec-pc}
Each bench allocates its device ports itself — from 5551 up — and keeps them, so a device has the same address from day to day. A console set to the master role also lists other benches' devices beside its own; the rest are nodes that serve only their own. Across Two PCs is this wiring on two PCs.
Read next
- Data Flow — what travels over these connections, and what deliberately does not.