B3.3 follow-up: drop _unitView mirror; use UnitPolicy property bags directly
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) <noreply@anthropic.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user