docs: rotatingMachine trial-ready — submodule bumps, wiki manual, session note
Some checks failed
CI / lint-and-test (push) Has been cancelled
Some checks failed
CI / lint-and-test (push) Has been cancelled
Bumps: - nodes/generalFunctions 024db55 -> 75d16c6 (FSM abort recovery + schema sync) - nodes/rotatingMachine 07af7ce -> 17b8887 (interruptible sequences, dual-curve tests, rewritten README) Wiki: - wiki/manuals/nodes/rotatingMachine.md — new user manual covering inputs, outputs, state machine, supported curves, and troubleshooting. - wiki/sessions/2026-04-13-rotatingMachine-trial-ready.md — session note with findings, fixes, test additions, and dual-curve E2E results. - wiki/index.md — link both and bump updated date. Status: rotatingMachine is now trial-ready. 91/91 unit tests green, live Docker E2E verifies shutdown/emergency-stop during ramps and prediction behaviour across both shipped pump curves (hidrostal-H05K-S03R, hidrostal-C5-D03R-SHN1). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
134
wiki/sessions/2026-04-13-rotatingMachine-trial-ready.md
Normal file
134
wiki/sessions/2026-04-13-rotatingMachine-trial-ready.md
Normal file
@@ -0,0 +1,134 @@
|
||||
---
|
||||
title: "Session: rotatingMachine trial-ready — FSM interruptibility, config schema, UX fixes"
|
||||
created: 2026-04-13
|
||||
updated: 2026-04-13
|
||||
status: proven
|
||||
tags: [session, rotatingMachine, state-machine, docker, e2e]
|
||||
---
|
||||
|
||||
# 2026-04-13 — rotatingMachine trial-ready
|
||||
|
||||
## Scope
|
||||
|
||||
Honest review + production-hardening pass on `rotatingMachine`. Fixes landed on top of the 2026-04-07 hardening and are verified against a Docker-hosted Node-RED stack.
|
||||
|
||||
## Findings (before fixes)
|
||||
|
||||
From a live E2E run captured via the Node-RED debug websocket (`/comms`):
|
||||
|
||||
- **Clean startup→operational→shutdown→idle path** works to spec: 3 s starting + 2 s warmup + 3 s stopping + 2 s cooldown, matching config exactly.
|
||||
- **Tick cadence:** 1000 ms (min 1000, max 1005, avg 1002.5).
|
||||
- **Predictions** gate correctly on pressure injection; at 900 mbar Δp the hidrostal-H05K-S03R curve yields a monotonic flow/power response.
|
||||
- **State machine FSM** *rejects* `stopping`/`coolingdown`/`idle` transitions while the machine is in `accelerating`/`decelerating`, leaving a shutdown command silently dropped. Log symptom: `Invalid transition from accelerating to stopping. Transition not executed.`
|
||||
- **Sequence `emergencyStop` not defined** warn appears when a parent orchestrator with the capital-S casing (e.g. `machineGroupControl` config) forwards the sequence name.
|
||||
- **Config validator strips** `functionality.distance` and top-level `output` that `buildConfig` adds; every deploy prints removal warnings.
|
||||
- Cosmetic: typo "acurate" in single-side pressure warn; editor lacks unit hints for `speed` / `startup` / etc.
|
||||
|
||||
## Fixes
|
||||
|
||||
### 1. Interruptible movement (`generalFunctions/src/state/state.js`)
|
||||
|
||||
`moveTo`'s `catch` block now detects `Movement aborted` / `Transition aborted` errors and transitions the FSM back to `operational`, unblocking subsequent sequence transitions. A new `movementAborted` event is emitted for observability.
|
||||
|
||||
### 2. Auto-abort on shutdown/emergency-stop (`rotatingMachine/src/specificClass.js`)
|
||||
|
||||
`executeSequence` now:
|
||||
|
||||
- Normalizes the sequence name to lowercase (defensive against parent callers using mixed case).
|
||||
- When `shutdown` or `emergencystop` is requested from `accelerating`/`decelerating`, calls `state.abortCurrentMovement(...)` and waits up to 2 s for the FSM to return to `operational` via the new `_waitForOperational(timeoutMs)` helper that listens on the state emitter.
|
||||
|
||||
### 3. Config schema sync (`generalFunctions/src/configs/rotatingMachine.json`)
|
||||
|
||||
Added to the schema:
|
||||
|
||||
- `functionality.distance`, `.distanceUnit`, `.distanceDescription` (produced by the HTML editor).
|
||||
- Top-level `output.process` / `output.dbase` (produced by `buildConfig`).
|
||||
|
||||
Also reverted an overly broad `buildConfig` addition to only emit `distance` (not `distanceUnit`/`distanceDescription`) so other nodes aren't forced to add these to their schemas.
|
||||
|
||||
### 4. UX polish
|
||||
|
||||
- Fixed typo "acurate" → "accurate" in the single-side pressure warning, plus made the message actionable.
|
||||
- Added unit hints to Reaction Speed / Startup / Warmup / Shutdown / Cooldown fields in the editor.
|
||||
- Expanded the Node-RED help panel with a topic reference, state diagram, prediction rules, and port documentation.
|
||||
|
||||
## Tests added
|
||||
|
||||
`test/integration/interruptible-movement.integration.test.js` — three regression tests for the FSM fix:
|
||||
|
||||
- `shutdown during accelerating aborts the move and reaches idle`
|
||||
- `emergency stop during accelerating reaches off`
|
||||
- `executeSequence accepts mixed-case sequence names`
|
||||
|
||||
`test/integration/curve-prediction.integration.test.js` — 12 parametrized tests across both shipped pump curves (`hidrostal-H05K-S03R` and `hidrostal-C5-D03R-SHN1`):
|
||||
|
||||
- Curve loader returns nq + np with matching pressure slices.
|
||||
- Predicted flow and power at mid-pressure / mid-ctrl are finite and inside the curve envelope.
|
||||
- Flow is monotonically non-decreasing across a ctrl sweep at fixed pressure.
|
||||
- Flow decreases (or stays level) when pressure rises at fixed ctrl — centrifugal-pump physics.
|
||||
- CoG / NCog are computed, finite, and inside [0, 100] controller units.
|
||||
- Reverse predictor (flow → ctrl via reversed nq) round-trips within 10 % of the known controller position.
|
||||
|
||||
`test/e2e/curve-prediction-benchmark.py` + `test/e2e/README.md` — live Dockerized Node-RED benchmark that deploys one rotatingMachine per curve and records a (pressure × ctrl) sweep.
|
||||
|
||||
Full unit suite: **91/91 passing** (was 76/76 on the morning review).
|
||||
|
||||
## E2E verification (Dockerized Node-RED)
|
||||
|
||||
Via `/tmp/rm_e2e_verify.py` — deploys the example flow to `docker compose`-hosted Node-RED, drives it via `POST /inject/:id`, captures port-output via `ws://localhost:1880/comms`.
|
||||
|
||||
| Scenario | Observed state sequence | Pass? |
|
||||
|---|---|---|
|
||||
| Shutdown fired while `accelerating` | starting → warmingup → operational → accelerating → decelerating → stopping → coolingdown → **idle** | ✅ |
|
||||
| Emergency stop fired while `accelerating` | starting → warmingup → operational → accelerating → **off** | ✅ |
|
||||
| Clean startup → shutdown (regression) | starting → warmingup → operational → stopping → coolingdown → idle | ✅ |
|
||||
|
||||
Container log scan over a 3-minute window:
|
||||
|
||||
- `Unknown key` warns: 0 (was 6+ per deploy)
|
||||
- `acurate` typo: 0 (was 2)
|
||||
- `Invalid transition from accelerating/decelerating to ...` errors: 0 (was 3+)
|
||||
- `Sequence '...' not defined`: 0 (was 1)
|
||||
|
||||
### Dual-curve prediction sweep
|
||||
|
||||
Via `nodes/rotatingMachine/test/e2e/curve-prediction-benchmark.py`. Deploys two live rotatingMachines, one per pump curve, and runs a (pressure × ctrl) sweep per pump. Each pump is tested only inside its own curve envelope.
|
||||
|
||||
| Pump | Pressures swept (mbar) | Ctrl setpoints (%) | Samples in envelope | Flow monotonic | Flow observed (m³/h) | Power observed (kW) |
|
||||
|---|---|---|---|---|---|---|
|
||||
| hidrostal-H05K-S03R | 700 / 2300 / 3900 | 20 / 40 / 60 / 80 | 12/12 ✅ | ✅ | 10.3 – 208.3 | 12.3 – 50.3 |
|
||||
| hidrostal-C5-D03R-SHN1 | 400 / 1700 / 2900 | 20 / 40 / 60 / 80 | 12/12 ✅ | ✅ | 8.7 – 45.6 | 0.7 – 13.0 |
|
||||
|
||||
Inverse-pressure monotonicity (centrifugal-pump physics) also verified: for both pumps, flow at the highest pressure slice is strictly lower than flow at the lowest pressure slice for the same ctrl.
|
||||
|
||||
**Known limitation** captured in the memory file: extrapolating pressure *below* the curve's minimum slice produces nonsensical flow values (e.g. H05K at 400 mbar ctrl=20% predicts ~30 000 m³/h vs envelope max 227 m³/h). Upstream `measurement` nodes are expected to clamp sensors to realistic ranges; rotatingMachine itself does not.
|
||||
|
||||
Separately, the C5 curve still exhibits the previously-documented power non-monotonicity at p=1700 mbar (sparse-data spline artefact noted in the 2026-04-07 session); this is compensated by the group-optimization marginal-cost refinement loop.
|
||||
|
||||
## Files changed
|
||||
|
||||
```
|
||||
nodes/generalFunctions/src/state/state.js # abort recovery
|
||||
nodes/generalFunctions/src/configs/index.js # buildConfig trim
|
||||
nodes/generalFunctions/src/configs/rotatingMachine.json # schema sync
|
||||
nodes/rotatingMachine/src/specificClass.js # exec + typo
|
||||
nodes/rotatingMachine/rotatingMachine.html # UX hints + help
|
||||
nodes/rotatingMachine/test/integration/interruptible-movement.integration.test.js # +3 tests (FSM)
|
||||
nodes/rotatingMachine/test/integration/curve-prediction.integration.test.js # +12 tests (dual curve)
|
||||
nodes/rotatingMachine/test/e2e/curve-prediction-benchmark.py # new E2E benchmark
|
||||
nodes/rotatingMachine/test/e2e/README.md # benchmark docs
|
||||
nodes/rotatingMachine/README.md # rewrite
|
||||
```
|
||||
|
||||
## Production readiness
|
||||
|
||||
Status: **trial-ready**. The caveats flagged in the 2026-04-13 memory file (`node_rotatingMachine.md`) are resolved. Remaining items are in the wishlist (interruptible curve validation feedback, domain review of ctrl≈0% + backpressure flow prediction, opt-in full-snapshot port-0 mode, per-machine `/health` endpoint).
|
||||
|
||||
## Verification command
|
||||
|
||||
```bash
|
||||
cd /mnt/d/gitea/EVOLV
|
||||
docker compose up -d nodered influxdb
|
||||
cd nodes/rotatingMachine && npm test
|
||||
python3 /tmp/rm_e2e_verify.py # end-to-end smoke
|
||||
```
|
||||
Reference in New Issue
Block a user