Function node - how I can inject one switch at time

Hi,

I try to make cycle button. I wann cycle trough modes with press on button.

Here is function node script, but not working correctly (script cycle trough all modes on button press.
How I can correct loop script to cycle one mode at one press:

var modes = ["switch.ir_bathroom_light_work_template", "switch.ir_bathroom_light_sun_template", "switch.ir_bathroom_light_star_template", "switch.ir_bathroom_light_moon_template", ];
var i = i;

node.warn("1");
for (i = 0; i < modes.length; i++) {
node.warn("2");
  msg.payload = {
  domain: 'switch',
  service: 'turn_on',
  data: { entity_id: modes[i] },
  };
  node.send(msg)
}

Your for loop is doing just what you have told it to do (don't you hate that :joy:)

if you mean that you want to run thru the 'modes' but only when a new msg arrives at the function, you will need to store the index in context and incriment it each time a msg arrives and - presumably - reset it when it gets to the end.

The functionality you’re looking for is called a state machine. As an alternative to the function node, have you thought about using one of the specialised state machine nodes for it, such as node-red-contrib-dsm

I don't know if this is ideal solution but is working:)

In case someone need cycle function with button press - cycle button, here is code:

var modes = ["switch.ir_bathroom_light_work_template", "switch.ir_bathroom_light_sun_template", "switch.ir_bathroom_light_star_template", "switch.ir_bathroom_light_moon_template", ];
var i = context.get('i')||0;

start: while(true) {
node.warn("1");
  msg.payload = {
  domain: 'switch',
  service: 'turn_on',
  data: { entity_id: modes[i] },
  };
  i++;
  context.set('i',i);
  msg.count = i;
  node.send(msg);
  node.warn("2");
if (i == 4)  {
    context.set('i',0);
}
if(i > 4) continue start;
  break;
}

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.