# Reference — Contracts ![code-ref](https://img.shields.io/badge/code--ref-b825ac1-blue) ![autogen](https://img.shields.io/badge/sections-autogenerated-orange) > [!NOTE] > Full topic contract, configuration schema, and child-registration filters for `pumpingStation`. The topic-contract and data-model sections are **regenerated by `npm run wiki:all`** — do not hand-edit between the `BEGIN AUTOGEN` / `END AUTOGEN` markers. Source of truth for everything on this page: the node's `src/commands/index.js`, `src/specificClass.js` `configure()`, and the schema at `generalFunctions/src/configs/pumpingStation.json`. > > For an intuitive overview, return to the [Home](Home). --- ## Topic contract The **Unit** column reflects each descriptor's `units: { measure, default }` declaration. The default unit is what the commandRegistry coerces incoming `msg.unit` values to before the handler runs. | Canonical topic | Aliases | Payload | Unit | Effect | |---|---|---|---|---| | `set.mode` | `changemode` | `string` | — | Switch the station between auto / manual control modes. | | `child.register` | `registerChild` | `string` | — | Register a child node (machine group, measurement, …) with this station. | | `cmd.calibrate.volume` | `calibratePredictedVolume` | any | `volume` (default `m3`) | Calibrate the predicted-volume integrator to a known basin volume. | | `cmd.calibrate.level` | `calibratePredictedLevel` | any | `length` (default `m`) | Calibrate the predicted-volume integrator to a known basin level. | | `set.inflow` | `q_in` | any | `volumeFlowRate` (default `m3/h`) | Push a measured inflow value into the basin balance. | | `set.outflow` | `q_out` | any | `volumeFlowRate` (default `m3/h`) | Push a measured outflow value into the basin balance. | | `set.demand` | `Qd` | any | `volumeFlowRate` (default `m3/h`) | Operator outflow demand setpoint for the station. | --- ## Data model — `getOutput()` shape Keys composed each tick by `specificClass.getOutput()` and emitted via `outputUtils.formatMsg` on Port 0. Delta-compressed: consumers see only the keys that changed. | Key | Type | Unit | Sample | |---|---|---|---| | `direction` | string | — | `"steady"` | | `dryRunLevel` | number | — | `0.20400000000000001` | | `dryRunSafetyVol` | number | — | `0.20400000000000001` | | `flowSource` | null | — | `null` | | `heightBasin` | number | m | `1` | | `highVolumeSafetyLevel` | number | — | `2.45` | | `highVolumeSafetyVol` | number | — | `2.45` | | `inflowLevel` | number | m | `2` | | `inletPipeDiameter` | number | — | `0.4` | | `maxVol` | number | m3 | `1` | | `maxVolAtOverflow` | number | m3 | `2.5` | | `minHeightBasedOn` | string | — | `"outlet"` | | `minVol` | number | m3 | `0.2` | | `minVolAtInflow` | number | m3 | `2` | | `minVolAtOutflow` | number | m3 | `0.2` | | `outflowLevel` | number | m | `0.2` | | `outletPipeDiameter` | number | — | `0.4` | | `overflowLevel` | number | m | `2.5` | | `percControl` | number | % | `0` | | `predictedOverflowRate` | number | — | `0` | | `predictedOverflowVolume` | number | — | `0` | | `predictedUnderflowVolume` | number | — | `0` | | `surfaceArea` | number | m2 | `1` | | `timeleft` | null | s | `null` | | `volEmptyBasin` | number | m3 | `1` | | `volume.predicted.atequipment.wikigen-pumpingstation-id` | number | m3 | `0.2` | Sample values come from a stub instantiation in `wikiGen` — in a live deployment the volume key is shaped `volume...` per the standard [Measurement Key Shape](https://gitea.wbd-rd.nl/RnD/EVOLV/wiki/Topic-Conventions#measurement-key-shape). --- ## Configuration schema — editor form to config keys Source of truth: `generalFunctions/src/configs/pumpingStation.json`. ### Basin geometry (`config.basin`) | Form field | Config key | Default | Unit | Notes | |:---|:---|:---|:---|:---| | Basin Volume | `basin.volume` | `1` | m3 | Total geometric storage from floor to rim | | Basin Height | `basin.height` | `1` | m | Floor-to-rim wall height | | Inlet Elevation | `basin.inflowLevel` | `2` | m | Bottom of incoming pipe, from floor | | Outlet Elevation | `basin.outflowLevel` | `0.2` | m | Top of pump-suction pipe, from floor | | Inlet Pipe Diameter | `basin.inletPipeDiameter` | `0.4` | m | For future hydraulic upgrades | | Outlet Pipe Diameter | `basin.outletPipeDiameter` | `0.4` | m | For future hydraulic upgrades | | Overflow Level | `basin.overflowLevel` | `2.5` | m | Physical overflow weir crest | ### Safety thresholds (`config.safety`) | Form field | Config key | Default | Notes | |:---|:---|:---|:---| | High-Volume Safety % | `safety.highVolumeSafetyThresholdPercent` | `98` | Trigger high-volume safety at this fill % | | Dry-Run Safety Level | `safety.dryRunLevel` | `0.2` | Below this level all pumps stop | | Enable High-Volume Safety | `safety.enableHighVolumeSafety` | `true` | Master switch | > [!WARNING] > Earlier versions used `enableOverfillProtection` and `overfillThresholdPercent`. Those names are deprecated. The current canonical names are `enableHighVolumeSafety` and `highVolumeSafetyThresholdPercent`. See `.claude/refactor/OPEN_QUESTIONS.md` for the alias-removal timeline. ### Control mode (`config.control`) | Form field | Config key | Default | Notes | |:---|:---|:---|:---| | Mode | `control.mode` | `"levelbased"` | One of `levelbased`, `manual`, `flowbased`*, `pressureBased`*, `percentageBased`*, `powerBased`*, `hybrid`*. Asterisked modes are placeholders in code. | | Level Curve Type | `control.levelbased.curveType` | `"linear"` | `linear` or `log` | | Log Curve Factor | `control.levelbased.logCurveFactor` | `0.5` | Slope tuning for log curve | | Min Level | `control.levelbased.minLevel` | `0.3` | Demand hard-zero below this | | Start Level | `control.levelbased.startLevel` | `0.5` | Falling-ramp returns to 0 % here | | Stop Level | `control.levelbased.stopLevel` | `0.4` | Schmitt-trigger lower bound for pump-count keep-alive | | Max Level | `control.levelbased.maxLevel` | `2.3` | Demand saturates at 100 % here | | Enable Shifted Ramp | `control.levelbased.enableShiftedRamp` | `true` | Hysteresis-armed shift between rising / falling ramps | | Manual Flow Setpoint | `control.manual.flowSetpoint` | `0` | Honoured in `manual` mode | ### General (`config.general`) | Form field | Config key | Default | Notes | |:---|:---|:---|:---| | Time-left full / empty threshold | `general.timeleftToFullOrEmptyThresholdSeconds` | `120` | ETA below this triggers warning state | | Flow dead-band | `general.flowThreshold` | `1e-4` m³/s | Net-flow below this is treated as steady | --- ## Child registration Source: `nodes/pumpingStation/src/specificClass.js` `configure()`, lines 107–116. | Software type | Filter | Wired to | Side-effect | |:---|:---|:---|:---| | `measurement` | any | `_subscribeMeasurement` | Subscribes to the measurement's emitter; updates basin balance | | `machine` | only if no `machinegroup` parent is present | direct dispatch | Bypassed when an MGC is the predicted-flow source | | `machinegroup` | any | `_subscribePredictedFlow` | Reads aggregated predicted flow from the MGC | | `pumpingstation` | any | `_subscribePredictedFlow` | Cascaded PS — reads predicted outflow of upstream station | The router only subscribes to the **highest-level aggregator** for predicted flow. If an MGC is present, direct `machine` children are not double-counted. --- ## Unit policy Source: `nodes/pumpingStation/src/specificClass.js` lines 21–30. | Quantity | Canonical (internal) | Output (rendered) | |:---|:---|:---| | Flow | `m3/s` | `m3/s` (also `netFlowRate`) | | Level | `m` | `m` | | Volume | `m3` | `m3` | | Pressure | `Pa` | (not surfaced) | | Power | `W` | (not surfaced) | | Temperature | `K` | (not surfaced) | `overflowVolume` and `underflowVolume` are explicitly listed in the policy output so the `MeasurementContainer` keeps the integrator's `m3` unit on those streams (`FlowAggregator` writes spill / underflow per tick). --- ## Related pages | Page | Why | |:---|:---| | [Home](Home) | Intuitive overview | | [Reference — Architecture](Reference-Architecture) | Code map, state chart, lifecycle | | [Reference — Examples](Reference-Examples) | Shipped example flows | | [Reference — Limitations](Reference-Limitations) | Known limitations and open questions | | [EVOLV — Topic Conventions](https://gitea.wbd-rd.nl/RnD/EVOLV/wiki/Topic-Conventions) | Platform-wide topic rules | | [EVOLV — Telemetry](https://gitea.wbd-rd.nl/RnD/EVOLV/wiki/Telemetry) | Port 0 / 1 / 2 InfluxDB layout |