Waterschap Brabantse Delta · R&D-lab · uitleg

EVOLV · settler — één influent-trigger door de 3-weg-massabalans

eigenaar R&D-lab laatst getest 2026-07-17 versie 2.0 concept
settler is in EVOLV de digitale twin van een secundaire nabezinktank (clarifier). Uit één influentstroom (debiet F_in + een 13-species concentratievector) splitst hij drie stromen: gezuiverd effluent, spuislib (surplus) en retourslib. Dat gebeurt met één instantane TSS-massabalans — niet met een bezinkmodel. De node is stateless en event-driven: geen klok, geen slibvoorraad, geen toestandsmachine; hij herrekent de splitsing telkens als een influent-commando, een upstream-reactor-stateChange of een TSS-meting binnenkomt (src/nodeClass.js:6-16). Deze pagina volgt letterlijk wat de code doet aan de hand van één voorbeeld-trigger, een interactieve console en één splitsings-figuur die de kernformule getrouw naspeelt.

Doel & rol in de keten

settler is een S88-Unit (lane L4, kleur #50a8d9; nodes/settler/CLAUDE.md, S88-tabel). Hij registreert zich typisch als kind softwareType: 'settler' met positionVsParent: 'downstream' tegen een reactor, en is zélf parent van drie soorten kinderen: een upstream reactor (die stateChange vuurt en zo het influent levert), een TSS-meting (die de target-concentratie C_TS zet) en een downstream retourpomp (die bepaalt hoeveel slib retour gaat) (CONTRACT.md §Children; src/specificClass.js:27-30).

De node is expliciet een stateless transformstatic tickInterval = null: er is geen periodieke loop, geen interne slibvoorraad en geen tijdsintegrator. Output verschijnt op het domein-event 'output-changed' via notifyOutputChanged(); alleen de statusbadge wordt elke 1000 ms gepolld (src/nodeClass.js:6-17; docs/functional.html:51).

Rode draad door de hele pagina: één nabezinktank op werkpunt F_in = 120 m³/h, influent-TSS X_TS,in = 4000 mg/L (index 12 van de 13-species-vector), target retourconcentratie C_TS = 8000 mg/L (via een TSS-meting gezet; de code-default is 2500) en een geregistreerde retourpomp op 40 m³/h. Alle getallen in de rode draad zijn met node tegen de échte Settler-domeincode doorgerekend (scratchpad/settler-verify.js; testgevallen als commentaar onderaan de pagina-JS): F_s = 60, effluent 60, spui 20, retour 40 m³/h (ΣF = F_in).

Praat met deze node

Het I/O-contract in één oogopslag: kies een verb, stel de velden in, kopieer het exacte injecteerbare msg, en klik Injecteer ▸ om te zien wat er uit de drie poorten komt — met live doorgerekende splitsing op de voorbeeld-context van de rode draad (C_TS 8000 mg/L via TSS-meting, retourpomp 40 m³/h). Elke bewering draagt een pad:regel-chip. Poortlabels ["process","dbase","parent"]. Er zijn maar twee injecteerbare berichten: het influent-verb (envelope) en het legacy child.register-topic.

Stuurinput · 1 poort
Bericht
Poortenoutput · 3 poorten
Volledige poort-referentie
Poortcontract (labels ["process","dbase","parent"], settler.html:26-28). Let op: settler overschrijft _emitOutputs() (src/nodeClass.js:23-30) — poort 0 draagt de rúwe 3-berichten-array uit getEffluent, níét door de process-formatter.
PoortLabelBelangrijkste keys
0process Array van drie Node-RED-berichten, elk topic:'Fluent', payload:{ inlet, F, C }, timestamp (src/specificClass.js:57-61): inlet=0 effluent (F=F_eff, particulaten idx 7–12 op 0 als F_s>0); inlet=1 spuislib/surplus (F=F_so, particulaten geconcentreerd); inlet=2 retourslib (F=F_sr).
1dbase Delta-gecomprimeerde scalar-snapshot via formatMsg(getOutput(), cfg, 'influxdb'); msg.topic = config.general.name. Velden (src/specificClass.js:124-134): F_in, C_TS, F_eff, F_surplus, F_return + de platte metingen-snapshot. Omzetbaar naar frost/json/csv (settler.html:84-91).
2parent In _emitOutputs altijd null. De enige Port-2-emit is de eenmalige startup-handshake { topic:'child.register', payload:node.id, positionVsParent, distance } (BaseNodeAdapter.js:117-132; CONTRACT.md §Outputs).

Wie praat met wie

De settler staat centraal en is parent van drie kinderen. Het influent komt binnen als in-process event: de upstream reactor vuurt stateChange op zijn eigen emitter (niet de measurements-emitter), waarna de settler reactor.getEffluent pullt. De TSS-meting zet C_TS via een measurement-event; de retourpomp is een object-referentie waarvan de settler de flow afleest. De drie Fluent-stromen en de telemetrie gaan via draden naar downstream consumenten; registratie naar de eigen parent loopt via poort 2.

downstream reactor / cel parent settler deze node · S88 Unit upstream reactor stateChange → F_in, Cs_in TSS-meting quantity (tss) → C_TS retourpomp (machine) flow.measured → F_sr p2 registratie p0 3× Fluent · p1 Influx in-process events (reactor.emitter / measurement / object-ref)
registratie · via draad (poort 2) Fluent-stromen + telemetrie · via draad (poort 0/1) in-process events · reactor/measurement-emitter & object-ref

Kinderen worden via de ChildRouter gerouteerd op softwareType (src/specificClass.js:27-30): een reactor moet upstream zijn (anders een warn) en levert bij stateChange zijn getEffluent als nieuwe F_in/Cs_in (src/specificClass.js:86-100); een measurement van type quantity (tss) zet C_TS (src/specificClass.js:111-120); een downstream machine wordt de returnPump en krijgt upstreamSource = this (src/specificClass.js:102-109).

De reis van één influent-trigger

Klik een stap in de lijst (of gebruik ◀ ▶). Boven zie je waar in de massabalans je bent; rechts wat er gebeurt, de waarde van het rode-draadvoorbeeld op dat punt (met node tegen de échte Settler-code doorgerekend), en het codepad.

De 3-weg-splitsing, interactief

Dit is de complete kernlogica van get getEffluent (src/specificClass.js:37-62) als één live figuur. Schuif het influentdebiet F_in, de influent-TSS X_TS,in (= Cs_in[12]), de target-concentratie C_TS en de retourpomp-flow; de gestapelde balk verdeelt F_in in effluent / spui / retour volgens F_s = min(F_in·Cs_in[12]/C_TS, F_in). Let op het klem-gedrag: zodra X_TS,in > C_TS wordt F_s begrensd door F_in en valt het effluent op nul.

120 m³/h
4000 mg/L
8000 mg/L
40 m³/h
Werkpunt (live)
Concentraties
Bij F_s > 0 worden in het effluent de particulaten (idx 7–12) op 0 gezet; in het slib worden ze geconcentreerd met Cs_s[i] = F_in·Cs_in[i]/F_s. Oplosbare species (idx 0–6) gaan onveranderd mee (src/specificClass.js:50-54).

Wat de settler wél en niet is

Stateless massabalans — GEEN bezinkmodel
De settler splitst instantaan op één TSS-massabalans. Er is geen Vesilind-, Takács- of flux-lagenmodel, geen slibspiegel/blanket-hoogte, geen bezinksnelheid en geen tijdsintegratie. De blanket in de figuur van docs/functional.html is illustratief, niet gemodelleerd (docs/functional.html:51,65; src/specificClass.js:37-62).
De clamp F_s ≤ F_in
Als X_TS,in > C_TS zou F_in·Cs_in[12]/C_TS groter dan F_in worden; de min(…, F_in) voorkomt negatief effluent — al het debiet gaat dan naar slib (src/specificClass.js:38; tests specificClass.basic.test.js:39-47).
C_TS-default is laag (2500)
De hard-gecodeerde default C_TS = 2500 mg/L ligt onder een typische influent-TSS; zonder een quantity (tss)-meting die C_TS ophoogt, klemt het effluent al snel op 0. aanname: in bedrijf wordt C_TS via meting gezet (src/specificClass.js:24,113-116).
Retour vs. spui
F_sr = min(returnPump.flow(measured, atEquipment), F_s) — de pomp kan nooit méér trekken dan er slib bezinkt; de rest is spui F_so = F_s − F_sr. Zónder geregistreerde pomp is F_sr = 0 en gaat al het slib naar spui (src/specificClass.js:42-48).
Deling door nul afgeschermd
Cs_s[i] = F_in·Cs_in[i]/F_s draait alléén binnen if (F_s > 0); bij F_s = 0 blijft Cs_s de ongewijzigde kopie — geen NaN (src/specificClass.js:53-54).
13-species-vector, impliciet
C is getypeerd any, dus een array van afwijkende lengte wordt ongevalideerd overgenomen (handlers.js:28; commands/index.js:19-22). aanname: een te korte vector kan downstream problemen geven — geen guard gezien.

Toestanden & configuratie

Er is geen state-machine en geen AUTO/MAN-mode. De "toestand" is uitsluitend de dataset F_in, Cs_in (13-vector), C_TS en de aangesloten returnPump (src/specificClass.js:20-25). De statusbadge toont idle('no influent') (blauw) zolang F_in ≤ 0, anders een groene dot met F_in/eff/surplus (src/specificClass.js:136-142). Drie triggers leiden via notifyOutputChanged() tot nieuwe output: het influent-verb, een upstream-reactor-stateChange, en een TSS-meting.

Kernvelden uit generalFunctions/src/configs/settler.json + editor (settler.html:7-25). Opvallend: geen geometrie- of slibmodel-parameters — geen tankoppervlak, oppervlaktebelasting of bezinkcoëfficiënten. De enige "slibparameter" is de constante C_TS = 2500 (src/specificClass.js:24), overschrijfbaar via een TSS-meting, niet via config.
VeldDefaultBetekenis
general.name"Settler"leesbare naam; wordt ook het Influx-topic (fallback <softwareType>_<id>).
functionality.softwareType"settler"type voor parent-child-registratie.
functionality.positionVsParent"downstream"positie t.o.v. de eigen parent (enum upstream/atEquipment/downstream).
processOutputFormat / dbaseOutputFormat"process" / "influxdb"uitvoerformaat poort 0 / 1 (dbase ook frost/json/csv).
general.logging.logLevel"info"enum debug/info/warn/error.
asset-blokuuid/model/unit/assetTagNumber/frostServer/geoLat/geoLon (FROST-identiteit, settler.html:17-24).

Aandachtspunten uit de code-analyse

Alle punten zijn code-observaties d.d. 2026-07-17 (statisch, niet in runtime geverifieerd); de submodule-tip be671fa96872 is identiek aan origin/main (herverifieerd 2026-07-17).

Verder lezen

Bron statische code-analyse van de werkkopie RnD/EVOLV (super-repo 74c4089, 2026-07-03) — submodule settler geanalyseerd @ be671fa96872, plus het feitendossier van deze analyse. Analysedatum 2026-07-17.
Versheids-herverificatie op 2026-07-17 is git fetch gedraaid; origin/main van settler = be671fa96872, identiek aan de geanalyseerde tip. Geen open fix-branches relevant voor deze node.
Methode statische code-analyse (geen runtime-verificatie); elk feit draagt een pad:regel-verwijzing. De interactieve figuur en de console zijn getrouwe herimplementaties, vooraf met node tegen de échte Settler-domeincode doorgerekend (testgevallen als commentaar in de pagina-JS); illustratieve aannames zijn expliciet zo gelabeld.
Beperking beschrijft de geanalyseerde revisie; gedrag op andere branches of deployments kan afwijken.
Contact R&D-lab · lab.wbd-rd.nl