Node-RED: integrate a connected object MySensors v2 [Exclusive Guide]

4:08 pm November 11, 20166182

it is very easy to create its own connected Arduino-based objects that communicate by radio waves using the library MySensors v2 and to use them in a project Node-RED . For this tutorial, we will use a simple probe temperature and humidity (DHT22). We will post the measures temperature and humidity using the Dashboard module.

I took the code and the wiring of the previous project. You also need a network gateway (follow this tutorial to prepare ) or a gateway series.

materials

Circuit

mysensors arduino micro dht22 nrf24l01

Code

upload the following code in the Arduino Nano.

 / * * The MySensors Arduino library handles the wireless radio link protocol and * your home built between sensors/actuators and HA controller of choice.
 * The sensors forms a self healing radio network with optional repeaters. Each * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes.
 * Created by Henrik Ekblad  * Copyright (C) 2013-2015 Sensnology AB * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors * Documentation: http://www.mysensors.org * Support Forum: http://forum.mysensors.org * This program is free software; You can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation.
 * * * REVISION HISTORY * Version 1.0 - DIY PROJECTS * DESCRIPTION * Example sketch showing how-to measue light level using a photo-resistor LM393 * http://www.mysensors.org/build/light * / / / Active debug mode / Enable debug prints to serial monitor #define MY_DEBUG / / Radio Mode / Enable and select radio type attached #define MY_RADIO_NRF24 //#define MY_RADIO_RFM69 #define MY_RF24_PA_LEVEL RF24_PA_LOW / / node of the object / Object Node MY_NODE_ID 3 #include #define  #include  #include  #define CHILD_ID_TEMP 0 CHILD_ID_HUM 1 #define SLEEP_NODE true #define / / set to True to enable the implementation of sleep (Sleep Mode) / True to activate Sleep Mode unsigned long SLEEP_TIME = 10 * 1000; Time to sleep (in ms) / Sleep time between reads (in milliseconds) DHTPIN 3 #define / / pin on which the DHT is connected / what we're connected to #define DHTTYPE DHT22 pin / / DHT 22 (AM2302), DHT11 float lastTemp;
float lastHum;
Boolean metric = true; 
MsgHum (CHILD_ID_HUM, V_HUM) MyMessage;
MsgTemp (CHILD_ID_TEMP, V_TEMP) MyMessage;

void setup() {} void presentation() {/ / Presenttion of the sketch / Send the sketch version information to the gateway and Controller sendSketchInfo("Sonde Temp/Hum DHT22", "1.0");}

  Statement of the sensors attached to the node present (CHILD_ID_TEMP, S_TEMP);
  present (CHILD_ID_HUM, S_HUM);
} void loop() {DHT dht(DHTPIN, DHTTYPE,3); / / create an object of dht in the loop, otherwise the values are not measured wake up float temperature = dht.readTemperature ();}
  float humidity = dht.readHumidity ();
  If (isnan (temperature)) {Serial.println ("could not read the temperature on the DHT");
  } else {if (temperature! = lastTemp) {lastTemp = temperature;}
      If (! metric) {temperature = dht.readTemperature (true);}
      } Serial.print ("T:");
      Serial.print (temperature);
      Serial.print("|) H: ");
      Serial.println (humidity);
      send (msgTemp.set(temperature, 1));
      send (msgHum.set(humidity, 1));
    } else {Serial.println("Temperature identique => on force l'envoi");  
      Serial.print ("T:");
      Serial.print (temperature);
      Serial.print("|) H: ");
      Serial.println (humidity);
      send (msgTemp.set(temperature, 1));
      send (msgHum.set(humidity, 1));
    }} if (SLEEP_NODE) {Serial.println ("Sleep");
    sleep (SLEEP_TIME);
  } else {delay (SLEEP_TIME);
  }} 

