diff --git a/advanced-reactor.js b/advanced-reactor.js index e2eca51..ee954cd 100644 --- a/advanced-reactor.js +++ b/advanced-reactor.js @@ -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) { - function reactor(config) { + // Register the node type + RED.nodes.registerType(nameOfNode, function(config) { + // Initialize the Node-RED node first RED.nodes.createNode(this, config); - var node = this; - - 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); + // Then create your custom class and attach it + this.nodeClass = new nodeClass(config, RED, this, nameOfNode); + }); }; diff --git a/dependencies/asm3_class.js b/src/asm3_class.js similarity index 100% rename from dependencies/asm3_class.js rename to src/asm3_class.js diff --git a/src/nodeClass.js b/src/nodeClass.js new file mode 100644 index 0000000..9281a45 --- /dev/null +++ b/src/nodeClass.js @@ -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; \ No newline at end of file diff --git a/dependencies/reactor_class.js b/src/reactor_class.js similarity index 100% rename from dependencies/reactor_class.js rename to src/reactor_class.js