Debouncer subflow

Hi everyone,
I'm developing a subflow that gets the stable version of a message in imput; in my case I've got signals of connection to various IoT devices (implemented by me with ESP32 or similar) and I would like to send a message on telegram when one of this states changes but the state have to remain stable for 30 secs at least.
I've developed this subflow that works fine most of the times but sometimes the algorithm crashes and I recive for tens of times the same message whithout the state change; eg: if the IoT device 1 disconnects at 10:00 I'll recive a message at 10:00:30 with message "IoT device 1 disconnected", then at 11:00 the device reconnects (whit the same structure of above) I'm reciving the message of connetion at 11:00:30 and that's right; the problem is if I'll recive a message of connection another time (or for tens of times) because it's not possible thar a device is connecting without a disconnection!!

code of subflow:

[{"id":"46dafb0003a660d7","type":"subflow","name":"deboucer","info":"","category":"function","in":[{"x":80,"y":180,"wires":[{"id":"5104df4de4cfa693"},{"id":"80e8c2d2e784e6dd"}]}],"out":[{"x":580,"y":120,"wires":[{"id":"e904a681559aad4f","port":0}]}],"env":[{"name":"TIME","type":"num","value":"30","ui":{"icon":"font-awesome/fa-clock-o","label":{"en-US":"Time [sec.]"},"type":"input","opts":{"types":["str","num"]}}}],"meta":{},"color":"#E2D96E","icon":"node-red/rbe.png","status":{"x":580,"y":200,"wires":[{"id":"e904a681559aad4f","port":2}]}},{"id":"df215108c2de7da0","type":"trigger","z":"46dafb0003a660d7","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"30","extend":true,"overrideDelay":true,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":410,"y":240,"wires":[["e904a681559aad4f"]]},{"id":"11d4ee40e027f02c","type":"inject","z":"46dafb0003a660d7","name":"R","props":[{"p":"payload"},{"p":"reset","v":"true","vt":"bool"}],"repeat":"","crontab":"","once":true,"onceDelay":"0.5","topic":"","payloadType":"date","x":190,"y":120,"wires":[["e904a681559aad4f"]]},{"id":"e904a681559aad4f","type":"function","z":"46dafb0003a660d7","name":"deb","func":"let debonceTime = env.get(\"TIME\")*1000;\nlet trig = flow.get(\"trig\");\nlet lastVal = flow.get(\"lastVal\");\nlet valAtTrigger = flow.get(\"valAtTrigTime\")\n\n\nif(msg.reset !== undefined){\n    flow.set(\"lastVal\", undefined);\n    node.status({fill:\"blue\",shape:\"dot\",text:\"TO INIT\"});\n    return [null, {payload:\"\", reset:true}, {payload:{fill:\"blue\",shape:\"dot\",text:\"TO INIT\"}}];\n}\nif(msg.init != undefined){\n    if(lastVal === undefined){\n        node.status({fill:\"blue\",shape:\"dot\",text:\"TO INIT\"});\n        return [null, {payload:\"\", reset:true}, {payload:{fill:\"blue\",shape:\"dot\",text:\"TO INIT\"}}];\n    }else{\n        node.status({fill:\"green\",shape:\"dot\",text:\"WAITING - \" + lastVal.payload});\n        return [null, {payload:\"\", reset:true}, {payload:{fill:\"green\",shape:\"dot\",text:\"WAITING - \" + lastVal.payload}}];\n    }\n}\nif(lastVal === undefined){\n    flow.set(\"lastVal\", msg);\n    flow.set(\"valAtTrigTime\", msg.payload);\n    flow.set(\"trig\", false);\n    msg.initMsg = true;\n    node.status({fill:\"green\",shape:\"dot\",text:\"WAITING - \" + msg.payload});\n    return [msg, null, {payload:{fill:\"green\",shape:\"dot\",text:\"WAITING - \" + msg.payload}}];\n}else{\n    if(trig === false){ //Se NON sono stato triggerto in prec: WAITING\n        flow.set(\"valAtTrigTime\", lastVal.payload);\n        flow.set(\"lastVal\", msg);\n        flow.set(\"trig\", true);\n        let str = \"COUNTING\"+ (msg.payload != lastVal.payload ? \" - \" + msg.payload : \"\");\n        node.status({fill:\"green\",shape:\"ring\", text: str});\n        msg.trig = true;\n        msg.delay = debonceTime;\n        return [null, msg, {payload:{fill:\"green\",shape:\"ring\", text: str}}]; //Trigger the trigger node\n    }else if(trig === true){ //Se sono stato triggerto in prec: COUNTING\n        if(msg.trig === undefined){ //E ti arriva un nuovo messaggio\n            flow.set(\"lastVal\", msg);\n            let str = \"COUNTING\" + (msg.payload != valAtTrigger ? \" - \" + msg.payload: \"\");\n            node.status({fill:\"green\",shape:\"ring\",text:str});\n            msg.trig = true;\n            msg.delay = debonceTime;\n            return [null, msg, {payload:{fill:\"green\",shape:\"ring\",text:str}}]; //Azzera il timer\n        }else if(msg.trig == true){//E ti arriva il messaggio dal trigger: TC\n            if(lastVal.payload != valAtTrigger){\n                node.status({fill:\"green\",shape:\"dot\",text:\"WAITING - \" + lastVal.payload});\n                flow.set(\"trig\", false);\n                return [lastVal, {reset: true}, {payload:{fill:\"green\",shape:\"dot\",text:\"WAITING - \" + lastVal.payload}}];\n            }else{\n                node.status({fill:\"green\",shape:\"dot\",text:\"WAITING - \" + valAtTrigger});\n                flow.set(\"trig\", false);\n                return [null, {reset: true}, {payload:{fill:\"green\",shape:\"dot\",text:\"WAITING - \" + valAtTrigger}}];\n            }\n        }\n    }\n}","outputs":3,"noerr":0,"initialize":"","finalize":"","libs":[],"x":410,"y":160,"wires":[[],["df215108c2de7da0"],[]]},{"id":"5104df4de4cfa693","type":"rbe","z":"46dafb0003a660d7","name":"","func":"rbe","gap":"","start":"","inout":"out","septopics":false,"property":"payload","topi":"topic","x":190,"y":160,"wires":[["e904a681559aad4f"]]},{"id":"80e8c2d2e784e6dd","type":"function","z":"46dafb0003a660d7","name":"bypass","func":"if(msg.init !== undefined || msg.reset !== undefined){\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":200,"y":200,"wires":[["e904a681559aad4f"]]}]

Thanks for your help
Alan

