Been a while.
Im exerpiencing this issue in node red :
My code in the node is :
module.exports = function (RED) {
function rotating_machine(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;
//fetch class
var Machine = require("./dependencies/machine_class");
//make new class on creation to work with.
var machine = new Machine();
//fetch name from node into the machine code
machine.name = config.name;
machine.number = Number(config.number);
machine.supplier = config.supplier;
machine.type = config.machine_type;
machine.position.sync_delay = Number(config.sync_delay);
machine.position.startup = Number(config.startup);
machine.position.shutdown = Number(config.shutdown);
machine.position.warmup = Number(config.warmup);
machine.position.cooldown = Number(config.cooldown);
/*------------ Declare node functions -----------*/
function update_node_state(){
switch ( machine.mode ){
//virtual operator
case 0:
switch ( machine.position.o_state ){
//off
case 0:
node.status({ fill: "red", shape: "dot", text: "VR operator : OFF " });
break;
//on
case 1:
node.status({ fill: "green", shape: "dot", text: "VR operator : " + machine.position.set + "%" });
break;
//default
default:
machine.error.text = "no such state : " + machine.state + " in mode : " + machine.mode ;
machine.error.state = true;
}
//break case 0
break;
//auto ( for now the 2 states give the same output ... open the curve however should we move write output to this part? seems to make more sense)
case 1:
switch ( machine.position.o_state ){
//off
case 0:
node.status({ fill: "red", shape: "dot", text: "Autonomous :" + "OFF " });
break;
//on
case 1:
node.status({ fill: "green", shape: "dot", text: "Autonomous : " + machine.position.set + "%" });
break;
//force a machine to stay on (for example when warmup time locks the machine)
case 2:
node.status({ fill: "blue", shape: "dot", text: "Autonomous forced : " + machine.position.set + "%" });
break;
//default
default:
machine.error.text = "no such state : " + machine.state + " in mode : " + machine.mode ;
machine.error.state = true ;
}
//break case 1
break;
//local operator (does almost the same as the virtual operator with soul difference that we depend on the machine to give us their position in order to calculate anything)
case 2:
switch (machine.position.o_state){
//off
case 0:
node.status({ fill: "red", shape: "dot", text: "Local operator : OFF " });
break;
//on
case 1:
node.status({ fill: "yellow", shape: "dot", text: "Local operator : " + machine.position.set + "%" });
break;
//default
default:
machine.error.text = "no such state : " + machine.state + " in mode : " + machine.mode ;
machine.error.state = true ;
}
//break case 2
break;
//default
default:
machine.error.text = "No such mode : " + machine.mode ;
machine.error.state = true;
}
}
function send_output(){
let msgs = [];
msgs[0] = { topic : ("ctrl_"+ machine.number) , payload: machine.o_flow };
msgs[1] = { topic : "object" , payload : machine };
msgs[2] = {
topic: machine.name,
payload: {
ctrl: machine.i_ctrl,
state: machine.state,
flow: machine.o_flow,
pressure: machine.i_pressure,
power: machine.o_power,
o_ctrl: machine.o_ctrl,
},
measurement: machine.name+machine.number,
}; //output to database
//send outputs
node.send(msgs);
}
//never ending functions
function tick(){
machine.tick();
update_node_state();
send_output();
}
// register machine on first output this timeout is needed because of node - red stuff
setTimeout(
() => {
/*---execute code on first start----*/
let msgs = [];
msgs[0] = { topic : "register_machine" , payload: machine };
//send msg
this.send(msgs);
},
100
);
//declare refresh interval internal node
setTimeout(
() => {
/*---execute code on first start----*/
var f = setInterval(function(){ tick() },1000)
},
100
);
//-------------------------------------------------------------------->>what to do on input
node.on("input", function (msg,send,done) {
/* --------------------- input --------------------- */
if ( msg.topic.match(/pt.*/)){
machine.i_pressure = msg.payload;
}
//set current flow
if ( msg.topic.match(/ft.*/)){
machine.i_flow = msg.payload;
}
//set current power
if ( msg.topic.match(/et.*/)){
machine.i_power = msg.payload;
}
/* --------------------- change mode --------------------- */
if(msg.topic == "mode_change"){
machine.mode = msg.payload;
}
/* --------------------- change state --------------------- */
if ( msg.topic == "state_change"){
switch( msg.payload ){
case 1:
//automatically switches the machine to minimum flow
machine.switch_on();
break;
case 0:
//automatically switches the machine to minimum flow
machine.switch_off();
break;
default:
//no such state
node.error('no such state for machine');
}
}
//input from user
if(msg.topic == "i_ctrl"){
machine.i_ctrl = msg.payload;
}
//input from auto software
if(msg.topic == "hapo_i_ctrl"){
if (msg.payload[machine.number] >= 0 ) {
if(machine.state == 0){
machine.switch_on();
}
machine.i_ctrl = msg.payload[machine.number];
}
else{
if(machine.state != 0){
machine.switch_off();
}
}
}
/*-------------------------------- Node Messaging ------------------------------*/
done();
});
}
RED.nodes.registerType("rotating_machine", rotating_machine);
};
is this a node red bug? The first time I run this when restarting node red the node runs like normal and the visualisation also. As soon as I deploy another change regardless where it looks like it spawns 2 the same nodes which each have their own refresh rates?