docs(contract): add worked msg examples for every input + output port
Reference-Contracts.md now carries a concrete `msg = { topic, payload, ... }`
example for each of the 7 input topics (plus the built-in query.units) and for
all three output ports (Port 0 process, Port 1 InfluxDB, Port 2 registration),
plus the emitter-event shape. Shapes verified against commandRegistry unit
normalisation and the process/influxdb formatters. Examples sit outside the
AUTOGEN markers so `npm run wiki:all` stays a no-op on them.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -27,6 +27,48 @@ The **Unit** column reflects each descriptor's `units: { measure, default }` dec
|
|||||||
|
|
||||||
<!-- END AUTOGEN: topic-contract -->
|
<!-- END AUTOGEN: topic-contract -->
|
||||||
|
|
||||||
|
### Input message examples
|
||||||
|
|
||||||
|
One worked `msg` per accepted topic. Send these into **Port 0**. For unit-bearing
|
||||||
|
topics the commandRegistry converts `msg.unit` (or a `{ value, unit }` payload) to
|
||||||
|
the default unit *before* the handler runs — so the unit is optional and any
|
||||||
|
[compatible unit](https://gitea.wbd-rd.nl/RnD/EVOLV/wiki/Topic-Conventions) is accepted.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// 1. set.mode — switch control strategy
|
||||||
|
msg = { topic: 'set.mode', payload: 'manual' }; // manual | levelbased | flowbased | none
|
||||||
|
|
||||||
|
// 2. child.register — register a child (usually arrives on Port 2 from the child;
|
||||||
|
// this is the manual form). payload = the child node's Node-RED id.
|
||||||
|
msg = { topic: 'child.register', payload: 'a1b2c3d4.ef567', positionVsParent: 'upstream' };
|
||||||
|
// positionVsParent: upstream | downstream | atequipment (or in | out for predicted-flow children)
|
||||||
|
|
||||||
|
// 3. cmd.calibrate.volume — seed the predicted-volume integrator (default m³)
|
||||||
|
msg = { topic: 'cmd.calibrate.volume', payload: 12.5 }; // 12.5 m³
|
||||||
|
msg = { topic: 'cmd.calibrate.volume', payload: 12500, unit: 'L' }; // 12 500 L → auto-converted to 12.5 m³
|
||||||
|
|
||||||
|
// 4. cmd.calibrate.level — seed the predicted level (default m)
|
||||||
|
msg = { topic: 'cmd.calibrate.level', payload: 1.8 }; // 1.8 m
|
||||||
|
|
||||||
|
// 5. set.inflow — push a measured inflow (default m³/h)
|
||||||
|
msg = { topic: 'set.inflow', payload: 45 }; // 45 m³/h
|
||||||
|
msg = { topic: 'set.inflow', payload: 12.5, unit: 'L/s' }; // 12.5 L/s → 45 m³/h
|
||||||
|
msg = { topic: 'set.inflow', payload: { value: 45, unit: 'm3/h' }, timestamp: 1716998400000 };
|
||||||
|
|
||||||
|
// 6. set.outflow — push a measured/forced outflow (default m³/h)
|
||||||
|
msg = { topic: 'set.outflow', payload: 30 }; // 30 m³/h drawn from the basin
|
||||||
|
|
||||||
|
// 7. set.demand — operator outflow setpoint (default m³/h); ignored unless mode === 'manual'
|
||||||
|
msg = { topic: 'set.demand', payload: 120 }; // 120 m³/h
|
||||||
|
|
||||||
|
// Built-in (every EVOLV node): query.units — ask which units each topic accepts.
|
||||||
|
// Replies on Port 0 with { topic:'query.units', payload:{ node, units } }.
|
||||||
|
msg = { topic: 'query.units', payload: null };
|
||||||
|
```
|
||||||
|
|
||||||
|
> Deprecated aliases behave identically and log a one-time warning, e.g.
|
||||||
|
> `{ topic: 'q_in', payload: 45 }` ≡ `set.inflow`, `{ topic: 'Qd', payload: 120 }` ≡ `set.demand`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Data model — `getOutput()` shape
|
## Data model — `getOutput()` shape
|
||||||
@@ -75,6 +117,52 @@ Sample values come from a stub instantiation in `wikiGen` — in a live depl
|
|||||||
> - `mode` — string, the active control strategy (`levelbased` / `manual` / `flowbased` / `none`). Echoes the most recent `set.mode` input.
|
> - `mode` — string, the active control strategy (`levelbased` / `manual` / `flowbased` / `none`). Echoes the most recent `set.mode` input.
|
||||||
> - `manualDemand` — number (m³/h) or `null`. The operator outflow setpoint last accepted via `set.demand`; `null` outside `manual` mode.
|
> - `manualDemand` — number (m³/h) or `null`. The operator outflow setpoint last accepted via `set.demand`; `null` outside `manual` mode.
|
||||||
|
|
||||||
|
### Output message examples
|
||||||
|
|
||||||
|
The node emits on three ports every tick (`outputUtils.formatMsg`). Port 0 / Port 1
|
||||||
|
fire only when at least one field changed (delta-compression); Port 2 fires once at
|
||||||
|
startup. `topic` is the station's configured name (here `"PS-Influent-01"`).
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Port 0 — process data. payload = only the keys that changed this tick.
|
||||||
|
msg = {
|
||||||
|
topic: 'PS-Influent-01',
|
||||||
|
payload: {
|
||||||
|
mode: 'levelbased',
|
||||||
|
direction: 'filling',
|
||||||
|
percControl: 25,
|
||||||
|
'level.predicted.atequipment.default': 3.25, // m
|
||||||
|
'volume.predicted.atequipment.default': 32.5, // m³
|
||||||
|
timeleft: 400, // s, or null when steady
|
||||||
|
manualDemand: null // m³/h, or null outside manual mode
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Port 1 — InfluxDB telemetry. Same changed fields, wrapped for the InfluxDB node.
|
||||||
|
msg = {
|
||||||
|
topic: 'PS-Influent-01',
|
||||||
|
payload: {
|
||||||
|
measurement: 'PS-Influent-01',
|
||||||
|
fields: { percControl: 25, 'volume.predicted.atequipment.default': 32.5 },
|
||||||
|
tags: { id: 'a1b2c3d4.ef567', softwareType: 'pumpingstation', type: 'pumpingStation' },
|
||||||
|
timestamp: '2026-05-29T10:00:00.000Z' // Date
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Port 2 — registration handshake, sent once at startup to the upstream parent.
|
||||||
|
msg = {
|
||||||
|
topic: 'child.register',
|
||||||
|
payload: 'a1b2c3d4.ef567', // this node's id
|
||||||
|
positionVsParent: 'atEquipment',
|
||||||
|
distance: null
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Child-facing events** are not Port messages — they fire on
|
||||||
|
> `source.measurements.emitter` as `<type>.<variant>.<position>`, e.g. event
|
||||||
|
> `volume.predicted.atequipment` with payload `{ value: 32.5, unit: 'm3', timestamp }`.
|
||||||
|
> Parents subscribe by event name.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Configuration schema — editor form to config keys
|
## Configuration schema — editor form to config keys
|
||||||
|
|||||||
Reference in New Issue
Block a user