Refactor reactor node registration

This commit is contained in:
2025-07-04 10:44:54 +02:00
parent d0db1b416c
commit 25cd728b68
4 changed files with 118 additions and 96 deletions

View File

@@ -1,99 +1,12 @@
const nameOfNode = "advanced-reactor"; // name of the node, should match file name and node type in Node-RED
const nodeClass = require('./src/nodeClass.js'); // node class
module.exports = function(RED) { module.exports = function(RED) {
function reactor(config) { // Register the node type
RED.nodes.registerType(nameOfNode, function(config) {
// Initialize the Node-RED node first
RED.nodes.createNode(this, config); RED.nodes.createNode(this, config);
var node = this; // Then create your custom class and attach it
this.nodeClass = new nodeClass(config, RED, this, nameOfNode);
let name = config.name; });
const { Reactor_CSTR, Reactor_PFR } = require('./dependencies/reactor_class');
let new_reactor;
switch (config.reactor_type) {
case "CSTR":
new_reactor = new Reactor_CSTR(
parseFloat(config.volume),
parseInt(config.n_inlets),
parseFloat(config.kla),
[
parseFloat(config.S_O_init),
parseFloat(config.S_I_init),
parseFloat(config.S_S_init),
parseFloat(config.S_NH_init),
parseFloat(config.S_N2_init),
parseFloat(config.S_NO_init),
parseFloat(config.S_HCO_init),
parseFloat(config.X_I_init),
parseFloat(config.X_S_init),
parseFloat(config.X_H_init),
parseFloat(config.X_STO_init),
parseFloat(config.X_A_init),
parseFloat(config.X_TS_init)
]
);
break;
case "PFR":
new_reactor = new Reactor_PFR(
parseFloat(config.volume),
parseFloat(config.length),
parseInt(config.resolution_L),
parseInt(config.n_inlets),
parseFloat(config.kla),
[
parseFloat(config.S_O_init),
parseFloat(config.S_I_init),
parseFloat(config.S_S_init),
parseFloat(config.S_NH_init),
parseFloat(config.S_N2_init),
parseFloat(config.S_NO_init),
parseFloat(config.S_HCO_init),
parseFloat(config.X_I_init),
parseFloat(config.X_S_init),
parseFloat(config.X_H_init),
parseFloat(config.X_STO_init),
parseFloat(config.X_A_init),
parseFloat(config.X_TS_init)
]
);
break;
default:
console.warn("Unknown reactor type: " + config.reactor_type);
}
const reactor = new_reactor; // protect from reassignment
node.on('input', function(msg, send, done) {
let toggleUpdate = false;
switch (msg.topic) {
case "clock":
toggleUpdate = true;
break;
case "Fluent":
reactor.setInfluent = msg;
if (msg.payload.inlet == 0) {
toggleUpdate = true;
}
break;
case "OTR":
reactor.setOTR = msg;
break;
case "Dispersion":
reactor.setDispersion = msg;
break;
default:
console.log("Unknown topic: " + msg.topic);
}
if (toggleUpdate) {
reactor.updateState(msg.timestamp);
send(reactor.getEffluent);
}
if (done) {
done();
}
});
}
RED.nodes.registerType("advanced-reactor", reactor);
}; };

109
src/nodeClass.js Normal file
View File

@@ -0,0 +1,109 @@
const { Reactor_CSTR, Reactor_PFR } = require('./reactor_class.js');
class nodeClass {
/**
* Create a ReactorNode.
* @param {object} uiConfig - Node-RED node configuration.
* @param {object} RED - Node-RED runtime API.
* @param {object} nodeInstance - The Node-RED node instance.
* @param {string} nameOfNode - The name of the node, used for
*/
constructor(uiConfig, RED, nodeInstance, nameOfNode) {
// Preserve RED reference for HTTP endpoints if needed
this.node = nodeInstance;
this.RED = RED;
this.name = nameOfNode;
let new_reactor;
switch (uiConfig.reactor_type) {
case "CSTR":
new_reactor = new Reactor_CSTR(
parseFloat(uiConfig.volume),
parseInt(uiConfig.n_inlets),
parseFloat(uiConfig.kla),
[
parseFloat(uiConfig.S_O_init),
parseFloat(uiConfig.S_I_init),
parseFloat(uiConfig.S_S_init),
parseFloat(uiConfig.S_NH_init),
parseFloat(uiConfig.S_N2_init),
parseFloat(uiConfig.S_NO_init),
parseFloat(uiConfig.S_HCO_init),
parseFloat(uiConfig.X_I_init),
parseFloat(uiConfig.X_S_init),
parseFloat(uiConfig.X_H_init),
parseFloat(uiConfig.X_STO_init),
parseFloat(uiConfig.X_A_init),
parseFloat(uiConfig.X_TS_init)
]
);
break;
case "PFR":
new_reactor = new Reactor_PFR(
parseFloat(uiConfig.volume),
parseFloat(uiConfig.length),
parseInt(uiConfig.resolution_L),
parseInt(uiConfig.n_inlets),
parseFloat(uiConfig.kla),
[
parseFloat(uiConfig.S_O_init),
parseFloat(uiConfig.S_I_init),
parseFloat(uiConfig.S_S_init),
parseFloat(uiConfig.S_NH_init),
parseFloat(uiConfig.S_N2_init),
parseFloat(uiConfig.S_NO_init),
parseFloat(uiConfig.S_HCO_init),
parseFloat(uiConfig.X_I_init),
parseFloat(uiConfig.X_S_init),
parseFloat(uiConfig.X_H_init),
parseFloat(uiConfig.X_STO_init),
parseFloat(uiConfig.X_A_init),
parseFloat(uiConfig.X_TS_init)
]
);
break;
default:
console.warn("Unknown reactor type: " + uiConfig.reactor_type);
}
const reactor = new_reactor; // protect from reassignment
this.node.on('input', function(msg, send, done) {
let toggleUpdate = false;
switch (msg.topic) {
case "clock":
toggleUpdate = true;
break;
case "Fluent":
reactor.setInfluent = msg;
if (msg.payload.inlet == 0) {
toggleUpdate = true;
}
break;
case "OTR":
reactor.setOTR = msg;
break;
case "Dispersion":
reactor.setDispersion = msg;
break;
default:
console.log("Unknown topic: " + msg.topic);
}
if (toggleUpdate) {
reactor.updateState(msg.timestamp);
send(reactor.getEffluent);
}
if (done) {
done();
}
});
}
}
module.exports = nodeClass;