Timing of events and notification if something doesn't happen

#1

Before you read any further: Sorry. This is not entirely thought through on how to describe it.

But I am trying to get my head around how to do this little thing:

Machine comes online. Tick. Got that. Done with PING every x seconds.
NR loads up and becomes active. Tick. Got that. But it may take a while.
Prior to all that the PING is dead, and the other signal from NR is (obviously) dead.

Here's the "problem":
Say I give it 2 minutes to get all sorted and NR up and running. (Way enough time)
If - in the 2 minutes from when the machine initially started to respond to PING - nothing is heard beyond that, a notification/event happens.
But if NR does get itself up, the notification is not done.
So the PING and the other timed reading from NR are getting through.

NR will then continue to notify me at regular intervals.

I am thinking the TRIGGER node, but I am still not exactly sure on how to (a) word it, and (b) make it a flow.

Any offers?

Thanks in advance.
And again sorry I haven't thought it through too much.

Here is a NEARLY GOT IT flow. No UI widgets.

It NEARLY works.

[{"id":"7ebbba69.89153c","type":"inject","z":"9fb43887.43d798","name":"Online","topic":"","payload":"On-line","payloadType":"str","repeat":"5","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":110,"wires":[["a3c9d966.1feed"]]},{"id":"a76ef8cf.bd10b","type":"random","z":"9fb43887.43d798","name":"Temp","low":"1","high":"10","inte":"true","property":"payload","x":330,"y":430,"wires":[["b3a8c499.e0c9b8","94413e96.e3aed","223e59a5.7285ae","25eba889.3b45c8"]]},{"id":"5c06244f.ed94dc","type":"trigger","z":"9fb43887.43d798","op1":"","op2":"Off-line","op1type":"nul","op2type":"str","duration":"8","extend":true,"units":"s","reset":"","bytopic":"all","name":"","x":240,"y":270,"wires":[["2dcbcc96.39b53c"]]},{"id":"a3c9d966.1feed","type":"traffic","z":"9fb43887.43d798","name":"","property_allow":"payload","filter_allow":"go","ignore_case_allow":false,"negate_allow":false,"send_allow":false,"property_stop":"payload","filter_stop":"stop","ignore_case_stop":false,"negate_stop":false,"send_stop":false,"default_start":false,"differ":false,"x":120,"y":320,"wires":[["5c06244f.ed94dc","2dcbcc96.39b53c","9c86ceff.64f18"]]},{"id":"5f54b55d.0f23d4","type":"inject","z":"9fb43887.43d798","name":"","topic":"","payload":"go","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":230,"wires":[["a3c9d966.1feed"]]},{"id":"a5999ef4.be1f8","type":"inject","z":"9fb43887.43d798","name":"","topic":"","payload":"stop","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":190,"wires":[["a3c9d966.1feed"]]},{"id":"223e59a5.7285ae","type":"function","z":"9fb43887.43d798","name":"Status","func":"var x = context.get('x') || 0;\n//node.warn(x);\n\nif (msg.payload == \"Off-line\")\n{\n    //\n    msg  = {payload: '<i class=\"fa fa-bullseye fa-2x nr-dashboard-error\"></i>'};\n    node.status({fill:\"red\",shape:\"dot\",text:\"Off-line\"});\n    context.set('x',0);\n    var msg2 = {payload: \"Off-line\", background:\"brown\" };\n    return [msg,msg2];\n}\nif (x == 0)\n{\n    if (msg.payload == \"On-line\")\n    {\n        msg  = {payload: '<font color = \"yellow\" i class=\"fa fa-bullseye fa-2x\"></i>'};\n        node.status({fill:\"yellow\",shape:\"dot\",text:\"Ping-line\"});\n        //node.warn(\"Ping ok\");\n        var msg2 = {payload: \"On-line\", background:\"yellow\" };\n        context.set('x',1);\n        return [msg,msg2];\n    }\n}\nif (x == 1)\n{\n    if (msg.payload > 0)\n    {\n        msg  = {payload: '<i class=\"fa fa-bullseye fa-2x nr-dashboard-ok\"></i>'};\n        node.status({fill:\"green\",shape:\"dot\",text:\"Temperature\"});\n        //node.warn(\"Temperature packet received\");\n        var msg2 = {payload: \"On-line\", background:\"green\" };\n        context.set('x',1);\n        return [msg,msg2];\n    }\n}\n","outputs":2,"noerr":0,"x":1000,"y":300,"wires":[["8386e3e6.7a8c7","f8b9db62.0e56a"],[]]},{"id":"b3a8c499.e0c9b8","type":"function","z":"9fb43887.43d798","name":"MusicPi temp","func":"//  WORKING!\n//  2018 08 11\nvar count = context.get('count') || 0;\nvar mtopic = msg.topic;\nvar mpayload = msg.payload;\nvar device = 'MusicPi';           ///////    NAME OF COMPUTER HERE!\nvar save_this_message = \"TEMP/\"+device\nvar save_this_message = \"TEMP/\"+device\nif (msg.topic == 'RESET')\n{\n    //node.warn(device + \" RESET message RX\");\n    msg.payload = 'Off-line';\n    count = 1;\n    context.set('count',count);\n    msg.payload = 'N/C';\n    var msg2 = { payload:\"0\"};\n    return [msg, msg2];    \n}\nif (mtopic == save_this_message)\n{\n    //node.warn(device + \" Temperature received\");\n    context.set('message',msg.payload);  //  save the payload as this is the temperature.\n    node.status({fill:\"yellow\",shape:\"dot\",text:\"message received\"});\n}\n\nif (mpayload === 'On-line')\n{\n    msg.topic = device;\n    node.status({fill:\"green\",shape:\"dot\",text:\"On-line\"});\n    //node.warm(\"On-line message received\");\n    context.set('count',0);\n    msg.payload = context.get('message');  //  get stored value back.\n    return [msg, msg];\n}\nelse\nif (mpayload === 'Off-line')\n{\n    //node.warn(device + \" Is Off-line\");\n    msg.topic = device;\n    count = count + 1;\n    context.set('count',count);\n    msg.topic = count;\n\n    if (count === 1)\n    {\n        node.status({fill:\"blue\",shape:\"dot\",text:\"Off-line\"});\n        var msg2 = { payload:\"0\", topic: device};\n    \tmsg.payload = \"0\";\n    \treturn [msg, msg2];\n    }\n    if (count === 2)\n    {\n        node.status({fill:\"red\",shape:\"dot\",text:\"Off-line\"});\n        msg.payload = [];\n        var msg2 = { payload:\"N/C\" };\n        return [msg2, msg];\n    }\n//    else\n//    {\n    \t//msg.payload = null;\n        //return msg;\n//    }\n}\n","outputs":2,"noerr":0,"x":1030,"y":210,"wires":[[],[]]},{"id":"91a61852.eccf48","type":"change","z":"9fb43887.43d798","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"TEMP/MusicPi","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":300,"y":390,"wires":[["a76ef8cf.bd10b"]]},{"id":"8386e3e6.7a8c7","type":"debug","z":"9fb43887.43d798","name":"Status","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":1150,"y":270,"wires":[]},{"id":"51c2fee4.7bedd","type":"debug","z":"9fb43887.43d798","name":"Pings","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":460,"y":280,"wires":[]},{"id":"94413e96.e3aed","type":"debug","z":"9fb43887.43d798","name":"Temp","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":450,"y":480,"wires":[]},{"id":"2dcbcc96.39b53c","type":"function","z":"9fb43887.43d798","name":"Dummy","func":"\nreturn msg;","outputs":1,"noerr":0,"x":340,"y":320,"wires":[["b3a8c499.e0c9b8","51c2fee4.7bedd","223e59a5.7285ae","25eba889.3b45c8"]]},{"id":"25eba889.3b45c8","type":"traffic","z":"9fb43887.43d798","name":"","property_allow":"payload","filter_allow":"On-line","ignore_case_allow":false,"negate_allow":false,"send_allow":false,"property_stop":"payload","filter_stop":"Off-line","ignore_case_stop":false,"negate_stop":false,"send_stop":false,"default_start":false,"differ":false,"x":820,"y":400,"wires":[["cbd9a7c.4599d58"]]},{"id":"cbd9a7c.4599d58","type":"trigger","z":"9fb43887.43d798","op1":"","op2":"Error","op1type":"nul","op2type":"str","duration":"12","extend":true,"units":"s","reset":"","bytopic":"all","name":"Wait for life","x":990,"y":400,"wires":[["3101ee4f.8d83ca"]]},{"id":"9c86ceff.64f18","type":"traffic","z":"9fb43887.43d798","name":"","property_allow":"payload","filter_allow":"go","ignore_case_allow":false,"negate_allow":false,"send_allow":false,"property_stop":"payload","filter_stop":"stop","ignore_case_stop":false,"negate_stop":false,"send_stop":false,"default_start":false,"differ":false,"x":120,"y":390,"wires":[["91a61852.eccf48"]]},{"id":"4d458781.fb6b9","type":"inject","z":"9fb43887.43d798","name":"","topic":"","payload":"go","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":520,"wires":[["9c86ceff.64f18"]]},{"id":"2e530069.a339c8","type":"inject","z":"9fb43887.43d798","name":"","topic":"","payload":"stop","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":480,"wires":[["9c86ceff.64f18"]]},{"id":"3101ee4f.8d83ca","type":"debug","z":"9fb43887.43d798","name":"Death","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":1130,"y":400,"wires":[]},{"id":"bf20c62d.d43e4","type":"comment","z":"9fb43887.43d798","name":"Remote device control","info":"","x":130,"y":150,"wires":[]},{"id":"d07edf33.4f0e7","type":"comment","z":"9fb43887.43d798","name":"Machine failure simulation","info":"","x":150,"y":560,"wires":[]},{"id":"fc71aab3.6f2c58","type":"comment","z":"9fb43887.43d798","name":"Working part","info":"","x":1030,"y":160,"wires":[]},{"id":"b190814c.41559","type":"comment","z":"9fb43887.43d798","name":"To Guages and Charts","info":"","x":1230,"y":210,"wires":[]},{"id":"2e7c574.024f128","type":"comment","z":"9fb43887.43d798","name":"Nearly got it here","info":"","x":880,"y":360,"wires":[]}]

It nearly works.

How to use it:
Press the LOWER GO BUTTON FIRST!
Then press the Go button up the top (remote device control)
You will see the STATUS go from RED, to YELLOW then to LIME.
That is good.

Press the upper STOP button and wait about 10 seconds to allow things to clear.

Then press the lower STOP button (machine failure simulation)
Then press the upper GO button.

Alas nothing happens and this is where I am stuck.

I am wanting the DEATH node to become active if you have pressed the lower STOP button before pressing the upper GO button.

Is that helpful?

0 Likes

#2

Your description is a little hard to follow !!

  1. I assume there is another machine involved on the network somewhere ?? If so is this the machine doing the monitoring or the monitored machine ??
  2. Probably be much easier to understand with a hand drawn sketch showing what is running where and what you are trying to achieve.

Craig

0 Likes

#3

I think I have nutted it out.

Stand by and I shall post the "working flow" once I get it really working.

See this flow:
Left side machine 1. Right side machine 2.

If you turn on BOTH GO buttons you will see the top right Function node "blink" as it gets data clocked into it.

You can then turn them off (STOP) and wait a bit for the tidy up, then turn OFF the bottom button and press the top GO button, and wait about 20 seconds you will get an error message in the DEATH node. Bottom right.

[{"id":"7ebbba69.89153c","type":"inject","z":"9fb43887.43d798","name":"Online","topic":"","payload":"On-line","payloadType":"str","repeat":"5","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":110,"wires":[["a3c9d966.1feed"]]},{"id":"a76ef8cf.bd10b","type":"random","z":"9fb43887.43d798","name":"Temp","low":"1","high":"10","inte":"true","property":"payload","x":330,"y":440,"wires":[["b3a8c499.e0c9b8","94413e96.e3aed","223e59a5.7285ae","77bcb4f2.02b004"]]},{"id":"5c06244f.ed94dc","type":"trigger","z":"9fb43887.43d798","op1":"","op2":"Off-line","op1type":"nul","op2type":"str","duration":"8","extend":true,"units":"s","reset":"","bytopic":"all","name":"","x":240,"y":270,"wires":[["2dcbcc96.39b53c"]]},{"id":"a3c9d966.1feed","type":"traffic","z":"9fb43887.43d798","name":"","property_allow":"payload","filter_allow":"go","ignore_case_allow":false,"negate_allow":false,"send_allow":false,"property_stop":"payload","filter_stop":"stop","ignore_case_stop":false,"negate_stop":false,"send_stop":false,"default_start":false,"differ":false,"x":120,"y":320,"wires":[["5c06244f.ed94dc","2dcbcc96.39b53c","9c86ceff.64f18"]]},{"id":"5f54b55d.0f23d4","type":"inject","z":"9fb43887.43d798","name":"","topic":"","payload":"go","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":230,"wires":[["a3c9d966.1feed"]]},{"id":"a5999ef4.be1f8","type":"inject","z":"9fb43887.43d798","name":"","topic":"","payload":"stop","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":190,"wires":[["a3c9d966.1feed"]]},{"id":"223e59a5.7285ae","type":"function","z":"9fb43887.43d798","name":"Status","func":"var x = context.get('x') || 0;\n//node.warn(x);\n\nif (msg.payload == \"Off-line\")\n{\n    //\n    msg  = {payload: '<i class=\"fa fa-bullseye fa-2x nr-dashboard-error\"></i>'};\n    node.status({fill:\"red\",shape:\"dot\",text:\"Off-line\"});\n    context.set('x',0);\n    var msg2 = {payload: \"Off-line\", background:\"brown\" };\n    return [msg,msg2];\n}\nif (x == 0)\n{\n    if (msg.payload == \"On-line\")\n    {\n        msg  = {payload: '<font color = \"yellow\" i class=\"fa fa-bullseye fa-2x\"></i>'};\n        node.status({fill:\"yellow\",shape:\"dot\",text:\"Ping-line\"});\n        //node.warn(\"Ping ok\");\n        var msg2 = {payload: \"On-line\", background:\"yellow\" };\n        context.set('x',1);\n        return [msg,msg2];\n    }\n}\nif (x == 1)\n{\n    if (msg.payload > 0)\n    {\n        msg  = {payload: '<i class=\"fa fa-bullseye fa-2x nr-dashboard-ok\"></i>'};\n        node.status({fill:\"green\",shape:\"dot\",text:\"Temperature\"});\n        //node.warn(\"Temperature packet received\");\n        var msg2 = {payload: \"On-line\", background:\"green\" };\n        context.set('x',1);\n        return [msg,msg2];\n    }\n}\n","outputs":2,"noerr":0,"x":1000,"y":300,"wires":[["8386e3e6.7a8c7","f8b9db62.0e56a"],[]]},{"id":"b3a8c499.e0c9b8","type":"function","z":"9fb43887.43d798","name":"MusicPi temp","func":"//  WORKING!\n//  2018 08 11\nvar count = context.get('count') || 0;\nvar mtopic = msg.topic;\nvar mpayload = msg.payload;\nvar device = 'MusicPi';           ///////    NAME OF COMPUTER HERE!\nvar save_this_message = \"TEMP/\"+device\nvar save_this_message = \"TEMP/\"+device\nif (msg.topic == 'RESET')\n{\n    //node.warn(device + \" RESET message RX\");\n    msg.payload = 'Off-line';\n    count = 1;\n    context.set('count',count);\n    msg.payload = 'N/C';\n    var msg2 = { payload:\"0\"};\n    return [msg, msg2];    \n}\nif (mtopic == save_this_message)\n{\n    //node.warn(device + \" Temperature received\");\n    context.set('message',msg.payload);  //  save the payload as this is the temperature.\n    node.status({fill:\"yellow\",shape:\"dot\",text:\"message received\"});\n}\n\nif (mpayload === 'On-line')\n{\n    msg.topic = device;\n    node.status({fill:\"green\",shape:\"dot\",text:\"On-line\"});\n    //node.warm(\"On-line message received\");\n    context.set('count',0);\n    msg.payload = context.get('message');  //  get stored value back.\n    return [msg, msg];\n}\nelse\nif (mpayload === 'Off-line')\n{\n    //node.warn(device + \" Is Off-line\");\n    msg.topic = device;\n    count = count + 1;\n    context.set('count',count);\n    msg.topic = count;\n\n    if (count === 1)\n    {\n        node.status({fill:\"blue\",shape:\"dot\",text:\"Off-line\"});\n        var msg2 = { payload:\"0\", topic: device};\n    \tmsg.payload = \"0\";\n    \treturn [msg, msg2];\n    }\n    if (count === 2)\n    {\n        node.status({fill:\"red\",shape:\"dot\",text:\"Off-line\"});\n        msg.payload = [];\n        var msg2 = { payload:\"N/C\" };\n        return [msg2, msg];\n    }\n//    else\n//    {\n    \t//msg.payload = null;\n        //return msg;\n//    }\n}\n","outputs":2,"noerr":0,"x":1030,"y":210,"wires":[[],[]]},{"id":"91a61852.eccf48","type":"change","z":"9fb43887.43d798","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"TEMP/MusicPi","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":300,"y":400,"wires":[["a76ef8cf.bd10b"]]},{"id":"8386e3e6.7a8c7","type":"debug","z":"9fb43887.43d798","name":"Status","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":1150,"y":270,"wires":[]},{"id":"51c2fee4.7bedd","type":"debug","z":"9fb43887.43d798","name":"Pings","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":460,"y":280,"wires":[]},{"id":"94413e96.e3aed","type":"debug","z":"9fb43887.43d798","name":"Temp","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":330,"y":360,"wires":[]},{"id":"2dcbcc96.39b53c","type":"function","z":"9fb43887.43d798","name":"Dummy","func":"\nreturn msg;","outputs":1,"noerr":0,"x":340,"y":320,"wires":[["b3a8c499.e0c9b8","51c2fee4.7bedd","223e59a5.7285ae","b6823d8c.97f82"]]},{"id":"25eba889.3b45c8","type":"traffic","z":"9fb43887.43d798","name":"","property_allow":"payload","filter_allow":"go","ignore_case_allow":false,"negate_allow":false,"send_allow":false,"property_stop":"payload","filter_stop":"stop","ignore_case_stop":false,"negate_stop":false,"send_stop":false,"default_start":false,"differ":false,"x":1080,"y":460,"wires":[["e2590fb9.f5b9e"]]},{"id":"9c86ceff.64f18","type":"traffic","z":"9fb43887.43d798","name":"","property_allow":"payload","filter_allow":"go","ignore_case_allow":false,"negate_allow":false,"send_allow":false,"property_stop":"payload","filter_stop":"stop","ignore_case_stop":false,"negate_stop":false,"send_stop":false,"default_start":false,"differ":false,"x":120,"y":400,"wires":[["91a61852.eccf48"]]},{"id":"4d458781.fb6b9","type":"inject","z":"9fb43887.43d798","name":"","topic":"","payload":"go","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":520,"wires":[["9c86ceff.64f18"]]},{"id":"2e530069.a339c8","type":"inject","z":"9fb43887.43d798","name":"","topic":"","payload":"stop","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":480,"wires":[["9c86ceff.64f18"]]},{"id":"3101ee4f.8d83ca","type":"debug","z":"9fb43887.43d798","name":"Death","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":1160,"y":510,"wires":[]},{"id":"bf20c62d.d43e4","type":"comment","z":"9fb43887.43d798","name":"Remote device control","info":"","x":130,"y":150,"wires":[]},{"id":"d07edf33.4f0e7","type":"comment","z":"9fb43887.43d798","name":"Machine failure simulation","info":"","x":150,"y":560,"wires":[]},{"id":"fc71aab3.6f2c58","type":"comment","z":"9fb43887.43d798","name":"Working part","info":"","x":1030,"y":160,"wires":[]},{"id":"b190814c.41559","type":"comment","z":"9fb43887.43d798","name":"To Guages and Charts","info":"","x":1230,"y":210,"wires":[]},{"id":"b6823d8c.97f82","type":"function","z":"9fb43887.43d798","name":"","func":"\nreturn msg;","outputs":1,"noerr":0,"x":500,"y":490,"wires":[["de39c7bf.46f5a8"]]},{"id":"77bcb4f2.02b004","type":"function","z":"9fb43887.43d798","name":"","func":"msg.payload = \"stop\";\nreturn msg;","outputs":1,"noerr":0,"x":500,"y":560,"wires":[["25eba889.3b45c8"]]},{"id":"de39c7bf.46f5a8","type":"delay","z":"9fb43887.43d798","name":"","pauseType":"delay","timeout":"30","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":880,"y":460,"wires":[["25eba889.3b45c8"]]},{"id":"3907ea7a.541df6","type":"inject","z":"9fb43887.43d798","name":"","topic":"","payload":"go","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"2","x":1070,"y":400,"wires":[["25eba889.3b45c8"]]},{"id":"e2590fb9.f5b9e","type":"function","z":"9fb43887.43d798","name":"","func":"msg.payload = \"ERROR\";\nreturn msg;","outputs":1,"noerr":0,"x":1010,"y":510,"wires":[["3101ee4f.8d83ca"]]}]
0 Likes

#4

OK - so are you saying this is now solved - or is this still demonstrating the problem you are having ?

Craig

0 Likes

#5

It is resolved....

What I was doing wrong (if you want to call it that) was using the TRIGGER node rather than the DELAY node.

If you are interested I will try to explain how it "works":

All buttons (traffic lights) OFF: Nothing.

Press BOTH GO buttons. Not critical of order, but quickly enough: All will be good.
Watching the STATUS FUNCTION node you will see it blinking green and yellow.
The node above it (MusicPi Temp) will show ON-LINE under it.

Further break down:

Starting from BOTH STOP buttons pressed and the flow settled down:
Press ONLY the TOP GO button: After about 20 seconds you will get a message from the DEATH message node saying error.

That is because "it" is seeing PINGs coming in for more than 20 seconds with no temperature messages.

0 Likes

#6

Um......

I don't think it does work.

:frowning:
But is it any clearer what I want to happen?

0 Likes

#7

Might I suggest an MQTT connection and the use of retained QOS 2 Birth, Close, and Will messages to monitor the status of the sequencing.

I also think MQTT might be a better way to pass around the data you seem to be sending (depending on what is in your function nodes).

Running mosquitto on localhost has worked great for me to communicate between flows (tabs) on the same machine as well as passing data among machines, using one as the broker for both.

0 Likes

#8

Thanks. That does sound plausible.

But what you suggest is beyond me at this time.

Would it be too much for an very basic flow to demonstrate what you mean with the MQTT packets?

0 Likes

#9

This series is a good introduction to MQTT. Take a day out to work through it and experiment a bit with it. Then you should have a good grasp of the basics.
https://www.hivemq.com/blog/mqtt-essentials-part-1-introducing-mqtt

2 Likes

#10

The HiveMQ site is where I really started understanding MQTT, but the nodered.org documentation had some simple stuff that got me interested initially:

https://cookbook.nodered.org/mqtt/connect-to-broker

Follow through the sequence to get an idea of how powerful it is and then get a better understanding of the details with the HiveMQ tutorials.

0 Likes

#11

Thanks,

I have a fair bit of MQTT stuff in the flows.

(I have had lots of fun with Birth Certificates and Death Certificates in the pas. Sure I have probably forgotten a lot of it, but still.....)

But when you say "use a birth certificate to see when the machine connects" when I go to the site, all I see is Death Certificate mentioned.

(Yeah, ok. SEARCH!)

I have. And haven't found anything applicable.

I am not getting what you are wanting me to do. As it is (though not working) I am using an incoming message from the machine to tell me it is "up and running" and not just online returning the PINGS.

I still haven't got it all working correctly. The test flow seemed to be ok, but when I put it to REAL LIFE testing, it falls over. Again: Missing the initial data packet from the machine to time out. Or something like that.

You are saying use the Birth Certificate from MQTT.

To me that is just changing the methodology but not the end problem. If anything it is making it more difficult as I seem to have to learn about MQTT Birth Certificates too.

The mechanics of the problem won't change if I use MQTT or a message package.

I appreciate your help in that you are replying. But MQTT won't change the over all problem I am having with detecting a machine coming online and after 2 minutes if I haven't received a "message package" the flow flags it and activates a message/signal I can then use to indicate a possible problem with the machine.

I am sure I nearly have it with the last flow I posted, but there still seems a problem with there not being an "initial signal" to be clocked into the receiving machine to indicate no comms.

0 Likes

#12

OK so if i can summarise

Machine 1

  1. Starts up - presumably you are continually pinging this machine (using TCP Ping) - once you get a response to this ping you essentially set a countodwn timer
  2. After 2 minutes if you have not received an "I am alive" message through Node-Red you then go into
  3. warning mode and send out an alert that the machine appears to have hung somewhere on the way up

Is that correct ?

0 Likes

#13

That sounds good.

But I am not sure if there are any "devils in the details" of what is not said.

Reading what you said, this is my best attempt:

The machine starts up. Yes, it is constantly being pinged.
Once it starts to return pings, a timer is started. If it expires:
An action is set to alert me of a possible hung machine.
If it doen't and does return a message ("I'm alive" to call it) then the condition is modified to ok.

There are three "conditions":
1 - OFF-line.
2 - Booting (well gotta call it something) This is between returning the pings and being fully booted.
3 - Alive. Pings are returned, and NR is also talking/sending messages.

If - during operations - it stops sending back the messages - but keeps returning pings - it falls back to the boot condition here also.

Thanks.

0 Likes

#14

In node-red these three messages can be setup when you edit the node to specify the server.

Sure the mechanics of the problem doesn't change with the tools you use, but using tools that address such issues directly gets you a solution much quicker with less work (although perhaps requiring more learning)

MQTT can automatically monitor and keep alive a connection and the broker notifies all machines or processes subscribed to the topic of the status of the connection.

I typically use a running/stopped/died set of birth/disconnect/will messages to a status topic.

For example if my python AI process hangs or crashes the broker detects the loss of "keep-alive" activity and since the node-red flow that oversees the system is subscribed to the AI/STATUS topic it can quickly restart the python process to minimize the loss of function. The reality is this pretty much never happens as Python is solid and my code is well debugged and tested, but it was a big help during development and its reassuring to know I will get an alert if something unforeseen goes wrong among the interacting parts.

0 Likes

#15

Thanks.
Can you hang on a sec? Read further down. Sorry.

Craig,

If you are still reading/interested:

This flow seems to work, but I would like someone to sanity check it for me please.

Walk through:
I have reversed the machine location on the screen.
I have re-written the "PING" part of it.

There are two sets of controls:
On/Off line and Normal/Failed boot.

For the sake of it, you can try it with normal boot as well.

It should only ever give a message out the "Death detector" node IF the Boot failure it set to fail.

Here is the flow.

[{"id":"fe7104c4.80042","type":"inject","z":"791b3629.0b3fd","name":"PING","topic":"","payload":"On-line","payloadType":"str","repeat":"2","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":250,"wires":[["b3d827e0.9aac5","e6e7d777.6cb8e"]]},{"id":"171005e7.010cc2","type":"comment","z":"791b3629.0b3fd","name":"Main machine","info":"","x":150,"y":120,"wires":[]},{"id":"9add11a0.04618","type":"comment","z":"791b3629.0b3fd","name":"Remote machine","info":"","x":1140,"y":120,"wires":[]},{"id":"b3d827e0.9aac5","type":"traffic","z":"791b3629.0b3fd","name":"On-line","property_allow":"payload","filter_allow":"go","ignore_case_allow":false,"negate_allow":false,"send_allow":false,"property_stop":"payload","filter_stop":"stop","ignore_case_stop":false,"negate_stop":false,"send_stop":false,"default_start":false,"differ":false,"x":1140,"y":250,"wires":[["a7b79de5.20b1b8","7b4edb68.cdfac4"]]},{"id":"b80ba483.50d348","type":"inject","z":"791b3629.0b3fd","name":"On line","topic":"","payload":"go","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1130,"y":200,"wires":[["b3d827e0.9aac5","7631c160.357f88"]]},{"id":"16b1f322.eda0cd","type":"inject","z":"791b3629.0b3fd","name":"Off line","topic":"","payload":"stop","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1130,"y":160,"wires":[["b3d827e0.9aac5","7631c160.357f88"]]},{"id":"a7b79de5.20b1b8","type":"traffic","z":"791b3629.0b3fd","name":"","property_allow":"payload","filter_allow":"go","ignore_case_allow":false,"negate_allow":false,"send_allow":false,"property_stop":"payload","filter_stop":"stop","ignore_case_stop":false,"negate_stop":false,"send_stop":false,"default_start":false,"differ":false,"x":1140,"y":550,"wires":[["75c72031.e34b28"]]},{"id":"f07e5597.3e2a78","type":"inject","z":"791b3629.0b3fd","name":"Boot ok","topic":"","payload":"go","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":910,"y":620,"wires":[["a7b79de5.20b1b8"]]},{"id":"3843fc7d.02b084","type":"inject","z":"791b3629.0b3fd","name":"Boot Failure","topic":"","payload":"stop","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":920,"y":580,"wires":[["a7b79de5.20b1b8"]]},{"id":"c62d1d8.e29716","type":"delay","z":"791b3629.0b3fd","name":"","pauseType":"delay","timeout":"30","timeoutUnits":"seconds","rate":"1","nbRateUnits":"10","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":120,"y":630,"wires":[["ee2e3e71.a1a0c"]]},{"id":"75c72031.e34b28","type":"change","z":"791b3629.0b3fd","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"TEMP/MusicPi","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1130,"y":600,"wires":[["1689caa4.d4225d"]]},{"id":"1689caa4.d4225d","type":"random","z":"791b3629.0b3fd","name":"Temp","low":"1","high":"10","inte":"true","property":"payload","x":1160,"y":640,"wires":[["f66956f4.0bbe8","f633b9ec.7d6d7"]]},{"id":"a921b813.3f538","type":"function","z":"791b3629.0b3fd","name":"MusicPi temp","func":"//  WORKING!\n//  2018 08 11\nvar count = context.get('count') || 0;\nvar mtopic = msg.topic;\nvar mpayload = msg.payload;\nvar device = 'MusicPi';           ///////    NAME OF COMPUTER HERE!\nvar save_this_message = \"TEMP/\"+device\nif (msg.topic == 'RESET')\n{\n    //node.warn(device + \" RESET message RX\");\n    msg.payload = 'Off-line';\n    count = 1;\n    context.set('count',count);\n    msg.payload = 'N/C';\n    var msg2 = { payload:\"0\"};\n    return [msg, msg2];    \n}\nif (mtopic == save_this_message)\n{\n    //node.warn(device + \" Temperature received\");\n    context.set('message',msg.payload);  //  save the payload as this is the temperature.\n    node.status({fill:\"yellow\",shape:\"dot\",text:\"message received\"});\n}\n\nif (mpayload === 'On-line')\n{\n    msg.topic = device;\n    node.status({fill:\"green\",shape:\"dot\",text:\"On-line\"});\n    //node.warm(\"On-line message received\");\n    context.set('count',0);\n    msg.payload = context.get('message');  //  get stored value back.\n    return [msg, msg];\n}\nelse\nif (mpayload === 'Off-line')\n{\n    //node.warn(device + \" Is Off-line\");\n    msg.topic = device;\n    count = count + 1;\n    context.set('count',count);\n    msg.topic = count;\n\n    if (count === 1)\n    {\n        node.status({fill:\"blue\",shape:\"dot\",text:\"Off-line\"});\n        var msg2 = { payload:\"0\", topic: device};\n    \tmsg.payload = \"0\";\n    \treturn [msg, msg2];\n    }\n    if (count === 2)\n    {\n        node.status({fill:\"red\",shape:\"dot\",text:\"Off-line\"});\n        msg.payload = [];\n        var msg2 = { payload:\"N/C\" };\n        return [msg2, msg];\n    }\n//    else\n//    {\n    \t//msg.payload = null;\n        //return msg;\n//    }\n}\n","outputs":2,"noerr":0,"x":220,"y":360,"wires":[["da71fa16.30aa1","5bbecb14.ebb294"],[]]},{"id":"758e4804.41f408","type":"function","z":"791b3629.0b3fd","name":"Status","func":"var x = context.get('x') || 0;\n//node.warn(x);\n\nif (msg.payload == \"Off-line\")\n{\n    //\n    msg  = {payload: '<i class=\"fa fa-bullseye fa-2x nr-dashboard-error\"></i>'};\n    node.status({fill:\"red\",shape:\"dot\",text:\"Off-line\"});\n    context.set('x',0);\n    var msg2 = {payload: \"Off-line\", background:\"brown\" };\n    return [msg,msg2];\n}\nif (x == 0)\n{\n    if (msg.payload == \"On-line\")\n    {\n        msg  = {payload: '<font color = \"yellow\" i class=\"fa fa-bullseye fa-2x\"></i>'};\n        node.status({fill:\"yellow\",shape:\"dot\",text:\"Ping-line\"});\n        //node.warn(\"Ping ok\");\n        var msg2 = {payload: \"On-line\", background:\"yellow\" };\n        context.set('x',1);\n        return [msg,msg2];\n    }\n}\nif (x == 1)\n{\n    if (msg.payload > 0)\n    {\n        msg  = {payload: '<i class=\"fa fa-bullseye fa-2x nr-dashboard-ok\"></i>'};\n        node.status({fill:\"green\",shape:\"dot\",text:\"Temperature\"});\n        //node.warn(\"Temperature packet received\");\n        var msg2 = {payload: \"On-line\", background:\"green\" };\n        context.set('x',1);\n        return [msg,msg2];\n    }\n}\n","outputs":2,"noerr":0,"x":200,"y":410,"wires":[["c3dcfc8e.67927","514c20e7.a64cd8"],[]]},{"id":"c3dcfc8e.67927","type":"debug","z":"791b3629.0b3fd","name":"Status","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":430,"y":400,"wires":[]},{"id":"514c20e7.a64cd8","type":"ui_text","z":"791b3629.0b3fd","group":"c9674ee2.6b7ff","order":8,"width":"2","height":"1","name":"94","label":"94","format":"{{msg.payload}}","layout":"row-center","x":430,"y":430,"wires":[]},{"id":"e6e7d777.6cb8e","type":"debug","z":"791b3629.0b3fd","name":"Sending","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":270,"y":210,"wires":[]},{"id":"8ccdb970.79eb","type":"trigger","z":"791b3629.0b3fd","op1":"","op2":"ERROR","op1type":"nul","op2type":"str","duration":"10","extend":false,"units":"s","reset":"ok","bytopic":"all","name":"","x":380,"y":520,"wires":[["3ba3e7e.2bd4398"]]},{"id":"7aa87fe2.9ba25","type":"function","z":"791b3629.0b3fd","name":"","func":"if (msg.payload == \"On-line\")\n{\n    msg.payload = \"OK\";\n} else\nif (msg.payload == \"Off-line\")\n{\n    msg.payload = \"NOT\";\n}\nreturn msg;","outputs":1,"noerr":0,"x":170,"y":460,"wires":[["ee2e3e71.a1a0c"]]},{"id":"da71fa16.30aa1","type":"debug","z":"791b3629.0b3fd","name":"TEMPERATURE READING","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":510,"y":330,"wires":[]},{"id":"f66956f4.0bbe8","type":"debug","z":"791b3629.0b3fd","name":"Temperature","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1200,"y":720,"wires":[]},{"id":"b4744d0e.f1424","type":"debug","z":"791b3629.0b3fd","name":"Line status","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1180,"y":460,"wires":[]},{"id":"7b4edb68.cdfac4","type":"function","z":"791b3629.0b3fd","name":"","func":"\nreturn msg;","outputs":1,"noerr":0,"x":1130,"y":500,"wires":[["f633b9ec.7d6d7","b4744d0e.f1424"]]},{"id":"f633b9ec.7d6d7","type":"link out","z":"791b3629.0b3fd","name":"TEMP--RETURN-PATH","links":["1eaad11d.8cd71f"],"x":1305,"y":520,"wires":[]},{"id":"1eaad11d.8cd71f","type":"link in","z":"791b3629.0b3fd","name":"TEMP--RETURN-PATH","links":["f633b9ec.7d6d7"],"x":85,"y":360,"wires":[["a921b813.3f538","758e4804.41f408","5a9cee18.ef4f38","25ddc368.646cb4","7aa87fe2.9ba25"]]},{"id":"3ba3e7e.2bd4398","type":"debug","z":"791b3629.0b3fd","name":"Death detector","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":560,"y":520,"wires":[]},{"id":"5bbecb14.ebb294","type":"function","z":"791b3629.0b3fd","name":"","func":"msg.payload = \"ok\"\nreturn msg;","outputs":1,"noerr":0,"x":330,"y":470,"wires":[["8ccdb970.79eb","ac57eb44.3dd2e"]]},{"id":"7631c160.357f88","type":"traffic","z":"791b3629.0b3fd","name":"Off-line","property_allow":"payload","filter_allow":"stop","ignore_case_allow":false,"negate_allow":false,"send_allow":false,"property_stop":"payload","filter_stop":"go","ignore_case_stop":false,"negate_stop":false,"send_stop":false,"default_start":false,"differ":false,"x":1140,"y":300,"wires":[["7b4edb68.cdfac4"]]},{"id":"471acb4f.7323fc","type":"inject","z":"791b3629.0b3fd","name":"Offline injection","topic":"","payload":"Off-line","payloadType":"str","repeat":"2","crontab":"","once":false,"onceDelay":0.1,"x":950,"y":300,"wires":[["7631c160.357f88"]]},{"id":"5a9cee18.ef4f38","type":"debug","z":"791b3629.0b3fd","name":"Receiving","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":200,"y":320,"wires":[]},{"id":"25ddc368.646cb4","type":"switch","z":"791b3629.0b3fd","name":"Online?","property":"payload","propertyType":"msg","rules":[{"t":"regex","v":"On-line","vt":"str","case":false}],"checkall":"true","repair":false,"outputs":1,"x":100,"y":510,"wires":[["29d091ed.33a14e","c62d1d8.e29716"]]},{"id":"29d091ed.33a14e","type":"debug","z":"791b3629.0b3fd","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":140,"y":550,"wires":[]},{"id":"ac57eb44.3dd2e","type":"debug","z":"791b3629.0b3fd","name":"Reset","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":470,"y":470,"wires":[]},{"id":"ee2e3e71.a1a0c","type":"traffic","z":"791b3629.0b3fd","name":"","property_allow":"payload","filter_allow":"OK","ignore_case_allow":false,"negate_allow":false,"send_allow":false,"property_stop":"payload","filter_stop":"NOT","ignore_case_stop":false,"negate_stop":false,"send_stop":false,"default_start":false,"differ":false,"x":290,"y":630,"wires":[["8ccdb970.79eb"]]},{"id":"5d1e003b.67a3d","type":"comment","z":"791b3629.0b3fd","name":"Boot condition switch","info":"","x":920,"y":540,"wires":[]},{"id":"c9674ee2.6b7ff","type":"ui_group","z":"","name":"Group2","tab":"e68d55fd.06eaa8","order":2,"disp":true,"width":"6","collapse":false},{"id":"e68d55fd.06eaa8","type":"ui_tab","z":"","name":"TEMP","icon":"dashboard","order":33}]

I whole heartedly agree.

But there is a line between "learning" and "re-inventing the wheel".

That blurs a lot with the internet and all that.

Yes, maybe there is an "easier" way of doing it, and I am (stupidly) making things difficult for my self.
But again it gets back to where is the learning and re-inventing the wheel.

I can only attack the problem with the knowledge I have. Sure it would be nice to increase my knowledge base, but...... at what cost?

I used to be able to juggle stuff like this in my mind with "one hand behind my back". These days it is a little bit harder. So I like to study the problem more (maybe because I don't get it as quickly, or I have completely changed in HOW I think.) and I seem to find "nicer" answers.

Nicer - yeah, well..... I understand it more than I maybe used to. I think a lot of my younger years were spent emptying the "luck bucket" and not filling the "knowledge bucket". Nice then, not so nice now.

I used to have a nice chair, desk and ergonomics to sit and program. Now I am sitting in a bad chair, at a bad desk with poor ergonomics. Yeah, my problem/fault. But those are the cards in my hand at this point in time.

I am also leaning towards "cut/paste programming" where as before I would type EVERY THING.
I am undergoing a complete change of paradyme (spelling) of thinking and lifestyle.

I shall have to do more reading/learning on MQTT but I don't think it will be today.

Thanks though.

0 Likes

#16

I don't want to repost the flow, but I have found a bug which could cause problems:

In the "MusicPi Temp" node:

In the part where it detects if the message is "Off-line" and does stuff.

else
if (mpayload === 'Off-line')
{
    //node.warn(device + " Is Off-line");
    context.set('message',null);

You need to add the last line - which isn't in the original code.

That was causing a lot of problems.

Because the node "remembered" the last value from the last connection session, it sent it and so negated the "no new data received" part of the flow.

0 Likes

#17

Trying to import and i am getitng unknown node Traffic ???

0 Likes

#18

Craig,

As much as I tried to not use "exotic" nodes I had to include the "Traffic" node.

Hope that explains the problem with the error.

0 Likes