IF - THEN - ELSE and other program flows. I am really not getting it.

3,160 views
Skip to first unread message

shykitten55

unread,
Sep 26, 2017, 3:08:54 AM9/26/17
to Node-RED
(Attempt 2)
Machine locked up while typing the first attempt.

I accept I am stupid.   But this is just getting beyond ridiculous.

Short version:
There are 7 devices on this network (for now/at this point) and I am doign telemerty between them.
I am needing to determine if the machines are turned on or off.
(node-red-contrib)isonline doesn't do what I want.

I found a FLOW which nearly does what I want/need.
Alas it only says if the machine is OFF LINE.   I need an OFF LINE / ON LINE indication.

Can't be that hard to change it - can it?

I started at about 09:00 (maybe earlier) and it is now 16:00+
With only TWO breaks - one to get food and one to clear my head - I have spent all but maybe 1.5 hours on this today and got NOWHERE

I admit also that I know "jack" about all these modern languages and understanding the syntax.

After a previous IF() THEN() ELSE() fiasco, I though I had it worked out.

HA!  Not likely.


Here's a quick explanation of that:
Variable.
if(V > 20)
{
  blah
}
if(V > 10)
{
  blah-de-blah
}

I thought that was the wrong way of testing, as if V > 10 and it does blah.
But if it is > 20 then it is also > 10 so it also does blah-de-blah.

But - I have been told - that way is WRONG.

I have to test it like this:

if (v > 10)
{
  blah
}
if (v > 20)
{
  blah-de-blah
}


Yeah, ok not the exact structure, but the meaning is there.
I FAILED ENGLISH.  Don't pick on minor differences.  This is hard enough.


Anyway, putting that aside and LEARNING from the lesson, I moved on.

So I do the testing in the reverse order to how I would think.
Ok.  If that is the RIGHT way of doing it....   And it works, who am I to argue?

So I get onto another part where I am editing messages (msg.payload) to switch what goes where.

I am getting messages (msg.payloads) like:
"TimePi 99 is on-line"

"BedPi 83 is off-line"

Suffice to split them to different paths to then determine "who is turned on" and who isn't.

This is in light of my using a "switch" (NODE) which gets input and toggles depending on what is sent to it.
Basically On/Off and the switch toggles.

Ain't rocket science.

So the next problem appears:  How to get than a bit nicer for switch input.   Yes, I could parse the whole string and determine the switch's statuc, but for the sake of "doing it right the first time" I wanted to optimise the message sent to the switch to maybe something like:  On-line and Off-line.

And again:  How hard can that be?
Honestly:   I DON'T KNOW!
I have NO IDEA of what commands to use or even what they look like.

I spent more than an hour searching JAVASCRIPT substring matching, to no avail.   Command not found was a classic.

So, I found this amazing command:  msg.payload.match( )

The instructions were in a foreign language to me, but I kind of got the structure.

var find = "off-line";
if(msg.payload.match(find) > 0)

It was actually written in a longer worded version but that is what I got it down to.
Oh, and there was this regex thing mentioned.

This is the code:

var parts = msg.payload.match(/^=(F|W|B)([0-9]+)\%\@([0-9]+)C([0-9A-F]+)(;X([0-9]+) *)?;?(T([0-9]+ [0-9]+) ([^;]*))?;?(S([0-9]+) ([0-9]+) ([0-9]+))?;?(H([0-9]+ [0-9]+)*)?;?.*{(.*)}$/);
if(null === parts) {
    node.error("Failed to parse input", msg);
    return null;
}


Martian?   May well just have been, cos it doesn't mean much to me.



Anyway, so I have a test and it returns a value which will tell me if "x" is in "y".



This is the NODE code:
var find = "off-line";
var state;
if(msg.payload.match(find) > 0)
{
    state = "off-line";
}
else
{
    state = "on-line";
}
msg.payload = state;
return msg;


