# settler ![code-ref](https://img.shields.io/badge/code--ref-a3583a3-blue) ![s88](https://img.shields.io/badge/S88-Unit-50a8d9) ![status](https://img.shields.io/badge/status-stub--level-lightgrey) A `settler` models a secondary clarifier — the sludge-separation stage that sits downstream of a biological reactor. It receives the upstream reactor's effluent stream, performs a 13-species TSS mass balance, and splits the result into three Fluent envelopes: clarified effluent, surplus sludge, and return sludge. A downstream return pump (a `rotatingMachine` registered as `machine` / `downstream`) draws the return-sludge flow. > [!NOTE] > Pending full node review (2026-05). Content reflects `CONTRACT.md` and current source only. The shipped `examples/` folder ships stubs only — production-grade flows are still TODO. Treat this page as informative, not authoritative. --- ## At a glance | Thing | Value | |:---|:---| | What it represents | Secondary clarifier / sludge settler — the gravity-separation stage between a biological reactor and its downstream sludge handling | | S88 level | Unit | | Use it when | You have a reactor whose effluent must be split into clarified water + return / surplus sludge by a TSS mass balance | | Don't use it for | Primary sedimentation (species 7–12 zeroing is wrong), generic mass-balance transforms (the 13-species ASM3 vector is hard-coded), single-tank SBRs that don't need a 3-stream split | | Children it accepts | `measurement` (any, but `quantity (tss)` is the only one that mutates state), `reactor` (upstream), `machine` (downstream — the return pump) | | Parents it talks to | Typically a downstream `reactor` — the three Fluent streams are routed by `payload.inlet` | --- ## How it fits ```mermaid flowchart LR upstream[reactor
upstream
Unit]:::unit settler[settler
Unit]:::unit downstream[reactor
downstream
Unit]:::unit return_pump[rotatingMachine
return pump
Equipment]:::equip tss[measurement
quantity tss
atequipment]:::ctrl upstream -.stateChange.-> settler settler -->|Fluent inlet=0 effluent| downstream settler -->|Fluent inlet=1 surplus| downstream settler -->|Fluent inlet=2 return| return_pump return_pump -->|child.register downstream| settler tss -->|quantity tss.measured.atequipment| settler classDef unit fill:#50a8d9,color:#000 classDef equip fill:#86bbdd,color:#000 classDef ctrl fill:#a9daee,color:#000 ``` S88 colours are anchored in `.claude/rules/node-red-flow-layout.md`. The settler editor colour is currently `#e4a363` (orange) — tracked as drift in §16 of that rule; diagrams in this wiki use the correct Unit blue (`#50a8d9`). --- ## Try it — 1-minute demo > [!IMPORTANT] > The shipped examples (`examples/basic.flow.json`, `integration.flow.json`, `edge.flow.json`) are skeleton stubs — they create a settler node and a debug tap, but do not exercise the reactor → settler → pump chain. A proper Tier-1 / Tier-2 / Tier-3 example set is on the TODO list; until then this section walks the minimum stimulus. Import the basic stub, deploy, then drive influent manually: ```bash curl -X POST -H 'Content-Type: application/json' \ --data @nodes/settler/examples/basic.flow.json \ http://localhost:1880/flow ``` After deploy, send one inject: | Topic | Payload | What it does | |:---|:---|:---| | `data.influent` | `{ "F": 1000, "C": [0,0,0,0,0,0,0,0,0,0,0,0,3000] }` | Pushes 1000 m³/h influent with 3000 mg/L total solids (index 12 = `X_TS`). Three Fluent envelopes appear on Port 0 immediately. | > [!NOTE] > Pending full node review (2026-05). Real flows (Tier-1 inject only, Tier-2 reactor + settler + pump, Tier-3 dashboard) are not yet shipped. See [Reference — Examples](Reference-Examples). --- ## The two things you'll send | Topic | Aliases | Payload | What it does | |:---|:---|:---|:---| | `data.influent` | `influent`, `setInfluent` | `{F: number, C: number[13]}` — either field optional | Override the influent stream directly. Triggers a recompute of all three Fluent envelopes. | | `child.register` | `registerChild` | `string` (child node id) | Register a `measurement`, `reactor`, or `machine` child. Port 2 wiring does this automatically in normal flows. | That is the entire input contract. Settler has no FSM, no setpoint, no startup sequence — it is a stateless transform on top of whatever the upstream reactor + measurement children push into it. --- ## What you'll see come out Sample Port 0 messages (one push, three envelopes): ```json [ { "topic": "Fluent", "payload": { "inlet": 0, "F": 850.0, "C": [/*7-12 zeroed*/] }, "timestamp": 1715000000000 }, { "topic": "Fluent", "payload": { "inlet": 1, "F": 50.0, "C": [/*7-12 concentrated*/] }, "timestamp": 1715000000000 }, { "topic": "Fluent", "payload": { "inlet": 2, "F": 100.0, "C": [/*7-12 concentrated*/] }, "timestamp": 1715000000000 } ] ``` | `payload.inlet` | Meaning | Particulate species (indices 7–12) | |:---:|:---|:---| | `0` | Clarified effluent | zeroed when `F_s > 0` | | `1` | Surplus sludge (the fraction the return pump does not draw) | concentrated by `F_in / F_s` | | `2` | Return sludge (drawn by the downstream return pump, capped at `F_s`) | concentrated by `F_in / F_s` | Mass balance invariant: `F_eff + F_surplus + F_return = F_in` (modulo float). Port 1 (InfluxDB) is the scalar dashboard view — see [Reference — Contracts](Reference-Contracts#data-model--getoutput-shape). Port 2 carries the one-shot `child.register` upward at startup. --- ## Capability matrix | Capability | Status | Notes | |:---|:---:|:---| | TSS mass-balance split (3 streams) | yes | `F_s = min(F_in * Cs[12] / C_TS, F_in)` — clamped to prevent negative effluent. | | Particulate zeroing in effluent | yes | Species 7–12 set to 0 in `inlet=0` when `F_s > 0`. | | Particulate concentration in sludge | yes | Species 7–12 scaled by `F_in / F_s` in `inlet=1` + `inlet=2`. | | Return-pump flow draw | yes | `F_sr = min(pump flow at equipment, F_s)`. Surplus = `F_s - F_sr`. | | `F_s` clamp to `F_in` | yes | Prevents negative effluent when `X_TS_in > C_TS`. | | Manual influent override | yes | `data.influent` lets ops supply `{F, C}` directly. | | Multiple reactor upstreams | no | Only one `upstreamReactor` slot; last registration wins. | | Stateful FSM | no | Stateless transform — recomputes on every trigger. | | Curve loading / drift / sequence-abort | n/a | Not applicable to a passive split. | --- ## Need more? | Page | What you'll find | |:---|:---| | [Reference — Contracts](Reference-Contracts) | Topic registry, config schema, child registration filters | | [Reference — Architecture](Reference-Architecture) | Three-tier code map, reactor ↔ settler wiring (the load-bearing bit), lifecycle, output ports | | [Reference — Examples](Reference-Examples) | Shipped example flows (currently stubs) + the TODO list for production-grade demos | | [Reference — Limitations](Reference-Limitations) | When not to use, known limitations, open questions | [EVOLV master wiki](https://gitea.wbd-rd.nl/RnD/EVOLV/wiki/Home) · [Topology Patterns](https://gitea.wbd-rd.nl/RnD/EVOLV/wiki/Topology-Patterns) · [Topic Conventions](https://gitea.wbd-rd.nl/RnD/EVOLV/wiki/Topic-Conventions)