# Reference — Examples ![code-ref](https://img.shields.io/badge/code--ref-cd185dc-blue) > [!NOTE] > Every example flow shipped under `nodes/monster/examples/`, plus how to load them, what they show, and the debug recipes that go with them. Live source: `nodes/monster/examples/`. > [!NOTE] > Pending full node review (2026-05). Content reflects `CONTRACT.md`, `examples/README.md`, and current source only. Example flows have not been validated end-to-end on a live Docker instance. --- ## Shipped examples | File | Tier | Dependencies | What it shows | |:---|:---:|:---|:---| | `basic.flow.json` | 1 | EVOLV only | Quick-start flow — manual flow inject, manual start, seeded `rain_data` and `monsternametijden`, debug taps on the three ports. **Status: pending validation.** | | `02-integrated-e2e.json` | 2 | EVOLV only | End-to-end integration — measurement child wired in, schedule arming, sampling-run completion. **Status: pending validation.** | Per `examples/README.md`, the following files are also referenced but **not currently in this directory** at `cd185dc`: | Referenced filename | Status | |:---|:---| | `integration.flow.json` | Referenced in README; not present in `examples/` — possibly renamed to `02-integrated-e2e.json`. Flag for review. | | `edge.flow.json` | Referenced in README; not present. Flag for review. | | `monster-dashboard.flow.json` | Referenced in README + top-level `README.md`; not present. Flag for review. | | `monster-api-dashboard.flow.json` | Referenced in README + top-level `README.md`; not present. Flag for review. The README warns that production use requires hardening of placeholder credentials (`__SET_*__`). | > [!IMPORTANT] > Reconcile the example flow inventory: either restore the four referenced flows from history, or update `examples/README.md` + the top-level `README.md` to remove dangling references. Tracked. --- ## Loading a flow ### Via the editor 1. Open the Node-RED editor at `http://localhost:1880`. 2. Menu → Import → drag the JSON file. 3. Click Deploy. ### Via the Admin API ```bash curl -X POST -H 'Content-Type: application/json' \ --data @"nodes/monster/examples/basic.flow.json" \ http://localhost:1880/flows ``` --- ## Example 01 — Basic (`basic.flow.json`) Single-cabinet flow with the minimum inputs to drive one sampling run. Pending live validation. ### Suggested click order after deploy 1. **Seed the rain forecast.** Click the `set.rain` inject. `sumRain` / `avgRain` populate; `predictedRateM3h` jumps from `nominalFlowMin` to a band-scaled value. (Skip this step and the prediction collapses to `nominalFlowMin`, which is `0` out of the box — the run will still start, but `predFlow` will be 0 and `m3PerPuls` will round to 0; see [Limitations](Reference-Limitations#mperpuls-can-round-to-zero).) 2. **Seed the schedule.** Click the `set.schedule` inject with an AQUON row array containing at least one `START_DATE` in the future for `aquonSampleName=112100` (the default). 3. **Push a manual flow.** Click `data.flow = {value: 240, unit: 'm3/h'}`. 4. **Start.** Click `cmd.start = true`. On the next tick `validateFlowBounds` runs — if `nominalFlowMin < flowMax`, `_beginRun` fires and `running` flips to `true`. 5. **Watch Port 0.** `pulse` blips to `true` for one tick on each integrated-volume threshold cross. `bucketVol` rises in 50 mL steps. `sumPuls` increments. 6. **Stop.** Either wait `samplingtime` hours for `_endRun`, or redeploy. > [!IMPORTANT] > **Screenshot needed.** Editor capture of `basic.flow.json` after step 4. Save as `wiki/_partial-screenshots/monster/basic-running.png`. ### Try the cooldown guard After the first pulse: 1. Push a higher manual flow (`data.flow = {value: 1200, unit: 'm3/h'}`) so the integrator races past `m3PerPuls` again within `minSampleIntervalSec` (default 60 s). 2. Watch the log: `Sampling too fast. Cooldown active for Ns.` 3. `missedSamples` increments, `pulse` stays `false`, `sampleCooldownMs` ticks down to 0, then the next pulse fires. --- ## Example 02 — Integrated end-to-end (`02-integrated-e2e.json`) > [!IMPORTANT] > **Screenshot needed.** Editor capture of `02-integrated-e2e.json`. Save as `wiki/_partial-screenshots/monster/02-integrated.png`. Replace this callout with the image link. One monster + one or more `measurement` flow children. Demonstrates: - Auto-registration via Port 2 at deploy (each child's `child.register` reaches the monster). - Measured + manual flow blend — `getEffectiveFlow` averages both when present. - Schedule-armed sampling run — `nextDate` triggers `_beginRun` without an `i_start` click. Detailed click order: pending review. --- ## Dashboard / API example flows The `examples/README.md` references `monster-dashboard.flow.json` (FlowFuse charts for `pulse`, `bucket`, `predFlow`) and `monster-api-dashboard.flow.json` (Open-Meteo + AQUON SFTP + Grafana publish template with placeholder credentials). Neither file is present at `cd185dc`. See the inventory note at the top of this page. When restored, the API flow MUST be hardened before production: - Replace every `__SET_*__` placeholder with an env-backed secret. - Pin the Open-Meteo endpoint and Aquon SFTP host to environment variables. - Route the dashboard publish through `dashboardAPI`, not a hardcoded Grafana URL. --- ## Docker compose snippet To bring up Node-RED + InfluxDB with EVOLV nodes pre-loaded: ```yaml # docker-compose.yml (extract) services: nodered: build: ./docker/nodered ports: ['1880:1880'] volumes: - ./docker/nodered/data:/data/evolv influxdb: image: influxdb:2.7 ports: ['8086:8086'] ``` Full file: [EVOLV/docker-compose.yml](https://gitea.wbd-rd.nl/RnD/EVOLV/src/branch/development/docker-compose.yml). --- ## Debug recipes | Symptom | First thing to check | Where to look | |:---|:---|:---| | `pulse` never fires | Is `running=true`? If not, check `validateFlowBounds` — the `Invalid flow bounds. nominalFlowMin=…, flowMax=…` warn means the default `flowMax=0` is in play. Set `nominalFlowMin < flowMax` in the editor. | `parameters/parameters.js → validateFlowBounds` | | `pulse` never fires (bounds OK) | Is `m3PerPuls` zero? `_beginRun` rounds `predFlow / targetPuls` to nearest integer m³. Low `predFlow` rounds to 0; integrator divides by 0 → `temp_pulse = Infinity`, the `sumPuls < absMaxPuls` guard then runs out. | `sampling/samplingProgram.js → _beginRun` | | Pulses arrive too fast / skipped | Cooldown guard active. Inspect `missedSamples` + `sampleCooldownMs`. Look for `Sampling too fast. Cooldown active for Ns.` in the log. | `sampling/samplingProgram.js → _maybeEmitPulse` | | `q` always zero | Measured-flow child not registered, manual flow not pushed. Watch Port 2 + `data.flow` history. | `flow/flowTracker.js` | | Measurement child ignored at register | Child's `config.asset.type` is set to something other than `"flow"` (e.g. `"flow-electromagnetic"`). monster only accepts `asset.type = "flow"` or unset. Set `asset.type: "flow"` on the measurement node. | `specificClass.js → _wireMeasurementChild` | | Measured-flow values look 60× high or wrong unit | `flowTracker.handleMeasuredFlow` does **not** convert: it stores the value as-supplied (defaulting unit to `'m3/h'`). Wire children that already emit m³/h or fix at the source. | `flow/flowTracker.js → handleMeasuredFlow` | | `nextDate` not arming | `set.schedule` payload didn't include any rows matching `aquonSampleName` with a future `START_DATE`. | `schedule/schedule.js → regNextDate` | | `sumRain` stays zero with rain input | `set.rain` is ignored while `running=true` — only consumed between runs. Wait for `_endRun` or push the rain payload before `cmd.start`. | `specificClass.js → updateRainData` | | `data.flow` payloads dropped silently | The handler requires `{value: , unit: }`. Bare numbers or missing `unit` log `data.flow payload must include numeric value and unit.` | `commands/handlers.js → dataFlow` | | `predictedRateM3h` stays at `nominalFlowMin` | `set.rain` not sent, `lastRainUpdate` is 0, or > 2 hours have passed (`RAIN_STALE_MS`). Re-push the rain payload. | `parameters/parameters.js → getRainIndex` | | `flowmeter=false` has no effect | `constraints.flowmeter` is in the schema but **not** wired in `buildDomainConfig`. The sampling program always runs in proportional mode. | `src/nodeClass.js → buildDomainConfig` | | `set.mode` / `set.model-prediction` no-op | Handlers delegate to `source.setMode()` / `source.setModelPrediction()` which don't exist. These topics are reserved for future use. | `commands/handlers.js` | | Status badge stuck at `Config error: …` | `nominalFlowMin >= flowMax`. Fix the bounds and redeploy. | `io/statusBadge.js` | > Never ship `enableLog: 'debug'` in a demo — fills the container log within seconds and obscures real errors. --- ## Related pages | Page | Why | |:---|:---| | [Home](Home) | Intuitive overview | | [Reference — Contracts](Reference-Contracts) | Topic + config + child filters | | [Reference — Architecture](Reference-Architecture) | Code map, sampling-program loop, prediction + cooldown pipeline | | [Reference — Limitations](Reference-Limitations) | Known issues and open questions | | [EVOLV — Topology Patterns](https://gitea.wbd-rd.nl/RnD/EVOLV/wiki/Topology-Patterns) | Where monster fits in a larger plant |