The commands registry has `child.register` (with `registerChild` alias); CONTRACT.md mentioned it only in the Port 2 prose. contract-verify required it in the canonical Inputs table. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
51 lines
2.9 KiB
Markdown
51 lines
2.9 KiB
Markdown
# 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.
|