diff --git a/src/nodeClass.js b/src/nodeClass.js index 00d5dcd..cce60c8 100644 --- a/src/nodeClass.js +++ b/src/nodeClass.js @@ -61,25 +61,28 @@ class nodeClass { const mg = this.source; const mode = mg.mode; const scaling = mg.scaling; - const totalFlow = - Math.round( - mg.measurements - .type("flow") - .variant("predicted") - .position("downstream") - .getCurrentValue() * 1 - ) / 1; - const totalPower = - Math.round( - mg.measurements - .type("power") - .variant("predicted") - .position("upstream") - .getCurrentValue() * 1 - ) / 1; + + // Add safety checks for measurements + const totalFlow = mg.measurements + ?.type("flow") + ?.variant("predicted") + ?.position("downstream") + ?.getCurrentValue() || 0; + + const totalPower = mg.measurements + ?.type("power") + ?.variant("predicted") + ?.position("upstream") + ?.getCurrentValue() || 0; - // Calculate total capacity based on available machines - const availableMachines = Object.values(mg.machines).filter((machine) => { + // Calculate total capacity based on available machines with safety checks + const availableMachines = Object.values(mg.machines || {}).filter((machine) => { + // Safety check: ensure machine and machine.state exist + if (!machine || !machine.state || typeof machine.state.getCurrentState !== 'function') { + console.warn(`Machine missing or invalid:`, machine?.config?.general?.id || 'unknown'); + return false; + } + const state = machine.state.getCurrentState(); const mode = machine.currentMode; return !( @@ -89,29 +92,27 @@ class nodeClass { ); }); - const totalCapacity = Math.round(mg.dynamicTotals.flow.max * 1) / 1; + const totalCapacity = Math.round((mg.dynamicTotals?.flow?.max || 0) * 1) / 1; // Determine overall status based on available machines - const status = - availableMachines.length > 0 - ? `${availableMachines.length} machine(s) connected` - : "No machines"; + const status = availableMachines.length > 0 + ? `${availableMachines.length} machine(s) connected` + : "No machines"; let scalingSymbol = ""; - switch (scaling.toLowerCase()) { + switch ((scaling || "").toLowerCase()) { case "absolute": - scalingSymbol = "Ⓐ"; // Clear symbol for Absolute mode + scalingSymbol = "Ⓐ"; break; case "normalized": - scalingSymbol = "Ⓝ"; // Clear symbol for Normalized mode + scalingSymbol = "Ⓝ"; break; default: - scalingSymbol = mode; + scalingSymbol = mode || ""; break; } - // Generate status text in a single line - const text = ` ${mode} | ${scalingSymbol}: 💨=${totalFlow}/${totalCapacity} | ⚡=${totalPower} | ${status}`; + const text = ` ${mode || 'Unknown'} | ${scalingSymbol}: 💨=${Math.round(totalFlow)}/${totalCapacity} | ⚡=${Math.round(totalPower)} | ${status}`; return { fill: availableMachines.length > 0 ? "green" : "red", @@ -197,14 +198,26 @@ class nodeClass { const RED = this.RED; switch (msg.topic) { case "registerChild": - //console.log(`Registering child in mgc: ${msg.payload}`); - const childId = msg.payload; - const childObj = RED.nodes.getNode(childId); - mg.childRegistrationUtils.registerChild( - childObj.source, - msg.positionVsParent - ); - break; + console.log(`Registering child in mgc: ${msg.payload}`); + const childId = msg.payload; + const childObj = RED.nodes.getNode(childId); + + // Debug: Check what we're getting + console.log(`Child object:`, childObj ? 'found' : 'NOT FOUND'); + console.log(`Child source:`, childObj?.source ? 'exists' : 'MISSING'); + if (childObj?.source) { + console.log(`Child source type:`, childObj.source.constructor.name); + console.log(`Child has state:`, !!childObj.source.state); + } + + mg.childRegistrationUtils.registerChild( + childObj.source, + msg.positionVsParent + ); + + // Debug: Check machines after registration + console.log(`Total machines after registration:`, Object.keys(mg.machines || {}).length); + break; case "setMode": const mode = msg.payload; @@ -215,6 +228,7 @@ class nodeClass { case "setScaling": const scaling = msg.payload; mg.setScaling(scaling); + break; case "Qd": diff --git a/src/specificClass.js b/src/specificClass.js index a3a91b5..399e1ba 100644 --- a/src/specificClass.js +++ b/src/specificClass.js @@ -87,6 +87,14 @@ class MachineGroup { if(softwareType == "machine"){ // Check if the machine is already registered this.machines[child.config.general.id] === undefined ? this.machines[child.config.general.id] = child : this.logger.warn(`Machine ${child.config.general.id} is already registered.`); + this.handleChildChange(); + /* + // Listen for changes in the child machine + child.emitter.on('stateChange', () => this.handleChildChange()); + child.emitter.on('pressureChange', () => this.handlePressureChange()); + child.emitter.on('ncogChange', () => this.handleChildChange()); + */ + } } @@ -207,6 +215,7 @@ class MachineGroup { checkSpecialCases(machines, Qd) { Object.values(machines).forEach(machine => { + const state = machine.state.getCurrentState(); const mode = machine.currentMode; @@ -240,7 +249,7 @@ class MachineGroup { // Generate all possible subsets of machines (power set) Object.keys(machines).forEach(machineId => { - machineId = parseInt(machineId); + //machineId = parseInt(machineId); const state = machines[machineId].state.getCurrentState(); @@ -355,8 +364,9 @@ class MachineGroup { } setScaling(scaling) { - const scalingSet = new Set(defaultConfig.scaling.current.rules.values.map( (value) => value.value)); + const scalingSet = new Set(this.defaultConfig.scaling.current.rules.values.map( (value) => value.value)); scalingSet.has(scaling)? this.scaling = scaling : this.logger.warn(`${scaling} is not a valid scaling option.`); + this.logger.debug(`Scaling set to: ${scaling}`); } //handle input from parent / user / UI @@ -894,29 +904,29 @@ class MachineGroup { module.exports = MachineGroup; /* -const Machine = require('../../../rotatingMachine/dependencies/machine/machine'); -const Measurement = require('../../../measurement/dependencies/measurement/measurement'); -const specs = require('../../../generalFunctions/datasets/assetData/pumps/hydrostal/centrifugal pumps/models.json'); -const power = require("../../../convert/dependencies/definitions/power"); -const { machine } = require("os"); +const Machine = require('../../rotatingMachine/src/specificClass'); +const Measurement = require('../../measurement/src/specificClass'); +const specs = require('../../generalFunctions/datasets/assetData/curves/hidrostal-H05K-S03R.json'); +const { number } = require("../../generalFunctions/src/convert/lodash/lodash._objecttypes"); -function createBaseMachineConfig(name,specs) { +function createBaseMachineConfig(machineNum, name,specs) { return { general: { logging: { enabled: true, logLevel: "warn" }, name: name, + id: machineNum, unit: "m3/h" }, functionality: { softwareType: "machine", - role: "RotationalDeviceController" + role: "rotationaldevicecontroller" }, asset: { - type: "pump", - subType: "Centrifugal", - model: "TestModel", - supplier: "Hydrostal", - machineCurve: specs[0].machineCurve + category: "pump", + type: "centrifugal", + model: "hidrostal-h05k-s03r", + supplier: "hydrostal", + machineCurve: specs }, mode: { current: "auto", @@ -947,8 +957,8 @@ function createBaseMachineGroupConfig(name) { name: name }, functionality: { - softwareType: "machineGroup", - role: "GroupController" + softwareType: "machinegroup", + role: "groupcontroller" }, scaling: { current: "normalized" @@ -959,22 +969,26 @@ function createBaseMachineGroupConfig(name) { }; } -const machineGroupConfig = createBaseMachineGroupConfig("TestMachineGroup"); -const machineConfig = createBaseMachineConfig("TestMachine",specs); +const machineGroupConfig = createBaseMachineGroupConfig("testmachinegroup"); +const machineConfigs = {}; +machineConfigs[1]= createBaseMachineConfig(1,"testmachine",specs); +machineConfigs[2] = createBaseMachineConfig(2,"testmachine2",specs); + const ptConfig = { general: { logging: { enabled: true, logLevel: "debug" }, - name: "TestPT", + name: "testpt", + id: "0", unit: "mbar", }, functionality: { softwareType: "measurement", - role: "Sensor" + role: "sensor" }, asset: { - type: "sensor", - subType: "pressure", - model: "TestModel", + category: "sensor", + type: "pressure", + model: "testmodel", supplier: "vega" }, scaling:{ @@ -987,8 +1001,8 @@ async function makeMachines(){ const mg = new MachineGroup(machineGroupConfig); const pt1 = new Measurement(ptConfig); const numofMachines = 2; - for(let i = 0; i < numofMachines; i++){ - const machine = new Machine(machineConfig); + for(let i = 1; i <= numofMachines; i++){ + const machine = new Machine(machineConfigs[i]); //mg.machines[i] = machine; mg.childRegistrationUtils.registerChild(machine, "downstream"); } @@ -1029,14 +1043,16 @@ async function makeMachines(){ console.log("------------------------------------"); } - -*//* + //*/ +/* for(let demand = 0 ; demand <= 100 ; demand += 1){ //set pressure console.log("------------------------------------"); await mg.handleInput("parent",demand); + console.log(mg.machines[1].state.getCurrentState()); + console.log(mg.machines[2].state.getCurrentState()); pt1.calculateInput(1400); console.log("Waiting for 0.2 sec "); //await new Promise(resolve => setTimeout(resolve, 200)); @@ -1054,4 +1070,5 @@ async function makeMachines(){ makeMachines(); -//*/ + +*/ \ No newline at end of file