Consumer half of the abort-token mechanism added in generalFunctions
state.js. executeSequence captures host.state.sequenceAbortToken at
entry, then re-checks before every state transition and after the
optional ramp-down. If MGC (or any external caller) bumps the token
mid-sequence, the loop bails out cleanly — no more barge-through where
a pre-empted shutdown advances through stopping → coolingdown after a
fresh demand has already engaged the pump.
Without this the MGC rendezvous planner can't reliably re-dispatch a
pump that's mid-shutdown: the new flowmovement claims the gate, but
the old shutdown's for-loop keeps running on microtasks and steps the
FSM into idle/off underneath it.
Also: wiki regen following the same visual-first 14-section template as
the other EVOLV nodes — Reference-{Architecture,Contracts,Examples,
Limitations}.md split with _Sidebar.md index.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
106 lines
6.9 KiB
Markdown
106 lines
6.9 KiB
Markdown
# Reference — Limitations
|
|
|
|

|
|
|
|
> [!NOTE]
|
|
> What `rotatingMachine` 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 passive non-return / check valve (no motor) | `valve` — no curve, no FSM-driven motor. |
|
|
| A valve actuator (motorised, no characteristic curve) | `valve` (and `valveGroupControl` if grouped). |
|
|
| A group of 2 + pumps load-sharing on a header | `machineGroupControl` — instantiate this as a child. |
|
|
| A curve-less asset | Predictions degrade to zero, drift becomes meaningless, status badge falls into `predictionQuality: 'invalid'`. There is no fallback model. |
|
|
| A compressor with significant gas compressibility | Predictor uses an incompressible-flow curve; output is qualitatively right but quantitatively biased. Tracked. |
|
|
|
|
---
|
|
|
|
## Known limitations
|
|
|
|
### Single-side pressure degrades silently
|
|
|
|
`pressureSelector.getMeasuredPressure` accepts only-upstream or only-downstream readings as a fallback when the differential is unknown. It logs a warn (`Using downstream pressure only for prediction: …. Prediction accuracy is degraded; inject upstream pressure too.`) but proceeds. The predictor uses the absolute pressure as a surrogate differential, which can materially bias flow predictions under varying suction conditions. The warn is one-shot per state transition, not per tick — it can be missed in long-running deployments. Tracked.
|
|
|
|
### Multi-parent registration
|
|
|
|
`childRegistrationUtils` accepts registration under multiple parents. The pump emits child-register messages to each, and parents listen in parallel. Teardown ordering (parent gone first vs pump gone first) is not test-covered; observed behaviour in production is "fine, mostly". If you wire one pump to two MGCs and remove one MGC mid-deployment, the pump's listener set may keep a stale reference. Open question.
|
|
|
|
### `data.simulate-measurement` doesn't clear stale values
|
|
|
|
If you toggle a virtual pressure off (stop sending the inject), the last-known value persists in the MeasurementContainer. There is no TTL and no explicit clear topic. Workaround: send `value: null` or `0` explicitly. Tracked.
|
|
|
|
### `execSequence` legacy umbrella
|
|
|
|
The `execSequence` topic (with `payload.action = "startup" | "shutdown"`) is kept alive for legacy flows. The handler demuxes to the canonical topic; both emit a one-time deprecation warning. Scheduled for removal in a later phase. Use `cmd.startup` / `cmd.shutdown` instead.
|
|
|
|
### Drift confidence collapses on long pressure-source outages
|
|
|
|
`predictionHealth.refresh` reduces `predictionConfidence` to 0 when no pressure source has produced a reading in > 30 s. The quality string flips to `invalid` — downstream consumers should treat this as "predictor is offline, ignore values" rather than "predictor is broken". The recovery is automatic: as soon as a pressure measurement lands, health climbs back. Open question whether to model this as a discrete "stale" quality state instead.
|
|
|
|
### `state` stays in residue after a routine abort
|
|
|
|
`abortCurrentMovement` with default options (the kind MGC fires) does **not** auto-transition the FSM back to `operational`. The pump stays parked in `accelerating` / `decelerating` until the next `moveTo` arrives — at which point the residue handler in `state.moveTo` runs the transition synchronously. By design (a previous version auto-transitioned and created a bounce loop where every tick aborted, returned, re-moved, aborted again). See the comment in `state.js` `moveTo` line 76 for the historical detail.
|
|
|
|
### Editor cosmetics don't reflect `asset` derivation
|
|
|
|
The editor form still has visual sections for supplier / category / type even though the registry derives them. They're read-only and informational; some fields render as blank until you select a model. Cosmetic; the registry is the source of truth.
|
|
|
|
---
|
|
|
|
## Open questions (tracked)
|
|
|
|
| Question | Where it lives |
|
|
|:---|:---|
|
|
| Should the predictor use an explicit "stale" quality state instead of collapsing to `invalid` when pressure data dries up? | Internal — not yet ticketed |
|
|
| Multi-parent teardown ordering | Internal |
|
|
| Add an explicit `data.clear-simulated-measurement` topic for sim cleanup | Internal |
|
|
| Compressor / gas-flow curve handling | Internal (long-term) |
|
|
| Phase 7 removal of `execSequence` umbrella + legacy aliases | Internal |
|
|
| Curve loader robustness: warn / refuse mismatched curve units instead of best-effort normalising | `OPEN_QUESTIONS.md` (rotatingMachine entry) |
|
|
|
|
---
|
|
|
|
## Migration notes
|
|
|
|
### From pre-AssetResolver
|
|
|
|
Old flows saved with `supplier`, `category`, or `assetType` fields will throw on deploy:
|
|
|
|
```
|
|
rotatingMachine: legacy asset field(s) [supplier, category] are saved on this node.
|
|
After the AssetResolver refactor these are derived from the model id.
|
|
Open the node in the editor, re-select the model, and save to migrate.
|
|
```
|
|
|
|
The fix is mechanical: open each rotatingMachine node, re-pick the model from the asset menu, save. No data is lost — the registry has the same supplier / category / type the old flow carried.
|
|
|
|
### From pre-sequence-abort-token
|
|
|
|
Before 2026-05-15 a mid-decel re-engage was a race — sometimes the shutdown's for-loop won and parked the pump at `idle` with an orphaned `delayedMove`. With the `sequenceAbortToken` mechanism in `state.js` + `sequenceController.js` (from `394a972` onward), the new-dispatch's `abortCurrentMovement` always wins: the shutdown's for-loop breaks out before its next transition.
|
|
|
|
If you have an integration test that relied on the older "shutdown always completes" behaviour, expect to see `Sequence 'shutdown' interrupted ... by external abort` warnings instead. That's the intended new state.
|
|
|
|
### From `setpoint` topic name (pre-canonical)
|
|
|
|
The old `setpoint` topic without a `set.` prefix has been retired. Use `set.setpoint` (alias `execMovement`) for control-% setpoints and `set.flow-setpoint` (alias `flowMovement`) for flow setpoints.
|
|
|
|
### From `execMovement` payload shape change
|
|
|
|
Legacy payloads were `{source, action: "execMovement", setpoint: number}`. The current shape is the same minus `action` (the handler dispatches via topic). Both are accepted.
|
|
|
|
---
|
|
|
|
## Related pages
|
|
|
|
| Page | Why |
|
|
|:---|:---|
|
|
| [Home](Home) | Intuitive overview |
|
|
| [Reference — Contracts](Reference-Contracts) | Topic + config + child filters (alias map at the end) |
|
|
| [Reference — Architecture](Reference-Architecture) | Code map, FSM (including sequence-abort token), prediction + drift |
|
|
| [Reference — Examples](Reference-Examples) | Shipped flows + debug recipes |
|
|
| [machineGroupControl — Limitations](https://gitea.wbd-rd.nl/RnD/machineGroupControl/wiki/Reference-Limitations) | Where the parent's planner currently bypasses priority mode |
|