Files
pumpingStation/wiki/modes/flowbased.md
znetsixe 66fd3feff8 Add eval harness + Tier 2/3 mode template pages
### 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>
2026-04-22 16:49:41 +02:00

3.8 KiB
Raw Blame History

title, mode, tier, status, updated
title mode tier status updated
Flow-based mode flowbased 2 placeholder 2026-04-22

Flow-based mode — Tier 2 template

Status — not yet implemented. The flowbased entry is a placeholder in _controlLogic. This page reserves the shape and documents the intended design so all Tier-2 modes share the same layout.

At a glance

Item Value
Tier 2 — parameterised transfer function
Signal driving demand measured outflow (actual pumps)
Secondary inputs integrator + derivative state (for PID)
Output demand 0100 % via PID correction
Thresholds adjusted at runtime? No (but the demand can move independently of level)
Use when The station has a flow sensor on the outlet and you want to hold a target outflow rate regardless of basin level

Diagram

Primary plot. Demand vs outflow-error (not level!) is the meaningful transfer function for flow-based control. The curve is a classic PID surface — proportional slope times error, plus integral + derivative terms.

Secondary plot. Level still enters as gates (STOP below minLevel, don't overfill above maxLevel) — same thresholds as levelbased, but the mode doesn't use level to pick demand.

Placeholder image — replace with:
  diagrams/modes/flowbased.drawio.svg  (demand vs outflow-error, showing Kp slope)

Inputs

Signal Where from Role
measured outflow sum of flow.measured.* at outflow positions error = (flowSetpoint measuredOutflow)
config.control.flowBased.flowSetpoint editor, static target outflow in m³/h
config.control.flowBased.flowDeadband editor, static zone around setpoint where PID output holds
config.control.flowBased.pid.{kp, ki, kd, ...} editor / schema PID gains + rate limits
current level fallback → threshold gates only used for minLevel/maxLevel bounds

Threshold policy

The control thresholds (minLevel, startLevel, maxLevel) are still enforced but for different reasons than levelbased:

Threshold Role in flowbased
minLevel If level drops below, force demand=0 regardless of PID output (prevents pump undercut)
startLevel unused — demand is driven by error, not level
maxLevel If level climbs above, force demand=100 regardless of PID output (prevents spill)

Demand formula

error = flowSetpoint  measuredOutflow

if level < minLevel:
    demand = 0                           # pump-undercut guard
elif level > maxLevel:
    demand = 100                         # anti-spill guard
else:
    # normal PID branch
    P = Kp × error
    I += Ki × error × dt                 # with anti-windup clamp
    D = Kd × d(error)/dt                 # with low-pass filter
    demand = clamp(P + I + D, 0, 100)    # with rate limits Δup/Δdown

Edge cases

  • Cold start, no prior outflow measurement. PID state starts at 0; first error is flowSetpoint. Integral term will build up — rate-limit the demand ramp to avoid over-shoot.
  • Sensor dropout on the outflow meter. Fall back to predicted outflow (sum of pump curve predictions). Log a warning — PID on predicted-only is unreliable.
  • Setpoint step change. PID with derivative filter + rate limits handles this gracefully; without filter, the D-kick would saturate output.
  • Safety layer interaction. Same as levelbased — dryRunLevel and overflowLevel override the PID output. See functional description § Safety.