Now, whether the off-line and on-line bits are the right way around or not is (ultimately for THIS story - academic) not a big worry at that stage.
If they are the wrong way, I simply reverse them and all is good.

So:  I have the computers/machines.
As one of them is the same machine, I think it is silly testing if it is on or off line.
So I skipped that.
"now" 3 are on and three are off.  Pretty good t see both results.

I set it all up, trigger the flow and I get......   rubbish.
Machines that are on are showing off, and machines that are off showing on.

Ok, let's look at this.
Went through and found some mistakes and fixed that part.
But it still shows the wrong state on 50% of the machines.

So let's look at it a bit more....

var find = "off-line";                                 This is for what I am looking.
var state;                                                 Used in a minute.
if(msg.payload.match(find) > 0)             Search for the string "off-line" in msg.payload.   Get a value.   If > 0 do this bit.
{
    state = "off-line";                                 Set state to OFF_LINE
}
else                                                           OTHERWISE
{
    state = "on-line";                                  Set state to ON_LINE
}
msg.payload = state;
return msg;


Now, let's look at what is going into this before anyone rips me a new one....

"TimePi 99 is on-line"

"PiFace 86 is on-line"

"MusicPi 82 is on-line"

"Modem 254 is on-line"

"BedPi 83 is off-line"

"CameraPi 91 is off-line"


And that is correct.

Once I pass it through that above bit of code I get weird results.
I put all the switches to the OFF position and trigger it.
The switches turn on as they were before.  Yet, all the DEBUG nodes connected to that part show NOTHING.

Now, "machines that are off being shown as on...  ha ha ha!".    No, because with the same bit of code machines that are on are shown as off.

So it isn't that I have my logic back to front.

If I have things off and they show on, and on showing off, that would be simple.

But of the 3 nodes, 2 are on and one is off, yet they all show as on.


If you are still reading this, here is the block of code.
Given it pings (sorry ADVANCE PING) the nodes and gets back a reply.
It then determines who is on and who is off.
That is sent as a message (or what ever you want to call it) to another node which looks at the IP number and splits it on that.
That goes to 6 outputs and then the message is looked at again to see if it contains the off or on line status.
That is then sent tot he switch.

It doesn't work and it is not consistent with how it behaves.
Beyond me for obeying rules.