It would be useful if you provided some sample data for us to test it with.

Hi,
You can inject what ever you want, it's similar to node-red filter node, if I've understood the question!

Alan

How do you distinguish which IOT device is being debounced?

Hi,
right, every device has a dedicated flow to menage connection state!!

Alan

So you are going to put a subflow on each flow?
if so this should work

[{"id":"abd43b1efe575b6e","type":"subflow","name":"Debouncer with no device id","info":"","category":"","in":[{"x":60,"y":300,"wires":[{"id":"a8b0fb7ee18b1ae7"}]}],"out":[{"x":700,"y":200,"wires":[{"id":"4d1750fa2fcf2821","port":0}]}],"env":[{"name":"TIME","type":"num","value":"30","ui":{"label":{"en-US":"Time"},"type":"input","opts":{"types":["num"]}}}],"meta":{},"color":"#E2D96E","status":{"x":740,"y":60,"wires":[{"id":"7b80bbdb03dac62e","port":0},{"id":"680d7736bf91e62c","port":0}]}},{"id":"a8b0fb7ee18b1ae7","type":"trigger","z":"abd43b1efe575b6e","name":"","op1":"1","op2":"","op1type":"str","op2type":"payl","duration":"250","extend":false,"overrideDelay":false,"units":"ms","reset":"","bytopic":"all","topic":"topic","outputs":2,"x":180,"y":120,"wires":[["ecd079f143922876"],["e45f96f41e1e0823"]]},{"id":"ecd079f143922876","type":"change","z":"abd43b1efe575b6e","name":"","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":100,"wires":[["4d1750fa2fcf2821","7b80bbdb03dac62e"]]},{"id":"e45f96f41e1e0823","type":"change","z":"abd43b1efe575b6e","name":"","rules":[{"t":"set","p":"delay","pt":"msg","to":"$env(\"TIME\") * 1000","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":140,"wires":[["4d1750fa2fcf2821"]]},{"id":"4d1750fa2fcf2821","type":"trigger","z":"abd43b1efe575b6e","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"30","extend":true,"overrideDelay":true,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":530,"y":140,"wires":[["680d7736bf91e62c"]]},{"id":"7b80bbdb03dac62e","type":"change","z":"abd43b1efe575b6e","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t   \"fill\":\"blue\",\t   \"shape\":\"dot\",\t   \"text\": \"Waiting 1\" \t}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":60,"wires":[[]]},{"id":"680d7736bf91e62c","type":"change","z":"abd43b1efe575b6e","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t   \"fill\":\"blue\",\t   \"shape\":\"dot\",\t   \"text\": \"Waiting 0\" \t}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":720,"y":140,"wires":[[]]},{"id":"13f4f3f6ec8a6b6b","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic1","v":"one","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":110,"y":2480,"wires":[["04629729aa53e1b6"]]},{"id":"04629729aa53e1b6","type":"subflow:abd43b1efe575b6e","z":"65617ffeb779f51c","name":"d","env":[{"name":"TIME","value":"5","type":"num"}],"x":330,"y":2660,"wires":[["23ef1981ba506af7"]]},{"id":"3c842f8813133e41","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic1","v":"two","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":110,"y":2620,"wires":[["04629729aa53e1b6"]]},{"id":"68fd84d410044d24","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"two","payload":"false","payloadType":"bool","x":120,"y":2660,"wires":[["04629729aa53e1b6"]]},{"id":"084ee734bbd38a75","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic1","v":"one","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":110,"y":2520,"wires":[["04629729aa53e1b6"]]},{"id":"23ef1981ba506af7","type":"debug","z":"65617ffeb779f51c","name":"telegram","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":640,"y":2520,"wires":[]}]

No function nodes where employed to do this.

[edit]
If you gave each IOT device a property to identify it, then you could use one flow/subflow to do all devices
e.g.

[{"id":"46dafb0003a660d7","type":"subflow","name":"deboucer with device topic","info":"","category":"","in":[{"x":60,"y":280,"wires":[{"id":"a75434f7efe4421b"}]}],"out":[{"x":940,"y":120,"wires":[{"id":"bc18c5cfc9f784f3","port":0}]}],"env":[{"name":"TIME","type":"num","value":"30","ui":{"icon":"font-awesome/fa-clock-o","label":{"en-US":"Time [sec.]"},"type":"input","opts":{"types":["num"]}}},{"name":"device","type":"str","value":"topic","ui":{"label":{"en-US":"Device Property"},"type":"input","opts":{"types":["str"]}}}],"meta":{},"color":"#E2D96E","icon":"node-red/rbe.png","status":{"x":780,"y":40,"wires":[{"id":"7b1c74085c4ec673","port":0}]}},{"id":"4e57370fe77077c2","type":"rbe","z":"46dafb0003a660d7","name":"","func":"rbe","gap":"","start":"","inout":"out","septopics":true,"property":"payload","topi":"device_topic","x":170,"y":180,"wires":[["d871221863d63e67"]]},{"id":"626d74dc96a5586e","type":"trigger","z":"46dafb0003a660d7","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"30","extend":true,"overrideDelay":true,"units":"s","reset":"","bytopic":"topic","topic":"device_topic","outputs":1,"x":510,"y":120,"wires":[["bc18c5cfc9f784f3"]]},{"id":"84d0fcd69a374950","type":"change","z":"46dafb0003a660d7","name":"","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"},{"t":"set","p":"waiting[msg.device_topic]","pt":"flow","to":"device_topic","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":340,"y":80,"wires":[["626d74dc96a5586e","7b1c74085c4ec673"]]},{"id":"d871221863d63e67","type":"trigger","z":"46dafb0003a660d7","name":"","op1":"1","op2":"","op1type":"str","op2type":"payl","duration":"250","extend":false,"overrideDelay":false,"units":"ms","reset":"","bytopic":"topic","topic":"device_topic","outputs":2,"x":160,"y":100,"wires":[["84d0fcd69a374950"],["51abdd2a4202d0df"]]},{"id":"51abdd2a4202d0df","type":"change","z":"46dafb0003a660d7","name":"","rules":[{"t":"set","p":"delay","pt":"msg","to":"$env(\"TIME\") * 1000","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":340,"y":120,"wires":[["626d74dc96a5586e"]]},{"id":"7b1c74085c4ec673","type":"change","z":"46dafb0003a660d7","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t   \"fill\":\"blue\",\t   \"shape\":\"dot\",\t   \"text\": \"Waiting \" & $join($flowContext(\"waiting\").*, \", \")\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":580,"y":40,"wires":[[]]},{"id":"bc18c5cfc9f784f3","type":"change","z":"46dafb0003a660d7","name":"","rules":[{"t":"delete","p":"waiting[msg.device_topic]","pt":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":750,"y":120,"wires":[["7b1c74085c4ec673"]]},{"id":"14e62201a27610c5","type":"switch","z":"46dafb0003a660d7","name":"","property":"device_topic","propertyType":"msg","rules":[{"t":"nnull"}],"checkall":"true","repair":false,"outputs":1,"x":170,"y":220,"wires":[["4e57370fe77077c2"]]},{"id":"a75434f7efe4421b","type":"change","z":"46dafb0003a660d7","name":"","rules":[{"t":"set","p":"device_topic","pt":"msg","to":"${device}","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":200,"y":280,"wires":[["14e62201a27610c5"]]},{"id":"13f4f3f6ec8a6b6b","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic1","v":"one","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":110,"y":2480,"wires":[["90d96e6793d607bb"]]},{"id":"90d96e6793d607bb","type":"subflow:46dafb0003a660d7","z":"65617ffeb779f51c","name":"","env":[{"name":"TIME","value":"5","type":"num"},{"name":"device","value":"topic1","type":"str"}],"x":440,"y":2520,"wires":[["23ef1981ba506af7"]]},{"id":"3c842f8813133e41","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic1","v":"two","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":110,"y":2620,"wires":[["90d96e6793d607bb"]]},{"id":"68fd84d410044d24","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic1","v":"two","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":110,"y":2660,"wires":[["90d96e6793d607bb"]]},{"id":"084ee734bbd38a75","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic1","v":"one","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":110,"y":2520,"wires":[["90d96e6793d607bb"]]},{"id":"23ef1981ba506af7","type":"debug","z":"65617ffeb779f51c","name":"telegram","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":640,"y":2520,"wires":[]}]

In this example the device id property is set to topic1 in the sublow config.

Hi, thanks for you help,
my goal is to avoid to send another message if the state is not changed in the whole time range from the first message to the last, therefore if I send:

[time = 5 sec] //node time set to 5 secs
true then
false after 2 secs then
true after 1 sec

the subflow does not send any message because this is a glitch and isn't a state transition, instead if I send:

[time = 5 sec] //node time set to 5 secs
true then
false after 1 secs then
true after 1 sec
false after 1 sec

in this case the transition it true -> false in 5 secs and the node has to return false

I hope that's clear what is the goal of this node

Alan

Then store the output and add a switch to make sure it has changed before outputting
e.g.

[{"id":"abd43b1efe575b6e","type":"subflow","name":"Debouncer with no device id","info":"","category":"","in":[{"x":60,"y":300,"wires":[{"id":"d790773867bca66f"}]}],"out":[{"x":700,"y":200,"wires":[{"id":"680d7736bf91e62c","port":0}]}],"env":[{"name":"TIME","type":"num","value":"30","ui":{"label":{"en-US":"Time"},"type":"input","opts":{"types":["num"]}}}],"meta":{},"color":"#E2D96E","status":{"x":740,"y":60,"wires":[{"id":"7b80bbdb03dac62e","port":0},{"id":"28f331b5f49e2e7a","port":0}]}},{"id":"e45f96f41e1e0823","type":"change","z":"abd43b1efe575b6e","name":"","rules":[{"t":"set","p":"delay","pt":"msg","to":"$env(\"TIME\") * 1000","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":140,"wires":[["4d1750fa2fcf2821"]]},{"id":"4d1750fa2fcf2821","type":"trigger","z":"abd43b1efe575b6e","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"30","extend":true,"overrideDelay":true,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":530,"y":140,"wires":[["e564c8966089e3f0"]]},{"id":"7b80bbdb03dac62e","type":"change","z":"abd43b1efe575b6e","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t   \"fill\":\"blue\",\t   \"shape\":\"dot\",\t   \"text\": \"Waiting 1\" \t}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":60,"wires":[[]]},{"id":"680d7736bf91e62c","type":"change","z":"abd43b1efe575b6e","name":"","rules":[{"t":"set","p":"state","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":830,"y":160,"wires":[["28f331b5f49e2e7a"]]},{"id":"d790773867bca66f","type":"rbe","z":"abd43b1efe575b6e","name":"","func":"rbe","gap":"","start":"","inout":"out","septopics":true,"property":"payload","topi":"topic","x":110,"y":240,"wires":[["e45f96f41e1e0823","7b80bbdb03dac62e"]]},{"id":"e564c8966089e3f0","type":"switch","z":"abd43b1efe575b6e","name":"","property":"state","propertyType":"flow","rules":[{"t":"eq","v":"payload","vt":"msg"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":670,"y":140,"wires":[["28f331b5f49e2e7a"],["680d7736bf91e62c"]]},{"id":"28f331b5f49e2e7a","type":"change","z":"abd43b1efe575b6e","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t   \"fill\":\"blue\",\t   \"shape\":\"dot\",\t   \"text\": \"Waiting 0\" \t}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":840,"y":120,"wires":[[]]},{"id":"13f4f3f6ec8a6b6b","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic1","v":"one","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":110,"y":2480,"wires":[["04629729aa53e1b6"]]},{"id":"04629729aa53e1b6","type":"subflow:abd43b1efe575b6e","z":"65617ffeb779f51c","name":"d","env":[{"name":"TIME","value":"5","type":"num"}],"x":330,"y":2660,"wires":[["23ef1981ba506af7"]]},{"id":"3c842f8813133e41","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic1","v":"two","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":110,"y":2620,"wires":[["04629729aa53e1b6"]]},{"id":"68fd84d410044d24","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic1","v":"two","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":110,"y":2660,"wires":[["04629729aa53e1b6"]]},{"id":"084ee734bbd38a75","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic1","v":"one","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":110,"y":2520,"wires":[["04629729aa53e1b6"]]},{"id":"23ef1981ba506af7","type":"debug","z":"65617ffeb779f51c","name":"telegram","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":640,"y":2520,"wires":[]}]

Deselect extend delay in trigger 2 if you want the delay from the first input msg.

e.g.

[{"id":"abd43b1efe575b6e","type":"subflow","name":"Debouncer with no device id","info":"","category":"","in":[{"x":60,"y":300,"wires":[{"id":"d790773867bca66f"}]}],"out":[{"x":700,"y":200,"wires":[{"id":"680d7736bf91e62c","port":0}]}],"env":[{"name":"TIME","type":"num","value":"30","ui":{"label":{"en-US":"Time"},"type":"input","opts":{"types":["num"]}}}],"meta":{},"color":"#E2D96E","status":{"x":740,"y":60,"wires":[{"id":"7b80bbdb03dac62e","port":0},{"id":"28f331b5f49e2e7a","port":0}]}},{"id":"e45f96f41e1e0823","type":"change","z":"abd43b1efe575b6e","name":"","rules":[{"t":"set","p":"delay","pt":"msg","to":"$env(\"TIME\") * 1000","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":140,"wires":[["4d1750fa2fcf2821"]]},{"id":"4d1750fa2fcf2821","type":"trigger","z":"abd43b1efe575b6e","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"30","extend":false,"overrideDelay":true,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":530,"y":140,"wires":[["e564c8966089e3f0"]]},{"id":"7b80bbdb03dac62e","type":"change","z":"abd43b1efe575b6e","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t   \"fill\":\"blue\",\t   \"shape\":\"dot\",\t   \"text\": \"Waiting 1\" \t}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":60,"wires":[[]]},{"id":"680d7736bf91e62c","type":"change","z":"abd43b1efe575b6e","name":"","rules":[{"t":"set","p":"state","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":830,"y":160,"wires":[["28f331b5f49e2e7a"]]},{"id":"d790773867bca66f","type":"rbe","z":"abd43b1efe575b6e","name":"","func":"rbe","gap":"","start":"","inout":"out","septopics":true,"property":"payload","topi":"topic","x":110,"y":240,"wires":[["e45f96f41e1e0823","7b80bbdb03dac62e"]]},{"id":"e564c8966089e3f0","type":"switch","z":"abd43b1efe575b6e","name":"","property":"state","propertyType":"flow","rules":[{"t":"eq","v":"payload","vt":"msg"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":670,"y":140,"wires":[["28f331b5f49e2e7a"],["680d7736bf91e62c"]]},{"id":"28f331b5f49e2e7a","type":"change","z":"abd43b1efe575b6e","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t   \"fill\":\"blue\",\t   \"shape\":\"dot\",\t   \"text\": \"Waiting 0\" \t}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":840,"y":120,"wires":[[]]},{"id":"13f4f3f6ec8a6b6b","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic1","v":"one","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":110,"y":2480,"wires":[["04629729aa53e1b6"]]},{"id":"04629729aa53e1b6","type":"subflow:abd43b1efe575b6e","z":"65617ffeb779f51c","name":"d","env":[{"name":"TIME","value":"5","type":"num"}],"x":330,"y":2660,"wires":[["23ef1981ba506af7"]]},{"id":"3c842f8813133e41","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic1","v":"two","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":110,"y":2620,"wires":[["04629729aa53e1b6"]]},{"id":"68fd84d410044d24","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic1","v":"two","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":110,"y":2660,"wires":[["04629729aa53e1b6"]]},{"id":"084ee734bbd38a75","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic1","v":"one","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":110,"y":2520,"wires":[["04629729aa53e1b6"]]},{"id":"23ef1981ba506af7","type":"debug","z":"65617ffeb779f51c","name":"telegram","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":640,"y":2520,"wires":[]}]

[edited both flows, first will extend delay, second will not]

[edit] Just for completeness here is the multi id property version, that will handle multiple devices with a device id property.

[{"id":"46dafb0003a660d7","type":"subflow","name":"deboucer with device topic","info":"","category":"","in":[{"x":60,"y":280,"wires":[{"id":"a75434f7efe4421b"}]}],"out":[{"x":1260,"y":140,"wires":[{"id":"93823310d0ff6309","port":0}]}],"env":[{"name":"TIME","type":"num","value":"30","ui":{"icon":"font-awesome/fa-clock-o","label":{"en-US":"Time [sec.]"},"type":"input","opts":{"types":["num"]}}},{"name":"device","type":"str","value":"topic","ui":{"label":{"en-US":"Device Property"},"type":"input","opts":{"types":["str"]}}}],"meta":{},"color":"#E2D96E","icon":"node-red/rbe.png","status":{"x":620,"y":40,"wires":[{"id":"7b1c74085c4ec673","port":0}]}},{"id":"4e57370fe77077c2","type":"rbe","z":"46dafb0003a660d7","name":"","func":"rbe","gap":"","start":"","inout":"out","septopics":true,"property":"payload","topi":"device_topic","x":170,"y":180,"wires":[["84d0fcd69a374950"]]},{"id":"626d74dc96a5586e","type":"trigger","z":"46dafb0003a660d7","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"30","extend":true,"overrideDelay":true,"units":"s","reset":"","bytopic":"topic","topic":"device_topic","outputs":1,"x":450,"y":120,"wires":[["70023439ab0fa9cf"]]},{"id":"84d0fcd69a374950","type":"change","z":"46dafb0003a660d7","name":"","rules":[{"t":"set","p":"waiting[msg.device_topic]","pt":"flow","to":"device_topic","tot":"msg"},{"t":"set","p":"delay","pt":"msg","to":"$env(\"TIME\") * 1000","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":280,"y":100,"wires":[["7b1c74085c4ec673","626d74dc96a5586e"]]},{"id":"7b1c74085c4ec673","type":"change","z":"46dafb0003a660d7","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t   \"fill\":\"blue\",\t   \"shape\":\"dot\",\t   \"text\": \"Waiting \" & $join($flowContext(\"waiting\").*, \", \")\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":480,"y":40,"wires":[[]]},{"id":"bc18c5cfc9f784f3","type":"change","z":"46dafb0003a660d7","name":"","rules":[{"t":"set","p":"device_state[msg.device_topic]","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":840,"y":140,"wires":[["764516c62818c577","93823310d0ff6309"]]},{"id":"14e62201a27610c5","type":"switch","z":"46dafb0003a660d7","name":"","property":"device_topic","propertyType":"msg","rules":[{"t":"nnull"}],"checkall":"true","repair":false,"outputs":1,"x":170,"y":220,"wires":[["4e57370fe77077c2"]]},{"id":"a75434f7efe4421b","type":"change","z":"46dafb0003a660d7","name":"","rules":[{"t":"set","p":"device_topic","pt":"msg","to":"${device}","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":200,"y":280,"wires":[["14e62201a27610c5"]]},{"id":"70023439ab0fa9cf","type":"switch","z":"46dafb0003a660d7","name":"","property":"device_state[msg.device_topic]","propertyType":"flow","rules":[{"t":"eq","v":"payload","vt":"msg"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":610,"y":120,"wires":[["764516c62818c577"],["bc18c5cfc9f784f3"]]},{"id":"764516c62818c577","type":"change","z":"46dafb0003a660d7","name":"","rules":[{"t":"delete","p":"waiting[msg.device_topic]","pt":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":890,"y":80,"wires":[["7b1c74085c4ec673"]]},{"id":"93823310d0ff6309","type":"change","z":"46dafb0003a660d7","name":"","rules":[{"t":"delete","p":"delay","pt":"msg"},{"t":"delete","p":"device_topic","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1120,"y":140,"wires":[[]]},{"id":"13f4f3f6ec8a6b6b","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic1","v":"one","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":110,"y":2480,"wires":[["90d96e6793d607bb"]]},{"id":"90d96e6793d607bb","type":"subflow:46dafb0003a660d7","z":"65617ffeb779f51c","name":"","env":[{"name":"TIME","value":"5","type":"num"},{"name":"device","value":"topic1","type":"str"}],"x":440,"y":2520,"wires":[["23ef1981ba506af7"]]},{"id":"3c842f8813133e41","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic1","v":"two","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":110,"y":2620,"wires":[["90d96e6793d607bb"]]},{"id":"68fd84d410044d24","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic1","v":"two","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":110,"y":2660,"wires":[["90d96e6793d607bb"]]},{"id":"084ee734bbd38a75","type":"inject","z":"65617ffeb779f51c","name":"","props":[{"p":"payload"},{"p":"topic1","v":"one","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":110,"y":2520,"wires":[["90d96e6793d607bb"]]},{"id":"23ef1981ba506af7","type":"debug","z":"65617ffeb779f51c","name":"telegram","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":640,"y":2520,"wires":[]}]

Hi, excuse me (I'm not thinking about this flows can help to understand the behavior of my node)

[{"id":"46dafb0003a660d7","type":"subflow","name":"deboucer","info":"","category":"function","in":[{"x":80,"y":180,"wires":[{"id":"5104df4de4cfa693"},{"id":"80e8c2d2e784e6dd"}]}],"out":[{"x":580,"y":120,"wires":[{"id":"e904a681559aad4f","port":0}]}],"env":[{"name":"TIME","type":"num","value":"30","ui":{"icon":"font-awesome/fa-clock-o","label":{"en-US":"Time [sec.]"},"type":"input","opts":{"types":["str","num"]}}}],"meta":{},"color":"#E2D96E","icon":"node-red/rbe.png","status":{"x":580,"y":200,"wires":[{"id":"e904a681559aad4f","port":2}]}},{"id":"df215108c2de7da0","type":"trigger","z":"46dafb0003a660d7","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"30","extend":true,"overrideDelay":true,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":410,"y":240,"wires":[["e904a681559aad4f"]]},{"id":"11d4ee40e027f02c","type":"inject","z":"46dafb0003a660d7","name":"R","props":[{"p":"payload"},{"p":"reset","v":"true","vt":"bool"}],"repeat":"","crontab":"","once":true,"onceDelay":"0.5","topic":"","payloadType":"date","x":190,"y":120,"wires":[["e904a681559aad4f"]]},{"id":"e904a681559aad4f","type":"function","z":"46dafb0003a660d7","name":"deb","func":"// @ts-ignore\nlet debonceTime = env.get(\"TIME\")*1000;\nlet trig = flow.get(\"trig\");\nlet lastVal = flow.get(\"lastVal\");\nlet valAtTrigger = flow.get(\"valAtTrigTime\")\n\n\nif(msg.reset !== undefined){\n    flow.set(\"lastVal\", undefined);\n    node.status({fill:\"blue\",shape:\"dot\",text:\"TO INIT\"});\n    return [null, {payload:\"\", reset:true}, {payload:{fill:\"blue\",shape:\"dot\",text:\"TO INIT\"}}];\n}\nif(msg.init != undefined){\n    if(lastVal === undefined){\n        node.status({fill:\"blue\",shape:\"dot\",text:\"TO INIT\"});\n        return [null, {payload:\"\", reset:true}, {payload:{fill:\"blue\",shape:\"dot\",text:\"TO INIT\"}}];\n    }else{\n        node.status({fill:\"green\",shape:\"dot\",text:\"WAITING - \" + lastVal.payload});\n        return [null, {payload:\"\", reset:true}, {payload:{fill:\"green\",shape:\"dot\",text:\"WAITING - \" + lastVal.payload}}];\n    }\n}\nif(lastVal === undefined){\n    flow.set(\"lastVal\", msg);\n    flow.set(\"valAtTrigTime\", msg.payload);\n    flow.set(\"trig\", false);\n    msg.initMsg = true;\n    node.status({fill:\"green\",shape:\"dot\",text:\"WAITING - \" + msg.payload});\n    return [msg, null, {payload:{fill:\"green\",shape:\"dot\",text:\"WAITING - \" + msg.payload}}];\n}else{\n    if(trig === false){ //Se NON sono stato triggerto in prec: WAITING\n        flow.set(\"valAtTrigTime\", lastVal.payload);\n        flow.set(\"lastVal\", msg);\n        flow.set(\"trig\", true);\n        let str = \"COUNTING\"+ (msg.payload != lastVal.payload ? \" - \" + msg.payload : \"\");\n        node.status({fill:\"green\",shape:\"ring\", text: str});\n        msg.trig = true;\n        msg.delay = debonceTime;\n        return [null, msg, {payload:{fill:\"green\",shape:\"ring\", text: str}}]; //Trigger the trigger node\n    }else if(trig === true){ //Se sono stato triggerto in prec: COUNTING\n        if(msg.trig === undefined){ //E ti arriva un nuovo messaggio\n            flow.set(\"lastVal\", msg);\n            let str = \"COUNTING\" + (msg.payload != valAtTrigger ? \" - \" + msg.payload: \"\");\n            node.status({fill:\"green\",shape:\"ring\",text:str});\n            msg.trig = true;\n            msg.delay = debonceTime;\n            return [null, msg, {payload:{fill:\"green\",shape:\"ring\",text:str}}]; //Azzera il timer\n        }else if(msg.trig == true){//E ti arriva il messaggio dal trigger: TC\n            if(lastVal.payload != valAtTrigger){\n                node.status({fill:\"green\",shape:\"dot\",text:\"WAITING - \" + lastVal.payload});\n                flow.set(\"trig\", false);\n                return [lastVal, {reset: true}, {payload:{fill:\"green\",shape:\"dot\",text:\"WAITING - \" + lastVal.payload}}];\n            }else{\n                node.status({fill:\"green\",shape:\"dot\",text:\"WAITING - \" + valAtTrigger});\n                flow.set(\"trig\", false);\n                return [null, {reset: true}, {payload:{fill:\"green\",shape:\"dot\",text:\"WAITING - \" + valAtTrigger}}];\n            }\n        }\n    }\n}","outputs":3,"noerr":0,"initialize":"","finalize":"","libs":[],"x":410,"y":160,"wires":[[],["df215108c2de7da0"],[]]},{"id":"5104df4de4cfa693","type":"rbe","z":"46dafb0003a660d7","name":"","func":"rbe","gap":"","start":"","inout":"out","septopics":false,"property":"payload","topi":"topic","x":190,"y":160,"wires":[["e904a681559aad4f"]]},{"id":"80e8c2d2e784e6dd","type":"function","z":"46dafb0003a660d7","name":"bypass","func":"if(msg.init !== undefined || msg.reset !== undefined){\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":200,"y":200,"wires":[["e904a681559aad4f"]]},{"id":"8e07032912c027c7","type":"inject","z":"67ae6566.e0febc","name":"T","props":[{"p":"payload"},{"p":"topic","vt":"str"},{"p":"delay","v":"5000","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":170,"y":4220,"wires":[["cc2f75e155446309"]]},{"id":"4950813f3d09fe52","type":"inject","z":"67ae6566.e0febc","name":"Init","props":[{"p":"init","v":"true","vt":"bool"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":170,"y":4180,"wires":[["cc2f75e155446309"]]},{"id":"5fd2fb951bbe3603","type":"inject","z":"67ae6566.e0febc","name":"F","props":[{"p":"payload"},{"p":"topic","vt":"str"},{"p":"delay","v":"5000","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":170,"y":4260,"wires":[["cc2f75e155446309"]]},{"id":"f90cc59fba456e60","type":"inject","z":"67ae6566.e0febc","name":"STR","props":[{"p":"payload"},{"p":"topic","vt":"str"},{"p":"delay","v":"5000","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"STR","payloadType":"str","x":170,"y":4300,"wires":[["cc2f75e155446309"]]},{"id":"cc2f75e155446309","type":"subflow:46dafb0003a660d7","z":"67ae6566.e0febc","name":"","env":[{"name":"TIME","value":"5","type":"num"}],"x":440,"y":4240,"wires":[["47f4bec1617634a3","68c55de8dc182a51"]]},{"id":"47f4bec1617634a3","type":"debug","z":"67ae6566.e0febc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":610,"y":4260,"wires":[]},{"id":"fadd4aab65a2c1c3","type":"inject","z":"67ae6566.e0febc","name":"Reset","props":[{"p":"reset","v":"true","vt":"bool"},{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"sdaDAD","payloadType":"str","x":170,"y":4140,"wires":[["cc2f75e155446309","75bf9a7bff2c43b5"]]},{"id":"68c55de8dc182a51","type":"debug","z":"67ae6566.e0febc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":590,"y":4220,"wires":[]}]

This is what I use to test this node;

In my version the node's status gets information about what it is going to send, in fact when nothing changes the node's status is a green dot with text "WAITING - <last output payload>" (same as current input and no message expected), so when a different payload comes, node's status changes to ring shape with text "COUNTING - <future val>" (means after counting output will be <future val>) and if a payload whit the first value comes another time before the timeout, then the node's status's text, returns to "COUNTING" (means that the last value was reintroduced into the input or a "glitch" was detected)

Alan

You can easily block "same messages" with this filter node. It there any reason you don't use it?

Yeah.... I'm stupit... thanks, I'll try and then I'll post hear te resoult!!
Alan

[EDIT]: My node is essentially different to the filter node if you think about to simply use a filter node instead (I don't now if is it clear to everybody)

Have you tried such a setup:

  • Filter blocks on same message.
  • Trigger delays message for 30s & resets the delay on new incoming messages.

Hi, I think it's impossible that work fine, and I'm not sure you don't have understood my goal (or I'm not able to explain it)

The goal of this node is to cancel temporary variations of a messages train without repeating any value twice, or, in other words, to send a message when the input change and rest stable for enought time

Message train eg.

on -> //first message (with init prop setted to 'true')
on             
on            
OFF --X //this is a glitch
OFF --X        /\
on             |
on             |
OFF            |     //30 sec (or user defined time)
OFF            |
on --X         |
OFF            |
OFF            |
OFF            |
OFF            \/
OFF--> //then send an unique 'off' message 
on --X         /\
OFF            |
OFF            |
on             |
on             |
on             |
on             |     //30 sec (or user defined time)
on             |
on             |
on             |
on             \/
on --> //then send an unique 'on' message

[edit]
OFF ----------- 
on --X         /\
OFF            |
OFF            |
on             |
on             |
on             |
on             |     //30 sec (or user defined time)
on             |
on             |
OFF            |
OFF            \/
OFF --X //because the state isn't changed, before was 
        //an OFF msg an than there is another OFF message         


I hope that's clear now...

Alan

Yes i understand. Fixed error in last attempt

[{"id":"dab2306917c00924","type":"subflow","name":"Debouncer with no device id (2)","info":"","category":"","in":[{"x":60,"y":120,"wires":[{"id":"d74ed5c627bb991f"}]}],"out":[{"x":820,"y":300,"wires":[{"id":"e067a4a5e21133c0","port":0}]}],"env":[{"name":"TIME","type":"num","value":"30","ui":{"label":{"en-US":"Time"},"type":"input","opts":{"types":["num"]}}}],"meta":{},"color":"#E2D96E","status":{"x":720,"y":80,"wires":[{"id":"b47382eebd389ec6","port":0},{"id":"d44694fac9e58657","port":0},{"id":"67d5f9b06515163b","port":0}]}},{"id":"faefee044e7b09eb","type":"change","z":"dab2306917c00924","name":"","rules":[{"t":"set","p":"delay","pt":"msg","to":"$exists($$.delay) ? $$.delay : $env(\"TIME\") * 1000","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":300,"y":240,"wires":[["b2cdce641879c57b"]]},{"id":"b2cdce641879c57b","type":"trigger","z":"dab2306917c00924","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"30","extend":true,"overrideDelay":true,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":470,"y":240,"wires":[["038202709c606b95"]]},{"id":"b47382eebd389ec6","type":"change","z":"dab2306917c00924","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{    \"fill\": \"green\",    \"shape\": \"ring\",    \"text\": \"COUNTING\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":100,"wires":[[]]},{"id":"e067a4a5e21133c0","type":"change","z":"dab2306917c00924","name":"","rules":[{"t":"set","p":"device_state","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":660,"y":300,"wires":[["67d5f9b06515163b"]]},{"id":"67d5f9b06515163b","type":"change","z":"dab2306917c00924","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{    \"fill\": \"green\",    \"shape\": \"dot\",    \"text\": \"WAITING: \" & $$.payload}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":140,"wires":[[]]},{"id":"0eb8944d7aa716dc","type":"inject","z":"dab2306917c00924","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"fill\":\"blue\",\"shape\":\"dot\",\"text\":\"To Init\"}","payloadType":"json","x":230,"y":60,"wires":[["d44694fac9e58657"]]},{"id":"d44694fac9e58657","type":"change","z":"dab2306917c00924","name":"","rules":[{"t":"delete","p":"device_state","pt":"flow"},{"t":"set","p":"payload","pt":"msg","to":"{\"fill\":\"blue\",\"shape\":\"dot\",\"text\":\"TO INIT\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":60,"wires":[[]]},{"id":"d74ed5c627bb991f","type":"switch","z":"dab2306917c00924","name":"","property":"reset","propertyType":"msg","rules":[{"t":"true"},{"t":"jsonata_exp","v":"$count($flowContext(\"device_state\")) = 0","vt":"jsonata"},{"t":"else"}],"checkall":"false","repair":false,"outputs":3,"x":150,"y":120,"wires":[["d44694fac9e58657"],["e067a4a5e21133c0"],["5523bfb404583406"]]},{"id":"5523bfb404583406","type":"switch","z":"dab2306917c00924","name":"","property":"device_state","propertyType":"flow","rules":[{"t":"neq","v":"payload","vt":"msg"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":130,"y":240,"wires":[["faefee044e7b09eb","b47382eebd389ec6"],["faefee044e7b09eb"]]},{"id":"038202709c606b95","type":"switch","z":"dab2306917c00924","name":"","property":"device_state","propertyType":"flow","rules":[{"t":"eq","v":"payload","vt":"msg"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":610,"y":240,"wires":[["67d5f9b06515163b"],["e067a4a5e21133c0"]]},{"id":"e05b9351775e79ae","type":"inject","z":"65617ffeb779f51c","name":"Reset","props":[{"p":"reset","v":"true","vt":"bool"},{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"sdaDAD","payloadType":"str","x":170,"y":3020,"wires":[["27611f40ff2f67ef"]]},{"id":"27611f40ff2f67ef","type":"subflow:dab2306917c00924","z":"65617ffeb779f51c","name":"","env":[{"name":"TIME","value":"5","type":"num"}],"x":530,"y":3000,"wires":[["68e3cb67d964cfa3"]]},{"id":"fd557683b6d30995","type":"inject","z":"65617ffeb779f51c","name":"T","props":[{"p":"payload"},{"p":"topic","vt":"str"},{"p":"delay","v":"5000","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":170,"y":3100,"wires":[["27611f40ff2f67ef"]]},{"id":"727268ac0372c161","type":"inject","z":"65617ffeb779f51c","name":"F","props":[{"p":"payload"},{"p":"topic","vt":"str"},{"p":"delay","v":"5000","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":170,"y":3140,"wires":[["27611f40ff2f67ef"]]},{"id":"228728b0c42b220d","type":"inject","z":"65617ffeb779f51c","name":"STR","props":[{"p":"payload"},{"p":"topic","vt":"str"},{"p":"delay","v":"5000","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"STR","payloadType":"str","x":170,"y":3180,"wires":[["27611f40ff2f67ef"]]},{"id":"68e3cb67d964cfa3","type":"debug","z":"65617ffeb779f51c","name":"telegram","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":700,"y":2960,"wires":[]}]

Do you think or have you tested?

That's exactly what this small flow does. Try yourself:

Inject either true or false to simulate a signal glitch; you'll get a debug output only if the signal is stable for the defined number of seconds. The second filter node eliminates "true" ... "true" cases.

[
    {
        "id": "720e1c63e8c6ee0c",
        "type": "trigger",
        "z": "bd7d8967e98d1ec1",
        "name": "",
        "op1": "",
        "op2": "",
        "op1type": "nul",
        "op2type": "payl",
        "duration": "5",
        "extend": true,
        "overrideDelay": false,
        "units": "s",
        "reset": "",
        "bytopic": "all",
        "topic": "topic",
        "outputs": 1,
        "x": 580,
        "y": 300,
        "wires": [
            [
                "d794c033e34f0c61"
            ]
        ]
    },
    {
        "id": "d99e23e43595ba43",
        "type": "rbe",
        "z": "bd7d8967e98d1ec1",
        "name": "",
        "func": "rbe",
        "gap": "",
        "start": "",
        "inout": "out",
        "septopics": false,
        "property": "payload",
        "topi": "topic",
        "x": 430,
        "y": 300,
        "wires": [
            [
                "720e1c63e8c6ee0c"
            ]
        ]
    },
    {
        "id": "b25684978ebb7ac5",
        "type": "inject",
        "z": "bd7d8967e98d1ec1",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "v": "",
                "vt": "date"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "true",
        "payloadType": "bool",
        "x": 290,
        "y": 260,
        "wires": [
            [
                "d99e23e43595ba43"
            ]
        ]
    },
    {
        "id": "2068a860289a70d1",
        "type": "inject",
        "z": "bd7d8967e98d1ec1",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "v": "",
                "vt": "date"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "false",
        "payloadType": "bool",
        "x": 290,
        "y": 320,
        "wires": [
            [
                "d99e23e43595ba43"
            ]
        ]
    },
    {
        "id": "561507fd14d1b2b3",
        "type": "debug",
        "z": "bd7d8967e98d1ec1",
        "name": "debug 91",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 880,
        "y": 300,
        "wires": []
    },
    {
        "id": "d794c033e34f0c61",
        "type": "rbe",
        "z": "bd7d8967e98d1ec1",
        "name": "",
        "func": "rbe",
        "gap": "",
        "start": "",
        "inout": "out",
        "septopics": false,
        "property": "payload",
        "topi": "topic",
        "x": 730,
        "y": 300,
        "wires": [
            [
                "561507fd14d1b2b3"
            ]
        ]
    }
]

No need to make it more complicated...

1 Like

But the OP requires status output and a reset, so needs to be more complicated.

[{"id":"abd43b1efe575b6e","type":"subflow","name":"Debouncer with no device id","info":"","category":"","in":[{"x":60,"y":120,"wires":[{"id":"26ab79ce34deb151"}]}],"out":[{"x":960,"y":240,"wires":[{"id":"d1f1a8597caa3e52","port":0}]}],"env":[{"name":"TIME","type":"num","value":"30","ui":{"label":{"en-US":"Time"},"type":"input","opts":{"types":["num"]}}}],"meta":{},"color":"#E2D96E","status":{"x":720,"y":80,"wires":[{"id":"32c1db1585e3057d","port":0},{"id":"8cbcf9f0597fc2ad","port":0},{"id":"9481c6d29529e198","port":0}]}},{"id":"4e2d0570bdc095d0","type":"inject","z":"abd43b1efe575b6e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"fill\":\"blue\",\"shape\":\"dot\",\"text\":\"To Init\"}","payloadType":"json","x":130,"y":40,"wires":[["1d187256c333d32b"]]},{"id":"26ab79ce34deb151","type":"switch","z":"abd43b1efe575b6e","name":"","property":"reset","propertyType":"msg","rules":[{"t":"true"},{"t":"jsonata_exp","v":"$count($flowContext(\"device_state\")) = 0","vt":"jsonata"},{"t":"else"}],"checkall":"false","repair":false,"outputs":3,"x":150,"y":120,"wires":[["1d187256c333d32b"],["433647e5719b9aac"],["6a9cd143883ffe2d"]]},{"id":"433647e5719b9aac","type":"change","z":"abd43b1efe575b6e","name":"","rules":[{"t":"set","p":"initMsg","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":120,"wires":[["6a9cd143883ffe2d"]]},{"id":"30e0e58d5d15585f","type":"trigger","z":"abd43b1efe575b6e","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"5","extend":true,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":360,"y":220,"wires":[["32c1db1585e3057d","2a22bacd20bc8c2a"]]},{"id":"6a9cd143883ffe2d","type":"rbe","z":"abd43b1efe575b6e","name":"","func":"rbe","gap":"","start":"","inout":"out","septopics":false,"property":"payload","topi":"topic","x":110,"y":220,"wires":[["8cbcf9f0597fc2ad","3b07ea95db5c8edb"]]},{"id":"5fc27160bc4a3ef9","type":"rbe","z":"abd43b1efe575b6e","name":"","func":"rbe","gap":"","start":"","inout":"out","septopics":false,"property":"payload","topi":"topic","x":650,"y":240,"wires":[["d1f1a8597caa3e52"]]},{"id":"8cbcf9f0597fc2ad","type":"change","z":"abd43b1efe575b6e","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{    \"fill\": \"green\",    \"shape\": \"ring\",    \"text\": \"COUNTING: \" & $$.payload}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":260,"y":320,"wires":[[]]},{"id":"d1f1a8597caa3e52","type":"change","z":"abd43b1efe575b6e","name":"","rules":[{"t":"set","p":"device_state","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":820,"y":240,"wires":[["32c1db1585e3057d"]]},{"id":"32c1db1585e3057d","type":"change","z":"abd43b1efe575b6e","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{    \"fill\": \"green\",    \"shape\": \"dot\",    \"text\": \"WAITING: \" & $flowContext(\"device_state\")}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":580,"y":320,"wires":[[]]},{"id":"3b07ea95db5c8edb","type":"switch","z":"abd43b1efe575b6e","name":"","property":"initMsg","propertyType":"msg","rules":[{"t":"istype","v":"undefined","vt":"undefined"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":230,"y":240,"wires":[["30e0e58d5d15585f"],["5fc27160bc4a3ef9"]]},{"id":"2a22bacd20bc8c2a","type":"change","z":"abd43b1efe575b6e","name":"","rules":[{"t":"set","p":"trig","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":510,"y":220,"wires":[["5fc27160bc4a3ef9"]]},{"id":"1d187256c333d32b","type":"change","z":"abd43b1efe575b6e","name":"","rules":[{"t":"delete","p":"device_state","pt":"flow"},{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":380,"y":40,"wires":[["9481c6d29529e198"]]},{"id":"9481c6d29529e198","type":"change","z":"abd43b1efe575b6e","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"fill\":\"blue\",\"shape\":\"dot\",\"text\":\"TO INIT\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":40,"wires":[[]]},{"id":"98f51f75b20797eb","type":"inject","z":"65617ffeb779f51c","name":"Reset","props":[{"p":"reset","v":"true","vt":"bool"},{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"sdaDAD","payloadType":"str","x":210,"y":2760,"wires":[["04629729aa53e1b6"]]},{"id":"04629729aa53e1b6","type":"subflow:abd43b1efe575b6e","z":"65617ffeb779f51c","name":"d","env":[{"name":"TIME","value":"5","type":"num"}],"x":490,"y":2740,"wires":[["23ef1981ba506af7"]]},{"id":"d4e5657f4db65f73","type":"inject","z":"65617ffeb779f51c","name":"T","props":[{"p":"payload"},{"p":"topic","vt":"str"},{"p":"delay","v":"5000","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":210,"y":2800,"wires":[["04629729aa53e1b6"]]},{"id":"72589edc68fab3ad","type":"inject","z":"65617ffeb779f51c","name":"F","props":[{"p":"payload"},{"p":"topic","vt":"str"},{"p":"delay","v":"5000","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":210,"y":2840,"wires":[["04629729aa53e1b6"]]},{"id":"33432c8b3627aaf0","type":"inject","z":"65617ffeb779f51c","name":"STR","props":[{"p":"payload"},{"p":"topic","vt":"str"},{"p":"delay","v":"5000","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"STR","payloadType":"str","x":210,"y":2880,"wires":[["04629729aa53e1b6"]]},{"id":"23ef1981ba506af7","type":"debug","z":"65617ffeb779f51c","name":"telegram","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":660,"y":2740,"wires":[]}]

Hi, first of all I was thinking, but now I've tested and (as I thought) NOT work...


I hope the images show clearly the reason!!

Alan

Apologies for being so clear - but you're wrong.
This flow will never output twice the same status.

Your test just generated the first signal, triggered (@ 16:23:20) exactly five seconds after the signal stabilized (@ 16:23:15). If you continue to test, you'll see that you need a status change that is stable (again for 5 seconds) to generate another signal.

The two other debug messages never reached debug 91 - but are coming from the debug nodes you inserted.

Ok, you convinced me, I've got a mistake when I tested your solution: I've not initialized the second filter node, but one time first message reached the output no others equals messages are send... I'll disable the 'extend delay if new message arrives' proprety of trigger node, and I'll enable the second one... but this should work fine...

Now I'll test and I will keep you updated.
Thanks
Alan

What exactly does the reset do?

For me it seems not to work, because if a previously sent state is received it is still omitted.

  1. Send true --> true is output
  2. Send reset
  3. Send true --> no output

output_reset2