From 577c7e3de60f6023d5285c12e1549a8a054d216c Mon Sep 17 00:00:00 2001 From: JannekeTack26 Date: Tue, 11 Nov 2025 13:52:46 +0100 Subject: [PATCH] change to new version of code --- src/nodeClass.js | 42 +++++++-- src/specificClass.js | 220 ++++++++++++++++++++++++++++++++++--------- vgc.html | 23 +++-- 3 files changed, 224 insertions(+), 61 deletions(-) diff --git a/src/nodeClass.js b/src/nodeClass.js index c7e730a..2c488ec 100644 --- a/src/nodeClass.js +++ b/src/nodeClass.js @@ -59,19 +59,46 @@ class nodeClass { _updateNodeStatus() { const vg = this.source; - const mode = vg.mode; + const mode = vg.currentMode; const scaling = vg.scaling; const totalFlow = Math.round( vg.measurements .type("flow") - .variant("measured") - .position("downstream") + .variant("predicted") + .position("atEquipment") .getCurrentValue() * 1 ) / 1; + const maxDeltaP = + Math.round( + vg.measurements + .type("maxDeltaP") + .variant("predicted") + .position("delta") + .getCurrentValue() * 1 + ) / 1; + // Verkrijg alle valves uit de geneste structuur: + const allValves = []; + + // Voeg alle valve objects toe aan allValves + for (const [softwareType, typeData] of Object.entries(vg.child)) { + // Filter alleen valves + if (softwareType === 'valve') { + // Loop door categories (valves, etc.) + for (const childrenArray of Object.values(typeData)) { + if (Array.isArray(childrenArray)) { + allValves.push(...childrenArray); + } + } + } + } // Calculate total capacity based on available valves - const availableValves = Object.values(vg.valves).filter((valve) => { + const availableValves = allValves.filter((valve) => { + if (!valve || !valve.state) { + console.log('Valve missing state:', valve); + return false; + } const state = valve.state.getCurrentState(); const mode = valve.currentMode; return !( @@ -81,8 +108,8 @@ class nodeClass { ); }); - // const totalCapacity = Math.round(vg.dynamicTotals.flow.max * 1) / 1; ADD LATER? - + //const totalCapacity = Math.round(vg.dynamicTotals.flow.max * 1) / 1; //ADD LATER? + // Determine overall status based on available valves const status = availableValves.length > 0 @@ -91,7 +118,7 @@ class nodeClass { // Generate status text in a single line - const text = ` ${mode} | 💨=${totalFlow} | ${status}`; + const text = ` ${mode} | 💨=${totalFlow} | maxDeltaP = ${maxDeltaP} | ${status}`; return { fill: availableValves.length > 0 ? "green" : "red", @@ -178,6 +205,7 @@ class nodeClass { childObj.source, msg.positionVsParent ); + //console.log('CHECK HERE NOW', childObj); break; case 'setMode': diff --git a/src/specificClass.js b/src/specificClass.js index cdab3cb..428da36 100644 --- a/src/specificClass.js +++ b/src/specificClass.js @@ -63,9 +63,7 @@ class ValveGroupControl { // Initialize measurements this.measurements = new MeasurementContainer(); this.child = {}; - this.valves = {}; // hold child object so we can get information from its child valves - - + // this.valves = {}; // this.child; // hold child object so we can get information from its child valves // Initialize variables this.maxDeltaP = 0; // max deltaP is 0 als er geen child valves zijn @@ -74,9 +72,66 @@ class ValveGroupControl { } - registerOnChildEvents() {} + registerChild(child, softwareType) { //checken welke child er zijn + console.log('=== DEBUGGING this.child ==='); + console.log('Type of this.child:', typeof this.child); + console.log('this.child:', this.child); + + if (Object.keys(this.child).length === 0) { + console.log('✅ this.child is empty'); + } else { + console.log('✅ this.child contains:', Object.keys(this.child).length, 'items'); + Object.keys(this.child).forEach(key => { + console.log(` - Key: ${key}, Value type: ${typeof this.child[key]}`); + }); + } - registerChild(child, positionVsParent) { + this.addEventListenerForChild(child, softwareType); //subscribe to measurement changes from this specific child + } + + //MAAK SPECIFIEKE CHILD EVENT LISTENER - KAN EVT IN REGISTERCHILD FUNCTIE WORDEN BIJGEVOEGD + addEventListenerForChild(child, softwareType) { + if (child && child.emitter) { + child.measurements.emitter.on('change', (data) => { + const childName = child.config?.general?.name || `${softwareType}_child`; + console.log('🔔 EVENT RECEIVED!', childName, data); + this.logger.info(`Received change event from child ${childName}:`, data); + this.handleChildChange(child, data); + }); + console.log(`✅ Event listener added for ${softwareType} child`); + } else { + console.log(`❌ Child or emitter missing:`, { + child: !!child, + emitter: !!child?.measurements.emitter + }); + } + } + + handleChildChange(child, data) { + switch(data.type) { + case 'flow': + if (child.source === 'mg') { + this.logger.info("Total flow change from machineGroupControl detected by valveGroupControl"); + // als totalflow van mg veranderd, bereken dan de nieuwe valve flows + this.calcValveFlows(); + }; + break; + case 'pressure': + if (data.position === 'delta') { + this.logger.info("DeltaP change from child valve detected by valveGroupControl"); + // als deltaP van een van de childs valves verandert, bereken dan de nieuwe maxDeltaP + this.calcMaxDeltaP(); + }; + + // Insert actions this.calcMaxDeltaP(); + this.logger.info("Kijk ik kom bij handle child change aan!") + break; + case 'position': + // Handle position changes + break; + default: + this.logger.debug(`Unhandled change type: ${data.type}`); + } } isValidSourceForMode(source, mode) { @@ -99,7 +154,7 @@ class ValveGroupControl { await this.executeSequence(parameter); break; case "totalFlowChange": - await this.updateFlow(parameter); + await this.updateFlow("predicted", parameter, "atEquipment"); break; case "emergencyStop": this.logger.warn(`Emergency stop activated by '${source}'.`); @@ -175,12 +230,13 @@ updateFlow(variant,value,position) { default: this.logger.warn(`Unrecognized variant '${variant}' for flow update.`); + break; } } updateMeasurement(variant, subType, value, position) { - this.logger.debug(`---------------------- updating ${subType} ------------------ `); + this.logger.debug(`---------------------- updating ${subType} ------------------ NOT YET FURTHER DEFINED ------------------`); switch (subType) { case "pressure": // Update pressure measurement @@ -199,52 +255,129 @@ updateFlow(variant,value,position) { } calcValveFlows() { - const totalFlow = this.measurements.type("flow").variant("measured").position("atEquipment").getCurrentValue(); // get the total flow from the measurement container + const totalFlow = this.measurements.type("flow").variant("predicted").position("atEquipment").getCurrentValue(); // get the total flow from the measurement container let totalKv = 0; this.logger.debug(`Calculating valve flows... ${totalFlow}`); //Checkpoint + + - for (const key in this.valves){ //bereken sum kv values om verdeling total flow te maken - this.logger.info('kv: ' + this.valves[key].kv); //CHECKPOINT - if (this.valves[key].state.getCurrentPosition() != null) { - totalKv += this.valves[key].kv; - this.logger.info('Total Kv = ' + totalKv); //CHECKPOINT - } - if(totalKv === 0) { - this.logger.warn('Total Kv is 0, cannot calculate flow distribution.'); - return; // Avoid division by zero + // for (const key in this.child){ //bereken sum kv values om verdeling total flow te maken + // if (this.child[key].state.getCurrentPosition() != null) { + // totalKv += this.child[key].kv; + // this.logger.info('Total Kv = ' + totalKv); //CHECKPOINT + // } + // if(totalKv === 0) { + // this.logger.warn('Total Kv is 0, cannot calculate flow distribution.'); + // return; // Avoid division by zero + // } + // } + + // Loop door de geneste this.child structuur om total kv te berekenen + for (const [softwareType, typeData] of Object.entries(this.child)) { + // Filter alleen op valves + if (softwareType === 'valve') { + // Loop door categories (valves, etc.) + for (const [category, childrenArray] of Object.entries(typeData)) { + if (Array.isArray(childrenArray)) { + // Loop door alle valve objecten in deze array + childrenArray.forEach((valve, index) => { + if (valve && valve.state && valve.state.getCurrentPosition() != null) { + totalKv += valve.kv; + this.logger.info(`Adding valve ${index} Kv: ${valve.kv}, Total Kv now: ${totalKv}`); + } + }); + } + } } } - for (const key in this.valves){ - const valve = this.valves[key]; - this.logger.debug(`Calculating ratio for valve total: ${totalKv} valve.kv: ${valve.kv} ratio : ${valve.kv / totalKv}`); //Checkpoint - const ratio = valve.kv / totalKv; - const flow = ratio * totalFlow; // bereken flow per valve + if (totalKv === 0) { + this.logger.warn('Total Kv is 0, cannot calculate flow distribution.'); + return; // Avoid division by zero + } - //update flow per valve in de object zelf wat daar vervolgens weer de nieuwe deltaP berekent - valve.updateFlow("predicted", flow, "downstream"); - this.logger.info(`--> Sending updated flow to valves --> ${flow} `); //Checkpoint + // for (const key in this.child){ + // const valve = this.child[key]; + // this.logger.debug(`Calculating ratio for valve total: ${totalKv} valve.kv: ${valve.kv} ratio : ${valve.kv / totalKv}`); //Checkpoint + // const ratio = valve.kv / totalKv; + // const flow = ratio * totalFlow; // bereken flow per valve + // //update flow per valve in de object zelf wat daar vervolgens weer de nieuwe deltaP berekent + // valve.updateFlow("predicted", flow, "downstream"); + // this.logger.info(`--> Sending updated flow to valves --> ${flow} `); //Checkpoint + + // } + + // Flow verdelen over alle valves + for (const [softwareType, typeData] of Object.entries(this.child)) { + if (softwareType === 'valve') { + for (const [category, childrenArray] of Object.entries(typeData)) { + if (Array.isArray(childrenArray)) { + childrenArray.forEach((valve, index) => { + if (valve && valve.state && valve.state.getCurrentPosition() != null) { + const ratio = valve.kv / totalKv; + const flow = ratio * totalFlow; + + valve.updateFlow("predicted", flow, "downstream"); + this.logger.info(`--> Sending updated flow to valve --> Flow: ${flow}`); + } + }); + } + } + } } } calcMaxDeltaP() { // bereken de max deltaP van alle child valves - let maxDeltaP = 0; //max deltaP is 0 als er geen child valves zijn - this.logger.info('Calculating new max deltaP...'); - for (const key in this.valves) { - const valve = this.valves[key]; //haal de child valve object op - const deltaP = valve.measurements.type("pressure").variant("predicted").position("delta").getCurrentValue(); //get delta P - this.logger.info(`Delta P for valve ${key}: ${deltaP}`); - if (deltaP > maxDeltaP) { //als de deltaP van de child valve groter is dan de huidige maxDeltaP, dan update deze - maxDeltaP = deltaP; - } + let maxDeltaP = 0; + for (const [softwareType, typeData] of Object.entries(this.child)) { + // Filter alleen op valves + if (softwareType === 'valve') { + // Loop door categories (valves, etc.) + for (const [category, childrenArray] of Object.entries(typeData)) { + if (Array.isArray(childrenArray)) { + // Loop door alle valve objecten in deze array + childrenArray.forEach((valve, index) => { + try{ + const deltaP = valve.measurements.type("pressure").variant("predicted").position("delta").getCurrentValue(); + + if (deltaP > maxDeltaP) { + maxDeltaP = deltaP; + } + } catch (error) { + this.logger.error(`Error retrieving deltaP for valve at index ${index}: ${error}`); + } + }); + } + } + } } - this.logger.info('Max Delta P updated to: ' + maxDeltaP); - this.maxDeltaP = maxDeltaP; //update de max deltaP in de measurement container van de valveGroupControl class + this.measurements.type("maxDeltaP").variant("predicted").position("delta").value(maxDeltaP); //update de max deltaP in de measurement container van de valveGroupControl class + this.maxDeltaP = maxDeltaP; //update de max deltaP + this.logger.info('Max Delta P updated to: ' + maxDeltaP); + } + + + + + // let maxDeltaP = 0; //max deltaP is 0 als er geen child valves zijn + // this.logger.info('Calculating new max deltaP...'); + // for (const key in this.child) { + // const valve = this.child[key]; //haal de child valve object op + // const deltaP = valve.measurements.type("pressure").variant("predicted").position("delta").getCurrentValue(); //get delta P + // this.logger.info(`Delta P for valve ${key}: ${deltaP}`); + // if (deltaP > maxDeltaP) { //als de deltaP van de child valve groter is dan de huidige maxDeltaP, dan update deze + // maxDeltaP = deltaP; + // } + // } + // this.logger.info('Max Delta P updated to: ' + maxDeltaP); + + // this.measurements.type("maxDeltaP").variant("predicted").position("delta").value(maxDeltaP); //update de max deltaP in de measurement container van de valveGroupControl class + // this.maxDeltaP = maxDeltaP; //update de max deltaP + -} getOutput() { @@ -273,7 +406,6 @@ updateFlow(variant,value,position) { return output; } - } module.exports = ValveGroupControl; @@ -318,23 +450,23 @@ const stateConfig = { } }; -const valve1 = new valve(valveConfig, stateConfig); +//const valve1 = new valve(valveConfig, stateConfig); //const valve2 = new valve(valveConfig, stateConfig); //const valve3 = new valve(valveConfig, stateConfig); -valve1.kv = 10; // Set Kv value for valve1 +//valve1.kv = 10; // Set Kv value for valve1 //valve2.kv = 20; // Set Kv value for valve2 //valve3.kv = 30; // Set Kv value for valve3 -valve1.updateMeasurement("measured", "pressure" , 500, "downstream"); +//valve1.updateMeasurement("measured", "pressure" , 500, "downstream"); //valve2.updateMeasurement("measured" , "pressure" , 500, "downstream"); //valve3.updateMeasurement("measured" , "pressure" , 500, "downstream"); -const vgc = new ValveGroupControl(); +//const vgc = new ValveGroupControl(); -vgc.childRegistrationUtils.registerChild(valve1, "atEquipment"); +//vgc.childRegistrationUtils.registerChild(valve1, "atEquipment"); //vgc.childRegistrationUtils.registerChild(valve2, "atEquipment"); //vgc.childRegistrationUtils.registerChild(valve3, "atEquipment"); -vgc.updateFlow("measured", 1000, "atEquipment"); // Update total flow to 100 m3/h +//vgc.updateFlow("measured", 1000, "atEquipment"); // Update total flow to 100 m3/h diff --git a/vgc.html b/vgc.html index cb97e4f..c620fa2 100644 --- a/vgc.html +++ b/vgc.html @@ -1,12 +1,15 @@ @@ -14,7 +17,7 @@