The node sometimes returns, sometimes not

#1

The function node below, sometimes returns the message, and sometimes not....I couldn't find a pattern. (sometimes when I open the page at bluemix where node-red is hosted, it returns!)

I am probably making a very simple mistake as I am new to javascript :

msg.payload = flow.get('data');
var moo = flow.get("devid");

if (moo == "dragino_test") {
context.value1 = msg.payload;
} else (moo == "dragino_test2") {
context.value2 = msg.payload;
}

msg.pay1 = context.value1
msg.pay2 = context.value2
return [msg];

I didn't post the other nodes as things do work when the node returns, but I can post them too if necessary.

0 Likes

#2

you have an error in your If statement - look at the else ....

0 Likes

#3

Is there an if missing there?

0 Likes

#4

Whilst not causing your problem, you are also using the old way of storing context which may not work in future versions of Node-RED.
To future proof yourself you should set and get context values as described on this page:
https://nodered.org/docs/writing-functions#storing-data

0 Likes

#5

Sorry, in the original it is an "else if" statement, I was trying to make simpler when I accidentally omitted the "else if".
So the original is :

if (moo == "dragino_test") {
context.value1 = msg.payload;
} else if (moo == "dragino_test2") {
context.value2 = msg.payload;
} else {
context.value3 = msg.payload;
}

msg.pay1 = context.value1
msg.pay2 = context.value2
msg.pay3 = context.value3

And there is no syntax error

0 Likes

#6

Thanks for the tip. I will do that later on.

0 Likes

#7

What do you mean when you say the node does not return? There is no way that I can see that the node will not pass on a message. By the way, the last line can be

return msg;

there is no need to make it an array when there is only one output.

0 Likes

#8

This node is followed by a template node and then an http-out node, so that the results can be seen on a web page. When I noticed that the results on the webpage were so irregular, I checked the individual nodes, and added a debug node just after the function node to see what was happening. The debug, would sometimes show the results and sometimes not, with no noticeable regular pattern. Since I can get sometimes what I want to see at the debug, I decided that the function node was doing its job properly, but failing to convey the message at the last step. But it can as well be something else (maybe flow.get is not working as I expect it to work, but there is no meaningful difference between the data, so why does some data get through and some do not then?), I don't know.

You are right, I changed the last line to msg without brackets, but this doesn't have any effect on the outcome.

0 Likes

#9

Ok so what is being sent to trigger the node?
what happened to the first line in the original example?
where did msg.pay3 = context.value3 come from?

you see, by just providing a tiny snippet, you are generating more questions than the one you are asking.

Start by providing the versions of NR and Node.js
An explaination of what you are trying to do in the flow,
an explaintion of your issue,
then provide a copy of the flow so people can see what you are doing.

That would be most helpful.

0 Likes

#10

Also put a debug node showing the input to the function as well as one on the output, showing the complete message. Then you should be able to see where it is going wrong.
I did not expect that removing the array return would make any difference, just pointing out that it is not required.

0 Likes

#11

Sorry, I was thinking that I just made a simple mistake with the "return" statement or what, and this could be corrected with the same simplicity.

The system is supposed to work as such : Two trackers send their position to an MQTT server, which then publishes to node-red, which then tries to publish their positions on a google maps page. I think the reason I use "context" is evident; data comes from different sources at different times, but should be accessible at the web-page at all times.

Below is the full code. It may not be the "cleanest" code, not knowing much, I wrote it by looking it other written examples:

