Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Commissioning

A project goes onto a plant in steps, each one changing one thing: first the engine checks what it would connect to, then it reads the plant and writes nothing, then it writes. No step needs another binary or another project format; a bundle may carry one project file per step (Applications as packages).

flowchart LR
  A["check<br/>nothing contacted"] --> B["check --live<br/>every item verified"]
  B --> C["run, writes = dry-run<br/>reads, logs writes"]
  C --> D["check --live --write<br/>writability"]
  D --> E["run --write<br/>or writes = on"]

1. Offline

taktwerk check project.toml

Loads every model, binds every dimension, resolves every signal and checks every connector’s settings and map against the plan; contacts nothing. A project whose opcua-client or rest map writes and that does not say writes = "on" or "dry-run" is refused here, so no project starts writing to a plant, or stops, without saying so.

Run the project as a simulation first: the plant connectors replaced by a plant model in the image, or the project with --no-connectors and a scenario.

2. The endpoints

taktwerk check project.toml --live

Runs the verification every opcua-client session runs at its start against the live server, for every connector: each mapped node exists, has the signal’s type and shape, is readable, and is writable where the connector writes with writes on. It writes nothing. The report has a row per node and the connector’s own problems (an unreachable endpoint, a missing writes); --json gives the same as one object. A from-server dimension is resolved only here.

3. Reading, not writing

With writes = "dry-run" in the connector:

taktwerk run project.toml

Inputs and plain tunables are read as usual, the models step on plant data, the write gate is evaluated, and at most once a second the connector logs what it would write:

dry run, not written: plant.u (ns=4;s=Plant.u) = 0.25, …

Compare the logged values with what the plant runs today. Synced tunables stay idle in a dry run. Watch the engine meanwhile:

taktwerk engine status --url 127.0.0.1:8480 --expect 'taktwerk.overruns == 0' \
  --expect 'est.status & 255 == 0'
taktwerk engine read 'plant.*' --for 300          # mean, sd, min, max per signal over 5 min

(--http 127.0.0.1:8480 on the run, or an http connector; on a device the bundle’s unit has one, see Operating a running engine.)

A rest connector takes the same writes: a dry run reads, evaluates the gate and sends nothing, the heartbeat included, logging what it would send.

4. Writing

taktwerk check project.toml --live --write plc     # writability, as that run would write
taktwerk run project.toml --write plc              # writes on for this run

--write <id> turns a dry-run connector’s writes on for one run and is recorded in run.json’s invocation; it is refused while CI is set. Once the loop is accepted, set writes = "on" in the project (or deploy the bundle’s next project file).

A set point written to the engine and read back with its event:

taktwerk engine set ctl.sp 1.2                     # the plan, with the current value
taktwerk engine set ctl.sp 1.2 --yes               # write, wait for the tick, read back

Records of commissioning

Each step’s run is a run record when the project has a recorder: the project’s hash, every override, --write, the tunables’ values at every cycle and every gate change. @io records exactly what the engine exchanged with the plant.