rotatingMachine

Node-RED custom node for individual rotating-machine control — pumps, compressors, blowers. Part of the EVOLV wastewater-automation platform developed by R&D at Waterschap Brabantse Delta.

Models a single asset with an S88 state machine, curve-backed flow/power prediction, and parent/child registration for orchestration by machineGroupControl or pumpingStation.

Install

In a Node-RED user directory:

cd ~/.node-red
npm install github:gitea.wbd-rd.nl/RnD/rotatingMachine

Or consume the whole platform:

npm install github:gitea.wbd-rd.nl/RnD/EVOLV

Run node-red and the node appears in the editor palette under the EVOLV category.

Quick start

Drop a rotatingMachine onto a flow, fill the Asset menu (supplier, model — must match a curve in generalFunctions/datasets), and wire three debug nodes to the three output ports. Inject these in order:

Topic Payload Effect
setMode "virtualControl" allow manual commands
simulateMeasurement {type:"pressure",position:"upstream",value:200,unit:"mbar"} seed upstream pressure
simulateMeasurement {type:"pressure",position:"downstream",value:1100,unit:"mbar"} seed downstream pressure
execSequence {source:"GUI",action:"execSequence",parameter:"startup"} start the machine
execMovement {source:"GUI",action:"execMovement",setpoint:60} ramp to 60 % controller position
execSequence {source:"GUI",action:"execSequence",parameter:"shutdown"} shut down

Ready-made example flows are in examples/:

  • 01 - Basic Manual Control.json — inject-only smoke test
  • 02 - Integration with Machine Group.json — parent/child registration with machineGroupControl
  • 03 - Dashboard Visualization.json — FlowFuse dashboard with live charts

Import via Node-RED Import ▸ Examples ▸ EVOLV.

Input topics

Topic Payload Notes
setMode "auto" | "virtualControl" | "fysicalControl" mode gates which sources may command the machine
execSequence {source, action:"execSequence", parameter} — parameter: "startup" | "shutdown" | "entermaintenance" | "exitmaintenance" runs an S88 sequence
execMovement {source, action:"execMovement", setpoint} — setpoint in controller % moves controller position
flowMovement {source, action:"flowMovement", setpoint} — setpoint in configured flow unit converts flow → controller %, then moves
emergencystop {source, action:"emergencystop"} aborts any active movement and drives state to off
simulateMeasurement {type, position, value, unit} — type: pressure | flow | temperature | power dashboard-side measurement injection
showWorkingCurves diagnostic — reply on port 0
CoG diagnostic — reply on port 0

Topic case is preserved; sequence parameter and action names are normalized to lowercase internally (so "emergencyStop", "EmergencyStop", "emergencystop" all work).

Output ports

Port Label Payload
0 process delta-compressed process payload; keys are type.variant.position.childId (e.g. flow.predicted.downstream.default). Consumers must cache and merge each tick.
1 dbase InfluxDB line-protocol telemetry
2 parent {topic:"registerChild", payload:<nodeId>, positionVsParent} emitted once on deploy for parent group/station registration

State machine

idle ─► starting ─► warmingup ─► operational ◄─┐
                                      ▲          │
                                      │          ▼
                                      │    accelerating / decelerating
                                      │          │
                                      └──────────┘
                                      │
                                      ▼
                                  stopping ─► coolingdown ─► idle
                                      │
                                      ▼
                                  emergencystop ─► off
  • warmingup and coolingdown are protected — new commands cannot abort them.
  • accelerating and decelerating are interruptible. If a shutdown or emergencystop sequence is requested mid-ramp, the active movement is aborted automatically and the sequence proceeds once the FSM has returned to operational.
  • Timings come from the Startup / Warmup / Shutdown / Cooldown fields in the editor (seconds).

Predictions

Flow and power outputs are curve-backed predictions driven by the controller position and the differential pressure across the machine. Inject both upstream and downstream pressures for best accuracy. With only one side present the node warns and falls back to the available side. With no pressure, predictions use the minimum pressure dimension (flow/power will look unrealistic).

The active curve is selected from machineCurve.nq and machineCurve.np, keyed by the closest matching pressure level. Curve units are declared in the Asset menu (default: mbar, m³/h, kW, %).

Units

Canonical units are used internally (Pa / m³/s / W / K). All inputs and outputs convert at the boundary via the configured unit for each measurement type. The speed field in the editor is a ramp rate in controller-position units per second (so speed: 1 → 1 %/s → a setpoint of 60 % from idle completes in ~60 s).

Testing

cd nodes/rotatingMachine
npm test

79 tests cover construction, mode/input routing, config loading, sequences, emergency stop, shutdown, interruptible movement, movement lifecycle, prediction health, pressure initialization, CoolProp efficiency, registration, negative/null guards, output format, listener cleanup. Run the full suite in ~2 seconds.

For end-to-end verification, see ../../docker-compose.yml — a Docker stack (Node-RED + InfluxDB + Grafana) that hosts the live node. The scripts in ../../../memory/ and examples/ document the E2E protocol used for production-readiness benchmarks.

Production status

Last reviewed 2026-04-13 — trial-ready. See the project memory file node_rotatingMachine.md for the latest benchmarks, known caveats, and wishlist.

License

SEE LICENSE. Author: Rene De Ren, Waterschap Brabantse Delta R&D.

Description
No description provided
Readme 382 KiB
Languages
JavaScript 85%
Python 8.8%
HTML 6.2%