[{"id":"c9eaca60.7d3868","type":"function","z":"ca6ebd5b.5b082","name":"Decrypt Payload","func":"// msg1 - Unencrypted (vanilla data)\nvar msg1 = { payload: msg.payload.length };\nmsg1.payload = JSON.parse(msg.payload);\nmsg1.payload = msg1.payload.payload_raw;\n\n// msg2 - Decrypt to Text\nvar msg2 = { payload: msg.payload.length };\nmsg2.payload = JSON.parse(msg.payload);\nmsg2.payload = new Buffer(msg2.payload.payload_raw, 'base64').toString('ascii');\n\n// msg3 - Decrypt as Binary value (MSB,LSB)\nvar msg3 = { payload: msg.payload.length };\nmsg3.payload = JSON.parse(msg.payload);\nmsg3.payload = new Buffer(msg3.payload.payload_raw, 'base64').toString('hex');\nmsg3.payload = parseInt(msg3.payload, 16);\n\nreturn [ msg1, msg2, msg3 ];","outputs":"3","noerr":0,"x":642,"y":316.5,"wires":[[],["5e13be1e.7bff8","83015f42.a58e6"],[]]},{"id":"5e13be1e.7bff8","type":"debug","z":"ca6ebd5b.5b082","name":"msg.payload.payload_raw - DATA (decrypted to text)","active":false,"console":"false","complete":"payload","x":656.25,"y":581.2499961853027,"wires":[]},{"id":"605805e8.7aa81c","type":"debug","z":"ca6ebd5b.5b082","name":"message (as is)","active":false,"console":"false","complete":"payload","x":905.0000076293945,"y":260.74999809265137,"wires":[]},{"id":"dfc25552.be6be8","type":"json","z":"ca6ebd5b.5b082","name":"","pretty":false,"x":621.75,"y":261.24999618530273,"wires":[["605805e8.7aa81c","ead5469b.e367b8"]]},{"id":"cd533c.a4cefcc8","type":"comment","z":"ca6ebd5b.5b082","name":"For MQTT \"user\"/\"password\", use \"Application ID\"/\"default key\" ","info":"\n1) Sign in to TTN and go to your application page where \"app_1\" is your \"Application ID\" e.g.\nhttps://console.thethingsnetwork.org/applications/app_1\n\n2) For MQTT User, use \"Application ID\" \n\n3) For MQTT password, scroll to bottom and use \"default key\" (you need to press the \"eye\" to see the long text)","x":282.25,"y":88,"wires":[]},{"id":"83015f42.a58e6","type":"function","z":"ca6ebd5b.5b082","name":"","func":"flow.set('data',msg.payload);\nreturn msg;","outputs":1,"noerr":0,"x":901.4166870117188,"y":331.24999618530273,"wires":[["39c33a87.de57b6"]]},{"id":"39c33a87.de57b6","type":"debug","z":"ca6ebd5b.5b082","name":"","active":false,"console":"false","complete":"payload","x":1083.4166870117188,"y":299.24999618530273,"wires":[]},{"id":"217a20c4.1cc5c","type":"http response","z":"ca6ebd5b.5b082","name":"http out","statusCode":"","headers":{},"x":1196.25,"y":481.24999618530273,"wires":[]},{"id":"2156b606.87874a","type":"http in","z":"ca6ebd5b.5b082","name":"http in","url":"/test3","method":"get","upload":false,"swaggerDoc":"","x":626.25,"y":441.24999618530273,"wires":[["ba9a95d7.2a6e98"]]},{"id":"ead5469b.e367b8","type":"function","z":"ca6ebd5b.5b082","name":"","func":"flow.set(\"devid\",msg.payload.dev_id); \nreturn msg;\n","outputs":1,"noerr":0,"x":905,"y":171.24999618530273,"wires":[["ee0d17b3.b7f7b8"]]},{"id":"ba9a95d7.2a6e98","type":"function","z":"ca6ebd5b.5b082","name":"","func":"\n//msg.payload = flow.get('data')||0;\n//msg.payload.dev_id = flow.get('aygit2')||0;\n//msg.dev_id = flow.get('aygit2')||0;\n\n//var moo = global.get(\"foo\");\n//msg.moo = global.get(\"foo\");\n//msg.payload.moo = global.get(\"foo\");\nmsg.payload = flow.get('data');\nvar moo = flow.get(\"devid\");\n//var msg2 = { payload: moo };\n//msg.payload.moo = moo;\n//msg.moo = moo;\n\n\n if (moo == \"dragino_test\") {\n context.value1 = msg.payload;\n } else if (moo == \"dragino_test2\") { \n context.value2 = msg.payload;\n } else { \n context.value3 = msg.payload;\n }\n\n msg.pay1 = context.value1\n msg.pay2 = context.value2\n msg.pay3 = context.value3\n\n return msg;\n","outputs":1,"noerr":0,"x":827,"y":476.24999618530273,"wires":[["10e11238.3142fe","be465fd0.d3be","9e1553bd.e0f5b"]]},{"id":"ee0d17b3.b7f7b8","type":"debug","z":"ca6ebd5b.5b082","name":"","active":true,"console":"false","complete":"payload","x":1080.75,"y":176.24999618530273,"wires":[]},{"id":"10e11238.3142fe","type":"template","z":"ca6ebd5b.5b082","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"msg.pay1: {{pay1}}<br>\nmsg.pay2: {{pay2}}<br>\nmsg.pay3: {{pay3}}<br>\n<script></script>\n\n<!DOCTYPE html>\n<html>\n <head>\n <meta name=\"viewport\" content=\"initial-scale=1.0, user-scalable=no\">\n <meta charset=\"utf-8\">\n <title>Marker Clustering</title>\n <style>\n /* Always set the map height explicitly to define the size of the div\n * element that contains the map. */\n #map {\n height: 100%;\n }\n /* Optional: Makes the sample page fill the window. */\n html, body {\n height: 100%;\n margin: 0;\n padding: 0;\n }\n </style>\n </head>\n <body>\n <div id=\"map\"></div>\n <script>\n \n var loc1 = \"{{pay1}}\";\n var pos1 = loc1.indexOf(\",\");\n //var posit1 = loc1.indexOf(\"-\");\n var en1 = loc1.slice(0, pos1);\n en1 = Number(en1)\n var boy1 = loc1.slice(pos1+1,19)\n boy1 = Number(boy1)\n \n //var loc1 = \"3333\";\n \n \n var loc2 = \"{{pay2}}\";\n var pos2 = loc2.indexOf(\",\");\n //var posit2 = loc2.indexOf(\"-\");\n var en2 = loc2.slice(0, pos2);\n en2 = Number(en2)\n var boy2 = loc2.slice(pos2+1,19)\n boy2 = Number(boy2)\n \n \n document.write(boy2);\n \n \n var loc3 = \"{{pay3}}\";\n var pos3 = loc3.indexOf(\",\");\n var en3 = loc3.slice(0, pos3);\n en3 = Number(en3)\n var boy3 = loc3.slice(pos3+1,19)\n boy3 = Number(boy3)\n \n //en1: {en1}<br>\n \n //document.getElementById(\"demo\").innerHTML = \"text\";\n //document.getElementById(\"demo4\").innerHTML = text;\n //document.getElementById(\"demo2\").innerHTML = loc;\n //document.getElementById(\"demo3\").innerHTML = pos;\n //document.getElementById(\"demo5\").innerHTML = moo;\n //document.getElementById(\"demo3\").innerHTML = en;\n\n function initMap() {\n\n var map = new google.maps.Map(document.getElementById('map'), {\n zoom: 16,\n center: {lat: boy1, lng: en1}\n });\n\n // Create an array of alphabetical characters used to label the markers.\n var labels = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';\n\n // Add some markers to the map.\n // Note: The code uses the JavaScript Array.prototype.map() method to\n // create an array of markers based on a given \"locations\" array.\n // The map() method here has nothing to do with the Google Maps API.\n var markers = locations.map(function(location, i) {\n return new google.maps.Marker({\n position: location,\n label: labels[i % labels.length]\n });\n });\n\n // Add a marker clusterer to manage the markers.\n var markerCluster = new MarkerClusterer(map, markers,\n {imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'});\n }\n var locations = [\n {lat: boy1, lng: en1},\n {lat: boy2, lng: en2}\n ]\n </script>\n <script src=\"https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/markerclusterer.js\">\n </script>\n <script async defer\n src=\"https://maps.googleapis.com/maps/api/js?key=AIzaSyBMIEpESoY2V1loeaGAjHeYPxZ-guLod8c&callback=initMap\">\n </script>\n </body>\n</html>","output":"str","x":1006.25,"y":601.2499961853027,"wires":[["217a20c4.1cc5c"]]},{"id":"37707509.1f6e5a","type":"debug","z":"ca6ebd5b.5b082","name":"","active":false,"console":"false","complete":"payload","x":629.75,"y":141.24999618530273,"wires":[]},{"id":"c9ebe8b7.e92e78","type":"inject","z":"ca6ebd5b.5b082","name":"","topic":"","payload":"{\"app_id\":\"lorawan-lmic-test\",\"dev_id\":\"dragino_test2\",\"hardware_serial\":\"9876543210123456\",\"port\":1,\"counter\":0,\"is_retry\":true,\"payload_raw\":\"MjguOTUyOTA4LDQxLjAyODUyNg==\",\"metadata\":{\"time\":\"2018-01-03T20:30:24.876104392Z\",\"frequency\":868.3,\"modulation\":\"LORA\",\"data_rate\":\"SF7BW125\",\"airtime\":71936000,\"coding_rate\":\"4/5\",\"gateways\":[{\"gtw_id\":\"eui-b827ebfffee9e43a\",\"timestamp\":975497379,\"time\":\"2018-01-03T20:30:24.628736Z\",\"channel\":1,\"rssi\":-30,\"snr\":8.8,\"rf_chain\":1,\"latitude\":41.02859,\"longitude\":28.95312}]}}","payloadType":"str","repeat":"","crontab":"","once":false,"x":302.50000762939453,"y":290.00000190734863,"wires":[["37707509.1f6e5a","dfc25552.be6be8","c9eaca60.7d3868"]]},{"id":"be465fd0.d3be","type":"debug","z":"ca6ebd5b.5b082","name":"","active":true,"console":"false","complete":"payload","x":1020.75,"y":430.24999618530273,"wires":[]},{"id":"77ad9d11.ba6fc4","type":"mqtt in","z":"ca6ebd5b.5b082","name":"MQTT Node - TheThingsNetwork","topic":"#","qos":"2","broker":"56d9cd69.f93e64","x":267.00000762939453,"y":176.24999904632568,"wires":[["37707509.1f6e5a","dfc25552.be6be8","c9eaca60.7d3868"]]},{"id":"9e1553bd.e0f5b","type":"debug","z":"ca6ebd5b.5b082","name":"","active":true,"console":"false","complete":"true","x":974.5278472900391,"y":790.7049026489258,"wires":[]},{"id":"56d9cd69.f93e64","type":"mqtt-broker","z":"ca6ebd5b.5b082","broker":"eu.thethings.network","port":"1883","clientid":"","usetls":false,"verifyservercert":true,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willRetain":"false","willPayload":"","birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":""}]

0 Likes

#12

Your node won't import - make sure to put three backtic's before and after the code
In addition, something in your comment node seems to keep it from importing.

0 Likes

#13

All "context.value"s take the value of the payload, the purpose is to preserve the values received at different times, so that the webpage can be created with all the data available.

0 Likes

#17

The node-red version is 0.17.5, but I don'know about Node.js.

0 Likes

#18

When you start node-red the version of nodejs and node-red is printed in the terminal.

0 Likes

#19

Are you running this on a Pi?
If so, the current release of NR is v0.18.7 and you should run the update script
https://nodered.org/docs/hardware/raspberrypi

0 Likes

#20

No, it is run on IBM's bluemix service.

0 Likes

#21

How did you get on with putting debug nodes to monitor the input and output and look for anomalies?

0 Likes

#22

Well, I think I already have one, and when I look it carefully, it is telling me that "flow-set"s and "flow.get"s are not really communicating with each other - all the time. Looks strange to me.
(there doesn't seem to be an issue with the data coming through MQTT, I see the messages at the end of the MQTT flow)

0 Likes

#23

Remember that the map will not update until you do a browser refresh - only then will the http In thru http out run

Could this be the 'issue' you think you have?

0 Likes