Require X number of same messages before sending along

I have been unable to find an elegant and concise way of collecting multiple messages with the same value into one. I have a nagging sense that I am missing something obvious :slight_smile:

For example a node that evaluates to either true or false, and then another node that only passes on a "true" message after receiving for example 10 "true" messages in a row. One "false" message will reset the count.

Thanks :slight_smile:

Not sure one standard node would do this, there maybe a contrib node.

You can do ut with 3 standard nodes.
e.g.

[{"id":"f823969bdae166b3","type":"inject","z":"da8a6ef0b3c9a5c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":150,"y":1940,"wires":[["0dde7af39bb21306"]]},{"id":"0dde7af39bb21306","type":"change","z":"da8a6ef0b3c9a5c8","name":"","rules":[{"t":"set","p":"reset","pt":"msg","to":"$$.payload = false ? true","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":1900,"wires":[["badfca9947d35894"]]},{"id":"e1e8d7cc1dc239af","type":"inject","z":"da8a6ef0b3c9a5c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":150,"y":1900,"wires":[["0dde7af39bb21306"]]},{"id":"badfca9947d35894","type":"join","z":"da8a6ef0b3c9a5c8","name":"","mode":"custom","build":"array","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"10","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":510,"y":1900,"wires":[["5052c5d60c998a0a"]]},{"id":"5052c5d60c998a0a","type":"change","z":"da8a6ef0b3c9a5c8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[0]","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":660,"y":1900,"wires":[["0b2c5a93a5c3bbf5"]]},{"id":"0b2c5a93a5c3bbf5","type":"debug","z":"da8a6ef0b3c9a5c8","name":"debug 218","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":570,"y":1800,"wires":[]}]

Strangely I had the same requirement a few days ago and came up with a function node since I couldn't see another way either.
note: everyone in here and my wife all agree I'm not a good coder so take this with great skepticism

let Z = msg.payload;

//if good
if (Z != false) {
    context.set("CountBad",0);
    node.status({ fill: "blue", shape: "dot", text: "good" });
}
//if bad
if (Z == false){
    let W = context.get("CountBad") ?? 0;
    W = W + 1;
    context.set("CountBad", W);
    node.status({ fill: "red", shape: "ring", text: "bad " + W });
    if (W > 10) {
        flow.set("Alert",true);
    }
}

return msg;

I put this in a function node and if the message is not false it sets a counter to zero. If the message is false for ten messages it then sets an alert. Any not false message before it gets to ten resets the counter. Adjust code as needed. This is not the node-red way but sometimes you gotta do what you gotta do.

Thanks guys :slight_smile:

Since I am already making the true/false distinction in a javascript function node, I will just use the counter approach. It seems much simpler :slight_smile:

For future reference, I think the join node can be configured to do what you want. Here, it is set to wait for 3 messages, rather than 10, to simplify testing.

[{"id":"efcf54024f5b1558","type":"inject","z":"c3b4e23e95193f6b","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":110,"y":360,"wires":[["898355a08940da70"]]},{"id":"898355a08940da70","type":"join","z":"c3b4e23e95193f6b","name":"","mode":"custom","build":"array","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"3","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":430,"y":400,"wires":[["4c8f73321c998977"]]},{"id":"b42c3dc9636fa253","type":"inject","z":"c3b4e23e95193f6b","name":"complete ","props":[{"p":"complete","v":"true","vt":"bool"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":120,"y":440,"wires":[["898355a08940da70"]]},{"id":"2b9b9c11733cec31","type":"change","z":"c3b4e23e95193f6b","name":"reset","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":230,"y":400,"wires":[["898355a08940da70"]]},{"id":"4c8f73321c998977","type":"change","z":"c3b4e23e95193f6b","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[0]","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":580,"y":400,"wires":[["c6ae5dd7cfd03d2e"]]},{"id":"886e094a462d70ef","type":"inject","z":"c3b4e23e95193f6b","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":110,"y":400,"wires":[["2b9b9c11733cec31"]]},{"id":"c6ae5dd7cfd03d2e","type":"debug","z":"c3b4e23e95193f6b","name":"output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":730,"y":400,"wires":[]}]

The two change nodes do housekeeping that could be done in other ways, but the join node is key. The inject node with msg.complete has also been added for testing purposes.