[{"id":"e0f4dd31.ce185","type":"inject","z":"3a962246.4b4b06","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"x":126.75,"y":1226.25,"wires":[["f53b1717.3d5898"]]},{"id":"15a92475.d4d914","type":"ui_switch","z":"3a962246.4b4b06","name":"Music","label":"82","group":"1bc82180.b88ad7","order":1,"width":"2","height":"1","passthru":true,"decouple":"false","topic":"","style":"","onvalue":"on-line","onvalueType":"str","onicon":"","oncolor":"","offvalue":"off-line","offvalueType":"str","officon":"","offcolor":"","x":591.5,"y":1331.5,"wires":[["515584c.342c47c"]]},{"id":"757e8195.1b53f8","type":"switch","z":"3a962246.4b4b06","name":"Message check","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"82","vt":"str"},{"t":"cont","v":"83","vt":"str"},{"t":"cont","v":"86","vt":"str"},{"t":"cont","v":"91","vt":"str"},{"t":"cont","v":"99","vt":"str"},{"t":"cont","v":"254","vt":"str"}],"checkall":"true","outputs":6,"x":155.125,"y":1364.5,"wires":[["38e84125.2d7286"],["d3b9d512.fb24f"],["e5051544.ae55e"],["774e8289.e9d19c","3920beba.d6470a"],["fb33bdcc.07152"],["76705ee.a164ba","7eb17e9d.92d908"]]},{"id":"83055205.6a50d8","type":"debug","z":"3a962246.4b4b06","name":"","active":false,"console":"false","complete":"false","x":642.25,"y":1264.75,"wires":[]},{"id":"30a39e32.47fd52","type":"ui_switch","z":"3a962246.4b4b06","name":"Bed","label":"83","group":"1bc82180.b88ad7","order":3,"width":"2","height":"1","passthru":true,"decouple":"false","topic":"","style":"","onvalue":"on-line","onvalueType":"str","onicon":"","oncolor":"","offvalue":"off-line","offvalueType":"str","officon":"","offcolor":"","x":593.75,"y":1363,"wires":[["4db0960c.78b458"]]},{"id":"cd9b8c7f.687408","type":"ui_switch","z":"3a962246.4b4b06","name":"Face","label":"86","group":"1bc82180.b88ad7","order":5,"width":"2","height":"1","passthru":true,"decouple":"false","topic":"","style":"","onvalue":"on-line","onvalueType":"str","onicon":"","oncolor":"","offvalue":"off-line","offvalueType":"str","officon":"","offcolor":"","x":595.25,"y":1395,"wires":[["c0ea97f4.4bff68"]]},{"id":"6d5b13c4.0786c4","type":"ui_switch","z":"3a962246.4b4b06","name":"Camera","label":"91","group":"1bc82180.b88ad7","order":2,"width":"2","height":"1","passthru":true,"decouple":"false","topic":"","style":"","onvalue":"on-line","onvalueType":"str","onicon":"","oncolor":"","offvalue":"off-line","offvalueType":"str","officon":"","offcolor":"","x":604.5,"y":1426.75,"wires":[["c19469c3.19ee08"]]},{"id":"5f7f1118.3b20f8","type":"ui_switch","z":"3a962246.4b4b06","name":"Gateway","label":"254","group":"1bc82180.b88ad7","order":6,"width":"2","height":"1","passthru":true,"decouple":"false","topic":"","style":"","onvalue":"on-line","onvalueType":"str","onicon":"","oncolor":"","offvalue":"off-line","offvalueType":"str","officon":"","offcolor":"","x":605.25,"y":1491,"wires":[["a4d0128a.4e026"]]},{"id":"4c1f229c.60002c","type":"ui_switch","z":"3a962246.4b4b06","name":"Time","label":"99","group":"1bc82180.b88ad7","order":4,"width":"2","height":"1","passthru":true,"decouple":"false","topic":"","style":"","onvalue":"on-line","onvalueType":"str","onicon":"","oncolor":"","offvalue":"off-line","offvalueType":"str","officon":"","offcolor":"","x":596,"y":1458.75,"wires":[["47d3bce6.6313fc"]]},{"id":"f53b1717.3d5898","type":"function","z":"3a962246.4b4b06","name":"check list","func":"var checks = [\n    {'topic':'MusicPi    82 ', 'addr': \"192.168.0.82\"}, \n    {'topic':'BedPi      83 ', 'addr': \"192.168.0.83\"},\n    {'topic':'PiFace     86 ', 'addr': \"192.168.0.86\"}, \n    {'topic':'CameraPi   91 ', 'addr': \"192.168.0.91\"},\n    {'topic':'TimePi     99 ', 'addr': \"192.168.0.99\"},\n    {'topic':'Modem     254 ', 'addr': \"192.168.0.254\"},\n];\n\nfor ( var i in checks ) {\n    node.send({\n        \"topic\" : checks[i].topic,\n        \"host\"  : checks[i].addr,\n    });\n} ","outputs":1,"noerr":0,"x":287,"y":1227,"wires":[["94722ab0.cc1f28"]]},{"id":"94722ab0.cc1f28","type":"adv ping","z":"3a962246.4b4b06","name":"","host":"","x":460,"y":1227,"wires":[["1aeffae6.1c14cd"]]},{"id":"1aeffae6.1c14cd","type":"function","z":"3a962246.4b4b06","name":"msg","func":"var device = msg._topic;\nvar part_message;\nif (msg.payload===false)\n{\n    part_message=device + \" is off-line\";\n}\nelse\n{\n    part_message=device + \" is on-line\";\n} \nmsg.payload=part_message;\nreturn msg;","outputs":1,"noerr":0,"x":407,"y":1266,"wires":[["757e8195.1b53f8","83055205.6a50d8"]]},{"id":"76705ee.a164ba","type":"function","z":"3a962246.4b4b06","name":"Format message","func":"var find = \"off-line\";\nvar state;\nif(msg.payload.match(find) > 0)\n{\n    state = \"off-line\";\n}\nelse\n{\n    state = \"on-line\";\n}\nmsg.payload = state;\nreturn msg;","outputs":1,"noerr":0,"x":428,"y":1491,"wires":[["5f7f1118.3b20f8","82e8e2b3.8a1eb"]]},{"id":"fb33bdcc.07152","type":"function","z":"3a962246.4b4b06","name":"Format message","func":"var find = \"off-line\";\nvar state;\nif(msg.payload.match(find) > 0)\n{\n    state = \"off-line\";\n}\nelse\n{\n    state = \"on-line\";\n}\nmsg.payload = state;\nreturn msg;","outputs":1,"noerr":0,"x":428,"y":1459,"wires":[["4c1f229c.60002c"]]},{"id":"774e8289.e9d19c","type":"function","z":"3a962246.4b4b06","name":"Format message","func":"var find = \"off-line\";\nvar state;\nif(msg.payload.match(find) > 0)\n{\n    state = \"off-line\";\n}\nelse\n{\n    state = \"on-line\";\n}\nmsg.payload = state;\nreturn msg;","outputs":1,"noerr":0,"x":427,"y":1427,"wires":[["6d5b13c4.0786c4","ab852396.efbcc8"]]},{"id":"38e84125.2d7286","type":"function","z":"3a962246.4b4b06","name":"Format message","func":"var str = msg.payload;\nvar find = \"off-line\";\nvar state;\nif(msg.payload.match(find) > 0)\n{\n    state = \"off-line\";\n}\nelse\n{\n    state = \"on-line\";\n}\nmsg.payload = state;\nreturn msg;","outputs":1,"noerr":0,"x":426,"y":1331,"wires":[["15a92475.d4d914"]]},{"id":"d3b9d512.fb24f","type":"function","z":"3a962246.4b4b06","name":"Format message","func":"var find = \"off-line\";\nvar state;\nif(msg.payload.match(find) > 0)\n{\n    state = \"on-line\";\n}\nelse\n{\n    state = \"off-line\";\n}\nmsg.payload = state;\nreturn msg;","outputs":1,"noerr":0,"x":426,"y":1363,"wires":[["30a39e32.47fd52"]]},{"id":"e5051544.ae55e","type":"function","z":"3a962246.4b4b06","name":"Format message","func":"var find = \"off-line\";\nvar state;\nif(msg.payload.match(find) > 0)\n{\n    state = \"on-line\";\n}\nelse\n{\n    state = \"off-line\";\n}\nmsg.payload = state;\nreturn msg;","outputs":1,"noerr":0,"x":426,"y":1395,"wires":[["cd9b8c7f.687408"]]},{"id":"515584c.342c47c","type":"debug","z":"3a962246.4b4b06","name":"MusicPi","active":false,"console":"true","complete":"payload","x":746,"y":1330,"wires":[]},{"id":"4db0960c.78b458","type":"debug","z":"3a962246.4b4b06","name":"BedPi","active":false,"console":"true","complete":"payload","x":736,"y":1362,"wires":[]},{"id":"c0ea97f4.4bff68","type":"debug","z":"3a962246.4b4b06","name":"PiFace","active":false,"console":"true","complete":"payload","x":736,"y":1394,"wires":[]},{"id":"c19469c3.19ee08","type":"debug","z":"3a962246.4b4b06","name":"CameaPi","active":true,"console":"true","complete":"payload","x":748,"y":1426,"wires":[]},{"id":"47d3bce6.6313fc","type":"debug","z":"3a962246.4b4b06","name":"TimePi","active":false,"console":"true","complete":"payload","x":738,"y":1458,"wires":[]},{"id":"a4d0128a.4e026","type":"debug","z":"3a962246.4b4b06","name":"Gateway","active":false,"console":"true","complete":"payload","x":748,"y":1490,"wires":[]},{"id":"82e8e2b3.8a1eb","type":"debug","z":"3a962246.4b4b06","name":"Working","active":false,"console":"false","complete":"payload","x":582.5,"y":1575,"wires":[]},{"id":"ab852396.efbcc8","type":"debug","z":"3a962246.4b4b06","name":"Unknown","active":true,"console":"false","complete":"payload","x":635.5,"y":1531,"wires":[]},{"id":"7eb17e9d.92d908","type":"debug","z":"3a962246.4b4b06","name":"Raw working","active":false,"console":"false","complete":"payload","x":398.5,"y":1578,"wires":[]},{"id":"3920beba.d6470a","type":"debug","z":"3a962246.4b4b06","name":"Raw unknown","active":true,"console":"false","complete":"payload","x":416.5,"y":1535,"wires":[]},{"id":"1bc82180.b88ad7","type":"ui_group","z":"","name":"Status","tab":"d29ccfb1.b5e108","order":5,"disp":true,"width":"4"},{"id":"d29ccfb1.b5e108","type":"ui_tab","z":"","name":"TELEMETRY","icon":"dashboard","order":1}]




