Checking the Devices Before a Run

A run that starts with a device missing, switched off or at the wrong address fails at its first step, or worse, later. So before the first step, the experiment checks every device it uses. This check is called the preflight; Preflight: is the instrument actually there? explains how it works from the connection up.

What is checked

For every device of the experiment that runs on a server:

  1. it answers at its address, and says who it is (identity());

  2. it offers every method the experiment needs from it, as listed under requires;

  3. its server reports whether it can reach the instrument itself, for example that the instrument is on the USB bus but has no driver. This report is included in what the check says.

A device object inside the experiment’s own program is only checked for the methods under requires; it connects when the run starts.

The second check is what tells a wrong address apart from a right one: at a wrong address, a server may well answer, but it is a different instrument. List what each device must be able to do where the devices are configured, for example in the module’s config.yaml (see The module configuration: config.yaml):

devices:
  hwp:  {timeout_ms: 5000, requires: [home_stage, move_absolute, get_position]}
  spec: {timeout_ms: 5000, requires: [acquire, get_recent_file, write, query]}
  pm:   {timeout_ms: 5000, requires: [measure_power, write]}

hwp, spec and pm are the names the experiment uses for its devices. The keys are those of a device in a CompositeDevice; see Building a composite.

The check always runs inside the experiment’s setup(), so a run never starts with a device that failed it.

When a device fails the check

Started from The Command Line, a run whose check fails says what is wrong and asks what to do:

The rig is not ready — 1 device(s) failed the preflight:
  - pm: no answer from tcp://127.0.0.1:5557: TimeoutError('Server did not respond in time')
      address tcp://127.0.0.1:5557 (from PM_ADDRESS in .env / the environment)
Check that the pm server(s) are running and that PM_ADDRESS point at them
(a wrong port connects fine but is not the expected device).
[r] retry (after fixing .env or starting the server)  [a] abort  [s] continue without pm
>
  • r builds the devices again, so a corrected .env or a server started in the meantime is picked up.

  • a stops, with RigNotReadyError.

  • s continues without the failed devices. It is offered only when every failed device was declared optional (cli.optional("pm")), and the experiment is told which ones were left out, so that it can leave out the steps that need them.

Without a terminal to ask in, nothing waits: the problem is logged and RigNotReadyError raised.

Doing the same in your own code

ExperimentCLI uses connect_rig, which you can call yourself. Give it a function that builds the devices without the ones named in skip:

from plesty.lib.experiment import connect_rig

devices, skipped = connect_rig(
    lambda skip: PolPlRig(with_powermeter="pm" not in skip),
    optional={"pm"},              # the experiment can run without it
)

devices is the ready CompositeDevice; skipped names the optional devices the operator chose to go without.