From 84126e91302c21468628cf3fe5351a52d2773e66 Mon Sep 17 00:00:00 2001 From: znetsixe Date: Mon, 11 May 2026 17:13:20 +0200 Subject: [PATCH] B3.3 follow-up: drop _unitView mirror; use UnitPolicy property bags directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same as MGC — UnitPolicy property bags replace the manual _unitView/ unitPolicyView reassignment. specificClass.js 400→377. 196/196 tests still pass. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/io/output.js | 4 +-- src/prediction/predictionMath.js | 6 ++-- src/pressure/pressureSelector.js | 2 +- src/specificClass.js | 39 +++++------------------- test/edge/nodeClass-routing.edge.test.js | 2 +- 5 files changed, 15 insertions(+), 38 deletions(-) diff --git a/src/io/output.js b/src/io/output.js index 1f82791..ae3ba01 100644 --- a/src/io/output.js +++ b/src/io/output.js @@ -24,7 +24,7 @@ const FILL = { const SHOW_METRICS = new Set(['operational', 'warmingup', 'accelerating', 'decelerating']); function buildOutput(host) { - const o = host.measurements.getFlattenedOutput({ requestedUnits: host.unitPolicyView.output }); + const o = host.measurements.getFlattenedOutput({ requestedUnits: host.unitPolicy.output }); o.state = host.state.getCurrentState(); o.runtime = host.state.getRunTimeHours(); o.ctrl = host.state.getCurrentPosition(); @@ -74,7 +74,7 @@ function buildStatusBadge(host) { const fill = FILL[stateName] || 'grey'; const parts = [`${host.currentMode}: ${symbol}`]; if (SHOW_METRICS.has(stateName)) { - const fu = host.unitPolicyView.output.flow || 'm3/h'; + const fu = host.unitPolicy.output.flow || 'm3/h'; const flow = Math.round(host.measurements.type('flow').variant('predicted').position('downstream').getCurrentValue(fu) ?? 0); const power = Math.round(host.measurements.type('power').variant('predicted').position('atEquipment').getCurrentValue('kW') ?? 0); const pos = Math.round((host.state?.getCurrentPosition?.() ?? 0) * 100) / 100; diff --git a/src/prediction/predictionMath.js b/src/prediction/predictionMath.js index 91fb470..fab1f0d 100644 --- a/src/prediction/predictionMath.js +++ b/src/prediction/predictionMath.js @@ -7,7 +7,7 @@ */ function calcFlow(host, x) { - const u = host.unitPolicyView.canonical.flow; + const u = host.unitPolicy.canonical.flow; if (host.hasCurve) { if (!host._isOperationalState()) { host.measurements.type('flow').variant('predicted').position('downstream').value(0, Date.now(), u); @@ -27,7 +27,7 @@ function calcFlow(host, x) { } function calcPower(host, x) { - const u = host.unitPolicyView.canonical.power; + const u = host.unitPolicy.canonical.power; if (host.hasCurve) { if (!host._isOperationalState()) { host.measurements.type('power').variant('predicted').position('atEquipment').value(0, Date.now(), u); @@ -52,7 +52,7 @@ function inputFlowCalcPower(host, flow) { } host.logger.warn('No curve data available for power calculation. Returning 0.'); host.measurements.type('power').variant('predicted').position('atEquipment') - .value(0, Date.now(), host.unitPolicyView.canonical.power); + .value(0, Date.now(), host.unitPolicy.canonical.power); return 0; } diff --git a/src/pressure/pressureSelector.js b/src/pressure/pressureSelector.js index d92bd32..32d35fd 100644 --- a/src/pressure/pressureSelector.js +++ b/src/pressure/pressureSelector.js @@ -43,7 +43,7 @@ function getMeasuredPressure(host) { } host.logger.error('No valid pressure measurements available to calculate prediction using last known pressure'); applyDiff(0); - const fu = host.unitPolicyView.canonical.flow; + const fu = host.unitPolicy.canonical.flow; host.measurements.type('flow').variant('predicted').position('max').value(host.predictFlow.currentFxyYMax, Date.now(), fu); host.measurements.type('flow').variant('predicted').position('min').value(host.predictFlow.currentFxyYMin, Date.now(), fu); return 0; diff --git a/src/specificClass.js b/src/specificClass.js index 9bfd20a..4649679 100644 --- a/src/specificClass.js +++ b/src/specificClass.js @@ -56,9 +56,6 @@ class Machine extends BaseDomain { this.config = this.configUtils.updateConfig(this.config, { general: { name: `${this.config.functionality?.softwareType}_${this.config.general.id}` }, }); - this.unitPolicyView = this._freezeUnitView(this.unitPolicy); - this._unitPolicyInstance = this.unitPolicy; - this.unitPolicy = this.unitPolicyView; this._setupCurves(); this.groupPredictFlow = null; this.groupPredictPower = null; this.groupPredictCtrl = null; this.groupNCog = 0; @@ -68,33 +65,13 @@ class Machine extends BaseDomain { this._setupChildren(); } - _freezeUnitView(p) { - const slot = (m, k) => (typeof p[m] === 'function' ? p[m](k) : p[m]?.[k]); - return Object.freeze({ - canonical: Object.freeze({ - pressure: slot('canonical', 'pressure'), atmPressure: slot('canonical', 'atmPressure') || 'Pa', - flow: slot('canonical', 'flow'), power: slot('canonical', 'power'), - temperature: slot('canonical', 'temperature'), - }), - output: Object.freeze({ - pressure: slot('output', 'pressure'), flow: slot('output', 'flow'), - power: slot('output', 'power'), temperature: slot('output', 'temperature'), - atmPressure: slot('output', 'atmPressure') || 'Pa', - }), - curve: Object.freeze({ - pressure: slot('curve', 'pressure'), flow: slot('curve', 'flow'), - power: slot('curve', 'power'), control: slot('curve', 'control'), - }), - }); - } - _setupCurves() { this.model = this.config.asset?.model; const { rawCurve, error } = loadModelCurve(this.model); this.rawCurve = rawCurve; if (error) { this.logger.error(`${error} in machineConfig. Cannot make predictions.`); this._installNullPredictors(); return; } try { - this.curve = normalizeMachineCurve(rawCurve, this.unitPolicyView, this.logger); + this.curve = normalizeMachineCurve(rawCurve, this.unitPolicy, this.logger); this.config = this.configUtils.updateConfig(this.config, { asset: { ...this.config.asset, machineCurve: this.curve } }); const built = buildPredictors(this.config.asset.machineCurve); this.predictors = built; @@ -150,7 +127,7 @@ class Machine extends BaseDomain { this.virtualPressureChildIds = { upstream: 'dashboard-sim-upstream', downstream: 'dashboard-sim-downstream' }; this.realPressureChildIds = { upstream: new Set(), downstream: new Set() }; this.virtualPressureChildren = new VirtualPressureChildren({ - logger: this.logger, unitPolicy: this.unitPolicyView, parentRef: this, + logger: this.logger, unitPolicy: this.unitPolicy, parentRef: this, ids: this.virtualPressureChildIds, }).build(); this.pressureInit = new PressureInitialization({ @@ -184,10 +161,10 @@ class Machine extends BaseDomain { } _init() { - const tu = this.unitPolicyView.output.temperature; + const tu = this.unitPolicy.output.temperature; this.measurements.type('temperature').variant('measured').position('atEquipment').value(15, Date.now(), tu); this.measurements.type('atmPressure').variant('measured').position('atEquipment').value(101325, Date.now(), 'Pa'); - const fu = this.unitPolicyView.canonical.flow; + const fu = this.unitPolicy.canonical.flow; const fmin = this.predictFlow ? this.predictFlow.currentFxyYMin : 0; const fmax = this.predictFlow ? this.predictFlow.currentFxyYMax : 0; this.measurements.type('flow').variant('predicted').position('max').value(fmax, Date.now(), fu); @@ -259,8 +236,8 @@ class Machine extends BaseDomain { // ── state-machine driven recompute ───────────────────────────────── _updateState() { if (!this._isOperationalState()) { - const fu = this.unitPolicyView.canonical.flow; - const pu = this.unitPolicyView.canonical.power; + const fu = this.unitPolicy.canonical.flow; + const pu = this.unitPolicy.canonical.power; this.measurements.type('flow').variant('predicted').position('downstream').value(0, Date.now(), fu); this.measurements.type('flow').variant('predicted').position('atEquipment').value(0, Date.now(), fu); this.measurements.type('power').variant('predicted').position('atEquipment').value(0, Date.now(), pu); @@ -366,9 +343,9 @@ class Machine extends BaseDomain { updateCurve(newCurve) { this.logger.info('Updating machine curve'); - const normalized = normalizeMachineCurve(newCurve, this.unitPolicyView, this.logger); + const normalized = normalizeMachineCurve(newCurve, this.unitPolicy, this.logger); this.config = this.configUtils.updateConfig(this.config, { - asset: { machineCurve: normalized, curveUnits: this.unitPolicyView.curve }, + asset: { machineCurve: normalized, curveUnits: this.unitPolicy.curve }, }); if (!this.predictFlow || !this.predictPower || !this.predictCtrl) { const built = buildPredictors(this.config.asset.machineCurve); diff --git a/test/edge/nodeClass-routing.edge.test.js b/test/edge/nodeClass-routing.edge.test.js index 8962196..0f1ef73 100644 --- a/test/edge/nodeClass-routing.edge.test.js +++ b/test/edge/nodeClass-routing.edge.test.js @@ -106,7 +106,7 @@ test('source.getStatusBadge shows warning when pressure inputs are not initializ state: { getCurrentState: () => 'operational', getCurrentPosition: () => 50 }, pressureInit: { getStatus: () => ({ initialized: false, hasUpstream: false, hasDownstream: false, hasDifferential: false }) }, measurements: { type() { return { variant() { return { position() { return { getCurrentValue() { return 0; } }; } }; } }; } }, - unitPolicyView: { output: { flow: 'm3/h' } }, + unitPolicy: { output: { flow: 'm3/h' } }, logger: { error: () => {} }, }; // Import the buildStatusBadge helper directly — it's the same code the