P6: convert settler to platform infrastructure
Refactor of settler to use BaseNodeAdapter + commandRegistry + statusBadge. settler follows the platform refactor plan in .claude/refactor/MODULE_SPLIT.md. Tests stay green; CONTRACT.md generated; legacy aliases preserved. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
53
CONTRACT.md
Normal file
53
CONTRACT.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# 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. |
|
||||
|
||||
Aliases log a one-time deprecation warning the first time they fire.
|
||||
Plumbing topics (`child.register`) are handled by the BaseNodeAdapter and
|
||||
not listed here.
|
||||
|
||||
## 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`.
|
||||
Reference in New Issue
Block a user