Nick O'Leary

unread,
Sep 26, 2017, 3:46:51 AM9/26/17
to Node-RED Mailing List
Hi,

sorry Cat, I realise this is frustrating you and its good to vent, but the way you're telling the whole story of your day it is hard to understand where you are right now and what help you're looking for right now. Each time I think you've asked a question you go on to say you've found a solution or you've given up and you move onto something else.


I've imported your flow and as I don't have the Advanced Ping node installed, I have replaced it with some Inject nodes and a Change node to simulate the output of the Advanced Ping node. This makes it quick and easy to test without relying on real machines on the network. (The flow json for these nodes, just covering MusicPi, is below - you can copy/paste the inject nodes for your other machines.)






Using Debug nodes to trace through where messages are going, there is a problem with your Format Message function.

var find = "off-line";
var state;
if(msg.payload.match(find) > 0) // <<< problem here
{
    state = "on-line";
}
else
{
    state = "off-line";
}
msg.payload = state;
return msg;

The match function returns either null if it doesn't match, or an object if it does match. That means the '> 0' test you are doing on the result isn't correct - it will always be false
Here is the corrected code:

var find = "off-line";
var state;
if(msg.payload.match(find))  // << removed the > 0 check
{
    state = "on-line";
}
else
{
    state = "off-line";
}
msg.payload = state;
return msg;


