Files
valveGroupControl/wiki/Reference-Limitations.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

151 lines
9.7 KiB
Markdown

# Reference &mdash; Limitations
![code-ref](https://img.shields.io/badge/code--ref-b20a573-blue)
> [!NOTE]
> Pending full node review (2026-05). Content reflects `CONTRACT.md` and current source only.
>
> What `valveGroupControl` does not do, current rough edges, and open questions. Open items live in `.agents/improvements/IMPROVEMENTS_BACKLOG.md` in the superproject.
---
## When you would not use this node
| Scenario | Use instead |
|:---|:---|
| A single valve under one upstream parent | `valve` &mdash; VGC adds coordination overhead for no benefit with one child. |
| Valves in **series** rather than parallel | The Kv-share solver assumes parallel branches sharing a common header pressure. Series valves need their own coordination model. |
| Upstream already publishes per-branch flow setpoints | Route the per-branch setpoints directly to each `valve` &mdash; VGC's group-level redistribution would discard the upstream split. |
| Curve-based pumps grouped on a manifold | `machineGroupControl` &mdash; that's the pump-side equivalent (BEP-aware optimizer + planner). VGC has no curves and no optimizer. |
---
## Legacy file-naming drift
The entry file and editor HTML still use the abbreviated `vgc.{js,html}` filenames:
| Path | Currently | Should be |
|:---|:---|:---|
| Entry file | `vgc.js` | `valveGroupControl.js` |
| Editor HTML | `vgc.html` | `valveGroupControl.html` |
Per the EVOLV folder-naming convention (`.claude/rules/node-architecture.md` and `CLAUDE.md`), every per-node file MUST match the folder name exactly &mdash; no abbreviations. The rename is queued for the next touch:
```
files to update in one commit:
- rename vgc.js → valveGroupControl.js
- rename vgc.html → valveGroupControl.html
- update package.json#node-red.nodes (currently maps "valveGroupControl": "vgc.js")
- update any require() / import paths
- update superproject submodule references
```
Sibling drift: `machineGroupControl/mgc.{js,html}` and `dashboardAPI/dashboardapi.{js,html}` are in the same state. See `.claude/refactor/MODULE_SPLIT.md`.
---
## Known limitations
### `set.position` is a no-op
`commands/handlers.setPosition` intentionally does nothing &mdash; the handler debug-logs the payload and returns. Per-valve positional override is reserved pending Phase 7 topic standardisation of valve setpoint payloads. The canonical topic and alias are reserved so callers can't squat them in the meantime.
Workaround: route the position setpoint to the individual `valve` node directly.
### `isValidActionForMode` is not implemented
The schema declares `mode.allowedActions.<mode>` (`statusCheck` / `execSequence` / `emergencyStop` / `valvePositionChange` / `totalFlowChange` / `valveDeltaPchange`), but `specificClass.handleInput` only consults `isValidSourceForMode`. The action allow-list is effectively dead config. Source contradiction with `CONTRACT.md` which implies action gating is active.
Workaround: rely on the source allow-list for now. TODO: implement the action check (mirror `rotatingMachine`'s pattern) OR strip `allowedActions` from the schema.
### `calculationMode` is not consulted
Schema field `calculationMode` (`low` / `medium` / `high`) is declared but ignored by both `specificClass` and `nodeClass`. The tick interval is fixed at `tickInterval = 1000 ms` and only re-tunable via `set.reconcileInterval`. TODO: wire it through or remove.
### `mode.allowedSources.maintenance` is undefined
The `maintenance` mode is enumerated in `mode.current` and `mode.allowedActions`, but `mode.allowedSources` only declares `auto` / `virtualControl` / `fysicalControl`. `isValidSourceForMode('any', 'maintenance')` returns `false` for every source &mdash; effectively monitoring-only. This may be intentional, but it's not stated explicitly in any contract.
### Residual solver assumes Kv share is a valid first estimate
Pathological valve curves (very non-linear Kv vs position) may need more passes than the default `maxPasses: 2` to reach `residualTolerance: 0.001`. The loop exits gracefully but `lastFlowSolve.residual` carries the gap; `flow.predicted.atEquipment` reads only the sum of what was accepted.
There is no editor field for `flowReconciliation` &mdash; it's a runtime-only object. TODO: expose `maxPasses` / `residualTolerance` in the editor.
### Cascaded VGC not test-covered
`valvegroupcontrol` is in `SOURCE_SOFTWARE_TYPES` and `_registerSource` accepts it, so VGC-on-VGC cascades are wired by the router. But:
- No integration tests cover the case.
- No production deployments use it.
- Fluid-contract propagation across two VGCs hasn't been validated.
Treat as experimental. Open question whether to remove the entry or harden it.
### Multi-source aggregation is "last write wins" on shared positions
If two upstream sources both publish `flow.predicted.atEquipment` to the same VGC, the later write replaces the earlier one in the measurement container. There is no merge / max / priority logic. In practice this is fine when one VGC has one upstream source; with two upstream sources the behaviour is well-defined but may surprise.
### Source flow events listen on both case variants
`SOURCE_FLOW_EVENTS` includes both `flow.predicted.atEquipment` AND `flow.predicted.atequipment`. A source that emits the event twice (defensive code) will trigger `updateFlow` twice per change &mdash; harmless because the second call writes the same value, but it doubles the recompute. Open question whether to canonicalise the event name at the source.
### No FSM &mdash; sequences depend on `state` being pre-stamped operational
`specificClass.configure()` does `this.state.stateManager.currentState = 'operational'` immediately so `executeSequence('startup')` etc. can run. This is unusual &mdash; other nodes go through `boot` to reach `operational`. The shortcut is intentional (VGC doesn't model the group as a stateful machine; sequences are pass-through to valves) but it means `state.getCurrentState()` always reads `operational` regardless of what the valves are doing.
### No `test/_output-manifest.md`
Per `.claude/rules/output-coverage.md` every node should ship an output manifest with populated + degraded tests for each Port-0 / 1 / 2 key. **Not yet produced** for VGC. Backfill tracked in `.agents/improvements/IMPROVEMENTS_BACKLOG.md`.
### Wiki source-of-truth contradictions found during this review
| Source A | Source B | Issue | TODO |
|:---|:---|:---|:---|
| `CONTRACT.md` `set.mode` payload "`auto` / manual" | Schema enum `auto` / `virtualControl` / `fysicalControl` / `maintenance`; `setMode` validates against schema | `CONTRACT.md` prose understates mode count | Update `CONTRACT.md`. |
| Schema `mode.allowedActions` | `specificClass` only consults `isValidSourceForMode` | Action allow-list dead config | Implement or remove (see above). |
| Schema `calculationMode` | `specificClass` / `nodeClass` never read it | Dead config | Implement or remove. |
| `CONTRACT.md` &sect; Children: `valve`, `machine / rotatingmachine / machinegroup / machinegroupcontrol / pumpingstation / valvegroupcontrol` | `specificClass.SOURCE_SOFTWARE_TYPES` lists post-canonicalisation names only (`machine`, `machinegroup`, `pumpingstation`, `valvegroupcontrol`) | Pre-canonical aliases (`rotatingmachine`, `machinegroupcontrol`) are accepted by the router because BaseDomain normalises them &mdash; contract text remains correct in spirit | None &mdash; informational. |
| `examples/README.md` lists 3 flows with stub descriptions | Actual flow content not validated against current source | Tier labelling missing; live-deploy validation outstanding | Backfill validation; rename to Tier-1/2/3 convention. |
---
## Open questions (tracked)
| Question | Where it lives |
|:---|:---|
| Phase 7 standardisation of valve setpoint payloads (unblocks `set.position`) | `OPEN_QUESTIONS.md` Phase 7 |
| Should `flowReconciliation.maxPasses` / `residualTolerance` be editor-configurable? | Internal &mdash; not yet ticketed |
| Cascaded `valvegroupcontrol` as upstream source &mdash; harden or remove? | Internal |
| Multi-source priority / merge strategy for shared positions | Internal |
| Wire `calculationMode` through or strip from schema | Internal |
| Implement `isValidActionForMode` or strip `allowedActions` from schema | Internal |
| Output-coverage backfill (`test/_output-manifest.md` + populated/degraded tests) | `.agents/improvements/IMPROVEMENTS_BACKLOG.md` |
| Rename `vgc.{js,html}` &rarr; `valveGroupControl.{js,html}` | `.claude/refactor/MODULE_SPLIT.md` |
| Validate example flows against live Node-RED; rename to Tier-1/2/3 convention | Internal |
---
## Migration notes
### From `setpoint` topic name (pre-canonical)
The old `setpoint` alias for `set.position` still works but logs a one-time deprecation warning. Switch to `set.position` &mdash; though note the handler is currently a no-op (see above).
### From `setMode` / `registerChild` / `execSequence` / `totalFlowChange` / `emergencyStop` / `emergencystop` / `setReconcileInterval` aliases
Every legacy alias emits a one-time deprecation warning. Switch to the canonical topic names listed in [Contracts](Reference-Contracts#topic-contract).
---
## Related pages
| Page | Why |
|:---|:---|
| [Home](Home) | Intuitive overview |
| [Reference &mdash; Contracts](Reference-Contracts) | Topic + config + child filters (alias map) |
| [Reference &mdash; Architecture](Reference-Architecture) | Code map, flow-distribution loop, source aggregation |
| [Reference &mdash; Examples](Reference-Examples) | Shipped flows + debug recipes |
| [machineGroupControl &mdash; Limitations](https://gitea.wbd-rd.nl/RnD/machineGroupControl/wiki/Reference-Limitations) | Sibling Unit-level controller's known limitations |
| [valve wiki](https://gitea.wbd-rd.nl/RnD/valve/wiki/Home) | The child node VGC coordinates |