From efb99df10790f8439d9cc533776d530226d036b3 Mon Sep 17 00:00:00 2001
From: "p.vanderwilt"
Date: Thu, 23 Oct 2025 17:15:41 +0200
Subject: [PATCH] Implement settler class with reactor, measurement and machine
connection logic
---
package-lock.json | 119 +++++++++++++++++++++++++++++++++++++++++++
settler.html | 12 -----
src/specificClass.js | 79 ++++++++++++++++++++++++++++
3 files changed, 198 insertions(+), 12 deletions(-)
create mode 100644 package-lock.json
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..d46b61b
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,119 @@
+{
+ "name": "settler",
+ "version": "0.0.1",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "settler",
+ "version": "0.0.1",
+ "license": "SEE LICENSE",
+ "dependencies": {
+ "generalFunctions": "git+https://gitea.centraal.wbd-rd.nl/RnD/generalFunctions.git",
+ "mathjs": "^14.5.2"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
+ "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/complex.js": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.4.2.tgz",
+ "integrity": "sha512-qtx7HRhPGSCBtGiST4/WGHuW+zeaND/6Ld+db6PbrulIB1i2Ev/2UPiqcmpQNPSyfBKraC0EOvOKCB5dGZKt3g==",
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/rawify"
+ }
+ },
+ "node_modules/decimal.js": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
+ "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
+ "license": "MIT"
+ },
+ "node_modules/escape-latex": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz",
+ "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==",
+ "license": "MIT"
+ },
+ "node_modules/fraction.js": {
+ "version": "5.3.4",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz",
+ "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==",
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/rawify"
+ }
+ },
+ "node_modules/generalFunctions": {
+ "version": "1.0.0",
+ "resolved": "git+https://gitea.centraal.wbd-rd.nl/RnD/generalFunctions.git#9b7a8ae2c8ae149f48608e2fa5a180b486700978",
+ "license": "SEE LICENSE"
+ },
+ "node_modules/javascript-natural-sort": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz",
+ "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==",
+ "license": "MIT"
+ },
+ "node_modules/mathjs": {
+ "version": "14.9.1",
+ "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-14.9.1.tgz",
+ "integrity": "sha512-xhqv8Xjf+caWG3WlaPekg4v8QFOR3D5+8ycfcjMcPcnCNDgAONQLaLfyGgrggJrcHx2yUGCpACRpiD4GmXwX+Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@babel/runtime": "^7.26.10",
+ "complex.js": "^2.2.5",
+ "decimal.js": "^10.4.3",
+ "escape-latex": "^1.2.0",
+ "fraction.js": "^5.2.1",
+ "javascript-natural-sort": "^0.7.1",
+ "seedrandom": "^3.0.5",
+ "tiny-emitter": "^2.1.0",
+ "typed-function": "^4.2.1"
+ },
+ "bin": {
+ "mathjs": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/seedrandom": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz",
+ "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==",
+ "license": "MIT"
+ },
+ "node_modules/tiny-emitter": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
+ "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
+ "license": "MIT"
+ },
+ "node_modules/typed-function": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.2.1.tgz",
+ "integrity": "sha512-EGjWssW7Tsk4DGfE+5yluuljS1OGYWiI1J6e8puZz9nTMM51Oug8CD5Zo4gWMsOhq5BI+1bF+rWTm4Vbj3ivRA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 18"
+ }
+ }
+ }
+}
diff --git a/settler.html b/settler.html
index 09ebea5..9f3a639 100644
--- a/settler.html
+++ b/settler.html
@@ -27,10 +27,6 @@
};
waitForMenuData();
- $("#node-input-TS_set").typedInput({
- type:"num",
- types:["num"]
- });
$("#node-input-inlet").typedInput({
type:"num",
types:["num"]
@@ -47,10 +43,6 @@
window.EVOLV.nodes.rotatingMachine.positionMenu.saveEditor(this);
}
- const TS_set = parseFloat($("#node-input-TS_set").typedInput("value"));
- if (isNaN(TS_set) || TS_set < 0) {
- RED.notify("TS is not set correctly", {type: "error"});
- }
const inlet = parseInt($("#node-input-n_inlets").typedInput("value"));
if (inlet < 1) {
RED.notify("Number of inlets not set correctly", {type: "error"});
@@ -64,10 +56,6 @@
-
-
-
-
diff --git a/src/specificClass.js b/src/specificClass.js
index bc98902..2bf25f2 100644
--- a/src/specificClass.js
+++ b/src/specificClass.js
@@ -9,15 +9,94 @@ class Settler {
this.emitter = new EventEmitter();
this.measurements = new MeasurementContainer();
this.childRegistrationUtils = new childRegistrationUtils(this); // Child registration utility
+
+ this.upstreamReactor = null;
+ this.returnPump = null;
+
+ // state variables
+ this.F_in = 0;
+ }
+
+ get getEffluent() {
+ return;
}
registerChild(child, softwareType) {
switch (softwareType) {
+ case "measurement":
+ this.logger.debug(`Registering measurement child...`);
+ this._connectMeasurement(child);
+ break;
+ case "reactor":
+ this.logger.debug(`Registering reactor child...`);
+ this._connectReactor(child);
+ break;
+ case "machine":
+ this.logger.debug(`Registering machine child...`);
+ this._connectMachine(child);
+ break;
default:
this.logger.error(`Unrecognized softwareType: ${softwareType}`);
}
}
+
+ _connectMeasurement(measurementChild) {
+ if (!measurementChild) {
+ this.logger.error("Invalid measurement provided.");
+ return;
+ }
+
+ const position = measurementChild.config.functionality.positionVsParent;
+ const measurementType = measurementChild.config.asset.type;
+ const eventName = `${measurementType}.measured.${position}`;
+
+ // Register event listener for measurement updates
+ measurementChild.measurements.emitter.on(eventName, (eventData) => {
+ this.logger.debug(`${position} ${measurementType} from ${eventData.childName}: ${eventData.value} ${eventData.unit}`);
+
+ // Store directly in parent's measurement container
+ this.measurements
+ .type(measurementType)
+ .variant("measured")
+ .position(position)
+ .value(eventData.value, eventData.timestamp, eventData.unit);
+
+ this._updateMeasurement(measurementType, eventData.value, position, eventData);
+ });
+ }
+
+ _connectReactor(reactorChild) {
+ if (!reactorChild) {
+ this.logger.error("Invalid reactor provided.");
+ return;
+ }
+
+ if (reactorChild.config.functionality.positionVsParent != "upstream") {
+ this.logger.warn("Reactor children of reactors should always be upstream.");
+ }
+
+ this.upstreamReactor = reactorChild;
+
+ reactorChild.emitter.on("stateChange", (eventData) => {
+ this.logger.debug(`State change of upstream reactor detected.`);
+ const effluent = this.upstreamReactor.getEffluent[0];
+ this.F_in = effluent.payload.F;
+ this.Cs_in = effluent.payload.C;
+ });
+ }
+
+ _connectMachine(machineChild) {
+ if (!machineChild) {
+ this.logger.error("Invalid rotating machine provided.");
+ return;
+ }
+
+ if (machineChild.config.functionality.positionVsParent == "downstream") {
+ machineChild.upstreamReactor = this;
+ this.returnPump = machineChild;
+ }
+ }
}
module.exports = { Settler };
\ No newline at end of file