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

7.2 KiB
Raw Blame History

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.

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).

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

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

{
  "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.