Files
valveGroupControl/wiki/Home.md
znetsixe 9552e4fba9 docs(wiki): full 5-page wiki matching the rotatingMachine reference format
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>
2026-05-19 09:42:12 +02:00

8.9 KiB
Raw Blame History

valveGroupControl

code-ref s88 status

A valveGroupControl (VGC) coordinates a group of valve children that share a common manifold — selector-valve banks, dosing-valve trains, mixing manifolds. It accepts a group-level total flow target, splits the flow proportional to each valve's Kv rating, runs a residual-reconciliation pass against what every valve actually accepted, and aggregates max delta-P across the group. It also reconciles upstream-source fluid-contract advertisements (liquid / gas) into one group-level service-type view that downstream consumers can read.

Note

Pending full node review (2026-05). Content reflects CONTRACT.md and current source only.


At a glance

Thing Value
What it represents A parallel valve manifold — 2 + valves sharing a header, distributing one total flow target
S88 level Unit
Use it when You have 2 + parallel valves that should share an upstream flow target proportional to their Kv
Don't use it for A single valve (wire valve directly), series valves (the Kv-share solver assumes parallel branches), or a manifold whose upstream already publishes per-branch setpoints
Children it accepts valve (group members) + upstream sources (machine / rotatingmachine / machinegroup / machinegroupcontrol / pumpingstation / valvegroupcontrol)
Parents it talks to Any upstream node — typically pumpingStation, reactor, or another VGC; VGC registers via Port 2

How it fits

flowchart LR
    src[machine / MGC /<br/>pumpingStation<br/>upstream source]:::unit -.flow.predicted.*.-> vgc[valveGroupControl<br/>Unit]:::unit
    vgc -->|updateFlow predicted<br/>downstream| v1[valve A]:::equip
    vgc -->|updateFlow predicted<br/>downstream| v2[valve B]:::equip
    v1 -->|positionChange<br/>deltaPChange| vgc
    v2 -->|positionChange<br/>deltaPChange| vgc
    vgc -->|child.register| parent[upstream parent]:::pc
    classDef pc fill:#0c99d9,color:#fff
    classDef unit fill:#50a8d9,color:#000
    classDef equip fill:#86bbdd,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 2-valve group with an injected total-flow setpoint.

curl -X POST -H 'Content-Type: application/json' \
  --data @nodes/valveGroupControl/examples/basic.flow.json \
  http://localhost:1880/flow

What to click after deploy (the inject buttons map to canonical topics in Reference — Contracts):

  1. child.register for each valve — or rely on Port-2 wiring to auto-register.
  2. set.mode = auto — lets the parent source drive the group.
  3. data.totalFlow = 80 (with unit: 'm3/h') — VGC splits 80 m³/h across the available valves by Kv share; runs up to maxPasses: 2 residual passes; writes back atEquipment_predicted_flow = sum of accepted per-valve flows.
  4. cmd.execSequence with {action: "startup"} — runs the group-wide startup sequence through executeSequence, transitioning the group state machine through each step.
  5. cmd.emergencyStop — runs the emergencystop sequence on all valves ([emergencystop, off]).
  6. set.reconcileInterval = 2 — re-tunes the periodic tick to 2 s (reconcileIntervalChange event triggers the adapter to restart its tick loop; minimum 100 ms).

Important

GIF needed. Demo recording of steps 16 with the live status panel. Save as wiki/_partial-gifs/valveGroupControl/01-basic-demo.gif, target ≤ 1 MB after gifsicle -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. Each mode has its own allow-list of sources (mode.allowedSources).
set.position setpoint any No-op pending Phase 7. Reserved for future per-valve positional override. Debug-logged only.
child.register registerChild string (child node id) Manually register a child via RED.nodes.getNode; Port 2 wiring does this automatically in most flows.
cmd.execSequence execSequence { source, action, parameter } Forward to source.handleInput(source, action, parameter) — runs a group-wide sequence (startup / shutdown / emergencystop / boot).
data.totalFlow totalFlowChange number, { value, position?, variant?, unit? }, or { source, action, ... } Update the total measured/predicted flow at the configured position; triggers calcValveFlows to re-distribute across valves.
cmd.emergencyStop emergencyStop, emergencystop optional { source } Run the emergencystop sequence on all valves.
set.reconcileInterval setReconcileInterval number — seconds (> 0) Re-tune the periodic flow-reconciliation interval. Min clamp 100 ms.

Aliases log a one-time deprecation warning the first time they fire.


What you'll see come out

Sample Port 0 message (delta-compressed, after a data.totalFlow = 80 split across two valves):

{
  "topic": "valveGroupControl#VGC1",
  "payload": {
    "mode": "auto",
    "maxDeltaP": 1450,
    "atEquipment_measured_flow": 80,
    "atEquipment_predicted_flow": 80,
    "deltaMax_predicted_pressure": 1450
  }
}

Key shape: <position>_<variant>_<type> — same as MGC's key shape (inverse of rotatingMachine's per-measurement form). The output reflects the group aggregate, not per-valve snapshots; per-valve detail comes off each valve's own Port 0.

Field Meaning
mode Current operational mode (auto / virtualControl / fysicalControl / maintenance).
maxDeltaP Max delta-P across registered valves — refreshed whenever a child emits deltaPChange. Also surfaced as deltaMax_predicted_pressure via the measurement container.
atEquipment_measured_flow Total measured flow at the group inlet (from an upstream source's flow.measured.* event).
atEquipment_predicted_flow Sum of per-valve accepted flows after the Kv-share + residual pass.
deltaMax_predicted_pressure Max delta-P across the group, written via the measurement container at position delta / variant predicted / type pressure.

Flow-distribution loop — what one event does

When a data.totalFlow arrives (or an upstream source publishes flow.predicted.* / flow.measured.*), VGC re-distributes by Kv share:

flowchart LR
    src[data.totalFlow /<br/>upstream source event] --> upd[updateFlow<br/>predicted/measured atEquipment]
    upd --> avail[getAvailableValves<br/>state &ne; off/maintenance, kv > 0]
    avail --> solve[solveFlowDistribution<br/>share by Kv / totalKv]
    solve --> push[valve.updateFlow predicted<br/>downstream]
    push --> readback[read accepted from<br/>flow.predicted.downstream]
    readback --> residual[residual = target &minus; sum&#40;accepted&#41;]
    residual -->|residual &gt; tol & passes &lt; max| solve
    residual --> writeback[write flow.predicted.atEquipment<br/>= sum&#40;accepted&#41;]
    writeback --> dp[calcMaxDeltaP]
    dp --> emit[notifyOutputChanged]

Reconciliation defaults (flowReconciliation):

Field Default Notes
maxPasses 2 Max iterations of the residual-correction loop.
residualTolerance 0.001 Stops the loop when `

A valve is available if: state.getCurrentState() !== 'off' and !== 'maintenance', currentMode !== 'maintenance', and kv > 0. Unavailable valves are skipped and receive updateFlow('predicted', 0, 'downstream').

VGC has no FSM of its own — state semantics belong to the child valves. specificClass instantiates a state object internally and stamps it operational at boot for sequence dispatch; the group's only coordination loop is the Kv-share solver above.


Need more?

Page What you'll find
Reference — Contracts Topic registry, config schema, child-registration filters
Reference — Architecture Code map, flow-distribution loop, source aggregation, output ports
Reference — Examples Shipped flows, debug recipes
Reference — Limitations When not to use, known issues, open questions

EVOLV master wiki · Topology Patterns · Topic Conventions