Files
EVOLV/examples/WORKFLOW.md
Rene De Ren 0cab98c196
Some checks failed
CI / lint-and-test (push) Has been cancelled
Pumping-station demo overhaul + cross-node test harness + bumps
Submodule bumps land the deadlock fix (state.js residue unpark + MGC
optimalControl dispatch reorder) and pumpingStation stopLevel hysteresis.

- Renames examples/pumpingstation-3pumps-dashboard →
  pumpingstation-complete-example with regenerated flow.json. New
  dashboard groups, demand-broadcast wiring, S88 placement rule
  applied, ui-chart trend-split and link-channel naming follow
  .claude/rules/node-red-flow-layout.md.
- New cross-node test harness under test/: end-to-end-pumpingstation
  drives PS + MGC + 3 pumps + physics simulator end-to-end and
  verifies the ~5/15 min cycle.
- Adds Grafana provisioning dashboards (pumping-station.json) and a
  helper sync-example.sh script for export/import to live Node-RED.
- Docker entrypoint + settings + compose tweaks for the persistent
  user dir layout used by the demo.

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

5.6 KiB
Raw Permalink Blame History

EVOLV Examples — Team Workflow

This file is the canonical guide for working with the example flows that live under examples/. Each subfolder is a Node-RED project; the Docker stack is set up so switching between them is two clicks in the editor.

Stack at a glance

Container What URL
evolv-nodered Node-RED runtime + dashboard http://localhost:1880 · dashboard at http://localhost:1880/dashboard
evolv-influxdb Time-series store (port-1 telemetry) http://localhost:8086 · evolv / evolv-dev-pw
evolv-grafana Provisioned dashboards (anonymous viewer enabled) http://localhost:3000

The evolv_nodered_data named volume keeps /data (flows, projects, sessions) across docker compose down && up. The examples/ directory in this repo is the source of truth; the Node-RED Projects feature operates on a copy in the volume.

Quick start

cd /path/to/EVOLV
docker compose up -d
# Node-RED: http://localhost:1880
# Dashboard: http://localhost:1880/dashboard
# Grafana: http://localhost:3000  (anonymous viewer)

The first time you start it, the entrypoint copies every examples/<name>/ into /data/projects/<name>/ and git inits each. Subsequent starts skip folders that already exist in the volume.

Switching examples

Open the editor → menu → Projects → Open Project → pick another project. The editor reloads the chosen flow.

The default active project on first boot is pumpingstation-complete-example. To change the default for fresh volumes, set DEFAULT_PROJECT=<name> on the nodered service in docker-compose.yml.

Editing a flow

You have two paths. They serve different purposes — pick based on what you're doing.

# 1. Edit the Python generator
vim examples/<name>/build_flow.py

# 2. Regenerate flow.json
python3 examples/<name>/build_flow.py > examples/<name>/flow.json

# 3. Push to the runtime
./scripts/sync-example.sh <name>

The Python is the source of truth. It's diff-friendly and the right place for any change you intend to commit.

Path B — edit in the Node-RED editor (experimentation)

Open editor → Make changes → Deploy

Edits go into the volume (/data/projects/<name>/flow.json). They survive docker compose down && up but are not in the EVOLV git repo. To incorporate them back:

docker cp evolv-nodered:/data/projects/<name>/flow.json examples/<name>/flow.json

Then commit examples/<name>/flow.json (and reverse-engineer the change into build_flow.py if you want it diff-friendly going forward).

Adding a new example

mkdir examples/<scenario>-<focus>
# Build a flow.json (recommended: a build_flow.py that generates it)
vim examples/<scenario>-<focus>/{build_flow.py,README.md,flow.json}

# Restart Node-RED so the entrypoint bootstraps the new project
docker compose restart nodered

The entrypoint synthesizes package.json, runs git init, and makes an initial commit so Node-RED recognises it as a project. Bootstrap is idempotent — if a /data/projects/<name>/ already exists, it's left alone.

After restart, Projects → Open Project in the editor will list the new entry.

Resetting state

Goal Command
Push the repo's flow.json into the runtime, reload ./scripts/sync-example.sh <name>
Wipe one project's volume copy and re-bootstrap docker exec evolv-nodered rm -rf /data/projects/<name> then docker compose restart nodered
Wipe everything in the volume (flows, sessions, all projects, but NOT InfluxDB/Grafana) docker compose down && docker volume rm evolv_nodered_data && docker compose up -d
Wipe everything including telemetry docker compose down -v && docker compose up -d

Debugging

Symptom Where to look
Flow not loading after deploy docker logs evolv-nodered for crash backtraces
InfluxDB empty / not receiving Telemetry tab in editor → status of the Count writes node. Should show N POSTs · M lines (0 err).
Dashboard widget shows n/a Check the Process Plant tab → output formatter function for that node — c.<key> keys the dispatcher reads from
Grafana dashboard panels empty Open InfluxDB UI (http://localhost:8086) → Data Explorer → confirm the field name the panel queries actually exists. Field names are flat dotted keys like level.predicted.atequipment.default.
interpolation configuration: New f =... is constrained warnings The pump curve f-axis is out-of-range. f = downstream upstream pressure differential, in Pa, must be inside the curve's range (e.g. 70 000 390 000 Pa for hidrostal-H05K-S03R). Check the per-pump physics feeder formula.
High CPU in Node-RED Per-tick HTTP fan-out to InfluxDB; the pumpingstation example uses a 500 ms batch in the Telemetry tab. If CPU is still high, lower tickIntervalMs in the EVOLV node configs (currently 1000).

File map per example

examples/<name>/
├── build_flow.py          ← canonical source of flow.json (Python generator)
├── flow.json              ← regenerated artefact, also tracked in Git
├── README.md              ← topology, control modes, dashboard map, things to try
└── package.json           ← (synthesized in volume by entrypoint, not in repo)

The repo tracks build_flow.py, flow.json, and README.md. The package.json and .git/ directory of the project live only in the named volume — they're created by the entrypoint on first bootstrap and don't leak back into the EVOLV Git history.