From 839ae2f3da6c5483bc72a768c9210c28574cb9dc Mon Sep 17 00:00:00 2001 From: "p.vanderwilt" Date: Wed, 16 Jul 2025 15:34:58 +0200 Subject: [PATCH 01/10] feat: add reactor registration and handling in ChildRegistrationUtils --- src/helper/childRegistrationUtils.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/helper/childRegistrationUtils.js b/src/helper/childRegistrationUtils.js index f9b9cef..8f3106d 100644 --- a/src/helper/childRegistrationUtils.js +++ b/src/helper/childRegistrationUtils.js @@ -87,6 +87,11 @@ class ChildRegistrationUtils { this.logger.debug(`Registering linear actuator child: ${id}`); this.connectActuator(child,positionVsParent); break; + + case "reactor": + this.logger.debug(`Registering reactor child: ${id}`); + this.connectReactor(child); + break; default: this.logger.error(`Child registration unrecognized desc: ${desc}`); @@ -222,6 +227,20 @@ class ChildRegistrationUtils { } } + connectReactor(reactor) { + if (!reactor) { + this.logger.warn("Invalid reactor provided."); + return; + } + this.mainClass.upstreamReactor = reactor; // Add reactor to the main class + this.logger.info(`Reactor registered successfully.`); + + reactor.emitter.on("stateChange", (data) => { + this.mainClass.logger.debug(`State change of reactor detected: ${data}`); + this.mainClass.setInflux = data; + }); + } + //wanneer hij deze ontvangt is deltaP van een van de valves veranderd (kan ook zijn niet child zijn, maar dat maakt niet uit) } From 7cdfc87c834486ea4b9b3500bfc6a551bba49266 Mon Sep 17 00:00:00 2001 From: "p.vanderwilt" Date: Wed, 16 Jul 2025 16:04:32 +0200 Subject: [PATCH 02/10] Add state update on recieving child signal --- src/helper/childRegistrationUtils.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/helper/childRegistrationUtils.js b/src/helper/childRegistrationUtils.js index 8f3106d..8b90cb1 100644 --- a/src/helper/childRegistrationUtils.js +++ b/src/helper/childRegistrationUtils.js @@ -226,6 +226,8 @@ class ChildRegistrationUtils { } } } + + //wanneer hij deze ontvangt is deltaP van een van de valves veranderd (kan ook zijn niet child zijn, maar dat maakt niet uit) connectReactor(reactor) { if (!reactor) { @@ -238,10 +240,10 @@ class ChildRegistrationUtils { reactor.emitter.on("stateChange", (data) => { this.mainClass.logger.debug(`State change of reactor detected: ${data}`); this.mainClass.setInflux = data; + this.mainClass.updateState(data.timestamp); }); } - //wanneer hij deze ontvangt is deltaP van een van de valves veranderd (kan ook zijn niet child zijn, maar dat maakt niet uit) } module.exports = ChildRegistrationUtils; From 8c9301b128d8f9d107a6a6012af5f483141184bf Mon Sep 17 00:00:00 2001 From: "p.vanderwilt" Date: Mon, 21 Jul 2025 14:14:30 +0200 Subject: [PATCH 03/10] Remove undefined reference to 'desc' --- src/helper/childRegistrationUtils.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/helper/childRegistrationUtils.js b/src/helper/childRegistrationUtils.js index f9b9cef..e018a0b 100644 --- a/src/helper/childRegistrationUtils.js +++ b/src/helper/childRegistrationUtils.js @@ -89,7 +89,6 @@ class ChildRegistrationUtils { break; default: - this.logger.error(`Child registration unrecognized desc: ${desc}`); this.logger.error(`Unrecognized softwareType: ${softwareType}`); } } From 475caa90db60c35b491f82340069a1ea4ba6757d Mon Sep 17 00:00:00 2001 From: "p.vanderwilt" Date: Mon, 21 Jul 2025 17:32:00 +0200 Subject: [PATCH 04/10] Fixed bugs in connectReactor --- src/helper/childRegistrationUtils.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/helper/childRegistrationUtils.js b/src/helper/childRegistrationUtils.js index 8db49d8..7b3cbb7 100644 --- a/src/helper/childRegistrationUtils.js +++ b/src/helper/childRegistrationUtils.js @@ -237,9 +237,8 @@ class ChildRegistrationUtils { this.logger.info(`Reactor registered successfully.`); reactor.emitter.on("stateChange", (data) => { - this.mainClass.logger.debug(`State change of reactor detected: ${data}`); - this.mainClass.setInflux = data; - this.mainClass.updateState(data.timestamp); + this.mainClass.logger.debug(`State change of upstream reactor detected.`); + this.mainClass.updateState(data); }); } From 71643375fc1ace033bc6d4b2149e81464dab8e05 Mon Sep 17 00:00:00 2001 From: "p.vanderwilt" Date: Thu, 24 Jul 2025 15:09:04 +0200 Subject: [PATCH 05/10] Added additional reactor handling --- src/helper/childRegistrationUtils.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/helper/childRegistrationUtils.js b/src/helper/childRegistrationUtils.js index 7b3cbb7..0a2aaac 100644 --- a/src/helper/childRegistrationUtils.js +++ b/src/helper/childRegistrationUtils.js @@ -233,7 +233,18 @@ class ChildRegistrationUtils { this.logger.warn("Invalid reactor provided."); return; } - this.mainClass.upstreamReactor = reactor; // Add reactor to the main class + + // this is poor code, it should be fixed at some point + if (this.mainClass?.upstreamReactor){ + this.mainClass.upstreamReactor = reactor; // Add reactor to the main class + } else { + if (positionVsParent == "downstream") { + this.mainClass.reactors[0] = reactor; + } + if (positionVsParent == "upstream") { + this.mainClass.reactors[1] = reactor; + } + } this.logger.info(`Reactor registered successfully.`); reactor.emitter.on("stateChange", (data) => { From aec2d3692dbe59f73cf3a2fc91d920db55cb9442 Mon Sep 17 00:00:00 2001 From: "p.vanderwilt" Date: Thu, 31 Jul 2025 11:36:42 +0200 Subject: [PATCH 06/10] Fixed missing reference to position --- src/helper/childRegistrationUtils.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/helper/childRegistrationUtils.js b/src/helper/childRegistrationUtils.js index 0a2aaac..1d1a723 100644 --- a/src/helper/childRegistrationUtils.js +++ b/src/helper/childRegistrationUtils.js @@ -85,12 +85,12 @@ class ChildRegistrationUtils { case "actuator": this.logger.debug(`Registering linear actuator child: ${id}`); - this.connectActuator(child,positionVsParent); + this.connectActuator(child, positionVsParent); break; case "reactor": this.logger.debug(`Registering reactor child: ${id}`); - this.connectReactor(child); + this.connectReactor(child, positionVsParent); break; default: @@ -228,7 +228,7 @@ class ChildRegistrationUtils { //wanneer hij deze ontvangt is deltaP van een van de valves veranderd (kan ook zijn niet child zijn, maar dat maakt niet uit) - connectReactor(reactor) { + connectReactor(reactor, positionVsParent) { if (!reactor) { this.logger.warn("Invalid reactor provided."); return; From 7191e57aeaa864dafa0b5be331b040a82b9ecd73 Mon Sep 17 00:00:00 2001 From: "p.vanderwilt" Date: Thu, 31 Jul 2025 14:57:38 +0200 Subject: [PATCH 07/10] Improved reactor registration --- src/helper/childRegistrationUtils.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/helper/childRegistrationUtils.js b/src/helper/childRegistrationUtils.js index 1d1a723..3ba661a 100644 --- a/src/helper/childRegistrationUtils.js +++ b/src/helper/childRegistrationUtils.js @@ -234,18 +234,20 @@ class ChildRegistrationUtils { return; } - // this is poor code, it should be fixed at some point if (this.mainClass?.upstreamReactor){ this.mainClass.upstreamReactor = reactor; // Add reactor to the main class - } else { + this.logger.info(`Upstream reactor registered successfully.`); + } + + if (this.mainClass?.reactors) { if (positionVsParent == "downstream") { this.mainClass.reactors[0] = reactor; } if (positionVsParent == "upstream") { this.mainClass.reactors[1] = reactor; } + this.logger.info(`Reactor registered successfully.`); } - this.logger.info(`Reactor registered successfully.`); reactor.emitter.on("stateChange", (data) => { this.mainClass.logger.debug(`State change of upstream reactor detected.`); From 0bccad05f8eaa925f05a07bfefcf9416c7e32a59 Mon Sep 17 00:00:00 2001 From: "p.vanderwilt" Date: Fri, 1 Aug 2025 12:30:12 +0200 Subject: [PATCH 08/10] Added error message to node registration --- src/helper/childRegistrationUtils.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/helper/childRegistrationUtils.js b/src/helper/childRegistrationUtils.js index 3ba661a..532e414 100644 --- a/src/helper/childRegistrationUtils.js +++ b/src/helper/childRegistrationUtils.js @@ -237,9 +237,7 @@ class ChildRegistrationUtils { if (this.mainClass?.upstreamReactor){ this.mainClass.upstreamReactor = reactor; // Add reactor to the main class this.logger.info(`Upstream reactor registered successfully.`); - } - - if (this.mainClass?.reactors) { + } else if (this.mainClass?.reactors) { if (positionVsParent == "downstream") { this.mainClass.reactors[0] = reactor; } @@ -247,6 +245,8 @@ class ChildRegistrationUtils { this.mainClass.reactors[1] = reactor; } this.logger.info(`Reactor registered successfully.`); + } else { + this.logger.error(`Reactor not registered!`) } reactor.emitter.on("stateChange", (data) => { From 958ec2269c902f3ebb11b13527fbc860ee9381e7 Mon Sep 17 00:00:00 2001 From: "p.vanderwilt" Date: Wed, 3 Sep 2025 11:13:00 +0200 Subject: [PATCH 09/10] Print reactors state after configuration --- src/helper/childRegistrationUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helper/childRegistrationUtils.js b/src/helper/childRegistrationUtils.js index 532e414..eac2e7d 100644 --- a/src/helper/childRegistrationUtils.js +++ b/src/helper/childRegistrationUtils.js @@ -244,7 +244,7 @@ class ChildRegistrationUtils { if (positionVsParent == "upstream") { this.mainClass.reactors[1] = reactor; } - this.logger.info(`Reactor registered successfully.`); + this.logger.info(`Reactor registered successfully: ${this.mainClass.reactors}`); } else { this.logger.error(`Reactor not registered!`) } From a30f2c90f417e9f73540ebfea8ea739046ef116d Mon Sep 17 00:00:00 2001 From: znetsixe <73483679+znetsixe@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:18:42 +0200 Subject: [PATCH 10/10] physicalPosition 1D update --- src/menu/physicalPosition.js | 174 +++++++++++++++++++++++++++++------ 1 file changed, 145 insertions(+), 29 deletions(-) diff --git a/src/menu/physicalPosition.js b/src/menu/physicalPosition.js index 191dd79..e22cfb1 100644 --- a/src/menu/physicalPosition.js +++ b/src/menu/physicalPosition.js @@ -11,7 +11,25 @@ class PhysicalPositionMenu { { value: 'downstream', label: '→ Downstream' , icon: '→' } ] } - ] + ], + // Distance contexts for each position + distanceContexts: { + upstream: { + description: 'Distance from parent inlet', + placeholder: 'e.g., 2.5 (meters before parent)', + helpText: 'How far upstream from the parent equipment' + }, + downstream: { + description: 'Distance from parent outlet', + placeholder: 'e.g., 3.0 (meters after parent)', + helpText: 'How far downstream from the parent equipment' + }, + atEquipment: { + description: 'Distance from parent start', + placeholder: 'e.g., 1.2 (meters from start)', + helpText: 'Position within the parent equipment boundaries' + } + } }; } @@ -26,6 +44,24 @@ class PhysicalPositionMenu { + + +
+ + + +
+ +
`; } @@ -52,22 +88,40 @@ class PhysicalPositionMenu { window.EVOLV.nodes.${nodeName}.positionMenu.loadData = function(node) { const data = window.EVOLV.nodes.${nodeName}.menuData.position; const sel = document.getElementById('node-input-positionVsParent'); - if (!sel) return; - sel.innerHTML = ''; - (data.positionGroups||[]).forEach(grp => { - const optg = document.createElement('optgroup'); - optg.label = grp.group; - grp.options.forEach(o=>{ - const opt = document.createElement('option'); - opt.value = o.value; - opt.textContent = o.label; - opt.setAttribute('data-icon', o.icon); - optg.appendChild(opt); + const hasDistanceCheck = document.getElementById('node-input-hasDistance'); + const distanceInput = document.getElementById('node-input-distance'); + const distanceSection = document.getElementById('distance-section'); + + //Load position options + if (sel) { + sel.innerHTML = ''; + (data.positionGroups||[]).forEach(grp => { + const optg = document.createElement('optgroup'); + optg.label = grp.group; + grp.options.forEach(o=>{ + const opt = document.createElement('option'); + opt.value = o.value; + opt.textContent = o.label; + opt.setAttribute('data-icon', o.icon); + optg.appendChild(opt); + }); + sel.appendChild(optg); }); - sel.appendChild(optg); - }); - // default to “atEquipment” if not set - sel.value = node.positionVsParent || 'atEquipment'; + sel.value = node.positionVsParent || 'atEquipment'; + } + + //Load distance values + if (hasDistanceCheck) { + hasDistanceCheck.checked = node.hasDistance || false; + distanceSection.style.display = hasDistanceCheck.checked ? 'block' : 'none'; + } + + if (distanceInput) { + distanceInput.value = node.distance || ''; + } + + // Update distance context for current position + this.updateDistanceContext(node.positionVsParent || 'atEquipment', data.distanceContexts); }; `; } @@ -77,24 +131,86 @@ class PhysicalPositionMenu { return ` // PhysicalPosition events for ${nodeName} window.EVOLV.nodes.${nodeName}.positionMenu.wireEvents = function(node) { - // no dynamic behavior + const positionSel = document.getElementById('node-input-positionVsParent'); + const hasDistanceCheck = document.getElementById('node-input-hasDistance'); + const distanceSection = document.getElementById('distance-section'); + const data = window.EVOLV.nodes.${nodeName}.menuData.position; + + // Toggle distance section visibility + if (hasDistanceCheck && distanceSection) { + hasDistanceCheck.addEventListener('change', function() { + distanceSection.style.display = this.checked ? 'block' : 'none'; + + // Clear distance if unchecked + if (!this.checked) { + const distanceInput = document.getElementById('node-input-distance'); + if (distanceInput) { + distanceInput.value = ''; + } + } + }); + } + + // Update distance context when position changes + if (positionSel) { + positionSel.addEventListener('change', function() { + const position = this.value; + window.EVOLV.nodes.${nodeName}.positionMenu.updateDistanceContext(position, data.distanceContexts); + }); + } + }; + + // Helper function to update distance context + window.EVOLV.nodes.${nodeName}.positionMenu.updateDistanceContext = function(position, contexts) { + const distanceInput = document.getElementById('node-input-distance'); + const distanceHelp = document.getElementById('distance-help'); + + const context = contexts && contexts[position]; + + if (context && distanceInput && distanceHelp) { + distanceInput.placeholder = context.placeholder || '0.0'; + distanceHelp.textContent = context.helpText || 'Enter distance in meters'; + } }; `; } // 6) Save-logic injector - getSaveInjectionCode(nodeName) { - return ` - // PhysicalPosition Save injection for ${nodeName} - window.EVOLV.nodes.${nodeName}.positionMenu.saveEditor = function(node) { - const sel = document.getElementById('node-input-positionVsParent'); - node.positionVsParent = sel? sel.value : 'atEquipment'; - node.positionLabel = sel? sel.options[sel.selectedIndex].textContent : 'At Equipment'; - node.positionIcon = sel? sel.options[sel.selectedIndex].getAttribute('data-icon') : 'fa fa-cog'; - return true; - }; - `; - } +getSaveInjectionCode(nodeName) { + return ` + // PhysicalPosition Save injection for ${nodeName} + window.EVOLV.nodes.${nodeName}.positionMenu.saveEditor = function(node) { + const sel = document.getElementById('node-input-positionVsParent'); + const hasDistanceCheck = document.getElementById('node-input-hasDistance'); + const distanceInput = document.getElementById('node-input-distance'); + + // Save existing position data + node.positionVsParent = sel ? sel.value : 'atEquipment'; + node.positionLabel = sel ? sel.options[sel.selectedIndex].textContent : 'At Equipment'; + node.positionIcon = sel ? sel.options[sel.selectedIndex].getAttribute('data-icon') : 'fa fa-cog'; + + // Save distance data (NEW) + node.hasDistance = hasDistanceCheck ? hasDistanceCheck.checked : false; + + if (node.hasDistance && distanceInput && distanceInput.value) { + node.distance = parseFloat(distanceInput.value) || 0; + node.distanceUnit = 'm'; // Fixed to meters for now + + // Generate distance description based on position + const contexts = window.EVOLV.nodes.${nodeName}.menuData.position.distanceContexts; + const context = contexts && contexts[node.positionVsParent]; + node.distanceDescription = context ? context.description : 'Distance from parent'; + } else { + // Clear distance data if not specified + delete node.distance; + delete node.distanceUnit; + delete node.distanceDescription; + } + + return true; + }; + `; +} // 7) Compose everything into one client bundle getClientInitCode(nodeName) {