# Reference — Limitations ![code-ref](https://img.shields.io/badge/code--ref-394a972-blue) > [!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 |