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 @@