Command a machine with a row
Machines.commandRowMachines.commandTargetMachines.CommandResolutionconditionalStart, stop, pause or change over a machine by parking a row on its role; the machine's reply resolves the row as data.
The situation
An order needs the bonding cell changed over to a new recipe before its units arrive. The workflow should ask the machine the way it asks a person for anything, and read the answer as data, including “the machine never answered”.
The recipe
import { conditional, Machines } from '@hotmeshio/long-tail';
const target = Machines.commandTarget(line, 'bond-01');const reply = await conditional<Machines.CommandResolution>(`changeover-${orderId}`, { ...Machines.commandRow(target, 'changeover', { recipe: { id: 'RCP-BOND-B', version: '1' } }), timeout: '10m',});commandRow builds a machine-command row on the machine’s role. The gateway sends the command and resolves the row with the reply, as the machine that gave it:
{ accepted: true, machineId: 'bond-01', op: 'changeover', status: 'accepted', reason: 'changing over to RCP-BOND-B v1' }status |
Meaning |
|---|---|
accepted |
The machine took the command |
refused, failed |
The machine said no; the reason is in reason |
no-reply |
No reply after every attempt; the command expired |
unsupported |
Not a command a row may ask for, or not a machine on this line; nothing was sent |
Commands a row may ask for: start, stop, pause, resume, changeover and cancel (which needs args.jobId).
The guarantee
Asking a machine takes the same access as parking any row on its role: write access to that role, or a workflow that parks the row. A row commands only the machine whose role it is on. A no-reply command expired at the end of the asking, so a copy that reaches the machine later is refused, never run. See Machines.
Related patterns
The physical world
A machine is a resolver
A workflow parks a row and waits; a machine resolves it over MQTT exactly as a person would from the dashboard.
The physical world
Idempotent commands
Every command carries an id and an expiry, so a retry is answered rather than run twice, and a late copy is refused.
The queue as a market
Role is the wall, facets are capability
The role decides who can ever see a row. Metadata facets decide which consumer inside that role can take it.
