Files
settler/CONTRACT.md
znetsixe 70acef22d5 fix: settler icon colour + CONTRACT child.register row
- 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>
2026-05-19 15:59:11 +02:00

53 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 712 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`.