As for why the Debug nodes after you Button nodes show nothing, I think that is an old bug with the Dashboard nodes. Check what version of the dashboard nodes you're running (it is logged by node-red when it starts up, or you can see it in the 'manage palette' dialog in the editor which lists what you have installed). I tried it with the old version 2.4.0 and they didn't pass through, but then upgraded to the newly released 2.5.1 and they do pass through as I would expect.


Nick


Those Inject nodes to simulate Advanced Ping behaviour....

[{"id":"ca17424c.b3604","type":"inject","z":"cb327416.03e1d8","name":"","topic":"MusicPi    82 ","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"x":120,"y":120,"wires":[["a6e3dd10.9dc0c"]]},{"id":"c6ae5393.58217","type":"inject","z":"cb327416.03e1d8","name":"","topic":"MusicPi    82 ","payload":"false","payloadType":"bool","repeat":"","crontab":"","once":false,"x":120,"y":160,"wires":[["a6e3dd10.9dc0c"]]},{"id":"a6e3dd10.9dc0c","type":"change","z":"cb327416.03e1d8","name":"","rules":[{"t":"move","p":"topic","pt":"msg","to":"_topic","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":300,"y":140,"wires":[["c0edef2d.f5f91"]]}]




--
http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+unsubscribe@googlegroups.com.
To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.
To view this discussion on the web, visit https://groups.google.com/d/msgid/node-red/113636d9-326e-4d9a-b3fc-dd4aacbc35a1%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Cat

unread,
Sep 26, 2017, 4:10:22 AM9/26/17
to node...@googlegroups.com
Hi Nick.

Thanks for not taking it as  anything personal.

In no particular order:
The code I found with the msg.payload.match( )


var parts = msg.payload.match(/^=(F|W|B)([0-9]+)\%\@([0-9]+)C([0-9A-F]+)(;X([0-9]+) *)?;?(T([0-9]+ [0-9]+) ([^;]*))?;?(S([0-9]+) ([0-9]+) ([0-9]+))?;?(H([0-9]+ [0-9]+)*)?;?.*{(.*)}$/);
if(null === parts) {
    node.error("Failed to parse input", msg);
    return null;
}

Is vague...  to me.

I extrapolated the code I posted from it because I have NO KNOWLEDGE of how to read that.


So if it returns "null" does that mean it returns 0?
Because if it returns 0 if it can't find and an object if it finds it......    What's an object?
Wouldn't it be > 0?

Ok, so given that, why does it return some as online and others as offline?   (Rhetorical)

If it ALWAYS fails, there are 4 (of the 6) that are shown as online.  Of which only 3 are.  And the two off line one of which is online.

There doesn't seem to be any consistency.  That throws me off the tracks.

If I am "wrong" in what I think and do something which SHOWS ME how it works, I adapt to the new data and laern.

But this was/is just ......

Anyway.

I only used the ADVANCED PING because it was used in that flow which NEARLY did what I wanted.


I "move on" from things because there is a threshold reached where it just seems pointless spending more time/effort trying to get it working.

Maybe in the future I will have a bigger/better understanding and so be able to work out what I did wrong.

I am also not posting and "walking away" from the problem.
SOMETIMES it helps to post about the problem and somehow it helps me get my head around it.   Sometimes not.

But I *AM* looking/researching the "problem" which I mentioned after posting.

Not that I am expecting anyone to "drop everything" and help me, and so I keep digging - as it were.

Only by trying can I learn.

Alas it isn't (or doesn't seem) to be that you can try anything with computers and if you make a mistake, "reset" it and start again.

30 years ago, it was more like that.   If I made a programming mistake, a simple reboot/reset/what ever, it would all work out in the end.


Anyway, I'll look at your FLOW and see if I can learn how to get things working better.







You received this message because you are subscribed to a topic in the Google Groups "Node-RED" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/node-red/yTEugiJkYMU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to node-red+unsubscribe@googlegroups.com.

To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.

Nick O'Leary

unread,
Sep 26, 2017, 5:10:44 AM9/26/17
to Node-RED Mailing List
Hi,

pulling out your questions:

So if it returns "null" does that mean it returns 0?

null is not 0 - in JavaScript they are completely different types. Think of 'null' as nothing, empty, a blank. 0 is the Number with a value of 0. Its a subtle but important distinction. In JavaScript there are some rules around comparing types - which, to be frank, aren't worth getting into right now.

Because if it returns 0 if it can't find and an object if it finds it......    What's an object?
Wouldn't it be > 0?

It doesn't return 0 - it returns null. An Object is an actual tangible thing - but it doesn't have a numeric value - so the test Object > 0 does not have any meaning.


I don't think there were any other questions in your reply, but if there were, please do share them.


Nick


 

Cat

unread,
Sep 26, 2017, 5:41:30 AM9/26/17
to node...@googlegroups.com
Thanks Nick.

Taking in the bit of code you sent I applied it and all is working great!

Just for the sake of showing you what I did on the side of the dashboard, I have attached a picture.

(Sorry about the red mark on the TimePi history.  It is now working.

The only think I would like to add is so if the machine is turned off, the graph and history are marked as such.



Dashboard working.png
Reply all
Reply to author
Forward
0 new messages