there is an official plugin MySensor ( http://flows.nodered.org/node/node-red-contrib-mysensors ). For this project, I suggest you use the flow that I developed and published on the Node-RED online bookshop ( http://flows.nodered.org/flow/fa02078c160cb3e00e09f4980b534490 ). He is responsible for decoding the messages MySensors and referral output a JSON object. It is easier to filter values you want for a given node. (

code of the flow MySensors Decoder

 [{"id":"f4fd4940.32ba8","type":"function","z":"eb4ead14.fd77f","name":"Decode MySensor Message","func":"/* MySensors v2 Message Decodern*  Payload : JSON objectn*  www.projetsdiy.fr - oct. 2016n*/nvar mySensorsMessage = {}nvar newPayload = {};nvar message = msg.payload.toString();nmessage = message.replace(/(\r\n|\n|\r)/gm, "");nvar tokens = message.split(";")nif(tokens.length == 6)n{n    mySensorsMessage.nodeId =       parseInt(tokens[0]); n mySensorsMessage.childSensorId = parseInt(tokens[1]); n mySensorsMessage.messageType = parseInt(tokens[2]); n mySensorsMessage.ack = parseInt(tokens[3]); n mySensorsMessage.subType = parseInt(tokens[4]); n mySensorsMessage.value = Number(tokens[5]); nn var messageType = mySensorsMessage.messageType; n var subType = mySensorsMessage.subType; n var labelPresentation = ["S_DOOR","S_MOTION","S_SMOKE","S_LIGHT","S_BINARY","S_DIMMER","S_COVER","S_TEMP","S_HUM","S_BARO","S_WIND","S_RAIN","S_UV","S_WEIGHT","S_POWER","S_HEATER","S_DISTANCE","S_LIGHT_LEVEL","S_ARDUINO_NODE","S_ARDUINO_REPEATER_NODE","S_LOCK","S_IR","S_WATER","S_AIR_QUALITY","S_CUSTOM","S_DUST","S_SCENE_CONTROLLER","S_RGB_LIGHT","S_RGBW_LIGHT","S_COLOR_SENSOR","S_HVAC","S_MULTIMETER","S_SPRINKLER","S_WATER_LEAK","S_SOUND","S_VIBRATION","S_MOISTURE","S_INFO","S_GAS","S_GPS","S_WATER_QUALITY"]; n var labelSet = ["V_TEMP","V_HUM","V_STATUS","V_LIGHT","V_PERCENTAGE","V_DIMMER","V_PRESSURE","V_FORECAST","V_RAIN","V_RAINRATE","V_WIND","V_GUST","V_DIRECTION","V_UV","V_WEIGHT","V_DISTANCE","V_IMPEDANCE","V_ARMED","V_TRIPPED","V_WATT","V_KWH","V_SCENE_ON","V_SCENE_OFF","V_HVAC_FLOW_STATE","V_HVAC_SPEED","V_LIGHT_LEVEL","V_VAR1","V_VAR2","V_VAR3","V_VAR4","V_VAR5","V_UP","V_DOWN","V_STOP","V_IR_SEND","V_IR_RECEIVE","V_FLOW","V_VOLUME","V_LOCK_STATUS","V_LEVEL","V_VOLTAGE","V_CURRENT","V_RGB","V_RGBW","V_ID","V_UNIT_PREFIX","V_HVAC_SETPOINT_COOL","V_HVAC_SETPOINT_HEAT","V_HVAC_FLOW_MODE","V_TEXT","V_CUSTOM","V_POSITION","V_IR_RECORD","V_PH","V_ORP","V_EC","V_VAR","V_VA","V_POWER_FACTOR"] n var labelInternal = ["I_BATTERY_LEVEL","I_TIME","I_VERSION","I_ID_REQUEST","I_ID_RESPONSE","I_INCLUSION_MODE","I_CONFIG","I_FIND_PARENT","I_FIND_PARENT_RESPONSE","I_LOG_MESSAGE","I_CHILDREN","I_SKETCH_NAME","I_SKETCH_VERSION","I_REBOOT","I_GATEWAY_READY","I_REQUEST_SIGNING","I_GET_NONCE","I_GET_NONCE_RESPONSE","I_HEARTBEAT","I_PRESENTATION","I_DISCOVER","I_DISCOVER_RESPONSE","I_HEARTBEAT_RESPONSE","I_LOCKED","I_PING","I_PONG","I_REGISTRATION_REQUEST","I_REGISTRATION_RESPONSE","I_DEBUG"] n n switch (messageType) {n box 0 : / / Presentationn n newPayload.mode = "Presentation";n newPayload.type = labelPresentation [subType]; n break; n case 1: / / Setn newPayload.nodeId = mySensorsMessage.nodeId; newPayload.sensorId = n mySensorsMessage.childSensorId; n newPayload.mode = "Set";n newPayload.type = subType; n newPayload.typeLabel = labelSet [subType]; n newPayload.value = mySensorsMessage.value; n break; n case 2: / / Reqn newPayload.nodeId = mySensorsMessage.nodeId; newPayload.sensorId = n mySensorsMessage.childSensorId; n newPayload.mode = "Req";n newPayload.type = subType; n newPayload.typeLabel = labelSet [subType]; n newPayload.value = mySensorsMessage.value; n break;  n case 3: / / Internaln newPayload.nodeId = mySensorsMessage.nodeId; newPayload.sensorId = n mySensorsMessage.childSensorId; n newPayload.mode = "Internal";n newPayload.type = subType; n newPayload.typeLabel = labelInternal [subType]; n newPayload.value = mySensorsMessage.value; n break;    {n box 4: / / Stream - OTA firmware updaten newPayload.nodeId = mySensorsMessage.nodeId; newPayload.mode = "stream";n n break; n default:n break; n} nn msg.payload = newPayload; n} else {n msg.payload = "Error! [{[Nothingtodecode"n}nnreturnmsg;""outputs":1"noerr":0"x":3945555419921875"y":2795555725097656"wires":[["22cb3401.ef7e24","2d12c5a2.7304aa","fd30fa09.244ce8"]]}] 

connect to a Gateway network MySensors from Node-RED

to connect to a network MySensors gateway, we will use the Protocol tcp (filed in Input).

node-red tcp mysensors lan gateway

set up the Node like this:

  • Type: Connect To
  • Port: 5003 (by default, otherwise the port you configured for your gateway)
  • at host : ip address of the gateway
  • Output : stream of / string
  • you can also change the name displayed on the flow.
  • click Done to save the configuration

you can now connect the bridge to message decoder. By plugging a debug Node, you can read very easily all the (decoded) messages that pass over the network MySensors!

node-red tcp mysensors lan gateway settings parametres

watch the measures go in the log, it is good, but there for to be a little better! Let’s add a GUI to our project Node-RED. Open the palette Manager. It opens to the left of the screen. Go to the Install tab and install the Dashboard module. Refresh browser at the end of the installation page that the palette is displayed (bottom).

now let’s add a function that filters as you want to display from the DHT22 node. Paste this code

 if (msg.payload.nodeId == 3 & msg.payload.type = 0) {var msg;}
    Msg.payload = msg.payload.value;
    return msg;
} 

in this case, we don’t reference the value (value) that if the message comes from the node 3 (nodeId == 3) and that it is a type 0 (temperature, V_TEMP) or 1 (moisture, V_HUM).

from the palette dashboard drop one gauge and set up like this.

node-red dashboard gauge

must be already created one Tab . It is a WEB page. Moving from one page to the other from the menu in the upper left corner.

node-red mysensors dht22 dashboard tab

then one Group. Can be grouped views (switches, gauge, graph, form…) by (Group).

node-red mysensors dht22 dashboard group

Finally you can adjust the display settings of the gauge. There are 4 types of display:

  • Gauge
  • Donut
  • Compass
  • Level

node-red mysensors dht22 dashboard gauge

also add a chart. It works on the same principle. It must associate it with the Group a Tab

node-red mysensors dht22 dashboard graph

do the same for moisture measurement. Here is the completed flow.

node-red mysensors dht22 dashboard flow

now, to open a new page in the browser and enter the following address

 IP_NODE_RED:1880 / ui 

and so, now you have a graphical display of your DHT22 MySensors probe in a few minutes!

node-red mysensors dht22 dashboard

you don’t like blue, no problem. Turn on Node-RED. Go to the dashboard tab located next to the debug tab. In the Theme list, choose Dark and deploy the project.

node-red mysensors dht22 dashboard theme

return to the UI page for your project!

node-red mysensors dht22 dashboard black

you can also directly import this flow if you do not complete all the steps of this tutorial. {[

 [{"id":"4c979a2.0f86f64","type":"tcp in","z":"5c2ea4a9.8713cc","name":"MySensors Gateway","server":"client","host":"192.168.1.20","port":"5003","datamode":"stream","datatype":"utf8","newline":"","topic":"","base64":false,"x":154.00001525878906,"y":296,"wires":[["7710e899.e4b198"]]}, {"id": "7710e899.e4b198", "type": "function", "z": "5c2ea4a9.8713cc", "name": "Decode MySensor Message", "func": "/ * MySensors v2 Message Decodern * Payload: JSON objectn * www.projetsdiy.fr - oct."} 2016n * / nvar mySensorsMessage = {nvar newPayload = {}; message = msg.payload.toString();nmessage = message.replace(/(\r\n|\n|\r)/gm, "");nvar = message.split(";")nif(tokens.length tokens nvar is 6) n {n mySensorsMessage.nodeId = parseInt(tokens[0]); n mySensorsMessage.childSensorId = parseInt(tokens[1]); n mySensorsMessage.messageType = parseInt(tokens[2]); n mySensorsMessage.ack = parseInt(tokens[3]); n mySensorsMessage.subType = parseInt(tokens[4]); n mySensorsMessage.value = Number(tokens[5]); nn var messageType = mySensorsMessage.messageType; n var subType = mySensorsMessage.subType; n var labelPresentation = ["S_DOOR","S_MOTION","S_SMOKE","S_LIGHT","S_BINARY","S_DIMMER","S_COVER","S_TEMP","S_HUM","S_BARO","S_WIND","S_RAIN","S_UV","S_WEIGHT","S_POWER","S_HEATER","S_DISTANCE","S_LIGHT_LEVEL","S_ARDUINO_NODE","S_ARDUINO_REPEATER_NODE","S_LOCK","S_IR","S_WATER","S_AIR_QUALITY","S_CUSTOM","S_DUST","S_SCENE_CONTROLLER","S_RGB_LIGHT","S_RGBW_LIGHT","S_COLOR_SENSOR","S_HVAC","S_MULTIMETER","S_SPRINKLER","S_WATER_LEAK","S_SOUND","S_VIBRATION","S_MOISTURE","S_INFO","S_GAS","S_GPS","S_WATER_QUALITY"]; n var labelSet = ["V_TEMP","V_HUM","V_STATUS","V_LIGHT","V_PERCENTAGE","V_DIMMER","V_PRESSURE","V_FORECAST","V_RAIN","V_RAINRATE","V_WIND","V_GUST","V_DIRECTION","V_UV","V_WEIGHT","V_DISTANCE","V_IMPEDANCE","V_ARMED","V_TRIPPED","V_WATT","V_KWH","V_SCENE_ON","V_SCENE_OFF","V_HVAC_FLOW_STATE","V_HVAC_SPEED","V_LIGHT_LEVEL","V_VAR1","V_VAR2","V_VAR3","V_VAR4","V_VAR5","V_UP","V_DOWN","V_STOP","V_IR_SEND","V_IR_RECEIVE","V_FLOW","V_VOLUME","V_LOCK_STATUS","V_LEVEL","V_VOLTAGE","V_CURRENT","V_RGB","V_RGBW","V_ID","V_UNIT_PREFIX","V_HVAC_SETPOINT_COOL","V_HVAC_SETPOINT_HEAT","V_HVAC_FLOW_MODE","V_TEXT","V_CUSTOM","V_POSITION","V_IR_RECORD","V_PH","V_ORP","V_EC","V_VAR","V_VA","V_POWER_FACTOR"] n var labelInternal = ["I_BATTERY_LEVEL","I_TIME","I_VERSION","I_ID_REQUEST","I_ID_RESPONSE","I_INCLUSION_MODE","I_CONFIG","I_FIND_PARENT","I_FIND_PARENT_RESPONSE","I_LOG_MESSAGE","I_CHILDREN","I_SKETCH_NAME","I_SKETCH_VERSION","I_REBOOT","I_GATEWAY_READY","I_REQUEST_SIGNING","I_GET_NONCE","I_GET_NONCE_RESPONSE","I_HEARTBEAT","I_PRESENTATION","I_DISCOVER","I_DISCOVER_RESPONSE","I_HEARTBEAT_RESPONSE","I_LOCKED","I_PING","I_PONG","I_REGISTRATION_REQUEST","I_REGISTRATION_RESPONSE","I_DEBUG"] n n switch (messageType) {n box} 0: / / Presentationn n newPayload.mode = "Presentation";n newPayload.type = labelPresentation [subType]; n break; n case 1: / / Setn newPayload.nodeId = mySensorsMessage.nodeId; newPayload.sensorId = n mySensorsMessage.childSensorId; n newPayload.mode = "Set";n newPayload.type = subType; n newPayload.typeLabel = labelSet [subType]; n newPayload.value = mySensorsMessage.value; n break; n case 2: / / Reqn newPayload.nodeId = mySensorsMessage.nodeId; newPayload.sensorId = n mySensorsMessage.childSensorId; n newPayload.mode = "Req";n newPayload.type = subType; n newPayload.typeLabel = labelSet [subType]; n newPayload.value = mySensorsMessage.value; n break;  n case 3: / / Internaln newPayload.nodeId = mySensorsMessage.nodeId; newPayload.sensorId = n mySensorsMessage.childSensorId; n newPayload.mode = "Internal";n newPayload.type = subType; n newPayload.typeLabel = labelInternal [subType]; n newPayload.value = mySensorsMessage.value; n break;    {n box 4: / / Stream - OTA firmware updaten newPayload.nodeId = mySensorsMessage.nodeId; newPayload.mode = "stream";n n break; n default:n break; n} nn msg.payload = newPayload; n} else {n msg.payload = "Error! {[Nothingtodecode"n}nnreturnmsg;""outputs":1"noerr":0"x":29166668701171875"y":4246278991699219"wires":[["f10887ac.6a2f28","e4304f11.8e755","3c923a76.ea6cb6"]]}, {"id": "f10887ac.6a2f28", "type": "function", "z": "5c2ea4a9.8713cc", "name": "filter: temperature node 3", "func": "if (msg.payload.nodeId == 3 & msg.payload.type = 0) {n var msg; n msg.payload = msg.payload.value;n return msg; n}","outputs": 1, "noerr": 0, "x":574.5, "y": 394, "wires": [["7a1e3f92.b811d","f8fdeb6d.dcb858"]]}, {"id": "7a1e3f92.b811d", "type": "ui_gauge", "z": "5c2ea4a9.8713cc", "name": "Température"} {, 'group': "febe591f.8ca1f8", "order": 0, "width": 0, "height": 0, "gtype": "gage", "title": "DHT22 Température", "label": "MySensors v2","size": "{{value}} ° C","min": 0, "max": "50", "colors": ["#00b500","#e6e600","#ca3838"], "x":825.5, "y": 358, "wires": []}, {"id": "e4304f11.8e755", "type": "function", "z": "5c2ea4a9.8713cc", "name": "filter: moisture node 3", "func": "if (msg.payload.nodeId == 3 & msg.payload.type = 1) {n var msg; n msg.payload = msg.payload.value;n return msg; n}","outputs": 1, "noerr": 0, "x":564.8888549804688, "y":455.92767333984375} ,"wires":[["8e065da0.32b5f","e22f8ceb.eecbb"]]},{"id":"8e065da0.32b5f","type":"ui_gauge","z":"5c2ea4a9.8713cc","name":"Humidité","group":"febe591f.8ca1f8","order":0,"width":"0","height":"0","gtype":"gage","title":"Humidité DHT22","label":"MySensors v2","format":"{{value}}%","min":0,"max":"100","colors":["#1a25ab","#e6e600","#ca3838"],"x":811.8888549804688,"y":466.92767333984375,"wires":[]},{"id":"f8fdeb6d.dcb858","type":"ui_chart","z":"5c2ea4a9.8713cc","name":"Température","group":"45ccf5ba.b188ac","order":0,"width":0,"height":0,"label":"Température","chartType":"line","legend":"false","xformat":"%H :%M","interpolate":"linear","nodata":"","ymin":"0","ymax":"50","removeOlder":1,"removeOlderUnit":"3600","x":827.5,"y":413,"wires":[[],[]]},{"id":"e22f8ceb.eecbb","type":"ui_chart","z":"5c2ea4a9.8713cc","name":"Humidité","group":"45ccf5ba.b188ac","order":0,"width":0,"height":0,"label":"Humidité","chartType":"line","legend":"false","xformat":"%H:%M","interpolate":"linear","nodata":"","ymin":"0","ymax":"100","removeOlder":1,"removeOlderUnit":"3600","x":808,"y":514,"wires":[[],[]]},{"id" :"3c923a76.ea6cb6","type":"debug","z":"5c2ea4a9.8713cc","name":"Message décodé","active":true,"console":"false","complete":"payload","x":484.5,"y":295,"wires":[]},{"id":"febe591f.8ca1f8","type":"ui_group","z":"","name":"Mesures","tab":"99f501d2.56c31","disp":true,"width":"6"},{"id":"45ccf5ba.b188ac","type":"ui_group","z":"","name":"Graphiques","tab":"99f501d2.56c31","disp":true,"width":"6"},{"id":"99f501d2.56c31","type":"ui_tab","z":"","name":"Salon","icon":"dashboard"}]

Node-RED est vraiment magique , nothing prevents you to design your own home automation software and much more!

other items to go further with Node-RED: