A `valve` models a single actuated throttling valve. It loads a supplier Kv-vs-position characteristic curve, drives a position FSM (`accelerating` / `decelerating` through `operational`), and recomputes pressure drop from flow + Kv via a hydraulic model that picks a liquid or gas formula by `serviceType`. Used standalone, or as a child of `valveGroupControl`, downstream of a `rotatingMachine` / `machineGroupControl` / `pumpingStation`.
> The shipped `examples/{basic,integration,edge}.flow.json` files are minimal stubs (one inject → valve → debug). A tiered `01 - Basic Manual Control.json` / `02 - Integration with Valve Group.json` / `03 - Dashboard Visualization.json` set, matching the `rotatingMachine` template, is on the backlog. Until then, drive the node directly with injects.
3.`set.position = {setpoint: 60}` (position %) — valve ramps from 0 to 60; state goes `operational → accelerating → operational`. Each position tick fires a Kv lookup + deltaP recompute.
4.`data.flow = {variant: 'measured', value: 25, position: 'downstream', unit: 'm3/h'}` — push flow so the hydraulic model has something to chew on. `delta_predicted_pressure` updates and `evt.deltaPChange` fires upward.
5.`cmd.shutdown` — if currently `operational`, the controller first ramps to position 0, then transitions `stopping → coolingdown → idle`.
> **GIF needed.** Demo recording of steps 1–5 with the live status badge. Save as `wiki/_partial-gifs/valve/01-basic-demo.gif`, target ≤ 1 MB after `gifsicle -O3 --lossy=80`.
| `cmd.startup` | — | `{ source?: string }` | Run the configured `startup` sequence (default `[starting, warmingup, operational]`). |
| `cmd.shutdown` | — | `{ source?: string }` | Run `shutdown`. If currently `operational`, first ramps the valve to position 0, then transitions `stopping → coolingdown → idle`. |
| `set.position` | `execMovement` | `{ source?: string, action?: string, setpoint: number }` | Move the valve to a position (control-%, `0..100`). Setpoint is coerced to `Number`. |
| `data.flow` | `updateFlow` | `{ variant, value, position, unit? }` — `variant ∈ {'measured','predicted'}` | Push a flow measurement; triggers a Kv lookup + deltaP recompute via the hydraulic model. |
| `query.curve` | `showcurve` | any | Reply on Port 0 with `{ topic: 'Showing curve', payload: <curve snapshot> }`. |
The legacy umbrella `execSequence` (`{action: 'startup' \| 'shutdown' \| 'emergencystop'}`) is still accepted — it forwards to the canonical `cmd.*` handler and logs a one-time deprecation warning. Scheduled for removal in Phase 7.
Key shape: **`<position>_<variant>_<type>`** — the legacy three-segment shape. Position labels are lowercase (`downstream`, `delta`, `upstream`). `valve` does **not** use the four-segment `<type>.<variant>.<position>.<childId>` shape that `rotatingMachine` emits.