Files
monster/CONTRACT.md

51 lines
2.9 KiB
Markdown
Raw Normal View History

# monster — Contract
Hand-maintained for Phase 6; the `## Inputs` table is generated from
`src/commands/index.js` (see Phase 9 generator). Keep ≤ 80 lines.
## Inputs (msg.topic on Port 0)
| Canonical | Aliases (deprecated) | Payload | Effect |
|---|---|---|---|
| `cmd.start` | `i_start` | truthy/falsy | Sets `source.i_start`. On the next tick a sampling run begins if flow bounds validate. |
| `set.schedule` | `monsternametijden` | array of AQUON rows (`SAMPLE_NAME`, `DESCRIPTION`, `SAMPLED_DATE`, `START_DATE`, `END_DATE`) | Stores the schedule and recomputes `nextDate` + `daysPerYear` for the configured `aquonSampleName`. |
| `set.rain` | `rain_data` | per-location rain forecast (Open-Meteo shape) | Aggregates hourly precipitation into `sumRain` / `avgRain`; feeds the rain-scaled flow prediction. |
| `data.flow` | `input_q` | `{ value: number, unit: string }` | Converts to m³/h and pushes into `flow.manual.atequipment`. Blends with measured-child flow in `getEffectiveFlow()`. |
| `set.mode` | `setMode` | string | Delegated to `source.setMode()` if defined. Reserved for future use. |
| `set.model-prediction` | `model_prediction` | numeric | Delegated to `source.setModelPrediction()` if defined. Reserved for future use. |
| `child.register` | `registerChild` | `string` — the child node's Node-RED id | Resolves the child via `RED.nodes.getNode` and registers it through `childRegistrationUtils` at the supplied `msg.positionVsParent`. |
Aliases log a one-time deprecation warning the first time they fire.
## Outputs (msg.topic on Port 0/1/2)
- **Port 0 (process):** `msg.topic = config.general.name`. Payload built
by `outputUtils.formatMsg(..., 'process')` from `getOutput()`. Delta-
compressed — only changed fields are emitted. Carries `pulse`, `running`,
`bucketVol`, `sumPuls`, `predFlow`, `m3PerPuls`, `q`, `timeLeft`,
`targetVolumeM3`, `targetProgressPct`, `targetDeltaL`, `predictedRateM3h`,
`sumRain`, `avgRain`, `nextDate`, plus the flat measurements snapshot.
- **Port 1 (InfluxDB telemetry):** same shape as Port 0, formatted with the
`'influxdb'` formatter.
- **Port 2 (registration):** at startup the node sends one
`{ topic: 'child.register', payload: <node.id>, positionVsParent, distance }`
to its parent.
## Events emitted by `source.measurements.emitter`
The `MeasurementContainer` fires `<type>.measured.<position>` whenever a
matching series receives a new value. monster writes:
- `flow.manual.atequipment` — operator-supplied manual flow.
- `flow.measured.<position>` — re-emitted when a child measurement fires
(one of `flow.measured.upstream`, `flow.measured.downstream`,
`flow.measured.atequipment`).
## Children accepted
`measurement` only. The router subscribes to a child's
`flow.measured.<position>` events when the child's `config.asset.type` is
`'flow'` (or missing). Other asset types are ignored. monster has no
position-based filtering — all three positions are wired and the latest
value wins for each.