- wiki/functional-description.md: rename Overfill Protection → High-volume
Safety; tighten basin-ordering chain; relocate level-based mode
diagrams under wiki/diagrams/modes/level-based/; document the new
flow.predicted.overflow.default position (replaces the previous
child='overflow' under position 'out'); add underflowVolume +
predictedUnderflowVolume entries.
- wiki/modes/{levelbased,powerbased}.md: paragraph cleanups.
- wiki/diagrams: move level-linear basin diagram under modes/level-based/
alongside a new level-log variant.
- simulations/run.js: add max_demand_gt expectation.
- simulations/scenarios/*: minor fixture updates.
- test/basic/nodeClass-config.test.js: new config-shape coverage.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
84 lines
3.8 KiB
Markdown
84 lines
3.8 KiB
Markdown
---
|
||
title: Power-based mode
|
||
mode: powerBased
|
||
tier: 2
|
||
status: placeholder
|
||
updated: 2026-04-22
|
||
---
|
||
|
||
# Power-based mode — *Tier 2 template*
|
||
|
||
> **Status — not yet implemented.** Placeholder. This page documents the intended shape of a grid-aware / netcongestion-aware station.
|
||
|
||
## At a glance
|
||
|
||
| Item | Value |
|
||
|---|---|
|
||
| Tier | 2 — parameterised transfer function |
|
||
| Signal driving demand | basin level (primary), **max-power budget** (clip) |
|
||
| Secondary inputs | measured pump power, live grid-price / peak-hours signal |
|
||
| Output | demand 0–100 % clipped so `Σ pump power ≤ maxPowerKW(t)` |
|
||
| Thresholds adjusted at runtime? | `maxPowerKW(t)` yes — level thresholds no |
|
||
| Use when | Grid has peak-hour tariffs or net-congestion caps |
|
||
|
||
## Diagram — the levelbased curve with a moving clip ceiling
|
||
|
||
```
|
||
demand % ← dashed line: levelbased curve
|
||
100 ┤ ╱ ─────── ← solid: clip at powerBudget(t)
|
||
│ ╱ clip lowers
|
||
│ ╱ during grid peak
|
||
│ ╱ ─────────
|
||
│ ╱ ╱
|
||
│ ╱ ╱
|
||
│ ╱ ╱
|
||
0 ┼────────●───────●─────────────────────► level
|
||
startLevel maxLevel
|
||
|
||
↑ the family of curves:
|
||
clip=100% (grid idle),
|
||
clip=70% (shoulder),
|
||
clip=40% (peak).
|
||
```
|
||
|
||
The *shape* stays levelbased; the *ceiling* drops when the grid is strained. That's the Tier-2 signature: same input axis, parameter shifts the curve.
|
||
|
||
## Inputs
|
||
|
||
| Signal | Where from | Role |
|
||
|---|---|---|
|
||
| current level | as in levelbased | primary input |
|
||
| `config.control.powerBased.maxPowerKW` | editor, static | hard cap on station power |
|
||
| `config.control.powerBased.powerControlMode` | `limit` / `optimize` | whether to just clip or to schedule |
|
||
| live grid signal (future) | external topic or forecast | modulates the cap over time |
|
||
| measured pump power | `power.measured.*` from children | real-time feedback against the cap |
|
||
|
||
## Threshold policy
|
||
|
||
Level thresholds (`minLevel`, `startLevel`, `maxLevel`) are **identical to levelbased** — they define the shape of the underlying curve. What's new is a runtime-varying ceiling `demandCap(t)` derived from the power budget.
|
||
|
||
`demandCap(t) = 100 × (maxPowerKW(t) / nominalStationPowerAtFull)` — where `maxPowerKW(t)` may come from config (static `limit` mode) or an external grid-price feed (dynamic).
|
||
|
||
## Demand formula
|
||
|
||
```text
|
||
rawDemand = levelbasedDemand(level) # the underlying Tier-1 curve
|
||
demandCap = min(100, 100 × maxPowerKW(t) / nominalStationPower)
|
||
demand = min(rawDemand, demandCap)
|
||
```
|
||
|
||
When `demandCap < rawDemand`, the mode sacrifices drainage rate to stay within power budget. Level may rise — the high-volume safety layer still applies as the last line of defence before physical overflow.
|
||
|
||
## Edge cases
|
||
|
||
- **Peak hour with rising level.** demandCap drops faster than level rises → demand gets clipped; level approaches `overflowLevel`. If high-volume safety trips, it overrides the clip (safety wins).
|
||
- **Power signal dropout.** Fall back to static `maxPowerKW` from config; log warning.
|
||
- **Grid exit from peak while basin is nearly full.** demandCap jumps back to 100; PID is memoryless so demand rises in one tick to match rawDemand.
|
||
- **Measured vs predicted pump power.** Cap is enforced on predicted (decisions are made before the pump responds). Reconcile against measured for logging/diagnostics.
|
||
|
||
## Related
|
||
|
||
- [Functional description](../functional-description.md)
|
||
- [modes/levelbased.md](levelbased.md) — Tier 1 reference (the curve that powerBased clips)
|
||
- [modes/flowbased.md](flowbased.md) — other Tier-2 example with different control variable
|