Defines the 9-section template every node's wiki page follows: 1. Position in the platform (mermaid flowchart, S88-coloured) 2. Capability matrix (≤ 10 rows) 3. Topic contract (auto-generated from src/commands/index.js) 4. Lifecycle (mermaid sequenceDiagram) 5. Configuration (mermaid flowchart + form-to-config table) 6. Examples (basic/integration/dashboard tiers) 7. State chart (stateDiagram-v2, only for stateful nodes) 8. When you would NOT use this node 9. Known limitations / current issues Hard rules: diagrams before prose, ≤ 60 words of unbroken prose anywhere, topic contract auto-generated (no hand-written drift). Per-node application is the next step (P9.3-P9.6 in TASKS.md). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.2 KiB
Wiki page template — every node uses this shape
This is the canonical structure for every node's gitea wiki landing page. Visual-first, scannable, ≤ 60 words of unbroken prose anywhere.
Why this shape
The platform now has 12 nodes with the same architectural skeleton (BaseDomain + BaseNodeAdapter + ChildRouter + commands registry). The wiki should mirror that uniformity: a reader can flip between nodes and find the same sections in the same order.
Mermaid blocks lead. Tables annotate. Prose only fills gaps.
Template — copy this whole file as the seed for each node's wiki
# <Node name>
> One-paragraph "what is this node". Cap 60 words. Plain English.
> Example: "rotatingMachine models a single pump or compressor —
> takes pressure measurements and predicts flow + power from supplier
> curves. State machine drives startup/shutdown sequences."
## 1. Position in the platform
```mermaid
flowchart LR
parent[<Parent type — e.g. machineGroupControl>] -->|set.demand| this[<This node>]
this -->|evt.state-change| parent
sensor[<measurement>] -->|data.flow| this
this -->|child.register| parent
classDef proc fill:#0c99d9,color:#fff
classDef unit fill:#50a8d9
classDef equip fill:#86bbdd
classDef ctrl fill:#a9daee
class this <classname-by-S88-level>
The Mermaid block shows the typical neighbours and the data direction.
Pick the right classDef for the S88 level (Process Cell / Unit /
Equipment / Control Module). Match the colour codes from
.claude/rules/node-red-flow-layout.md.
2. Capability matrix
| Capability | Status | Notes |
|---|---|---|
| Predicts flow from pressure | ✅ | |
| Receives manual setpoint | ✅ | Topic set.setpoint |
| Auto-start on demand from parent | ✅ | |
| Self-calibrating | ❌ | Calibration is operator-triggered (cmd.calibrate) |
| Supports multi-parent registration | ⚠️ | Possible but not fully tested — see CONTRACT.md notes |
Keep this table to ≤ 10 rows. For longer feature inventories, link out.
3. Topic contract
Auto-generated from
src/commands/index.js. Do NOT hand-edit. Re-runnpm run wiki:contractafter any change to commands.
| Canonical topic | Aliases | Payload | Effect |
|---|---|---|---|
set.mode |
setMode |
string (auto | manual | maintenance) |
Switches operating mode. |
cmd.startup |
execSequence (with payload.action='startup') |
{source: string} |
Triggers startup sequence (state machine). |
| ... | ... | ... | ... |
4. Lifecycle — what one tick (or event) does
sequenceDiagram
participant parent
participant node as this node
participant sensor as measurement child
participant out as Port-0 output
sensor->>node: data.flow (12 m³/h, downstream)
node->>node: route → measurementHandlers
node->>node: drift assess → predictionHealth update
node->>node: getOutput composes snapshot
node->>out: msg{topic, payload, [process|influx]}
parent->>node: set.demand (15 m³/h)
node->>node: control.dispatch
node->>parent: child.register (handshake)
Keep the diagram to one screen. If you have multiple distinct flows (idle vs running vs error), pick the most common one and link out to the others.
5. Configuration — editor form & where each field lands
flowchart TB
subgraph editor["Node-RED editor form"]
f1[Mode]
f2[Demand]
f3[Threshold percent]
end
subgraph config["Domain config"]
c1[control.mode]
c2[control.targets.demand]
c3[safety.thresholdPercent]
end
f1 --> c1
f2 --> c2
f3 --> c3
| Form field | Config key | Default | Range |
|---|---|---|---|
| Mode | control.mode |
auto |
enum |
| Demand | control.targets.demand |
0 |
≥ 0 |
| Threshold % | safety.thresholdPercent |
95 |
0–100 |
6. Examples
| Tier | File | What it shows |
|---|---|---|
| Basic | examples/01-Basic.json |
Inject + dashboard, no parent |
| Integration | examples/02-Integration.json |
Wired to <parent> + 1 measurement child |
| Dashboard | examples/03-Dashboard.json |
Live FlowFuse charts of flow / power / state |
Include one screenshot per tier where helpful — keep them under 200 KB
each. Link to a runnable docker compose snippet under examples/README.md.
7. State chart (only for stateful nodes)
stateDiagram-v2
[*] --> off
off --> idle: cmd.startup
idle --> warmingup: setpoint > 0
warmingup --> operational: warmup_time elapsed
operational --> coolingdown: cmd.shutdown
coolingdown --> off: cooldown_time elapsed
operational --> emergencystop: cmd.estop
emergencystop --> off: cmd.reset
Skip this section for stateless / pure-aggregator nodes (e.g. measurement, dashboardAPI).
8. When you would NOT use this node
- "Use rotatingMachine for a SINGLE pump. For groups of 2+ pumps with load sharing, use machineGroupControl as the parent."
- "Use measurement only for sensor signal conditioning. For setpoint injection, use the dashboard or a parent's command topic."
Two or three bullets, each one sentence. Forces explicit non-goals.
9. Known limitations / current issues
| # | Issue | Tracked in |
|---|---|---|
| 1 | Drift confidence drops to 0 when pressure is missing for > 30 s | OPEN_QUESTIONS.md 2026-05-10 |
| 2 | Multi-parent teardown ordering | OPEN_QUESTIONS.md 2026-05-10 |
Link to repo issues when they exist. Keep this table living — it's the contract with the user about what "works".
## Hard rules for editors
1. The Mermaid platform-position block is **section 1**, before any
prose. Diagrams first.
2. Each section opens with a diagram or table; prose annotates the
visual, not the other way round.
3. No more than **60 words of unbroken prose** anywhere on a page.
4. The topic contract is **auto-generated** from `src/commands/index.js`.
Don't hand-write it.
5. Use `flowchart LR` for node connections, `sequenceDiagram` for
tick-to-output flow, `stateDiagram-v2` for state machines.
6. Skip `classDiagram` (we don't expose classes to users) and `gantt`
(no schedules in node docs).
## Auto-generation notes (Phase 9 follow-up)
The "Topic contract" table in section 3 should be generated by a small
`npm run wiki:contract` script, per node. Implementation:
```js
// scripts/generate-contract.js
const commands = require('../src/commands');
const rows = commands.map((c) => ({
topic: c.topic,
aliases: (c.aliases || []).join(', ') || '—',
payload: describeSchema(c.payloadSchema),
effect: c.description || '— (handler-only)',
}));
console.log(toMarkdownTable(rows));
describeSchema walks the lightweight schema ({type, properties})
and produces a one-line readable form. Wire each node's package.json:
"scripts": {
"wiki:contract": "node scripts/generate-contract.js > wiki/_partial-topics.md"
}
Then a thin wiki page <Node>.md includes _partial-topics.md (or
the section is regenerated in-place between markers).
What lives in the gitea wiki vs the repo
wiki/directory in the repo (where present): canonical, version- controlled.- gitea wiki UI: cosmetic mirror — re-rendered from
wiki/on push. - Auto-generated partials (
_partial-*.md): committed underwiki/but generated; never hand-edited.