From a14aa0dab8a05da47c1d40af17ae35b80da2eed3 Mon Sep 17 00:00:00 2001 From: Rene De Ren Date: Fri, 8 May 2026 20:10:50 +0200 Subject: [PATCH] handleInput: skip abort+redispatch when demand unchanged MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Live trace showed PS ticking every 1 s and re-firing the SAME demand (100% saturated under storm inflow) while the basin level evolved slowly. Each tick was calling abortActiveMovements + optimalControl, which aborted in-flight pump moves before they could finish (move duration ~0.4 s vs 1 s tick) and immediately re-issued the same setpoint. Pumps got stuck ramping from the same starting position toward the same target indefinitely — moveTimeleft stable at 0.379 s for minutes, flow.predicted frozen. Now early-return when |demandQ - prev| < max(0.5, prev*0.005). PS hysteresis float jitter is filtered, real demand changes still propagate. Pumps finish their first move and stay at the right setpoint instead of being aborted forever. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/specificClass.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/specificClass.js b/src/specificClass.js index 7dcc278..0499b49 100644 --- a/src/specificClass.js +++ b/src/specificClass.js @@ -1281,6 +1281,25 @@ class MachineGroup { return; } + // Skip abort + redispatch when the demand hasn't changed beyond a + // small tolerance. PS ticks every 1 s and re-fires the same demand + // while the basin level evolves slowly; without this guard, every + // PS tick aborted in-flight pump moves before they could finish + // (move duration ~0.4 s, abort cycle 1 s, but each abort + // immediately re-issued the same setpoint, so pumps got stuck + // ramping from the same starting position to the same target + // forever). Tolerance is 0.5 % — small enough that real demand + // changes still propagate, big enough to filter PS hysteresis + // float jitter. + const prev = this._lastDemandQ; + const unchanged = Number.isFinite(prev) + && Math.abs(demandQ - prev) < Math.max(0.5, Math.abs(prev) * 0.005); + if (unchanged) { + this.logger.debug(`Demand ${demandQ} unchanged from ${prev}; skipping abort+redispatch`); + return; + } + this._lastDemandQ = demandQ; + //abort current movements await this.abortActiveMovements("new demand received");