I am monitoring main power status in a remote place (using a GSM internet connection) and want that if the power outage takes more than a certain delay, a messages is issued. The system has a battery backup so messages still will be sent even if mains are down. My flow example should issue a debug message if a change in payload was detected AND within 5 seconds it has not been reverted back. However it does the opposite, if the payload is reverted back within 5 seconds, it issues a debug. Is this a matter of threading? In the example I've changed the MQTT input by INSERTs, and I'm only using 1 of the three topics which finally should be handled by the flow.
[{"id":"9e5bdacf.6dbba","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"672bef53.d7db1","type":"change","z":"9e5bdacf.6dbba","name":"convert value (up/down to 1/0)","rules":[{"t":"change","p":"payload","pt":"msg","from":"up","fromt":"str","to":"1","tot":"num"},{"t":"change","p":"payload","pt":"msg","from":"down","fromt":"str","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":370,"y":120,"wires":[["47f998e0.8fb31"]]},{"id":"901ea457.178658","type":"function","z":"9e5bdacf.6dbba","name":"Detect changed power status","func":"// define the date the power status change was detected\nvar Trigger_time = new Date();\n\n// fill the previous-state value if this node is run the first time\nif (msg.topic == \"fase1\") {\n if (context.previous_1 === null) {context.previous_1=msg.payload; return null;}\n}\nif (msg.topic == \"fase2\") {\n if (context.previous_2 === null) {context.previous_2=msg.payload; return null;}\n}\nif (msg.topic == \"fase3\") {\n if (context.previous_3 === null) {context.previous_3=msg.payload; return null;}\n}\n\n// pass the message through if it was changed\nif (msg.topic == \"fase1\" && msg.payload !== context.previous_1) {\n //msg.previous_state=context.previous_1\n context.previous_1=msg.payload;\n msg.triggertime=Trigger_time;\n msg.triggerphase=1;\n return msg;\n} \nif (msg.topic == \"fase2\" && msg.payload !== context.previous_2) {\n //msg.previous_state=context.previous_2\n context.previous_2=msg.payload;\n msg.triggertime=Trigger_time;\n msg.triggerphase=2;\n return msg;\n} \nif (msg.topic == \"fase3\" && msg.payload !== context.previous_3) {\n //msg.previous_state=context.previous_3\n context.previous_3=msg.payload; \n msg.triggertime=Trigger_time;\n msg.triggerphase=3;\n return msg;\n} \n\n","outputs":1,"noerr":0,"x":660,"y":180,"wires":[["5d5885a2.6b8b64"]],"info":"This function should pass through messages only if the payload has \nchanged compared to the previous message with the same topic.\n\n"},{"id":"5d5885a2.6b8b64","type":"delay","z":"9e5bdacf.6dbba","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":600,"y":240,"wires":[["3eb8e0b0.91ab"]]},{"id":"2ab09f68.4239e8","type":"function","z":"9e5bdacf.6dbba","name":"block if power is up before end of delay","func":"// if msg.status = raw, set the current value of the device and return nothing\nif (msg.msgstatus == \"raw\") {\n if(msg.topic == \"fase1\") {context.current_1 = msg.payload; return null;}\n if(msg.topic == \"fase2\") {context.current_2 = msg.payload; return null;}\n if(msg.topic == \"fase3\") {context.current_3 = msg.payload; return null;}\n}\n\nif(msg.msgstatus == \"delayed\" ) { \n if(msg.topic == \"fase1\" && msg.payload === context.current_1) { // the delayed message and the latest value seems to be the same\n return null; // no need to report\n } \n if(msg.topic == \"fase2\" && msg.payload === context.current_2) { // the delayed message and the latest value seems to be the same\n return null; // no need to report\n } \n if(msg.topic == \"fase3\" && msg.payload === context.current_3) { // the delayed message and the latest value seems to be the same\n return null; // no need to report\n } \n // the current payload and the delayed payload are (still) different so a message should be sent\n return msg;\n}\n\n","outputs":1,"noerr":0,"x":690,"y":360,"wires":[["3daca799.dc8eb8"]]},{"id":"3daca799.dc8eb8","type":"debug","z":"9e5bdacf.6dbba","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1010,"y":360,"wires":[]},{"id":"47f998e0.8fb31","type":"change","z":"9e5bdacf.6dbba","name":"set msgstatus = raw","rules":[{"t":"set","p":"msgstatus","pt":"msg","to":"raw","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":340,"y":180,"wires":[["2ab09f68.4239e8","901ea457.178658"]]},{"id":"3eb8e0b0.91ab","type":"change","z":"9e5bdacf.6dbba","name":"set msgstatus = delayed","rules":[{"t":"set","p":"msgstatus","pt":"msg","to":"delayed","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":650,"y":300,"wires":[["2ab09f68.4239e8"]]},{"id":"878a1a3c.c04828","type":"inject","z":"9e5bdacf.6dbba","name":"up","topic":"fase1","payload":"up","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":100,"wires":[["672bef53.d7db1"]]},{"id":"deb20734.0c1d8","type":"inject","z":"9e5bdacf.6dbba","name":"down","topic":"fase1","payload":"down","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":140,"wires":[["672bef53.d7db1"]]}]
The idea is that the function 'block if power is up before end of delay' immediately after a messages ('fase1') arrives stores an updated value representing the current power status (1=up). Simultaneously the function 'Detect change in power status' gets the same message and feeds it to the first function after 5 seconds. There the current status is compared with the delayed message. If they are the same (nothing has changed the last 5 seconds) nothing should be done (return null). If there is a difference (i.e. a new message has arrived with another payload), a messages is passed through to the debug node. If the message is the same, it can also mean that it has changed back and forth within the delay of 5 seconds.
I can't find out why it does not work....