Updated node status

This commit is contained in:
znetsixe
2025-11-03 07:42:51 +01:00
parent 2a31c7ec69
commit f243761f00
2 changed files with 86 additions and 71 deletions

View File

@@ -101,65 +101,60 @@ class nodeClass {
_updateNodeStatus() { _updateNodeStatus() {
const ps = this.source; const ps = this.source;
try {
// --- Basin & measurements ------------------------------------------------- const pickVariant = (type, prefer = ['measured', 'predicted'], position = 'atEquipment', unit) => {
for (const variant of prefer) {
const chain = ps.measurements.type(type).variant(variant).position(position);
const value = unit ? chain.getCurrentValue(unit) : chain.getCurrentValue();
if (value != null) return { value, variant };
}
return { value: null, variant: null };
};
const vol = pickVariant('volume', ['measured', 'predicted'], 'atEquipment', 'm3');
const volPercent = pickVariant('volumePercent', ['measured','predicted'], 'atEquipment'); // already unitless
const level = pickVariant('level', ['measured', 'predicted'], 'atEquipment', 'm');
const netFlow = pickVariant('netFlowRate', ['measured', 'predicted'], 'atEquipment', 'm3/s');
const maxVolBeforeOverflow = ps.basin?.maxVolOverflow ?? ps.basin?.maxVol ?? 0; const maxVolBeforeOverflow = ps.basin?.maxVolOverflow ?? ps.basin?.maxVol ?? 0;
const volumeMeasurement = ps.measurements.type("volume").variant("measured").position("atEquipment"); const currentVolume = vol.value ?? 0;
const currentVolume = volumeMeasurement.getCurrentValue("m3") ?? 0; const currentvolPercent = volPercent.value ?? 0;
const netFlowMeasurement = ps.measurements.type("netFlowRate").variant("predicted").position("atEquipment"); const netFlowM3h = (netFlow.value ?? 0) * 3600;
const netFlowM3s = netFlowMeasurement?.getCurrentValue("m3/s") ?? 0;
const netFlowM3h = netFlowM3s * 3600;
const percentFull = ps.measurements.type("volume").variant("procent").position("atEquipment").getCurrentValue() ?? 0;
// --- State information ---------------------------------------------------- const direction = ps.state?.direction ?? 'unknown';
const direction = ps.state?.direction || "unknown";
const secondsRemaining = ps.state?.seconds ?? null; const secondsRemaining = ps.state?.seconds ?? null;
const timeRemainingMinutes = secondsRemaining != null ? Math.round(secondsRemaining / 60) : null;
const timeRemaining = secondsRemaining ? `${Math.round(secondsRemaining / 60)}` : 0 + " min"; const badgePieces = [];
badgePieces.push(`${currentvolPercent.toFixed(1)}% `);
// --- Icon / colour selection --------------------------------------------- badgePieces.push(
let symbol = "❔"; `V=${currentVolume.toFixed(2)} / ${maxVolBeforeOverflow.toFixed(2)} m³ (${'n/a'})`
let fill = "grey"; );
badgePieces.push(`net=${netFlowM3h.toFixed(1)} m³/h (${'n/a'})`);
switch (direction) { if (timeRemainingMinutes != null) {
case "filling": badgePieces.push(`t≈${timeRemainingMinutes} min)`);
symbol = "⬆️";
fill = "blue";
break;
case "draining":
symbol = "⬇️";
fill = "orange";
break;
case "stable":
symbol = "⏸️";
fill = "green";
break;
default:
symbol = "❔";
fill = "grey";
break;
} }
// --- Status text ---------------------------------------------------------- const { symbol, fill } = (() => {
const textParts = [ switch (direction) {
`${symbol} ${percentFull.toFixed(1)}%`, case 'filling': return { symbol: '⬆️', fill: 'blue' };
`V=${currentVolume.toFixed(2)} / ${maxVolBeforeOverflow.toFixed(2)}`, case 'draining': return { symbol: '⬇️', fill: 'orange' };
`net=${netFlowM3h.toFixed(1)} m³/h`, case 'steady': return { symbol: '⏸️', fill: 'green' };
`t≈${timeRemaining}` default: return { symbol: '❔', fill: 'grey' };
]; }
})();
badgePieces[0] = `${symbol} ${badgePieces[0]}`;
return { return {
fill, fill,
shape: "dot", shape: 'dot',
text: textParts.join(" | ") text: badgePieces.join(' | ')
}; };
} catch (error) {
this.node.error("Error in updateNodeStatus: " + error.message);
return { fill: "red", shape: "ring", text: "Status Error" };
}
} }
// any time based functions here // any time based functions here
_startTickLoop() { _startTickLoop() {
setTimeout(() => { setTimeout(() => {

View File

@@ -1,6 +1,6 @@
const EventEmitter = require('events'); const EventEmitter = require('events');
const {logger,configUtils,configManager,childRegistrationUtils,MeasurementContainer,coolprop,interpolation} = require('generalFunctions'); const {logger,configUtils,configManager,childRegistrationUtils,MeasurementContainer,coolprop,interpolation} = require('generalFunctions');
class PumpingStationV2 { class PumpingStation {
constructor(config = {}) { constructor(config = {}) {
this.emitter = new EventEmitter(); this.emitter = new EventEmitter();
this.configManager = new configManager(); this.configManager = new configManager();
@@ -18,6 +18,8 @@ class PumpingStationV2 {
this.machines = {}; this.machines = {};
this.stations = {}; this.stations = {};
//variants in determining what gets priority //variants in determining what gets priority
this.flowVariants = ['measured', 'predicted']; this.flowVariants = ['measured', 'predicted'];
this.levelVariants = ['measured', 'predicted']; this.levelVariants = ['measured', 'predicted'];
@@ -61,6 +63,8 @@ class PumpingStationV2 {
this._updatePredictedVolume(snapshot); this._updatePredictedVolume(snapshot);
const netFlow = this._selectBestNetFlow(snapshot); const netFlow = this._selectBestNetFlow(snapshot);
//write netflow in measurment container
//this.measurements()
const remaining = this._computeRemainingTime(snapshot, netFlow); const remaining = this._computeRemainingTime(snapshot, netFlow);
this.state = { this.state = {
@@ -160,8 +164,8 @@ class PumpingStationV2 {
.value(volume, context.timestamp, 'm3'); .value(volume, context.timestamp, 'm3');
this.measurements this.measurements
.type('volume') .type('volumePercent')
.variant('percent') .variant('measured')
.position('atequipment') .position('atequipment')
.value(percent, context.timestamp, '%'); .value(percent, context.timestamp, '%');
} }
@@ -416,6 +420,22 @@ class PumpingStationV2 {
.value(nextLevel, writeTimestamp, 'm') .value(nextLevel, writeTimestamp, 'm')
.unit('m'); .unit('m');
//calc how full this is in procen using minVol vs maxVolOverflow
const percent = this.interpolate.interpolate_lin_single_point(
currentVolume,
this.basin.minVol,
this.basin.maxVolOverflow,
0,
100
);
//store this percent value
this.measurements
.type('volumePercent')
.variant('predicted')
.position('atequipment')
.value(percent);
this._predictedFlowState.lastTimestamp = writeTimestamp; this._predictedFlowState.lastTimestamp = writeTimestamp;
} }
@@ -465,7 +485,7 @@ class PumpingStationV2 {
.type('volume') .type('volume')
.variant('predicted') .variant('predicted')
.position('atEquipment') .position('atEquipment')
.value(maxVol) .value(maxVolOverflow)
.unit('m3'); .unit('m3');
this.logger.debug( this.logger.debug(
@@ -501,12 +521,12 @@ class PumpingStationV2 {
} }
} }
module.exports = PumpingStationV2; module.exports = PumpingStation;
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/* Example usage */ /* Example usage */
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/*
if (require.main === module) { if (require.main === module) {
const Measurement = require('../../measurement/src/specificClass'); const Measurement = require('../../measurement/src/specificClass');
const RotatingMachine = require('../../rotatingMachine/src/specificClass'); const RotatingMachine = require('../../rotatingMachine/src/specificClass');
@@ -525,10 +545,10 @@ if (require.main === module) {
}, },
basin: { basin: {
volume: 43.75, volume: 43.75,
height: 3.5, height: 10,
heightInlet: 0.3, heightInlet: 3,
heightOutlet: 0.2, heightOutlet: 0.2,
heightOverflow: 3.0 heightOverflow: 3.2
}, },
hydraulics: { hydraulics: {
refHeight: 'NAP', refHeight: 'NAP',
@@ -630,7 +650,7 @@ if (require.main === module) {
} }
(async function demo() { (async function demo() {
const station = new PumpingStationV2(createPumpingStationConfig('PumpingStationDemo')); const station = new PumpingStation(createPumpingStationConfig('PumpingStationDemo'));
const pump1 = new RotatingMachine(createMachineConfig('Pump1','downstream'), createMachineStateConfig()); const pump1 = new RotatingMachine(createMachineConfig('Pump1','downstream'), createMachineStateConfig());
const pump2 = new RotatingMachine(createMachineConfig('Pump2','upstream'), createMachineStateConfig()); const pump2 = new RotatingMachine(createMachineConfig('Pump2','upstream'), createMachineStateConfig());
@@ -638,20 +658,19 @@ if (require.main === module) {
const inflowSensor = new Measurement(createFlowMeasurementConfig('InfluentFlow', 'in')); const inflowSensor = new Measurement(createFlowMeasurementConfig('InfluentFlow', 'in'));
const outflowSensor = new Measurement(createFlowMeasurementConfig('PumpDischargeFlow', 'out')); const outflowSensor = new Measurement(createFlowMeasurementConfig('PumpDischargeFlow', 'out'));
/* //station.childRegistrationUtils.registerChild(levelSensor, levelSensor.config.functionality.softwareType);
station.childRegistrationUtils.registerChild(levelSensor, levelSensor.config.functionality.softwareType); //station.childRegistrationUtils.registerChild(inflowSensor, inflowSensor.config.functionality.softwareType);
station.childRegistrationUtils.registerChild(inflowSensor, inflowSensor.config.functionality.softwareType); //station.childRegistrationUtils.registerChild(outflowSensor, outflowSensor.config.functionality.softwareType);
station.childRegistrationUtils.registerChild(outflowSensor, outflowSensor.config.functionality.softwareType);
*/
station.childRegistrationUtils.registerChild(pump1, 'machine'); station.childRegistrationUtils.registerChild(pump1, 'machine');
station.childRegistrationUtils.registerChild(pump2, 'machine'); station.childRegistrationUtils.registerChild(pump2, 'machine');
// Seed initial measurements // Seed initial measurements
/*
seedSample(levelSensor, 'level', 1.8, 'm'); //seedSample(levelSensor, 'level', 1.8, 'm');
seedSample(inflowSensor, 'flow', 0.35, 'm3/s'); //seedSample(inflowSensor, 'flow', 0.35, 'm3/s');
seedSample(outflowSensor, 'flow', 0.20, 'm3/s'); //seedSample(outflowSensor, 'flow', 0.20, 'm3/s');
*/
setInterval( setInterval(
() => station.tick(), 1000); () => station.tick(), 1000);
@@ -672,3 +691,4 @@ if (require.main === module) {
console.error('Demo failed:', err); console.error('Demo failed:', err);
}); });
} }
//*/