updates
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
* Encapsulates all node logic in a reusable class. In future updates we can split this into multiple generic classes and use the config to specifiy which ones to use.
|
||||
* This allows us to keep the Node-RED node clean and focused on wiring up the UI and event handlers.
|
||||
*/
|
||||
const { outputUtils, configManager } = require('generalFunctions');
|
||||
const { outputUtils, configManager, convert } = require('generalFunctions');
|
||||
const Specific = require("./specificClass");
|
||||
|
||||
class nodeClass {
|
||||
@@ -42,25 +42,37 @@ class nodeClass {
|
||||
* @param {object} uiConfig - Raw config from Node-RED UI.
|
||||
*/
|
||||
_loadConfig(uiConfig,node) {
|
||||
const resolvedAssetUuid = uiConfig.assetUuid || uiConfig.uuid || null;
|
||||
const resolvedAssetTagCode = uiConfig.assetTagCode || uiConfig.assetTagNumber || null;
|
||||
const flowUnit = this._resolveUnitOrFallback(uiConfig.unit, 'volumeFlowRate', 'm3/h', 'flow');
|
||||
const curveUnits = {
|
||||
pressure: this._resolveUnitOrFallback(uiConfig.curvePressureUnit, 'pressure', 'mbar', 'curve pressure'),
|
||||
flow: this._resolveUnitOrFallback(uiConfig.curveFlowUnit || flowUnit, 'volumeFlowRate', flowUnit, 'curve flow'),
|
||||
power: this._resolveUnitOrFallback(uiConfig.curvePowerUnit, 'power', 'kW', 'curve power'),
|
||||
control: this._resolveControlUnitOrFallback(uiConfig.curveControlUnit, '%'),
|
||||
};
|
||||
|
||||
// Merge UI config over defaults
|
||||
this.config = {
|
||||
general: {
|
||||
name: this.name,
|
||||
id: node.id, // node.id is for the child registration process
|
||||
unit: uiConfig.unit, // add converter options later to convert to default units (need like a model that defines this which units we are going to use and then conver to those standards)
|
||||
unit: flowUnit,
|
||||
logging: {
|
||||
enabled: uiConfig.enableLog,
|
||||
logLevel: uiConfig.logLevel
|
||||
}
|
||||
},
|
||||
asset: {
|
||||
uuid: uiConfig.assetUuid, //need to add this later to the asset model
|
||||
tagCode: uiConfig.assetTagCode, //need to add this later to the asset model
|
||||
uuid: resolvedAssetUuid, // support both legacy and current editor field names
|
||||
tagCode: resolvedAssetTagCode, // support both legacy and current editor field names
|
||||
tagNumber: uiConfig.assetTagNumber || null,
|
||||
supplier: uiConfig.supplier,
|
||||
category: uiConfig.category, //add later to define as the software type
|
||||
type: uiConfig.assetType,
|
||||
model: uiConfig.model,
|
||||
unit: uiConfig.unit
|
||||
unit: flowUnit,
|
||||
curveUnits
|
||||
},
|
||||
functionality: {
|
||||
positionVsParent: uiConfig.positionVsParent
|
||||
@@ -71,6 +83,29 @@ class nodeClass {
|
||||
this._output = new outputUtils();
|
||||
}
|
||||
|
||||
_resolveUnitOrFallback(candidate, expectedMeasure, fallbackUnit, label) {
|
||||
const raw = typeof candidate === 'string' ? candidate.trim() : '';
|
||||
const fallback = String(fallbackUnit || '').trim();
|
||||
if (!raw) {
|
||||
return fallback;
|
||||
}
|
||||
try {
|
||||
const desc = convert().describe(raw);
|
||||
if (expectedMeasure && desc.measure !== expectedMeasure) {
|
||||
throw new Error(`expected '${expectedMeasure}' but got '${desc.measure}'`);
|
||||
}
|
||||
return raw;
|
||||
} catch (error) {
|
||||
this.node?.warn?.(`Invalid ${label} unit '${raw}' (${error.message}). Falling back to '${fallback}'.`);
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
_resolveControlUnitOrFallback(candidate, fallback = '%') {
|
||||
const raw = typeof candidate === 'string' ? candidate.trim() : '';
|
||||
return raw || fallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate the core Measurement logic and store as source.
|
||||
*/
|
||||
@@ -81,8 +116,8 @@ class nodeClass {
|
||||
const stateConfig = {
|
||||
general: {
|
||||
logging: {
|
||||
enabled: machineConfig.eneableLog,
|
||||
logLevel: machineConfig.logLevel
|
||||
enabled: machineConfig.general.logging.enabled,
|
||||
logLevel: machineConfig.general.logging.logLevel
|
||||
}
|
||||
},
|
||||
movement: {
|
||||
@@ -132,7 +167,8 @@ class nodeClass {
|
||||
if (pressureStatus.initialized) {
|
||||
this._pressureInitWarned = false;
|
||||
}
|
||||
const flow = Math.round(m.measurements.type("flow").variant("predicted").position('downstream').getCurrentValue('m3/h'));
|
||||
const flowUnit = m?.config?.general?.unit || 'm3/h';
|
||||
const flow = Math.round(m.measurements.type("flow").variant("predicted").position('downstream').getCurrentValue(flowUnit));
|
||||
const power = Math.round(m.measurements.type("power").variant("predicted").position('atEquipment').getCurrentValue('kW'));
|
||||
let symbolState;
|
||||
switch(state){
|
||||
@@ -179,16 +215,16 @@ class nodeClass {
|
||||
status = { fill: "blue", shape: "dot", text: `${mode}: ${symbolState}` };
|
||||
break;
|
||||
case "operational":
|
||||
status = { fill: "green", shape: "dot", text: `${mode}: ${symbolState} | ${roundedPosition}% | 💨${flow}m³/h | ⚡${power}kW` };
|
||||
status = { fill: "green", shape: "dot", text: `${mode}: ${symbolState} | ${roundedPosition}% | 💨${flow}${flowUnit} | ⚡${power}kW` };
|
||||
break;
|
||||
case "starting":
|
||||
status = { fill: "yellow", shape: "dot", text: `${mode}: ${symbolState}` };
|
||||
break;
|
||||
case "warmingup":
|
||||
status = { fill: "green", shape: "dot", text: `${mode}: ${symbolState} | ${roundedPosition}% | 💨${flow}m³/h | ⚡${power}kW` };
|
||||
status = { fill: "green", shape: "dot", text: `${mode}: ${symbolState} | ${roundedPosition}% | 💨${flow}${flowUnit} | ⚡${power}kW` };
|
||||
break;
|
||||
case "accelerating":
|
||||
status = { fill: "yellow", shape: "dot", text: `${mode}: ${symbolState} | ${roundedPosition}%| 💨${flow}m³/h | ⚡${power}kW` };
|
||||
status = { fill: "yellow", shape: "dot", text: `${mode}: ${symbolState} | ${roundedPosition}%| 💨${flow}${flowUnit} | ⚡${power}kW` };
|
||||
break;
|
||||
case "stopping":
|
||||
status = { fill: "yellow", shape: "dot", text: `${mode}: ${symbolState}` };
|
||||
@@ -197,7 +233,7 @@ class nodeClass {
|
||||
status = { fill: "yellow", shape: "dot", text: `${mode}: ${symbolState}` };
|
||||
break;
|
||||
case "decelerating":
|
||||
status = { fill: "yellow", shape: "dot", text: `${mode}: ${symbolState} - ${roundedPosition}% | 💨${flow}m³/h | ⚡${power}kW` };
|
||||
status = { fill: "yellow", shape: "dot", text: `${mode}: ${symbolState} - ${roundedPosition}% | 💨${flow}${flowUnit} | ⚡${power}kW` };
|
||||
break;
|
||||
default:
|
||||
status = { fill: "grey", shape: "dot", text: `${mode}: ${symbolState}` };
|
||||
@@ -299,7 +335,8 @@ class nodeClass {
|
||||
const type = String(payload.type || '').toLowerCase();
|
||||
const position = payload.position || 'atEquipment';
|
||||
const value = Number(payload.value);
|
||||
const unit = payload.unit;
|
||||
const unit = typeof payload.unit === 'string' ? payload.unit.trim() : '';
|
||||
const supportedTypes = new Set(['pressure', 'flow', 'temperature', 'power']);
|
||||
const context = {
|
||||
timestamp: payload.timestamp || Date.now(),
|
||||
unit,
|
||||
@@ -312,6 +349,21 @@ class nodeClass {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!supportedTypes.has(type)) {
|
||||
this.node.warn(`Unsupported simulateMeasurement type: ${type}`);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!unit) {
|
||||
this.node.warn('simulateMeasurement payload.unit is required');
|
||||
break;
|
||||
}
|
||||
|
||||
if (typeof m.isUnitValidForType === 'function' && !m.isUnitValidForType(type, unit)) {
|
||||
this.node.warn(`simulateMeasurement payload.unit '${unit}' is invalid for type '${type}'`);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 'pressure':
|
||||
if (typeof m.updateSimulatedMeasurement === "function") {
|
||||
@@ -326,8 +378,9 @@ class nodeClass {
|
||||
case 'temperature':
|
||||
m.updateMeasuredTemperature(value, position, context);
|
||||
break;
|
||||
default:
|
||||
this.node.warn(`Unsupported simulateMeasurement type: ${type}`);
|
||||
case 'power':
|
||||
m.updateMeasuredPower(value, position, context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user