The demo was a single 96-node tab with everything wired directly. Now 4 tabs wired only through named link-out / link-in pairs, and a permanent rule set for future Claude sessions to follow. Tabs (by concern, not by data flow): 🏭 Process Plant only EVOLV nodes (3 pumps + MGC + PS + 6 measurements) + per-node output formatters 📊 Dashboard UI only ui-* widgets, button/setpoint wrappers, trend splitters 🎛️ Demo Drivers random demand generator + state holder. Removable in production ⚙️ Setup & Init one-shot deploy-time injects (mode, scaling, auto-startup, random-on) Cross-tab wiring uses a fixed named-channel contract (cmd:demand, cmd:mode, cmd:setpoint-A, evt:pump-A, etc.) — multiple emitters can target a single link-in for fan-in, e.g. both the slider and the random generator feed cmd:demand. Bug fixes folded in: 1. Trend chart was empty / scrambled. Root cause: the trend-feeder function had ONE output that wired to BOTH flow and power charts, so each chart received both flow and power msgs and the legend garbled. Now: 2 outputs (flow → flow chart, power → power chart), one msg per output. 2. Every ui-text and ui-chart fell on the (0, 0) corner of the editor canvas. Root cause: the helper functions accepted x/y parameters but never assigned them on the returned node dict — Node-RED defaulted every widget to (0, 0) and they piled on top of each other. The dashboard render was unaffected (it lays out by group/ order), but the editor was unreadable. Fixed both helpers and added a verification step ("no node should be at (0, 0)") to the rule set. Spacing convention (now codified): - 6 lanes per tab at x = [120, 380, 640, 900, 1160, 1420] - 80 px standard row pitch, 30-40 px for tight ui-text stacks - 200 px gap between sections, with a comment header per section New rule set: .claude/rules/node-red-flow-layout.md - Tab boundaries by concern - Link-channel naming convention (cmd:/evt:/setup: prefixes) - Spacing constants - Trend-split chart pattern - Inject node payload typing pitfall (per-prop v/vt) - Dashboard widget rules (every ui-* needs x/y!) - Do/don't checklist - Link-out/link-in JSON cheat sheet - 5-step layout verification before declaring a flow done CLAUDE.md updated to point at the new rule set. Verified end-to-end on Dockerized Node-RED 2026-04-13: 168 nodes across 4 tabs, all wired via 22 link-out / 19 link-in pairs, no nodes at (0, 0), pumps reach operational ~5 s after deploy, MGC distributes random demand, trends populate per pump. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
EVOLV — End-to-End Example Flows
Demo flows that show how multiple EVOLV nodes work together in a realistic wastewater-automation scenario. Each example is self-contained: its folder has a flow.json you can import directly into Node-RED plus a README.md that walks through the topology, control modes, and dashboard layout.
These flows complement the per-node example flows under nodes/<name>/examples/ (which exercise a single node in isolation). Use the per-node flows for smoke tests during development; use the flows here when you want to see how a real plant section behaves end-to-end.
Catalogue
| Folder | What it shows |
|---|---|
pumpingstation-3pumps-dashboard/ |
Wet-well basin + machineGroupControl orchestrating 3 pumps (each with up/downstream pressure measurements), individual + auto control, process-demand input via dashboard slider or random generator, full FlowFuse dashboard. |
How to import
- Bring up the EVOLV stack:
docker compose up -dfrom the superproject root. - Open Node-RED at
http://localhost:1880. - Menu → Import → drop in the example's
flow.json(or paste the contents). - Open the FlowFuse dashboard at
http://localhost:1880/dashboard.
Each example uses a unique dashboard path so they can coexist in the same Node-RED runtime.
Adding new examples
When you create a new end-to-end example:
- Make a subfolder under
examples/named<scenario>-<focus>. - Include
flow.json(Node-RED export) andREADME.md(topology, control modes, dashboard map, things to try). - Test it on a fresh Dockerized Node-RED — clean import, no errors, dashboard loads.
- Add a row to the catalogue table above.
Wishlist for future examples
These are scenarios worth building when there's a session for it:
- Pump failure + MGC re-routing — kill pump 2 mid-run, watch MGC redistribute to pumps 1 and 3.
- Energy-optimal vs equal-flow control — same demand profile run through
optimalcontrolandprioritycontrolmodes side-by-side, energy comparison chart. - Schedule-driven demand — diurnal flow pattern (low at night, peak at 7 am), MGC auto-tuning over 24 simulated hours.
- Reactor + clarifier loop —
reactorupstream feedingsettler, return sludge controlled by a smallpumpingStation. - Diffuser + DO control — aeration grid driven by a PID controller from a dissolved-oxygen sensor.
- Digital sensor bundle — MQTT-style sensor (BME280, ATAS, etc.) feeding a
measurementnode in digital mode + parent equipment node. - Maintenance window — entermaintenance / exitmaintenance cycle with operator handover dashboard.
- Calibration walk-through — measurement node calibrate cycle with stable / unstable input demonstrations.