Compare commits
12 Commits
6e9ae9fc7e
...
0a6c7ee2e1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a6c7ee2e1 | ||
|
|
4cc529b1c2 | ||
|
|
fbfcec4b47 | ||
|
|
43eb97407f | ||
|
|
9e4b149b64 | ||
|
|
1848486f1c | ||
|
|
d44cbc978b | ||
|
|
f243761f00 | ||
|
|
2a31c7ec69 | ||
|
|
69f68adffe | ||
|
|
5a1eff37d7 | ||
|
|
e8f9207a92 |
109
src/nodeClass.js
109
src/nodeClass.js
@@ -101,65 +101,60 @@ class nodeClass {
|
|||||||
|
|
||||||
_updateNodeStatus() {
|
_updateNodeStatus() {
|
||||||
const ps = this.source;
|
const ps = this.source;
|
||||||
try {
|
|
||||||
// --- Basin & measurements -------------------------------------------------
|
|
||||||
const maxVolBeforeOverflow = ps.basin?.maxVolOverflow ?? ps.basin?.maxVol ?? 0;
|
|
||||||
const volumeMeasurement = ps.measurements.type("volume").variant("measured").position("atEquipment");
|
|
||||||
const currentVolume = volumeMeasurement.getCurrentValue("m3") ?? 0;
|
|
||||||
const netFlowMeasurement = ps.measurements.type("netFlowRate").variant("predicted").position("atEquipment");
|
|
||||||
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 pickVariant = (type, prefer = ['measured', 'predicted'], position = 'atEquipment', unit) => {
|
||||||
const direction = ps.state?.direction || "unknown";
|
for (const variant of prefer) {
|
||||||
const secondsRemaining = ps.state?.seconds ?? null;
|
const chain = ps.measurements.type(type).variant(variant).position(position);
|
||||||
|
const value = unit ? chain.getCurrentValue(unit) : chain.getCurrentValue();
|
||||||
const timeRemaining = secondsRemaining ? `${Math.round(secondsRemaining / 60)}` : 0 + " min";
|
if (value != null) return { value, variant };
|
||||||
|
|
||||||
// --- Icon / colour selection ---------------------------------------------
|
|
||||||
let symbol = "❔";
|
|
||||||
let fill = "grey";
|
|
||||||
|
|
||||||
switch (direction) {
|
|
||||||
case "filling":
|
|
||||||
symbol = "⬆️";
|
|
||||||
fill = "blue";
|
|
||||||
break;
|
|
||||||
case "draining":
|
|
||||||
symbol = "⬇️";
|
|
||||||
fill = "orange";
|
|
||||||
break;
|
|
||||||
case "stable":
|
|
||||||
symbol = "⏸️";
|
|
||||||
fill = "green";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
symbol = "❔";
|
|
||||||
fill = "grey";
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
return { value: null, variant: null };
|
||||||
|
};
|
||||||
|
|
||||||
// --- Status text ----------------------------------------------------------
|
const vol = pickVariant('volume', ['measured', 'predicted'], 'atEquipment', 'm3');
|
||||||
const textParts = [
|
const volPercent = pickVariant('volumePercent', ['measured','predicted'], 'atEquipment'); // already unitless
|
||||||
`${symbol} ${percentFull.toFixed(1)}%`,
|
const level = pickVariant('level', ['measured', 'predicted'], 'atEquipment', 'm');
|
||||||
`V=${currentVolume.toFixed(2)} / ${maxVolBeforeOverflow.toFixed(2)} m³`,
|
const netFlow = pickVariant('netFlowRate', ['measured', 'predicted'], 'atEquipment', 'm3/h');
|
||||||
`net=${netFlowM3h.toFixed(1)} m³/h`,
|
|
||||||
`t≈${timeRemaining}`
|
|
||||||
];
|
|
||||||
|
|
||||||
return {
|
const maxVolBeforeOverflow = ps.basin?.maxVolOverflow ?? ps.basin?.maxVol ?? 0;
|
||||||
fill,
|
const currentVolume = vol.value ?? 0;
|
||||||
shape: "dot",
|
const currentvolPercent = volPercent.value ?? 0;
|
||||||
text: textParts.join(" | ")
|
const netFlowM3h = netFlow.value ?? 0;
|
||||||
};
|
|
||||||
} catch (error) {
|
const direction = ps.state?.direction ?? 'unknown';
|
||||||
this.node.error("Error in updateNodeStatus: " + error.message);
|
const secondsRemaining = ps.state?.seconds ?? null;
|
||||||
return { fill: "red", shape: "ring", text: "Status Error" };
|
const timeRemainingMinutes = secondsRemaining != null ? Math.round(secondsRemaining / 60) : null;
|
||||||
|
|
||||||
|
const badgePieces = [];
|
||||||
|
badgePieces.push(`${currentvolPercent.toFixed(1)}% `);
|
||||||
|
badgePieces.push(
|
||||||
|
`V=${currentVolume.toFixed(2)} / ${maxVolBeforeOverflow.toFixed(2)} m³`
|
||||||
|
);
|
||||||
|
badgePieces.push(`net: ${netFlowM3h.toFixed(0)} m³/h`);
|
||||||
|
if (timeRemainingMinutes != null) {
|
||||||
|
badgePieces.push(`t≈${timeRemainingMinutes} min)`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { symbol, fill } = (() => {
|
||||||
|
switch (direction) {
|
||||||
|
case 'filling': return { symbol: '⬆️', fill: 'blue' };
|
||||||
|
case 'draining': return { symbol: '⬇️', fill: 'orange' };
|
||||||
|
case 'steady': return { symbol: '⏸️', fill: 'green' };
|
||||||
|
default: return { symbol: '❔', fill: 'grey' };
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
badgePieces[0] = `${symbol} ${badgePieces[0]}`;
|
||||||
|
|
||||||
|
return {
|
||||||
|
fill,
|
||||||
|
shape: 'dot',
|
||||||
|
text: badgePieces.join(' | ')
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// any time based functions here
|
// any time based functions here
|
||||||
_startTickLoop() {
|
_startTickLoop() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -182,8 +177,8 @@ class nodeClass {
|
|||||||
//pumping station needs time based ticks to recalc level when predicted
|
//pumping station needs time based ticks to recalc level when predicted
|
||||||
this.source.tick();
|
this.source.tick();
|
||||||
const raw = this.source.getOutput();
|
const raw = this.source.getOutput();
|
||||||
const processMsg = this._output.formatMsg(raw, this.config, 'process');
|
const processMsg = this._output.formatMsg(raw, this.source.config, 'process');
|
||||||
const influxMsg = this._output.formatMsg(raw, this.config, 'influxdb');
|
const influxMsg = this._output.formatMsg(raw, this.source.config, 'influxdb');
|
||||||
|
|
||||||
// Send only updated outputs on ports 0 & 1
|
// Send only updated outputs on ports 0 & 1
|
||||||
this.node.send([processMsg, influxMsg]);
|
this.node.send([processMsg, influxMsg]);
|
||||||
@@ -209,6 +204,14 @@ class nodeClass {
|
|||||||
const childObj = this.RED.nodes.getNode(childId);
|
const childObj = this.RED.nodes.getNode(childId);
|
||||||
this.source.childRegistrationUtils.registerChild(childObj.source ,msg.positionVsParent);
|
this.source.childRegistrationUtils.registerChild(childObj.source ,msg.positionVsParent);
|
||||||
break;
|
break;
|
||||||
|
case 'calibratePredictedVolume':
|
||||||
|
const calibratedVolume = this.source.measurements
|
||||||
|
.type('volume')
|
||||||
|
.variant('measured')
|
||||||
|
.position('atequipment')
|
||||||
|
.getCurrentValue('m3');
|
||||||
|
this.source.calibratePredictedVolume(calibratedVolume);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|||||||
1654
src/specificClass.js
1654
src/specificClass.js
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user