Files
EVOLV/wiki/Topic-Conventions.md
znetsixe 2ccc8aea9e wiki: master EVOLV wiki refactor — 7 new pages + corrected Home
Complete redesign of the platform-level wiki. Previous Home.md had a
broken Mermaid diagram (showed pumpingStation → valveGroupControl as a
parent/child edge, which isn't in any configure() declaration). Audit
of all 12 specificClass.js configure() calls drives the new ground-truth
hierarchy.

New pages:
- Home.md (rewritten — accurate mermaid, full node + concept index)
- Architecture.md (3-tier code structure, generalFunctions API surface,
  child-registration sequence)
- Topology-Patterns.md (5 verified plant configurations + worked example)
- Topic-Conventions.md (set./cmd./evt./data./child. + unit policy + S88
  palette + measurement key shape + status badge + HealthStatus)
- Telemetry.md (Port 0/1/2 contracts + InfluxDB line-protocol layout +
  FlowFuse charts + Grafana provisioning)
- Getting-Started.md (clone, install, Docker vs local, first example)
- Glossary.md (S88, EVOLV runtime, WWTP, pumps, control, project terms)
- _Sidebar.md (gitea wiki navigation)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 21:47:57 +02:00

186 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Topic Conventions
> **Reflects code as of `9ab9f6b` · regenerated `2026-05-11`**
Naming rules, unit policy, and S88 colour palette. Source of truth: `.claude/refactor/CONTRACTS.md` §1.
## Topic prefixes
Every topic is `<prefix>.<verb>` lowercase. Five prefixes only.
```mermaid
flowchart LR
ui[UI / parent / driver]:::neutral
node[Node]:::tier3
child[Child]:::tier1
ui -->|set.x / cmd.x| node
node -->|evt.x| ui
child -->|data.x| node
node -->|data.x| child
child -->|child.register| node
classDef neutral fill:#dddddd
classDef tier3 fill:#50a8d9,color:#000
classDef tier1 fill:#a9daee,color:#000
```
| Prefix | Direction | Semantics | Examples |
|---|---|---|---|
| `set.` | inbound | Set a configurable value. **Idempotent**, no side-effects beyond storing the value. | `set.mode`, `set.demand`, `set.position` |
| `cmd.` | inbound | Trigger an action. **Has side-effects** (state transitions, motor commands). | `cmd.startup`, `cmd.shutdown`, `cmd.calibrate`, `cmd.estop` |
| `data.` | bidirectional | Carries measurement / process data. Used by `measurement → parent` and emitters. | `data.pressure`, `data.flow`, `data.temperature` |
| `evt.` | outbound | Announces something happened. Consumer-driven. | `evt.state-change`, `evt.alarm`, `evt.health` |
| `child.` | inbound (parent) | Child node lifecycle. | `child.register` (with legacy alias `registerChild`) |
**Anti-patterns to avoid:**
- ❌ A topic that does two things (`setStartup` to both set a flag *and* trigger startup). Split into `set.` + `cmd.`.
- ❌ Reusing a `cmd.` topic for both inbound trigger and outbound ack — make a paired `evt.<verb>-complete`.
- ❌ Per-node prefixes (`pump.set.demand`). The prefix is the *kind*, not the *target*.
## Alias deprecation
Legacy topic names (pre-refactor) are still accepted as aliases. The current alias map per node lives in `src/commands/index.js`. Common aliases:
| Canonical | Legacy aliases |
|---|---|
| `set.mode` | `setMode` |
| `set.demand` | `Qd`, `setDemand` |
| `cmd.startup` | `execSequence` with `payload.action='startup'` |
| `cmd.shutdown` | `execSequence` with `payload.action='shutdown'` |
| `child.register` | `registerChild` |
| `data.pressure` | `pressure` |
| `data.flow` | `flow` |
Aliases are logged at debug level on use. Plan is to remove them in a future major version. Update integrations to canonical names.
## Unit policy
Every node declares canonical + output units via `UnitPolicy.declare({canonical, output})`. The command registry coerces incoming `msg.unit` to the canonical unit before the handler runs. Outputs are emitted in the declared output unit (often human-friendly).
```mermaid
flowchart LR
ui[UI message<br/>e.g. 50 m³/h]:::neutral
coerce[unit coercion<br/>m³/h → m³/s]:::tier1
sc[specificClass<br/>canonical m³/s]:::tier3
out[output<br/>renders back to m³/h]:::tier2
ui --> coerce --> sc --> out
classDef neutral fill:#dddddd
classDef tier1 fill:#a9daee,color:#000
classDef tier3 fill:#50a8d9,color:#000
classDef tier2 fill:#86bbdd,color:#000
```
| Quantity | Canonical (internal) | Common output |
|---|---|---|
| Flow | `m3/s` | `m3/h`, `l/s`, `gpm` |
| Pressure | `Pa` | `bar`, `mbar`, `kPa` |
| Power | `W` | `kW`, `MW` |
| Temperature | `K` | `degC`, `degF` |
| Level | `m` | `m`, `cm` |
| Volume | `m3` | `m3`, `l` |
**Rule:** anywhere in `specificClass`, treat values as canonical. Conversion happens at the boundary (input coercion + output formatting).
## S88 colour palette
```mermaid
flowchart TB
A[Area<br/>#0f52a5]:::area
PC[Process Cell<br/>#0c99d9]:::pc
UN[Unit<br/>#50a8d9]:::unit
EM[Equipment Module<br/>#86bbdd]:::equip
CM[Control Module<br/>#a9daee]:::ctrl
UT[Utility / neutral<br/>#dddddd]:::neutral
A --> PC --> UN --> EM --> CM
UT -.- A
classDef area fill:#0f52a5,color:#fff
classDef pc fill:#0c99d9,color:#fff
classDef unit fill:#50a8d9,color:#000
classDef equip fill:#86bbdd,color:#000
classDef ctrl fill:#a9daee,color:#000
classDef neutral fill:#dddddd,color:#000
```
| Hex | S88 level | Used by |
|---|---|---|
| `#0f52a5` | Area | (reserved — not in use yet) |
| `#0c99d9` | Process Cell | pumpingStation |
| `#50a8d9` | Unit | machineGroupControl, valveGroupControl, reactor, settler, monster |
| `#86bbdd` | Equipment Module | rotatingMachine, valve, diffuser |
| `#a9daee` | Control Module | measurement |
| `#dddddd` | Utility / neutral | dashboardAPI, helper function nodes |
**Rule:** every Mermaid diagram in this wiki, every Node-RED node's editor colour, and every dashboard grouping uses this palette. Source of truth: `.claude/rules/node-red-flow-layout.md` §14.
**Known outliers** (pending cleanup, tracked in OPEN_QUESTIONS.md):
- `settler` editor colour is `#e4a363` (orange) — should be `#50a8d9`.
- `monster` editor colour is `#4f8582` (teal) — should be `#50a8d9`.
- `diffuser` editor colour was missing pre-refactor; now `#86bbdd`.
- `dashboardAPI` registers under category `'wbd typical'` instead of `'EVOLV'`.
## Measurement key shape
The `MeasurementContainer` stores values under composite keys:
```
<type>.<variant>.<position>.<childId>
```
| Segment | Examples |
|---|---|
| `type` | `flow`, `pressure`, `power`, `temperature`, `level` |
| `variant` | `measured`, `predicted`, `setpoint`, `min`, `max` |
| `position` | `upstream`, `downstream`, `atequipment`, `inlet`, `outlet` (always lowercase in keys) |
| `childId` | The registering child's id, OR `default` for internal computations |
Examples:
- `flow.measured.downstream.dashboard-sim-downstream` — externally measured downstream flow.
- `flow.predicted.downstream.default` — node's own prediction.
- `power.measured.atequipment.default` — measured power at the equipment.
- `pressure.measured.upstream.<childId>` — pressure from a specific measurement child.
**Gotcha:** `position` is **always lowercase in keys**. The configuration form may use mixed case (`atEquipment`); the container normalises.
## Status badge
`statusBadge.compose(state)` returns `{fill, shape, text}` for `node.status(...)`:
| level | shape | fill | meaning |
|---|---|---|---|
| `info` | dot | blue | normal operation |
| `success` | dot | green | success / running optimally |
| `warning` | ring | yellow | degraded, attention needed |
| `error` | ring | red | fault, operator action required |
| `pending` | dot | grey | initialising / no data yet |
Composer reads from `HealthStatus.level` (03) — kept centralised so all nodes show consistent badges.
## HealthStatus shape
```json
{
"level": 0,
"flags": ["pressure_init_warming"],
"message": "warmup phase",
"source": "rotatingMachine#pump-A"
}
```
| Field | Range | Meaning |
|---|---|---|
| `level` | 0..3 | 0 = healthy, 1 = degraded, 2 = warning, 3 = error |
| `flags` | string[] | Machine-readable reason codes. |
| `message` | string | Human-readable summary (one line). |
| `source` | string | `<nodeType>#<id>` — for routing UI / alarm correlation. |
## Related pages
- [Architecture](Architecture) — generalFunctions API surface
- [Telemetry](Telemetry) — Port-1 InfluxDB schema (where these conventions appear in stored data)
- [Topology-Patterns](Topology-Patterns) — what topics flow where