- settler.html node colour was #e4a363 (legacy orange); aligned to
S88 Unit blue #50a8d9 per .claude/rules/node-red-flow-layout.md §16
cleanup list. Existing flows are unaffected — colour is editor-only.
- CONTRACT.md: add `child.register` row; previously mentioned only in
prose ("not listed here"), but contract-verify enforces the table.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
53 lines
2.9 KiB
Markdown
53 lines
2.9 KiB
Markdown
# settler — 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 |
|
||
|---|---|---|---|
|
||
| `data.influent` | `influent`, `setInfluent` | `{ F: number, C: number[13] }` — either field optional | Replaces influent flow and/or the 13-species concentration vector. Triggers `output-changed`, re-emits the 3-stream Fluent envelope. |
|
||
| `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
|
||
|
||
- **Port 0 (process):** array of three Node-RED messages, each with
|
||
`topic = 'Fluent'` and `payload = { inlet, F, C }`:
|
||
- `inlet=0` — clarified effluent (particulate species 7–12 zeroed when `F_s > 0`).
|
||
- `inlet=1` — surplus sludge (particulates concentrated by `F_in / F_s`).
|
||
- `inlet=2` — return sludge (drawn by the downstream return pump up to `F_s`).
|
||
Re-emitted whenever the upstream reactor fires `stateChange`, an
|
||
operator pushes `data.influent`, or a child measurement updates `C_TS`.
|
||
- **Port 1 (InfluxDB telemetry):** `msg.topic = config.general.name`,
|
||
payload built by `outputUtils.formatMsg(..., 'influxdb')` from
|
||
`getOutput()`. Carries `F_in`, `C_TS`, `F_eff`, `F_surplus`, `F_return`
|
||
plus the flat measurements snapshot. Delta-compressed.
|
||
- **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. Settler re-emits incoming child
|
||
measurements (e.g. `quantity (tss).measured.atequipment`) so its own
|
||
parent can subscribe.
|
||
|
||
## Children accepted
|
||
|
||
| Software type | Position | Effect |
|
||
|---|---|---|
|
||
| `measurement` | any | Re-emit on `source.measurements`. `quantity (tss)` updates `C_TS` and triggers `output-changed`. |
|
||
| `reactor` | `upstream` (warns otherwise) | Stored as `upstreamReactor`. Listener attached to the reactor's own `emitter` (NOT measurements) for `'stateChange'`; on fire, settler pulls `reactor.getEffluent` and copies `F_in` + `Cs_in`. Handles both array and single-envelope `getEffluent` shapes. |
|
||
| `machine` | `downstream` | Stored as `returnPump`. Settler reads `returnPump.measurements.type('flow').variant('measured').position('atEquipment').getCurrentValue()` to determine `F_sr`. Sets `machineChild.upstreamSource = this`. |
|
||
|
||
## Parent relationship
|
||
|
||
Settler typically registers as `softwareType: 'settler'` with
|
||
`positionVsParent: 'downstream'` against a reactor (the reactor's
|
||
downstream stage). The downstream reactor consumes the three Fluent
|
||
streams via `payload.inlet`.
|