Files
valve/wiki/Home.md
znetsixe 87214788d2 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:11 +02:00

135 lines
7.8 KiB
Markdown

# valve
![code-ref](https://img.shields.io/badge/code--ref-8c2b2c0-blue) ![s88](https://img.shields.io/badge/S88-Equipment_Module-86bbdd) ![status](https://img.shields.io/badge/status-pending--review-orange)
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.md` and current source only.
---
## At a glance
| Thing | Value |
|:---|:---|
| What it represents | One actuated throttling valve &mdash; 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
```mermaid
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 &mdash; 3-minute demo
Import the basic example flow, deploy, and drive a single valve through a position move.
```bash
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.json` files are minimal stubs (one inject &rarr; valve &rarr; 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.
What to send after deploy (the topics map one-to-one to entries in [Reference &mdash; Contracts](Reference-Contracts#topic-contract)):
1. `set.mode = virtualControl` &mdash; lets the GUI source drive the valve (parent path is for grouped use).
2. `cmd.startup` &mdash; FSM runs `idle &rarr; starting &rarr; warmingup &rarr; operational`.
3. `set.position = {setpoint: 60}` (position %) &mdash; valve ramps from 0 to 60; state goes `operational &rarr; accelerating &rarr; operational`. Each position tick fires a Kv lookup + deltaP recompute.
4. `data.flow = {variant: 'measured', value: 25, position: 'downstream', unit: 'm3/h'}` &mdash; push flow so the hydraulic model has something to chew on. `delta_predicted_pressure` updates and `evt.deltaPChange` fires upward.
5. `cmd.shutdown` &mdash; if currently `operational`, the controller first ramps to position 0, then transitions `stopping &rarr; coolingdown &rarr; idle`.
> [!IMPORTANT]
> **GIF needed.** Demo recording of steps 1&ndash;5 with the live status badge. Save as `wiki/_partial-gifs/valve/01-basic-demo.gif`, target &le; 1&nbsp;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. Source allow-list per mode (defaults from `valve.json`). |
| `cmd.startup` | &mdash; | `{ source?: string }` | Run the configured `startup` sequence (default `[starting, warmingup, operational]`). |
| `cmd.shutdown` | &mdash; | `{ source?: string }` | Run `shutdown`. If currently `operational`, first ramps the valve to position 0, then transitions `stopping &rarr; coolingdown &rarr; idle`. |
| `cmd.estop` | `emergencystop`, `emergencyStop` | `{ source?: string, action?: string }` | Trigger an emergency stop &mdash; 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? }` &mdash; `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 &mdash; 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):
```json
{
"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>`** &mdash; 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 &mdash; FSM](Reference-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 &mdash; Contracts](Reference-Contracts) | Full topic contract, config schema, child registration filters |
| [Reference &mdash; Architecture](Reference-Architecture) | Code map, FSM, hydraulic model, lifecycle |
| [Reference &mdash; Examples](Reference-Examples) | Shipped example flows + debug recipes |
| [Reference &mdash; Limitations](Reference-Limitations) | When not to use, known limitations, open questions |
[EVOLV master wiki](https://gitea.wbd-rd.nl/RnD/EVOLV/wiki/Home) &middot; [Topology Patterns](https://gitea.wbd-rd.nl/RnD/EVOLV/wiki/Topology-Patterns) &middot; [Topic Conventions](https://gitea.wbd-rd.nl/RnD/EVOLV/wiki/Topic-Conventions)