module.exports = function (RED) { function monster(config) { // create node RED.nodes.createNode(this, config); // call this => node so whenver you want to call a node function type node and the function behind it var node = this; try{ // fetch monster object from monster.js const Monster = require("./dependencies/monster/monster_class"); const OutputUtils = require("../generalFunctions/helper/outputUtils"); const mConfig={ general: { name: config.name, id: node.id, unit: config.unit, logging:{ logLevel: config.logLevel, enabled: config.enableLog, }, }, asset: { supplier: config.supplier, subType: config.subType, model: config.model, emptyWeightBucket: config.emptyWeightBucket, }, constraints: { minVolume: config.minVolume, maxWeight: config.maxWeight, samplingtime: config.samplingtime, }, } // make new monster on creation to work with. const m = new Monster(mConfig); // put m on node memory as source node.source = m; //load output utils const output = new OutputUtils(); //internal vars this.interval_id = null; //updating node state function updateNodeStatus() { try{ const bucketVol = m.bucketVol; const maxVolume = m.maxVolume; const state = m.running; const mode = "AI" ; //m.mode; let status; switch (state) { case false: status = { fill: "red", shape: "dot", text: `${mode}: OFF` }; break; case true: status = { fill: "green", shape: "dot", text: `${mode}: ON => ${bucketVol} | ${maxVolume}` }; break; } return status; } catch (error) { node.error("Error in updateNodeStatus: " + error); return { fill: "red", shape: "ring", text: "Status Error" }; } } function tick(){ try{ // load status node const status = updateNodeStatus(); // kick time based function in node m.tick(); //show node status node.status(status); } catch (error) { node.error("Error in tick function: " + error); node.status({ fill: "red", shape: "ring", text: "Tick Error" }); } } // register child on first output this timeout is needed because of node - red stuff setTimeout( () => { /*---execute code on first start----*/ let msgs = []; msgs[2] = { topic : "registerChild" , payload: node.id, positionVsParent: "upstream" }; msgs[3] = { topic : "registerChild" , payload: node.id, positionVsParent: "downstream" }; //send msg this.send(msgs); }, 100 ); //declare refresh interval internal node setTimeout( () => { /*---execute code on first start----*/ this.interval_id = setInterval(function(){ tick() },1000) }, 1000 ); node.on('input', function (msg,send,done) { try{ switch(msg.topic) { case 'registerChild': const childId = msg.payload; const childObj = RED.nodes.getNode(childId); m.childRegistrationUtils.registerChild(childObj.source ,msg.positionVsParent); break; case 'setMode': m.setMode(msg.payload); break; case 'start': m.i_start = true; break; } } catch (error) { node.error("Error in input function: " + error); node.status({ fill: "red", shape: "ring", text: "Input Error" }); } if(msg.topic == "i_flow"){ monster.q = parseFloat(msg.payload); } if(msg.topic == "i_start"){ monster.i_start = true; } if(msg.topic == "model_prediction"){ let var1 = msg.payload.dagvoorheen; let var2 = msg.payload.dagnadien; monster.get_model_prediction(var1, var2); } if(msg.topic == "aquon_monsternametijden"){ monster.monsternametijden = msg.payload; } if(msg.topic == "rain_data"){ monster.rain_data = msg.payload; } //register child classes if(msg.topic == "registerChild"){ let child = msg.payload; monster.registerChild(child); } done(); }); // tidy up any async code here - shutdown connections and so on. node.on('close', function() { clearTimeout(this.interval_id); }); } catch (error) { node.error("Error in monster function: " + error); node.status({ fill: "red", shape: "ring", text: "Monster Error" }); } } RED.nodes.registerType("monster", monster); };