72 lines
3.7 KiB
Markdown
72 lines
3.7 KiB
Markdown
|
|
# diffuser — Contract
|
|||
|
|
|
|||
|
|
Hand-maintained for Phase 6; the `## Inputs` table is generated from
|
|||
|
|
`src/commands/index.js` (see Phase 9 generator). Keep ≤ 100 lines.
|
|||
|
|
|
|||
|
|
## Inputs (msg.topic on Port 0)
|
|||
|
|
|
|||
|
|
| Canonical | Aliases (deprecated) | Payload | Effect |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| `data.flow` | `air_flow` | `number` — airflow in Nm³/h | Calls `source.setFlow(payload)`; clamps to ≥ 0 and recomputes OTR. |
|
|||
|
|
| `set.density` | `density` | `number` — diffuser density (per m²) | Calls `source.setDensity(payload)` and recomputes. |
|
|||
|
|
| `set.water-height` | `height_water` | `number` — water column height in m | Calls `source.setWaterHeight(payload)`; clamps to ≥ 0 and recomputes head + total pressure. |
|
|||
|
|
| `set.header-pressure` | `header_pressure` | `number` — header gauge pressure in mbar | Calls `source.setHeaderPressure(payload)` and recomputes. |
|
|||
|
|
| `set.elements` | `elements` | `number` — element count (rounded; must be > 0) | Calls `source.setElementCount(payload)` and recomputes per-element flow. |
|
|||
|
|
| `set.alfa-factor` | `alfaFactor` | `number` — alpha correction (≥ 0) | Calls `source.setAlfaFactor(payload)` and recomputes oxygen output. |
|
|||
|
|
|
|||
|
|
Aliases log a one-time deprecation warning the first time they fire.
|
|||
|
|
|
|||
|
|
## Outputs (msg.topic on Port 0/1/2)
|
|||
|
|
|
|||
|
|
- **Port 0 (process):** `msg.topic = config.general.name`. Payload built
|
|||
|
|
by `outputUtils.formatMsg(..., 'process')` from `getOutput()` —
|
|||
|
|
delta-compressed (only changed fields are emitted). Fields:
|
|||
|
|
- `iPressure`, `iMWater`, `iFlow` — echoed inputs.
|
|||
|
|
- `nFlow` — normalised airflow (Nm³/h).
|
|||
|
|
- `oOtr` — interpolated oxygen transfer rate (g O₂ / Nm³).
|
|||
|
|
- `oPLoss` — total head loss (mbar) = static head + diffuser ΔP.
|
|||
|
|
- `oKgo2H` — kg O₂ per hour at current operating point.
|
|||
|
|
- `oFlowElement` — flow per element (Nm³/h/element).
|
|||
|
|
- `efficiency` — combined OTR/ΔP efficiency (0–100).
|
|||
|
|
- `slope` — local OTR-vs-flow slope.
|
|||
|
|
- `oZoneOtr` — reactor zone OTR (kg O₂ / m³ / day) computed against
|
|||
|
|
`diffuser.zoneVolume`; `0` when zone volume is unset.
|
|||
|
|
- `idle` — true when `data.flow ≤ 0`.
|
|||
|
|
- `warning`, `alarm` — string arrays describing flow-per-element band
|
|||
|
|
excursions.
|
|||
|
|
- **Port 1 (InfluxDB telemetry):** same shape as Port 0, formatted with
|
|||
|
|
the `'influxdb'` formatter.
|
|||
|
|
- **Port 2 (registration):** at startup the node sends one
|
|||
|
|
`{ topic: 'child.register', payload: <node.id>, positionVsParent,
|
|||
|
|
distance }` to the upstream parent (typically a reactor).
|
|||
|
|
`positionVsParent` defaults to `'atEquipment'`.
|
|||
|
|
|
|||
|
|
## Port-count change (Phase 6)
|
|||
|
|
|
|||
|
|
Pre-refactor the diffuser exposed 4 outputs (process, dbase, reactor
|
|||
|
|
control with `topic: 'OTR'`, parent registration). The reactor control
|
|||
|
|
message merged into Port 0 as `oZoneOtr`; consumers that previously
|
|||
|
|
listened to the dedicated control port should switch to reading
|
|||
|
|
`payload.oZoneOtr` from the process output. The legacy `OTR` topic is
|
|||
|
|
removed in this refactor — there is no alias, since the data shape
|
|||
|
|
differs (single value vs full process payload).
|
|||
|
|
|
|||
|
|
## Events emitted by `source.measurements.emitter`
|
|||
|
|
|
|||
|
|
None today. The diffuser does not currently publish typed measurements
|
|||
|
|
through `MeasurementContainer`; all output flows via `getOutput()`.
|
|||
|
|
A future phase may promote `oOtr` and `oZoneOtr` to typed series so
|
|||
|
|
parent reactors can subscribe through the standard `ChildRouter`
|
|||
|
|
handshake.
|
|||
|
|
|
|||
|
|
## Events emitted by `source.emitter`
|
|||
|
|
|
|||
|
|
- `output-changed` — fires whenever an input setter recomputes the
|
|||
|
|
oxygen-transfer state. `BaseNodeAdapter` listens and pushes the
|
|||
|
|
delta-compressed Port 0 / Port 1 messages.
|
|||
|
|
|
|||
|
|
## Children registered by this node
|
|||
|
|
|
|||
|
|
None. The diffuser is a leaf Equipment Module; it registers itself with
|
|||
|
|
its parent (reactor / process cell) via the Port 2 handshake.
|