Super simple round-robin router implemented in a function node

Hello everyone,

The other day I was looking for a simple round-robin node that could forward the received messages to different destinations based on a simple counter. An example usage of this could be (in a smarthome context) a button, which on first press turns on the light, then dims it, then for the third press turns it off. (Then the cycle repeats of course.) This is a 3-state round-robin loop, but you could have one with only 2 states (on-off basically) or as many as you need.

I found node-red-contrib-round-robin, but its source repository seems gone, so I did not feel like using it, and also found node-red-contrib-msg-router, which supports round-robin routing, but seems like a heavy-weight solution, so I also did not feel like using that.

So I just implemented it in a custom function node! Here is the source:

const previous = (typeof context.get('localCounter') === 'undefined' ? -1 : context.get('localCounter'));
const current = (typeof msg._set === 'number' ? msg._set : previous + 1) % node.outputCount;

context.set('localCounter', current)

node.status({
    fill: 'green',
    shape: 'ring',
    text: `${current+1}/${node.outputCount}`
});

const msgs = [];
msgs[current] = msg;

return msgs;

You just basically need to copy this snippet into a function node and set the desired output count for the node and that's it!

Each instance of this function node remembers its local counter via context, and defaults to sending the first message to the first output.

It also supports forcing the output (basically setting the counter by hand) if the received message has a msg._set number property. It is a 0-based number, keep that in mind!

And lastly, it also displays the counter for the last message and the total output number as a node state in the editor.

Hope it helps anyone!

1 Like

Just a note that this can be simplified using the snappily named ' Nullish coalescing operator (??)'

const previous = context.get('localCounter') ?? -1

If you are using MQTT you can also achieve this for free using shared topics.

Hey @Colin thanks for the suggestion, I forgot about that operator! Makes it simpler indeed.

@Steve-Mcl thanks for this link, I didn't know about this MQTT feature! But I also want to keep all my logic within NR itself, and I need this router for non-MQTT related stuff too, so that's why I chose to implement it within a function node.

Glad you found a low-code solution!

In the spirit of providing another (essentially) no-code way to route messages via a counter, I have also used this technique based on a switch node:

image

Of course, it doesn't provide the nice status message, but it's useful when you just need to send a message down a different path, say for a poor-man's load-balancer.

2 Likes