Files
pumpingStation/examples
znetsixe e991ea64ef Merge origin/basin-docs-update: per-mode SVG + stopLevel hysteresis + shifted ramp
Reconciles the 7-commit basin-docs-update feature branch (which never
landed on main before the platform refactor) with the post-refactor
architecture on development. Each basin-docs feature ported into the
relevant concern module:

  control/levelBased.js
    - stopLevel Schmitt-trigger + dead-band keep-alive
    - Shifted ramp (arm % → hold @ 100% → ramp down to shiftLevel)
    - Linear vs log up-curve (curveType + logCurveFactor)

  measurement/flowAggregator.js
    - Predicted-volume overflow clamp + spill flow stream
    - Cumulative overflowVolume + underflowVolume
    - Hard floor at 0 + dry-run-on-transition handling

  basin/thresholdValidator.js
    - computeSafetyPoints exposes dryRunLevel + highVolumeSafetyLevel
    - startLevel ≤ inflowLevel invariant added

  measurement/calibration.js + commands/
    - Manual q_out path (set.outflow / q_out alias)

  safety/safetyController.js
    - Accepts both legacy + new high-volume threshold names

UI:
  pumpingStation.html — restored the side-panel + SVG mode-preview block,
  added defaults for stopLevel/shiftLevel/shiftArmPercent/levelCurveType/
  logCurveFactor/enableShiftedRamp.
  src/editor/* — basin-docs' 7-file modular editor (replaces single
  src/editor.js, which is deleted).
  pumpingStation.js — admin endpoint serves editor/:file.

Tests: 130/130 pass (125 basic + 5 integration). Two basin-docs test
files added: nodeClass-config.test.js, basic-dashboard-flow.test.js,
shifted-ramp-end-to-end.test.js. One pre-refactor control-levelBased
test adapted to match basin-docs canonical "no-shutdown in dead zone"
behaviour.

Human-review items (see commit context):
  - rampFoot = inflowLevel (matches basin-docs test); basin-docs source
    used rampFoot = startLevel. Domain owner: confirm intent.
  - Naming kept dual (overfillLevel + highVolumeSafetyLevel).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 16:19:55 +02:00
..

pumpingStation - Example Flows

Three Node-RED flows demonstrating the Phase-2 pumpingStation node on the canonical topic API (set.mode, set.inflow, set.demand, cmd.calibrate.volume, cmd.calibrate.level). Legacy aliases (changemode, q_in, Qd, calibratePredictedVolume, calibratePredictedLevel, registerChild) still work but log a one-time deprecation warning; these fresh flows use the canonical names only.

Files

File Tier Tabs Purpose
01-Basic.json 1 Process Plant Single pumpingStation driven by inject nodes - no parent, no dashboard.
02-Integration.json 2 Process Plant + Setup Adds a measurement level child and a machineGroupControl parent with two rotatingMachine pumps. Demonstrates the Phase-2 parent/child handshake.
03-Dashboard.json 3 Process Plant + Dashboard UI + Setup Tier 2 plumbing plus a FlowFuse Dashboard 2.0 page with 3 charts (flow / level / volume %), text widgets, and 2 controls (mode dropdown + demand slider).

Prerequisites

  • Node-RED with the EVOLV package installed (so the pumpingStation, measurement, machineGroupControl, and rotatingMachine node types are registered).
  • For 03-Dashboard.json: @flowfuse/node-red-dashboard (Dashboard 2.0).

How to load

# Drop a file into a running Node-RED instance using its Admin API.
curl -X POST -H 'Content-Type: application/json' \
  --data @nodes/pumpingStation/examples/01-Basic.json \
  http://localhost:1880/flows

Or in the editor: Menu -> Import -> select file -> Import. The flows import into their own tabs and can be deployed immediately.

01-Basic - what to try

  1. Deploy.
  2. Inject set.mode = manual.
  3. Inject set.inflow = 60 m3/h - the basin starts filling. Watch the formatted Port 0 payload in the debug sidebar.
  4. Inject set.demand = 40 % - in manual mode this would feed any registered children; here there are no pump children so it is logged and shown on Port 0.
  5. Inject cmd.calibrate.volume = 25 m3 to jump the predicted-volume integrator to half-full.

02-Integration - what to try

  1. Deploy. The Setup tab fires set.mode = levelbased to the station and set.mode = auto to the MGC.
  2. The two pumps register with the MGC via Port 2; the MGC and the level sensor register with the station via Port 2. Watch the registration debug taps to confirm.
  3. The level inject pushes a 1.6 m measurement so the station sees a non-zero starting level. Setup also seeds set.inflow = 60 m3/h.
  4. The station's controlMode = levelbased then drives the MGC, which dispatches to Pump A / Pump B.

03-Dashboard - what to try

  1. Deploy.
  2. Open the dashboard at http://localhost:1880/dashboard/page/pumping-station.
  3. Use the Control mode dropdown to switch between manual, levelbased, flowbased, none.
  4. In manual mode, drag the Manual demand slider - the demand cascades to the MGC and on to the pumps.
  5. The three charts (flow, level, volume %) plot live data; the four text widgets show state, percControl, direction, and time-to-empty.

Layout conventions

These flows follow the EVOLV layout rule set in .claude/rules/node-red-flow-layout.md:

  • Tabs split by concern: Process Plant (EVOLV nodes) / Dashboard UI (ui-* widgets) / Setup (once-true injects).
  • Cross-tab wiring via named link out / link in channels: setup:to-ps-mode, setup:to-ps-inflow, setup:to-mgc-mode, cmd:ps-mode, cmd:ps-demand, evt:flow, evt:level, evt:volpct, evt:state, evt:perc, evt:dir, evt:tempty.
  • Lane positions L0-L7 = [120, 360, 600, 840, 1080, 1320, 1560, 1800], driven by each node's S88 level (Process Cell on L5, Unit on L4, Equipment on L3, Control Module on L2).
  • Group boxes wrap each parent + its direct children, coloured by the parent's S88 level.

Regenerating

These flows are generated from tools/build-examples.js. Edit the generator, never the JSON, then:

node nodes/pumpingStation/tools/build-examples.js

The script writes 01-Basic.json, 02-Integration.json, and 03-Dashboard.json into this directory.