handleInput: skip abort+redispatch when demand unchanged

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) <noreply@anthropic.com>
This commit is contained in:
Rene De Ren
2026-05-08 20:10:50 +02:00
parent 69bdf11fc4
commit a14aa0dab8

View File

@@ -1281,6 +1281,25 @@ class MachineGroup {
return; 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 //abort current movements
await this.abortActiveMovements("new demand received"); await this.abortActiveMovements("new demand received");