Simple step through outputs on trigger

Hi,
I have what I think should be really simple challenge, but am struggling.

I want to setup a flow where each time the flow is triggered it triggers the next output in a sequence

I can do with a complex if then else in a function node, but it is not very elegant.

The use case is using a single button to trigger different radio channels to be played.
so each time you press, it switches to the next channel in a set list and when it gets to the last it restarts.

I'm sure there must be cone neat way to achieve this.

Any suggestions?

If your list of channels is in an array, you just need to increment a counter (and reset it when it points to a nonexistant array element)

Probably use a flow context variable for the counter.

Thanks, I could lok at that, i'm surprised that there isn't a state machine module that works like this.

Solved it with a function variable followed by a switch node.

if (flow.get("channel") == 6){
    flow.set("channel",4);
}else if (flow.get("channel") == 4){
    flow.set("channel",3);
}else if(flow.get("channel") == 3){
    flow.set("channel",6);
}
else{
    flow.set("channel",6);
}  
return msg;

There are several state machine nodes in the node-red flows library.

I know, but cant get my head around how I would achieve this functionality

Use the button trigger to step you through the states in whatever machine you are using. Personally I would just use a Function node, I think it is easier than using a state machine node.

const channels = [6, 4, 3]
let currentIndex = context.get("currentIndex") || 0
currentIndex = currentIndex + 1
if (currentIndex >= channels.length) {
    currentIndex = 0
}
msg.payload = channels[currentIndex]
node.status( `Channel ${msg.payload}` )
context.set("currentIndex", currentIndex)
return msg;
[{"id":"804aa6bce11220c3","type":"inject","z":"bdd7be38.d3b55","name":"Button simulator","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":180,"y":3280,"wires":[["a1d8ae260177640c"]]},{"id":"a1d8ae260177640c","type":"function","z":"bdd7be38.d3b55","name":"Cycle channels","func":"const channels = [6, 4, 3]\nlet currentIndex = context.get(\"currentIndex\") || 0\ncurrentIndex = currentIndex + 1\nif (currentIndex >= channels.length) {\n    currentIndex = 0\n}\nmsg.payload = channels[currentIndex]\nnode.status( `Channel ${msg.payload}` )\ncontext.set(\"currentIndex\", currentIndex)\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":3280,"wires":[["8b1f2296c8b345b7"]]},{"id":"8b1f2296c8b345b7","type":"debug","z":"bdd7be38.d3b55","name":"debug 106","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":630,"y":3280,"wires":[]}]

What did you need a Switch node for?

1 Like

I think using a state machine would be an overkill since you are just incrementing or decrementing by unity.

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