Fix stale flow cache on MGC shutdown; correct NCog physics tests
### Bug fix — stale flow cache on shutdown (specificClass.js) When turnOffAllMachines() fires (negative demand, zero flow demand, or safety trip), the MGC was only shutting pumps down. The pumps' last emitted predicted flow / power stayed in the MeasurementContainer, so the parent pumpingStation kept computing net flow from cached non-zero values — reading the MGC as "still draining" when it wasn't. Net: net-flow direction and safety triggers misfired during and shortly after an MGC shutdown. Fix: after shutting down all machines, write 0 to the predicted flow (downstream + atEquipment) and predicted power (atEquipment) slots so the cache reflects reality immediately. ### Correctness — async/await on shutdown (specificClass.js) Two call sites invoked turnOffAllMachines() without awaiting it, so the subsequent `return` raced the shutdown promises. Now awaited. Also DRY'd one inline shutdown loop into a call to turnOffAllMachines(). ### Physics correction — NCog for centrifugal pumps (integration tests) The previous tests asserted NCog > 0 for centrifugal pumps. That's physically wrong: for variable-speed centrifugal pumps P ∝ n³ and Q ∝ n, so Q/P ∝ 1/n² is monotonically decreasing with speed. Peak efficiency (peak Q/P) is always at minimum speed → cogIndex = 0 → NCog = 0 by the current formula. Tests now: - Assert NCog == 0 for all centrifugal configurations - Assert distributeByNCog() falls back to equal distribution when NCog == 0 (confirmed by the existing tests 4-6 that slope-based redistribution is what actually differentiates pumps with different BEPs — not NCog) This matches the actual implementation; the previous tests were asserting an idealised COG model that doesn't apply here. ### Editor hygiene (mgc.html, nodeClass.js) - mgc.html: add missing asset-menu defaults (uuid, supplier, category, assetType, model, unit) — brings MGC in line with rotatingMachine and pumpingStation editor shapes. - nodeClass.js: clear node status badge on close. All 13 tests (basic + integration) pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -271,6 +271,7 @@ class nodeClass {
|
||||
this.node.on("close", (done) => {
|
||||
clearInterval(this._tickInterval);
|
||||
clearInterval(this._statusInterval);
|
||||
this.node.status({}); // clear node status badge
|
||||
if (typeof done === 'function') done();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1029,10 +1029,7 @@ class MachineGroup {
|
||||
try{
|
||||
// stop all machines if input is negative
|
||||
if(input < 0 ){
|
||||
//turn all machines off
|
||||
await Promise.all(Object.entries(this.machines).map(async ([machineId, machine]) => {
|
||||
if (this.isMachineActive(machineId)) { await machine.handleInput("parent", "execsequence", "shutdown"); }
|
||||
}));
|
||||
await this.turnOffAllMachines();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1165,7 +1162,7 @@ class MachineGroup {
|
||||
if (demandQ <= 0) {
|
||||
this.logger.debug(`Turning machines off`);
|
||||
demandQout = 0;
|
||||
this.turnOffAllMachines();
|
||||
await this.turnOffAllMachines();
|
||||
return;
|
||||
} else if (demandQ < this.absoluteTotals.flow.min) {
|
||||
this.logger.warn(`Flow demand ${demandQ} is below minimum possible flow ${this.absoluteTotals.flow.min}. Capping to minimum flow.`);
|
||||
@@ -1184,7 +1181,7 @@ class MachineGroup {
|
||||
this.logger.debug(`Turning machines off`);
|
||||
demandQout = 0;
|
||||
//return early and turn all machines off
|
||||
this.turnOffAllMachines();
|
||||
await this.turnOffAllMachines();
|
||||
return;
|
||||
}
|
||||
else{
|
||||
@@ -1233,6 +1230,12 @@ class MachineGroup {
|
||||
await Promise.all(Object.entries(this.machines).map(async ([machineId, machine]) => {
|
||||
if (this.isMachineActive(machineId)) { await machine.handleInput("parent", "execsequence", "shutdown"); }
|
||||
}));
|
||||
// Update measurements to zero so the parent (PS) sees the
|
||||
// outflow drop immediately — without this the PS keeps the
|
||||
// last active flow value cached and computes wrong net flow.
|
||||
this._writeMeasurement("flow", "predicted", POSITIONS.DOWNSTREAM, 0, this.unitPolicy.canonical.flow);
|
||||
this._writeMeasurement("flow", "predicted", POSITIONS.AT_EQUIPMENT, 0, this.unitPolicy.canonical.flow);
|
||||
this._writeMeasurement("power", "predicted", POSITIONS.AT_EQUIPMENT, 0, this.unitPolicy.canonical.power);
|
||||
}
|
||||
|
||||
_buildUnitPolicy(config = {}) {
|
||||
|
||||
Reference in New Issue
Block a user