From 633a0884835c69095aa2696779371bbefafc8900 Mon Sep 17 00:00:00 2001 From: "p.vanderwilt" Date: Wed, 16 Jul 2025 16:08:14 +0200 Subject: [PATCH] Added handles for influent change emitter --- src/nodeClass.js | 20 ++++++++++--------- src/specificClass.js | 46 +++++++++++++++++++++----------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/nodeClass.js b/src/nodeClass.js index 9eba995..c36152d 100644 --- a/src/nodeClass.js +++ b/src/nodeClass.js @@ -32,12 +32,11 @@ class nodeClass { switch (msg.topic) { case "clock": toggleUpdate = true; + this.reactor.updateState(msg.timestamp); + send([this.reactor.getEffluent, null, null]); break; case "Fluent": this.reactor.setInfluent = msg; - if (msg.payload.inlet == 0) { - toggleUpdate = true; - } break; case "OTR": this.reactor.setOTR = msg; @@ -58,11 +57,6 @@ class nodeClass { console.log("Unknown topic: " + msg.topic); } - if (toggleUpdate) { - this.reactor.updateState(msg.timestamp); - send([this.reactor.getEffluent, null, null]); - } - if (done) { done(); } @@ -75,6 +69,14 @@ class nodeClass { */ _loadConfig(uiConfig) { this.config = { + general: { + name: uiConfig.name || this.name, + id: this.node.id, + unit: null + }, + functionality: { + softwareType: null // should be set in config manager + }, reactor_type: uiConfig.reactor_type, volume: parseFloat(uiConfig.volume), length: parseFloat(uiConfig.length), @@ -109,7 +111,7 @@ class nodeClass { this.node.send([ null, null, - { topic: 'registerChild', payload: this.node.id , positionVsParent: this.config?.functionality?.positionVsParent || 'atEquipment' }, + { topic: 'registerChild', payload: this.node.id, positionVsParent: this.config?.functionality?.positionVsParent || 'atEquipment' }, ]); }, 100); } diff --git a/src/specificClass.js b/src/specificClass.js index 8fb1448..474ebf7 100644 --- a/src/specificClass.js +++ b/src/specificClass.js @@ -1,13 +1,14 @@ const ASM3 = require('./reaction_modules/asm3_class.js'); -const { create, all } = require('mathjs'); +const { create, all, isArray } = require('mathjs'); const { assertNoNaN } = require('./utils.js'); const { childRegistrationUtils, logger, MeasurementContainer } = require('generalFunctions'); +const EventEmitter = require('events'); -const config = { +const mathConfig = { matrix: 'Array' // use Array as the matrix type }; -const math = create(all, config); +const math = create(all, mathConfig); const S_O_INDEX = 0; const NUM_SPECIES = 13; @@ -20,7 +21,8 @@ class Reactor { */ constructor(config) { // EVOLV stuff - this.logger = new logger(); //TODO: attach config + this.logger = new logger(undefined, undefined, config.general.name); + this.emitter = new EventEmitter(); this.measurements = new MeasurementContainer(); this.childRegistrationUtils = new childRegistrationUtils(this); // Child registration utility @@ -70,6 +72,17 @@ class Reactor { this.OTR = input.payload; } + /** + * Getter for effluent data. + * @returns {object} Effluent data object (msg), defaults to inlet 0. + */ + get getEffluent() { // getter for Effluent, defaults to inlet 0 + if (isArray(this.state.at(-1))) { + return { topic: "Fluent", payload: { inlet: 0, F: math.sum(this.Fs), C: this.state.at(-1) }, timestamp: this.currentTime }; + } + return { topic: "Fluent", payload: { inlet: 0, F: math.sum(this.Fs), C: this.state }, timestamp: this.currentTime }; + } + /** * Calculate the oxygen transfer rate (OTR) based on the dissolved oxygen concentration and temperature. * @param {number} S_O - Dissolved oxygen concentration [g O2 m-3]. @@ -104,11 +117,12 @@ class Reactor { let n_iter = Math.floor(this.speedUpFactor * (newTime-this.currentTime) / (this.timeStep*day2ms)); if (n_iter) { let n = 0; - while (n < n_iter) { - this.tick(this.timeStep); - n += 1; - } + while (n < n_iter) { + this.tick(this.timeStep); + n += 1; + } this.currentTime += n_iter * this.timeStep * day2ms / this.speedUpFactor; + this.emitter.emit("stateChanges", this.getEffluent); } } } @@ -123,14 +137,6 @@ class Reactor_CSTR extends Reactor { this.state = config.initialState; } - /** - * Getter for effluent data. - * @returns {object} Effluent data object (msg), defaults to inlet 0. - */ - get getEffluent() { // getter for Effluent, defaults to inlet 0 - return { topic: "Fluent", payload: { inlet: 0, F: math.sum(this.Fs), C: this.state }, timestamp: this.currentTime }; - } - /** * Tick the reactor state using the forward Euler method. * @param {number} time_step - Time step for the simulation [d]. @@ -191,14 +197,6 @@ class Reactor_PFR extends Reactor { this.D = input.payload; } - /** - * Getter for effluent data. - * @returns {object} Effluent data object (msg), defaults to inlet 0. - */ - get getEffluent() { - return { topic: "Fluent", payload: { inlet: 0, F: math.sum(this.Fs), C: this.state.at(-1) }, timestamp: this.currentTime }; - } - updateState(newTime) { super.updateState(newTime); let Pe_local = this.d_x*math.sum(this.Fs)/(this.D*this.A)