### eval/ (scenario-based evaluation)
Complements the unit tests under test/basic. Scenarios fluctuate inputs
over simulated time, record every tick to JSONL, print a summary
table + event log, and check expectations. Complementary to unit
tests — these answer "how does the system respond to this input
profile" rather than "is this function correct".
- eval/run.js — driver; monkey-patches Date.now so the
volume integrator ticks at 1 s/iter
regardless of wall-clock
- eval/scenarios/ — one file per scenario
- levelbased-steady.js — constant inflow, demand converges
- levelbased-storm.js — inflow surge, demand saturates
- safety-dry-run-trip.js — manual mode, empty basin, safety trips
- eval/formatters/table.js — ASCII summary of sampled ticks
- eval/logs/ — per-scenario JSONL output (one line per tick)
- eval/README.md — usage + scenario file shape + how to pipe
into InfluxDB/Grafana
All three starter scenarios PASS with their expectations.
### wiki/modes/ (tier template pages)
The levelbased page templated Tier-1 modes (static transfer function).
Added worked examples for the other two tiers so all mode pages share
a common skeleton and new modes have something concrete to imitate:
- flowbased.md — Tier 2 (PID on measured outflow)
- powerbased.md — Tier 2 (levelbased curve clipped by grid power budget)
- mpc.md — Tier 3 (optimisation + forecast; block diagram +
scenario time-series instead of a fixed curve)
- modes/README.md — updated with the three-tier classification table
and diagram-type-per-tier guidance
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2.2 KiB
2.2 KiB
Control modes
Each page describes one pumpingStation control mode and how it uses the shared basin model — specifically, how it uses the three control thresholds (minLevel, startLevel, maxLevel) and computes the demand it sends to the MGC.
The two safety thresholds (dryRunLevel and overflowLevel) are mode-independent and are enforced by the safety layer outside any mode. They never appear in a mode's policy.
Template
Every mode page follows the same structure:
- At a glance — one sentence + small fact table (inputs, output, status)
- Diagram — one or more, per tier (see below)
- Inputs — what signals the mode reads
- Threshold policy — how it uses / adjusts
minLevel,startLevel,maxLevel - Demand formula — pseudocode for Tier 1/2, objective function for Tier 3
- Edge cases — cold start, sensor dropout, interaction with safety layer
- Related — links to other modes + functional description
The three tiers classify modes by how dynamic the decision surface is:
| Tier | Curve | Example modes | Diagram type |
|---|---|---|---|
| 1 — static | Memoryless demand = f(x); single curve |
levelbased, manual |
Single-curve transfer function |
| 2 — parameterised | Shape fixed, curve moves with θ(t) | flowbased, pressureBased, percentageBased, powerBased |
Transfer function + parameter overlay / family |
| 3 — horizon-based | Optimisation, no fixed curve | hybrid-optimal, mpc, weather-aware |
Block diagram of signal flow + scenario time-series |
Implementation status
| Mode | Tier | Status | Page |
|---|---|---|---|
levelbased |
1 | ✅ implemented | levelbased.md |
manual |
1 | ✅ implemented (via Qd topic) |
— |
flowbased |
2 | 🚧 code placeholder, template | flowbased.md |
pressureBased |
2 | 🚧 code placeholder | — |
percentageBased |
2 | 🚧 code placeholder | — |
powerBased |
2 | 🚧 code placeholder, template | powerbased.md |
hybrid |
3 | 🚧 code placeholder | — |
mpc |
3 | 🚧 not in code yet, template | mpc.md |