--- title: Group Optimization Architecture created: 2026-04-07 updated: 2026-04-07 status: proven tags: [machineGroupControl, optimization, BEP-Gravitation] sources: [nodes/machineGroupControl/src/specificClass.js] --- > **⚠️ ARCHIVED — pre-refactor (Tier 1–4, 2026-05)** > > This page describes the architecture before the platform refactor. > The current page is the per-node wiki on **[gitea.wbd-rd.nl/RnD](https://gitea.wbd-rd.nl/RnD)** or **[Home](../Home)**. > > Kept for historical reference only. **Do not update.** # machineGroupControl Optimization ## Algorithm: BEP-Gravitation + Marginal-Cost Refinement ### Step 1 — Pressure Equalization Sets all non-operational pumps to the group's max downstream / min upstream pressure. Ensures fair curve evaluation across combinations. ### Step 2 — Combination Enumeration Generates all 2^n pump subsets (n = number of machines). Filters by: - Machine state (excludes off, cooling, stopping, emergency) - Mode compatibility (`execsequence` allowed in auto) - Flow bounds: `sumMinFlow ≤ Qd ≤ sumMaxFlow` - Optional power cap ### Step 3 — BEP-Gravitation Distribution (per combination) 1. **BEP seed**: `estimatedBEP = minFlow + span * NCog` per pump 2. **Slope estimation**: samples dP/dQ at BEP ± delta (directional: slopeLeft, slopeRight) 3. **Slope redistribution**: iteratively shifts flow from steep to flat curves (weight = 1/slope) 4. **Marginal-cost refinement**: after slope redistribution, shifts flow from highest actual dP/dQ to lowest using real `inputFlowCalcPower` evaluations. Converges regardless of curve convexity. Max 50 iterations, typically 5-15. ### Step 4 — Best Selection Pick combination with lowest total power. Tiebreak by deviation from BEP. ### Step 5 — Execution Start/stop pumps as needed, send `flowmovement` commands in output units via `_canonicalToOutputFlow()`. ## Three Control Modes | Mode | Distribution | Combination Selection | |------|-------------|----------------------| | optimalControl | BEP-Gravitation + refinement | exhaustive 2^n | | priorityControl | equal split, priority-ordered | sequential add/remove | | priorityPercentageControl | percentage-based, normalized | count-based | ## Key Design Decision The `flowmovement` command sends flow in the **machine's output units** (m3/h), not canonical (m3/s). The `_canonicalToOutputFlow()` helper converts before sending. Without this conversion, every pump stays at minimum flow (the critical bug fixed on 2026-04-07).