Replaces the prior stub/partial wiki with a Home + Reference-{Architecture,
Contracts,Examples,Limitations} + _Sidebar structure. Topic-contract and
data-model sections wrapped in AUTOGEN markers for the future wiki-gen tool.
Source-vs-spec contradictions surfaced and flagged inline (not silently
fixed). Pending-review notes mark sections that need a full node review.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.8 KiB
valve
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.
Note
Pending full node review (2026-05). Content reflects
CONTRACT.mdand current source only.
At a glance
| Thing | Value |
|---|---|
| What it represents | One actuated throttling valve — supplier Kv curve, position FSM, deltaP estimate |
| S88 level | Equipment Module |
| Use it when | You need a position-controlled valve whose deltaP depends on flow, Kv(position), and service-type (gas / liquid) |
| Don't use it for | Fixed-restriction orifices, non-return / check valves, or curveless throttling devices (no fallback model) |
| Children it accepts | Upstream sources (rotatingmachine, machinegroup / machinegroupcontrol, pumpingstation, valvegroupcontrol) for fluid-contract tracking; measurement for pressure / flow |
| Parents it talks to | valveGroupControl (typical) or any node that issues set.position / cmd.startup / cmd.shutdown |
How it fits
flowchart LR
parent[valveGroupControl]:::unit -->|set.position<br/>cmd.startup / shutdown| v[valve<br/>Equipment]:::equip
src["rotatingMachine /<br/>MGC / pumpingStation"]:::unit -->|child.register<br/>(fluid contract)| v
m_p[measurement<br/>pressure]:::ctrl -.measured.-> v
m_f[measurement<br/>flow]:::ctrl -.measured.-> v
v -->|child.register| parent
v -.->|evt.deltaPChange<br/>evt.fluidCompatibilityChange<br/>evt.fluidContractChange| parent
classDef unit fill:#50a8d9,color:#000
classDef equip fill:#86bbdd,color:#000
classDef ctrl fill:#a9daee,color:#000
S88 colours are anchored in .claude/rules/node-red-flow-layout.md.
Try it — 3-minute demo
Import the basic example flow, deploy, and drive a single valve through a position move.
curl -X POST -H 'Content-Type: application/json' \
--data @nodes/valve/examples/basic.flow.json \
http://localhost:1880/flow
Note
The shipped
examples/{basic,integration,edge}.flow.jsonfiles are minimal stubs (one inject → valve → debug). A tiered01 - Basic Manual Control.json/02 - Integration with Valve Group.json/03 - Dashboard Visualization.jsonset, matching therotatingMachinetemplate, is on the backlog. Until then, drive the node directly with injects.
What to send after deploy (the topics map one-to-one to entries in Reference — Contracts):
set.mode = virtualControl— lets the GUI source drive the valve (parent path is for grouped use).cmd.startup— FSM runsidle → starting → warmingup → operational.set.position = {setpoint: 60}(position %) — valve ramps from 0 to 60; state goesoperational → accelerating → operational. Each position tick fires a Kv lookup + deltaP recompute.data.flow = {variant: 'measured', value: 25, position: 'downstream', unit: 'm3/h'}— push flow so the hydraulic model has something to chew on.delta_predicted_pressureupdates andevt.deltaPChangefires upward.cmd.shutdown— if currentlyoperational, the controller first ramps to position 0, then transitionsstopping → coolingdown → idle.
Important
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 aftergifsicle -O3 --lossy=80.
The seven things you'll send
| Topic | Aliases | Payload | What it does |
|---|---|---|---|
set.mode |
setMode |
"auto" | "virtualControl" | "fysicalControl" | "maintenance" |
Switch operational mode. Source allow-list per mode (defaults from valve.json). |
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. |
cmd.estop |
emergencystop, emergencyStop |
{ source?: string, action?: string } |
Trigger an emergency stop — runs the emergencystop sequence (default [emergencystop, off]). |
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> }. |
Plus the registration topic emitted upward at startup and accepted from real measurement children:
| Topic | Aliases | Payload |
|---|---|---|
child.register |
registerChild |
child Node-RED id (string); msg.positionVsParent carries the position label |
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.
What you'll see come out
Sample Port 0 message (delta-compressed, while operational at ~60 % open with a 25 m³/h flow):
{
"topic": "valve#valve_a",
"payload": {
"state": "operational",
"percentageOpen": 60,
"moveTimeleft": 0,
"mode": "auto",
"downstream_measured_flow": 25,
"downstream_predicted_flow": 0,
"delta_predicted_pressure": 84
}
}
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.
| Field | Meaning |
|---|---|
state |
Current FSM state. See Architecture — FSM. |
percentageOpen |
Current position (0..100). 0 = closed, 100 = fully open. |
moveTimeleft |
Seconds remaining on the current position move (0 when stationary). |
mode |
One of auto / virtualControl / fysicalControl / maintenance. |
delta_predicted_pressure |
Predicted deltaP across the valve (output unit mbar). |
downstream_predicted_flow / _measured_flow |
Last flow pushed via data.flow (output unit m3/h). |
downstream_measured_pressure / _predicted_pressure |
Pressure measurements pushed via the MeasurementRouter. |
Need more?
| Page | What you'll find |
|---|---|
| Reference — Contracts | Full topic contract, config schema, child registration filters |
| Reference — Architecture | Code map, FSM, hydraulic model, lifecycle |
| Reference — Examples | Shipped example flows + debug recipes |
| Reference — Limitations | When not to use, known limitations, open questions |