# Monster Function Anchor (Baseline) ## 0) Connection Map (At a Glance) - **Node type**: `monster` (`nodes/monster/monster.js:1`, `nodes/monster/monster.html:5`) - **Consumes control/input topics**: `input_q`, `i_start`, `monsternametijden`, `rain_data`, `registerChild` (`nodes/monster/src/nodeClass.js:202`) - **Publishes periodic outputs**: - Output `0`: process payload (`nodes/monster/src/nodeClass.js:185`) - Output `1`: influx payload (`nodes/monster/src/nodeClass.js:186`) - Output `2`: parent registration (`registerChild`) (`nodes/monster/src/nodeClass.js:158`) - **Cross-node integrations**: - Accepts measurement children of type `flow` (`nodes/monster/src/specificClass.js:300`) - Common external orchestration pattern around this node: - Open-Meteo -> `rain_data` - Aquon schedule feed -> `monsternametijden` - PLC/MQTT pulse sink fed by `output.pulse` - Z-Info/report tooling fed by `m3Total` + `m3PerPuls` - Dashboard API/Grafana and Influx consumers - **Admin/UI endpoints**: - `GET /monster/menu.js` - `GET /monster/configData.js` (`nodes/monster/monster.js:17`, `nodes/monster/monster.js:27`) ## 1) Unit Table (Always First Data Section) | Signal/Field | Represents | Asset Type | Default Unit | Source of Truth | Produced By | Consumed By | Fallback/Degraded Behavior | |---|---|---|---|---|---|---|---| | `input_q.payload.value` | influent flow command | manual/control input | `m3/h` (normalized in wrapper) | `nodes/monster/src/nodeClass.js:216` | upstream control flow | sampling calculation loop | invalid/unit conversion failure is warned and ignored | | `flow.measured.*` | measured flow from child sensors | measurement child | `m3/h` | `nodes/monster/src/specificClass.js:300` | measurement nodes | effective flow selection | if missing, manual flow or 0 is used | | `q` | effective flow used by model | derived | `m3/h` | `nodes/monster/src/specificClass.js:775` | `tick()` | pulse and volume progression | defaults to `0` if no measured/manual flow | | `m3PerPuls` | reporting conversion factor for sampler pulse | derived/report field | `m3/pulse` | `nodes/monster/src/specificClass.js:660` | `sampling_program()` | Z-Info/report tooling, operations | `0` when not running | | `m3Total` | accumulated volume during active run | derived/report field | `m3` | `nodes/monster/src/specificClass.js:687` | `sampling_program()` | Z-Info/report tooling | reset to `0` when sampling window ends | | `pulse` | pulse command signal | control output | boolean | `nodes/monster/src/specificClass.js:707` | `sampling_program()` | PLC/MQTT pulse output paths | forced `false` under cooldown/capacity/end-of-run | | `bucketVol` | sampled bucket fill volume | derived/state | `L` | `nodes/monster/src/specificClass.js:712` | pulse accumulation | dashboard/operator checks | reset to `0` after run | | `predictedRateM3h` | rain-scaled prediction reference | derived | `m3/h` | `nodes/monster/src/specificClass.js:367` | `getOutput()` | dashboards/diagnostics | falls back to measured/manual effective rate | ## 2) Class Identity - **Runtime registration + endpoints**: `nodes/monster/monster.js` - **Node-RED wrapper/routing**: `nodes/monster/src/nodeClass.js` - **Domain sampling logic**: `nodes/monster/src/specificClass.js` - **Editor UI/defaults**: `nodes/monster/monster.html` - **Default config schema**: `nodes/generalFunctions/src/configs/monster.json` ## 3) Configuration Contract (Key) | UI Field | Runtime Path | Default | Behavior Impact | Source | |---|---|---|---|---| | `samplingtime` | `constraints.samplingtime` | `0` | sampling window hours | `nodes/monster/monster.html:16`, `nodes/monster/src/nodeClass.js:68` | | `minvolume` | `constraints.minVolume` | `5` | min valid sample volume | `nodes/monster/monster.html:17`, `nodes/monster/src/nodeClass.js:69` | | `maxweight` | `constraints.maxWeight` | `22` | max bucket load before invalid sample | `nodes/monster/monster.html:18`, `nodes/monster/src/nodeClass.js:70` | | `nominalFlowMin` / `flowMax` | `constraints.nominalFlowMin` / `constraints.flowMax` | `0` / `0` | prediction bounds and start guard | `nodes/monster/monster.html:19`, `nodes/monster/src/specificClass.js:226` | | `minSampleIntervalSec` | `constraints.minSampleIntervalSec` | `60` | pulse cooldown protection | `nodes/monster/monster.html:22`, `nodes/monster/src/specificClass.js:693` | | `emptyWeightBucket` | `asset.emptyWeightBucket` | `3` | max bucket volume derivation | `nodes/monster/monster.html:23`, `nodes/monster/src/specificClass.js:378` | | `aquon_sample_name` | `aquonSampleName` | `"112100"` internal default | schedule selector key | `nodes/monster/monster.html:24`, `nodes/monster/src/nodeClass.js:96` | ## 4) I/O and Integration Notes - Node-level output is process/influx/parent only. - External APIs are normally handled by surrounding flows, not by the node class itself. - Report tooling integration should read from process payload fields: - `m3Total` - `m3PerPuls` - `running` - `pulse` - Reference examples: - dashboard baseline: `nodes/monster/examples/monster-dashboard.flow.json` - full API + dashboard template: `nodes/monster/examples/monster-api-dashboard.flow.json` ## 5) Current Gaps / Risks 1. Wrapper exposes topics (`setMode`, `execSequence`, `execMovement`, `flowMovement`, `emergencystop`) that are not implemented in `Monster.handleInput` contract. 2. `showWorkingCurves`/`CoG` routes in wrapper call methods that are not present in `Monster`. 3. Existing legacy tests were not organized in required `basic/integration/edge` folders before this update. 4. External API credentials/tokens must remain outside committed example flows. ## 6) Test Evidence Matrix (Current Baseline) | Test file | What is covered | Methods/contracts anchored | |---|---|---| | `nodes/monster/test/basic/constructor.basic.test.js` | constructor + output field contract | `constructor`, `set_boundries_and_targets`, `getOutput` | | `nodes/monster/test/integration/flow-and-schedule.integration.test.js` | flow averaging, rain/schedule ingestion | `registerChild`, `handleInput`, `tick`, `updateRainData`, `regNextDate` | | `nodes/monster/test/edge/sampling-guards.edge.test.js` | invalid-bound guard + cooldown behavior | `validateFlowBounds`, `sampling_program`, cooldown gate | ## 7) Change Checklist - When `monster` behavior changes, update: - `nodes/monster/src/nodeClass.js` - `nodes/monster/src/specificClass.js` - `nodes/monster/monster.html` - `nodes/monster/test/basic|integration|edge/*` - `.agents/function-anchors/monster/ANCHOR-monster.md` - `.agents/function-anchors/monster/ANCHOR-monster.html` - `.agents/function-anchors/monster/EVIDENCE-monster-tests.md`