Page 1 of 1

NodeRed dust sensor [Solved]

Posted: Sunday 09 August 2020 9:56
by Jan Jansen
I have built a dust sensor (luftdaten.info) for indoor measurements. I want to get the data from the sensor in Domoticz via NodeRed. I am getting a stubborn red cross (line 52) in the function node. It seems simple, but I don’t get it.
Nodered fijnstof.png
Nodered fijnstof.png (60.83 KiB) Viewed 3137 times
Flow

Code: Select all

[{"id":"19594397.bed464","type":"tab","label":"Fijnstofsensor","disabled":false,"info":""},{"id":"34a357ee.159808","type":"http request","z":"19594397.bed464","name":" htttp Fijnstofsensor","method":"GET","ret":"obj","paytoqs":false,"url":"http://192.168.0.xxx/data.json","tls":"","persist":false,"proxy":"","authType":"","x":310,"y":120,"wires":[["e52e6090.66eb98","f15ff936.df9af"]]},{"id":"f9aaf097.2d524","type":"inject","z":"19594397.bed464","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":100,"y":120,"wires":[["34a357ee.159808"]]},{"id":"134d0e98.aa2a41","type":"mqtt out","z":"19594397.bed464","name":"Domoticz in","topic":"domoticz/in","qos":"","retain":"","broker":"78502dcb.64644c","x":810,"y":120,"wires":[]},{"id":"e52e6090.66eb98","type":"debug","z":"19594397.bed464","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":460,"y":300,"wires":[]},{"id":"f15ff936.df9af","type":"function","z":"19594397.bed464","name":"Naar Domoticz","func":"var msg1 ={}; // PM10 Alert\nvar msg2 ={}; // PM2.5 Alert\nvar msg3 ={}; // Temp/Hum\nvar msg4 ={}; // PM10 sensor\nvar msg5 ={}; // PM2.5 sensor\n\nfunction PM10level(x) {\n\nif (x < 5) {\n  return 0;\n} else if (x < 20) {\n  return 1;\n} else if (x < 30 ) {\n  return 2;\n} else if (x < 20 ) {\n  return 3;  \n} else {\n  return 4;\n}\n}\n\nfunction PM2level(y) {\n\nif (y < 3) {\n  return 0;\n} else if (y < 10) {\n  return 1;\n} else if (y < 15 ) {\n  return 2;\n} else if (y < 20 ) {\n  return 3;  \n} else {\n  return 4;\n}\n}\n\nfunction HUMlevel(z) {\n\n if (z <= 45 && z >= 30) {\n  return 0;\n} else if (z <= 70 && z >= 45 ){\n  return 1      \n} else if (z <30) {\n  return 2;\n} else {\n  return 3;\n}\n}\n\nmsg1.payload = {\"command\":\"udevice\",\"idx\":108,\"nvalue\":PM10level(msg.payload.sensordatavalues[0].value),\"svalue\":msg.payload.sensordatavalues[0].value.toFixed(2).toString() + \"µg/m³\"};\nmsg2.payload = {\"command\":\"udevice\",\"idx\":107,\"nvalue\":PM25level(msg.payload.sensordatavalues[1].value),\"svalue\":msg.payload.sensordatavalues[1].value.toFixed(2).toString() + \"µg/m³\"};\nmsg3.payload = {\"command\":\"udevice\",\"idx\":109,\"svalue\":msg.payload.sensordatavalues[2].value.toFixed(2).toString();msg.payload.sensordatavalues[3].value.toFixed(2).toString();HUMlevel(msg.payload.sensordatavalues[3].value)};\nmsg4.payload = {\"command\":\"udevice\",\"idx\":105,\"svalue\":msg.payload.sensordatavalues[0].value.toFixed(2).toString()};\nmsg5.payload = {\"command\":\"udevice\",\"idx\":104,\"svalue\":msg.payload.sensordatavalues[1].value.toFixed(2).toString()};\n\n\n\nreturn [[msg1,msg2,msg3,msg4,msg5]];","outputs":1,"noerr":6,"x":560,"y":120,"wires":[["134d0e98.aa2a41"]]},{"id":"78502dcb.64644c","type":"mqtt-broker","z":"","name":"Domoticz","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]
Thanks in advance for your help!

Re: NodeRed dust sensor

Posted: Sunday 09 August 2020 14:42
by FireWizard
@Jan Jansen

You wrote:
It seems simple, but I don’t get it
It is simple, but if you don't see it, you can look for it for hours.

Let me explain.

You want to send the data of multiple sensors to Domoticz.

I don't know the sensor, you have created, but as an example I take Temperature+Barometer.
The command you have to send for this sensor is: {"command":"udevice", "idx":1234, "svalue":"tm;ba;pr"}, where tm is the temperature, ba is the pressure and pr is the prediction.

You see that the value for "svalue" has to be a string (between " ")
You have to take care that the values are a string. You did that by adding after each value "toString", but you did not for the semicolon (;), which is also part of the string. The semicolon acts as a separator in the string, but has to be within quotes and concatenated with the other values.

The second thing, I discovered, is that your last value, which has to be also a string, is missing toString, so I suggest to add that as well, however the errors were gone, when I corrected the semicolon issue, but It may not function correct without the "toString". I cannot test this.
The result of the HUMlevel function is a number and not a string.

So change:

Code: Select all

msg3.payload = {"command":"udevice","idx":109,"svalue":msg.payload.sensordatavalues[2].value.toFixed(2).toString();msg.payload.sensordatavalues[3].value.toFixed(2).toString();HUMlevel(msg.payload.sensordatavalues[3].value)};
into

Code: Select all

msg3.payload = {"command":"udevice","idx":109,"svalue":msg.payload.sensordatavalues[2].value.toFixed(2).toString() + ";" + msg.payload.sensordatavalues[3].value.toFixed(2).toString() + ";" + HUMlevel(msg.payload.sensordatavalues[3].value.toString())};
I'm sure, you will not forget this anymore

Best regards

Re: NodeRed dust sensor

Posted: Sunday 09 August 2020 15:29
by Jan Jansen
@FireWizard,

Thanks for your quick answer and it's explanation. I have been staring for a long time indeed.
If I understand correctly + HUMlevel(msg.payload.sensordatavalues[3].value.toString())
still needs to be changed to >> + HUMlevel(msg.payload.sensordatavalues[3].value.toNumber())

The red cross is now gone, this error message came in its place "TypeError: msg.payload.sensordatavalues[0].value.toFixed is not a function"

I first thought it may have to do with the arrays. I found https://www.domoticz.com/forum/viewtopi ... ed#p224337 But it didn't bring me to a solution.

Thanks in advance
Jan

Re: NodeRed dust sensor

Posted: Sunday 09 August 2020 16:58
by FireWizard
Hello jan,

@Jan Jansen

You asked:
If I understand correctly + HUMlevel(msg.payload.sensordatavalues[3].value.toString())
still needs to be changed to >> + HUMlevel(msg.payload.sensordatavalues[3].value.toNumber())
No, your function, called HUMlevel produces a number (0,1, 2 or3). This number should be converted to a string.
However I see now, that I have a bracket incorrectly placed.

The line should be:

Code: Select all

msg3.payload = {"command":"udevice","idx":109,"svalue":msg.payload.sensordatavalues[2].value.toFixed(2).toString() + ";" + msg.payload.sensordatavalues[3].value.toFixed(2).toString() + ";" + HUMlevel(msg.payload.sensordatavalues[3]).toString()};
The red cross is now gone,
By correcting the semicolon issue the "red cross" disappears, as there are no syntax error anymore, but errors may appear.

Obviously
this error message came in its place "TypeError: msg.payload.sensordatavalues[0].value.toFixed is not a function"
This is the first msg (msg1) on line 50.
If you have solved this, you will get the next one, as this happens 7 times.

I have seen the link before, but where does "msg.payload.sensordatavalues[3].value" come from.
If you have questions about that flow, do not hesitate to ask.

I think that .value should not be there.

I have removed it, in the flow below.
If this doesn't work can you publish a screenshot of the debug node, which is connected to the http node?
But have also a look at line 15. This one is the same as line 11. And so line 15 will never be executed.

New flow:

Code: Select all

[{"id":"882d6476.13fee8","type":"http request","z":"22c784ae.68b6cc","name":" htttp Fijnstofsensor","method":"GET","ret":"obj","paytoqs":false,"url":"http://192.168.0.xxx/data.json","tls":"","persist":false,"proxy":"","authType":"","x":310,"y":120,"wires":[["43d7727f.ae131c","6719311c.7a8498"]]},{"id":"5fc93cfe.8359dc","type":"inject","z":"22c784ae.68b6cc","name":"","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":100,"y":120,"wires":[["882d6476.13fee8"]]},{"id":"1eb89c85.efbe5b","type":"mqtt out","z":"22c784ae.68b6cc","name":"Domoticz in","topic":"domoticz/in","qos":"","retain":"","broker":"28f2a34.5e04cdc","x":810,"y":120,"wires":[]},{"id":"43d7727f.ae131c","type":"debug","z":"22c784ae.68b6cc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":460,"y":300,"wires":[]},{"id":"6719311c.7a8498","type":"function","z":"22c784ae.68b6cc","name":"Naar Domoticz","func":"var msg1 ={}; // PM10 Alert\nvar msg2 ={}; // PM2.5 Alert\nvar msg3 ={}; // Temp/Hum\nvar msg4 ={}; // PM10 sensor\nvar msg5 ={}; // PM2.5 sensor\n\nfunction PM10level(x) {\n\nif (x < 5) {\n  return 0;\n} else if (x < 20) {\n  return 1;\n} else if (x < 30 ) {\n  return 2;\n} else if (x < 20 ) {\n  return 3;  \n} else {\n  return 4;\n}\n}\n\nfunction PM2level(y) {\n\nif (y < 3) {\n  return 0;\n} else if (y < 10) {\n  return 1;\n} else if (y < 15 ) {\n  return 2;\n} else if (y < 20 ) {\n  return 3;  \n} else {\n  return 4;\n}\n}\n\nfunction HUMlevel(z) {\n\n if (z <= 45 && z >= 30) {\n  return 0;\n} else if (z <= 70 && z >= 45 ){\n  return 1      \n} else if (z <30) {\n  return 2;\n} else {\n  return 3;\n}\n}\n\nmsg1.payload = {\"command\":\"udevice\",\"idx\":108,\"nvalue\":PM10level(msg.payload.sensordatavalues[0]),\"svalue\":msg.payload.sensordatavalues[0].toFixed(2).toString() + \"µg/m³\"};\nmsg2.payload = {\"command\":\"udevice\",\"idx\":107,\"nvalue\":PM25level(msg.payload.sensordatavalues[1]),\"svalue\":msg.payload.sensordatavalues[1].toFixed(2).toString() + \"µg/m³\"};\nmsg3.payload = {\"command\":\"udevice\",\"idx\":109,\"svalue\":msg.payload.sensordatavalues[2].toFixed(2).toString() + \";\" + msg.payload.sensordatavalues[3].toFixed(2).toString() + \";\" + HUMlevel(msg.payload.sensordatavalues[3]).toString()};\nmsg4.payload = {\"command\":\"udevice\",\"idx\":105,\"svalue\":msg.payload.sensordatavalues[0].toFixed(2).toString()};\nmsg5.payload = {\"command\":\"udevice\",\"idx\":104,\"svalue\":msg.payload.sensordatavalues[1].toFixed(2).toString()};\n\n\n\nreturn [[msg1,msg2,msg3,msg4,msg5]];","outputs":1,"noerr":0,"initialize":"","finalize":"","x":560,"y":120,"wires":[["1eb89c85.efbe5b"]]},{"id":"28f2a34.5e04cdc","type":"mqtt-broker","z":"","name":"Domoticz","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]
Looking forward to the result.

Best regards

Re: NodeRed dust sensor

Posted: Sunday 09 August 2020 17:14
by Jan Jansen
@FireWizard,

This error is displayed after installing your last Flow

TypeError: msg.payload.sensordatavalues[0].toFixed is not a function

Jan

Re: NodeRed dust sensor

Posted: Sunday 09 August 2020 17:19
by FireWizard
@Jan Jansen

Can you send a screenshot of the debug node, connected to the http node?

Oh sorry, I see it in the first post.
Is this correct?

Regards

Re: NodeRed dust sensor

Posted: Sunday 09 August 2020 18:25
by Jan Jansen
FireWizard wrote: Sunday 09 August 2020 17:19 Oh sorry, I see it in the first post.
Is this correct?
Yes it is correct

Re: NodeRed dust sensor

Posted: Sunday 09 August 2020 18:56
by FireWizard
@Jan Jansen

I created a simulation, that gives exactly the same output, as in your first post.

Can you replace the code in the function node by the code below:

Code: Select all

var msg1 ={}; // PM10 Alert
var msg2 ={}; // PM2.5 Alert
var msg3 ={}; // Temp/Hum
var msg4 ={}; // PM10 sensor
var msg5 ={}; // PM2.5 sensor

function PM10level(x) {

if (x < 5) {
  return 0;
} else if (x < 20) {
  return 1;
} else if (x < 30 ) {
  return 2;
} else if (x < 20 ) {
  return 3;  
} else {
  return 4;
}
}

function PM25level(y) {

if (y < 3) {
  return 0;
} else if (y < 10) {
  return 1;
} else if (y < 15 ) {
  return 2;
} else if (y < 20 ) {
  return 3;  
} else {
  return 4;
}
}

function HUMlevel(z) {

 if (z <= 45 && z >= 30) {
  return 0;
} else if (z <= 70 && z >= 45 ){
  return 1      
} else if (z <30) {
  return 2;
} else {
  return 3;
}
}

msg1.payload = {"command":"udevice","idx":108,"nvalue":PM10level(msg.payload.sensordatavalues[0].value),"svalue":msg.payload.sensordatavalues[0].value + "µg/m³"};
msg2.payload = {"command":"udevice","idx":107,"nvalue":PM25level(msg.payload.sensordatavalues[1].value),"svalue":msg.payload.sensordatavalues[1].value + "µg/m³"};
msg3.payload = {"command":"udevice","idx":109,"svalue":msg.payload.sensordatavalues[2].value + ";" + msg.payload.sensordatavalues[3].value + ";" + HUMlevel(msg.payload.sensordatavalues[3].value)};
msg4.payload = {"command":"udevice","idx":105,"svalue":msg.payload.sensordatavalues[0].value};
msg5.payload = {"command":"udevice","idx":104,"svalue":msg.payload.sensordatavalues[1].value};



return [[msg1,msg2,msg3,msg4,msg5]];

As said, you should look to the value in line 15 (value 20 might not be correct, as it is equal to the value in line 11)

Awaiting your results.

Regards

Re: NodeRed dust sensor

Posted: Sunday 09 August 2020 19:57
by Jan Jansen
@FireWizard,

Thank you very much, it works as desired!

Regards
Jan