Refactor of valveGroupControl to use the platform infrastructure (BaseDomain, BaseNodeAdapter, ChildRouter, commandRegistry, statusBadge). Extracts concerns into focused modules per .claude/refactor/MODULE_SPLIT.md generic template. Tests stay green; CONTRACT.md generated; legacy aliases preserved. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
68 lines
3.9 KiB
Markdown
68 lines
3.9 KiB
Markdown
# valveGroupControl — Contract
|
|
|
|
Hand-maintained for Phase 6; the `## Inputs` table is generated from
|
|
`src/commands/index.js` (see Phase 9 generator). Keep ≤ 80 lines.
|
|
|
|
## Inputs (msg.topic on Port 0)
|
|
|
|
| Canonical | Aliases (deprecated) | Payload | Effect |
|
|
|---|---|---|---|
|
|
| `set.mode` | `setMode` | `string` — one of `auto`, `virtualControl`, `fysicalControl`, `maintenance` | Switches the control strategy via `source.setMode(payload)`. |
|
|
| `set.position` | `setpoint` | `any` | Reserved for future per-valve positional override; currently a debug-logged no-op pending Phase 7. |
|
|
| `child.register` | `registerChild` | `string` — the child node's Node-RED id | Resolves the child via `RED.nodes.getNode` and registers it through `childRegistrationUtils.registerChild(childObj.source, msg.positionVsParent)`. |
|
|
| `cmd.execSequence` | `execSequence` | `{ source, action, parameter }` | Forwards to `source.handleInput(source, action, parameter)`. |
|
|
| `data.totalFlow` | `totalFlowChange` | numeric, `{ value, position?, variant?, unit? }`, or `{ source, action, ... }` | Updates total measured/predicted flow at the configured position; drives `calcValveFlows` to re-distribute across valves. |
|
|
| `cmd.emergencyStop` | `emergencyStop`, `emergencystop` | optional `{ source }` | Runs the `emergencystop` sequence via `handleInput`. |
|
|
| `set.reconcileInterval` | `setReconcileInterval` | numeric — seconds (> 0) | Re-tunes the periodic flow-reconciliation interval. Min clamp 100 ms. |
|
|
|
|
Aliases log a one-time deprecation warning the first time they fire.
|
|
|
|
## Outputs (msg.topic on Port 0/1/2)
|
|
|
|
- **Port 0 (process):** `msg.topic = config.general.name`. Payload built by
|
|
`outputUtils.formatMsg(..., 'process')` from `getOutput()` — delta-compressed
|
|
(only changed fields are emitted). Output keys follow
|
|
`<position>_<variant>_<type>` plus `mode` and `maxDeltaP`.
|
|
- **Port 1 (InfluxDB telemetry):** same shape as Port 0, formatted with the
|
|
`'influxdb'` formatter.
|
|
- **Port 2 (registration):** at startup the node sends one
|
|
`{ topic: 'child.register', payload: <node.id>, positionVsParent }`
|
|
to the upstream parent.
|
|
|
|
## Events emitted by `source.emitter` / `source.measurements.emitter`
|
|
|
|
- `output-changed` (`source.emitter`) — public output state shifted; the
|
|
adapter listens and pushes Ports 0/1.
|
|
- `fluidContractChange` (`source.emitter`) — group-level fluid contract
|
|
(status / serviceType / sourceCount) changed. Parents (e.g. an upstream
|
|
valve registering this VGC as its parent) subscribe to react.
|
|
- `reconcileIntervalChange` (`source.emitter`) — emitted by
|
|
`setReconcileIntervalSeconds`; the adapter restarts the tick loop.
|
|
- `flow.predicted.atequipment` (`source.measurements.emitter`) — total
|
|
predicted group flow (sum of per-valve assigned flows).
|
|
- `pressure.predicted.deltaMax` (`source.measurements.emitter`) — max
|
|
delta-P across registered valves.
|
|
|
|
The exact set is data-driven by which sources/valves register and what
|
|
they publish; downstream consumers subscribe by event name.
|
|
|
|
## Children registered by this node
|
|
|
|
valveGroupControl accepts two child classes through the
|
|
`childRegistrationUtils` handshake:
|
|
|
|
- `valve` — an individual valve. Stored in `source.valves[id]`. VGC binds
|
|
to the child's `positionChange` (via `child.state.emitter`) and
|
|
`deltaPChange` (via `child.emitter`) events to re-distribute flow and
|
|
re-compute group max delta-P.
|
|
- `machine` / `rotatingmachine` / `machinegroup` / `machinegroupcontrol` /
|
|
`pumpingstation` / `valvegroupcontrol` — an upstream **source**. Stored
|
|
in `source.sources[id]`. VGC subscribes to the source's
|
|
`flow.predicted.*` / `flow.measured.*` events to drive `updateFlow`,
|
|
and reads the child's `getFluidContract()` (if present) plus
|
|
`fluidContractChange` events to aggregate the group's upstream service
|
|
type (`getFluidContract()` exposes the resolved view).
|
|
|
|
Position labels accepted from children are `upstream`, `downstream`,
|
|
`atEquipment` (and case variants — normalised internally).
|