Simple settimeout function

Two things:

  • just to make sure you are using the second updated version of the function i posted?
  • im pretty sure there is a race condition happening where the closing messages are happening so close together that the timer var is not yet set to false in context when already the other 2 have triggered their own instances of the function as this would explain that only ever the false messages are duplicated

Maybe try adding a delay node in rate limit mode set to something like one message every 100ms before the function node.
Edit:
Do as @dceejay says below

so yes - that lastactivation property prevents the rbe from working (as it is always different). - so - use a change node to move msg.payload.ContactSensorSate to msg.payload (so we just have the useful part - ie the state) - then an rbe node (to deduplicate that) - then @JGKK original flow.

1 Like

Thanks alot! I re-implemented the state calling by not using homebridge node but directly from deconz where its originally implemented (Xiaomi Sensor read by Rasbee modul). That prevents from getting multiple different messages from the beginning. Could´ve thought about that eralier sorry :confused:
Now i´m getting one simple true if its opened and one false if its closed after rbe node and the original flow works fine. The function returns 2x true and 1x false when opened for +3sec and 3x false when closed again +1x false after another 3sec after closing.

[{"id":"a6a49b9f.703138","type":"deconz-input","z":"44c6aba9.4558b4","name":"","server":"b66ed896.a3d74","device":"00:15:8d:00:01:f3:6a:76-01-0006","device_name":"Haustür : ZHAOpenClose","topic":"","state":"open","output":"onchange","outputAtStartup":true,"x":280,"y":580,"wires":[[],["da1ab79c.c6761"]]},{"id":"da1ab79c.c6761","type":"rbe","z":"44c6aba9.4558b4","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":510,"y":580,"wires":[["24da88b9.53bc68"]]},{"id":"24da88b9.53bc68","type":"function","z":"44c6aba9.4558b4","name":"","func":"let timer = context.get(\"timer\") || false;\nswitch(msg.payload.ContactSensorState){\n    case 1:\n        if (!timer) {\n            timer = setTimeout(()=>{\n                context.set(\"timer\", false);\n                node.send({payload:{on:true}});\n            },3000);\n            context.set(\"timer\",timer);\n        }\n        break;\n    case 0:\n        if (timer) {\n            clearTimeout(timer);\n            context.set(\"timer\", false);\n            node.send({payload:{on:false}});\n        }\n        break;\n}\nreturn null;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":700,"y":580,"wires":[["21ecd98e.1d4e16"]]},{"id":"21ecd98e.1d4e16","type":"debug","z":"44c6aba9.4558b4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":890,"y":580,"wires":[]},{"id":"b66ed896.a3d74","type":"deconz-server","name":"Rasbee","ip":"192.168.178.17","port":"80","apikey":"B84F7EA25A","ws_port":"443","secure":false,"polling":"15"}]

Have a play with this:

[{"id":"5c34e9c0.c762","type":"inject","z":"c38d0f4.885dff","name":"Open","props":[{"p":"payload.ContactSensorState","v":"1","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":470,"y":460,"wires":[["efac3fa8.e076d","24da88b9.53bc68"]]},{"id":"c1c9de36.978c98","type":"inject","z":"c38d0f4.885dff","name":"Closed","props":[{"p":"payload.ContactSensorState","v":"0","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":470,"y":580,"wires":[["24da88b9.53bc68","26fa87b2.464718"]]},{"id":"24da88b9.53bc68","type":"function","z":"c38d0f4.885dff","name":"","func":"const last = context.get(\"last\");\nif (last !== msg.payload.ContactSensorState) {\n    context.set(\"last\", msg.payload.ContactSensorState);\n} else {\n    return null;\n}\nlet timer = context.get(\"timer\") || false;\nswitch(msg.payload.ContactSensorState){\n    case 1:\n        if (!timer) {\n            timer = setTimeout(()=>{\n                context.set(\"timer\", false);\n                node.send({payload:{on:true}});\n            },3000);\n            context.set(\"timer\",timer);\n        }\n        break;\n    case 0:\n        if (timer) {\n            clearTimeout(timer);\n            context.set(\"timer\", false);\n            node.send({payload:{on:false}});\n        } else {\n            node.send({payload:{on:false}});\n        }\n        break;\n}\nreturn null;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":800,"y":560,"wires":[["21ecd98e.1d4e16"]]},{"id":"21ecd98e.1d4e16","type":"debug","z":"c38d0f4.885dff","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":950,"y":560,"wires":[]},{"id":"d224ca9c.39cb7","type":"function","z":"c38d0f4.885dff","name":"open x3","func":"for(i=0;i<3;i++){\n    node.send({payload:{ContactSensorState:1}});\n}\nreturn null;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":640,"y":520,"wires":[["24da88b9.53bc68","efac3fa8.e076d"]]},{"id":"c545aee3.6cc78","type":"function","z":"c38d0f4.885dff","name":"close x3","func":"for(i=0;i<3;i++){\n    node.send({payload:{ContactSensorState:0}});\n}\nreturn null;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":640,"y":640,"wires":[["24da88b9.53bc68","26fa87b2.464718"]]},{"id":"efac3fa8.e076d","type":"debug","z":"c38d0f4.885dff","name":"Open","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":790,"y":460,"wires":[]},{"id":"1feff751.2512c9","type":"inject","z":"c38d0f4.885dff","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":480,"y":640,"wires":[["c545aee3.6cc78"]]},{"id":"ebfce448.1ef628","type":"inject","z":"c38d0f4.885dff","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":480,"y":520,"wires":[["d224ca9c.39cb7"]]},{"id":"26fa87b2.464718","type":"debug","z":"c38d0f4.885dff","name":"Closed","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":810,"y":640,"wires":[]}]

I don’t know what your sensor is sending but I can’t get the function node to behave in any way I wouldn’t expect even when throwing multiple things at it at the same time.
I added rbe functionality directly in the function node.

const last = context.get("last");
if (last !== msg.payload.ContactSensorState) {
    context.set("last", msg.payload.ContactSensorState);
} else {
    return null;
}
let timer = context.get("timer") || false;
switch(msg.payload.ContactSensorState){
    case 1:
        if (!timer) {
            timer = setTimeout(()=>{
                context.set("timer", false);
                node.send({payload:{on:true}});
            },3000);
            context.set("timer",timer);
        }
        break;
    case 0:
        if (timer) {
            clearTimeout(timer);
            context.set("timer", false);
            node.send({payload:{on:false}});
        } else {
            node.send({payload:{on:false}});
        }
        break;
}
return null;

2 Likes

The function just works perfectly fine now!
One "true" msg after 3 seconds of opening, one "false" msg after closing, before or after the timeframe.
Don´t know why the rbe didn´t work in the first place but the function is perfection now without any rbe involved!
Thanks a lot again for your ongoing help!!!

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