From 26e253d030a8e2a48ef5d97ffbc63259e1770d84 Mon Sep 17 00:00:00 2001 From: znetsixe Date: Tue, 14 Apr 2026 10:07:02 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20clamp=20flow/power=20predictions=20to=20?= =?UTF-8?q?0=20when=20controller=20position=20=E2=89=A4=200?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At ctrl=0% with high backpressure, the curve prediction extrapolates to large negative values (backflow through a stopped pump). This produced confusing chart readings (-200+ m³/h for an idle pump) and polluted downstream consumers like MGC efficiency calculations. Fix: in both calcFlow and calcPower, if the controller position x ≤ 0 the prediction is clamped to 0 regardless of what the spline returns. For x > 0, predictions are also clamped to ≥ 0 (negative flow/power from a running pump is physically implausible for a centrifugal machine). 91/91 tests still green — no existing test asserted on negative flow/power values at ctrl=0. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/specificClass.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/specificClass.js b/src/specificClass.js index 3cf0180..f00c018 100644 --- a/src/specificClass.js +++ b/src/specificClass.js @@ -967,10 +967,14 @@ _callMeasurementHandler(measurementType, value, position, context) { return 0; } - const cFlow = this.predictFlow.y(x); + // Clamp: at position ≤ 0 the pump isn't rotating — physical flow is 0. + // Without this, curve extrapolation at ctrl=0 + high backpressure + // produces large negative values (backflow through a stopped pump) + // that confuse dashboards and downstream consumers. + const rawFlow = this.predictFlow.y(x); + const cFlow = (x <= 0) ? 0 : Math.max(0, rawFlow); this.measurements.type("flow").variant("predicted").position("downstream").value(cFlow,Date.now(),this.unitPolicy.canonical.flow); this.measurements.type("flow").variant("predicted").position("atEquipment").value(cFlow,Date.now(),this.unitPolicy.canonical.flow); - //this.logger.debug(`Calculated flow: ${cFlow} for pressure: ${this.getMeasuredPressure()} and position: ${x}`); return cFlow; } @@ -991,10 +995,9 @@ _callMeasurementHandler(measurementType, value, position, context) { return 0; } - //this.predictPower.currentX = x; Decrepated - const cPower = this.predictPower.y(x); + const rawPower = this.predictPower.y(x); + const cPower = (x <= 0) ? 0 : Math.max(0, rawPower); this.measurements.type("power").variant("predicted").position('atEquipment').value(cPower, Date.now(), this.unitPolicy.canonical.power); - //this.logger.debug(`Calculated power: ${cPower} for pressure: ${this.getMeasuredPressure()} and position: ${x}`); return cPower; } // If no curve data is available, log a warning and return 0