Les objets MySensors communiquent entre eux sous la forme de petits messages envoyés par ondes radio. Il est très facile de décoder les messages en suivants les spécifications techniques de l’API série disponible sur le site officiel du projet.
Dernière mise à jour : 25 mars 2020
La librairie MySensors permet de faciliter le développement d’applications en tout genre (mobile, robotique, domotique) sans avoir à gérer la couche de communication entre les appareils. Nous allons utiliser Node-RED pour décoder les messages reçus par une gateway réseau ou série. Pour vous connecter à un réseau d’objets MySensors, vous aurez besoin d’une Gateway réseau WiFi. Suivez ce tutoriel pour en fabriquer une avec un ESP8266 avant d’aller plus loin.
Pour en savoir plus sur la librairie MySensors, vous pouvez commencer par lire cet article.
Sommaire
Structure d’un message MySensors (API)
MySensors communique avec de petits messages de 32 bytes (la taille maximale des messages envoyés par une puce nRF24L01). L’entête (header) du message d’une taille de 7 bytes est constitué ainsi :
node-id ; child-sensor-id ; message-type ; ack ; sub-type ; payload \n
- node-id : le numéro du noeud.
- child-sensor-id : l’identifiant d’un enfant. Par exemple la température mesurée par un capteur DHT22.
- message-type : type de message
- 0. Présentation du noeud. Il est envoyé lors de l’exécution de la fonction presentation() au démarrage du noeud
- 1. Set. Envoi de données par un capteur
- 2. Req. Demande à un actionneur d’executer la commande demandée
- 3. Internal. Message interne
- 4. Stream. Utilisé pour la mise à jour sans fil (OTA)
- ack : demande d’accusé réception (ou accusé reception)
- sub-type : le sous-type dépend du message-type
- payload : contenu du message. Il est limité à 25 bytes.
25 bytes peut sembler faible, mais le nRF24L01 n’est pas conçu pour transmettre de grands messages, plutôt des états ou des mesures physiques.
Cas des messages MQTT
Les messages MQTT ont une structure similaire. Le prefix peut être personnalisé dans le sketch Arduino.
prefix/node-id/child-sensor-id/message-type/ack/sub-type + payload
Comment se connecter à une gateway MySensors depuis Node-RED
On dispose de trois types de gateway MySensors. La serial gateway qui se branche sur le port USB d’un ordinateur ou d’un Raspberry. Elle est pratique pour débuter et lire les messages de debug envoyés sur le port série (par exemple avec le moniteur série de l’IDE Arduino). La passerelle réseau est maintenant très simple (et pas cher) à fabriquer à l’aide d’un ESP8266 (toutes les explications dans cet article). On peut l’installer (la cacher !) dans en endroit ou la réception radio est meilleure et on ne monopolise pas un port USB du Raspberry Pi.
Serial gateway, passerelle série connectée sur le port USB
Pour se connecter à une passerelle série, ajoutez un Node serial (dans Input)
Ouvrez le pour le configurer et appuyez sur le crayon pour configurer le port série. Appuyez sur la loupe et choisissez le port USB sur lequel est branché la gateway. Par exemple /dev/ttyUSB0.
Par défaut, la vitesse de communication avec la gateway est de 115200 bauds. Laissez la configuration par défaut. 8 bits Data, Parity None, Stop Bits 1.
Enregistrez la configuration en appuyant sur Done.
LAN Gateway, pour se connecter à une passerelle sur le réseau WiFi
Pour se connecter à une passerelle réseau, nous allons utiliser un Node TCP
Configurez la connexion ainsi :
- Type : Connect to
- Port : 5003 par défaut (à adapter à votre configuration)
- at host : l’adresse ip de la gateway réseau
- output : stream of … String
- Donnez un nom
- Enregistrez avec Done
Gateway MQTT
Dernière solution, utiliser un broker MQTT. Rien de bien compliqué ici, il suffit de se connecter au broker MQTT comme d’habitude.
Installer le plugin node-red-contrib-mysensors pour Node-RED
Le plugin node-red-contrib-mysensors développé par Thomas Mørch permet de décoder et d’envoyer des messages à un réseau d’objets MySensors. Le Plugin MySensors peut également d’enregistrer les états et les mesures dans une base de données sqlite.
Ouvrez le gestionnaire de palette de Node-RED
Faites une recherche sur le mot clé sqlite
Ensuite, vous pouvez installer le plugin mysensor. Vous trouverez 2 plugins :
-
node-red-contrib-mysensors, permet de décoder et d’envoyer des messages MySensors
- node-red-contrib-virtual-mysensors, permet de créer des objets MySensors virtuels pour tester votre flow sans avoir d’objet à disposition
Vous disposer maintenant d’une nouvelle palette appelée mysensors. Elle est constituée de cinq Nodes
- mysdecode : décode les messages MySensors
- mysencode : encodeur un message MySensors
- mysencap : prépare le message à envoyer au noeud
- mysdebug : affiche le message MySensors brut
- myscontroller : permet d’enregistrer dans une base de données sqlite l’activité des noeuds MySensors
Fonction mysdebug
Partons par la fin pour une fois. La fonction mysdebug permet de décoder et de rendre plus lisible les messages reçus en envoyés par la gateway. Chaque code est remplacé par sa signification.
Messages décodés affichés dans la console. Tout n’est pas correctement décodé (dans la version actuelle du plugin).
Comment utiliser la fonction mysdecode
Cette fonction permet de décoder les messages MySensors. Pour l’utiliser, il suffit de la brancher à une gateway (série, réseau ou MQTT). En sortie (payload), on récupère directement le payload de chaque message. Chaque information disponible est publiée sur un flux différent :
- msg.payload : contenu du message (payload) envoyé par le noeud
- msg.nodeId : noeud d’origine du message
- msg.childSensorId : Id de l’enfant attaché au noeud
- msg.messageType : type de message
- msg.ack : demande d’accusé réception
- msg.subType : sous-type de message
Cette architecture présente des avantages et des inconvénients. On récupère directement en sortie le payload de chaque message mais cela peut rapidement devenir compliqué pour filtrer les données de tel ou tel capteur.
Messages décodés affichés dans la console.
Code du flow
[{"id":"62351421.a2a7ec","type":"serial in","z":"eb4ead14.fd77f","name":"MySensors Serial Gateway","serial":"219cc581.f9b252","x":145.6666717529297,"y":134.66666412353516,"wires":[["2027984.714eb68","d8174c63.f752a"]]},{"id":"893c2411.1181e8","type":"debug","z":"eb4ead14.fd77f","name":"","active":false,"console":"false","complete":"payload","x":559,"y":35,"wires":[]},{"id":"d8174c63.f752a","type":"mysdecenc","z":"eb4ead14.fd77f","name":"","x":372.5,"y":36,"wires":[["893c2411.1181e8","80842fe1.74a72"]]},{"id":"80842fe1.74a72","type":"debug","z":"eb4ead14.fd77f","name":"","active":false,"console":"false","complete":"nodeId","x":559.5,"y":80,"wires":[]},{"id":"2027984.714eb68","type":"mysdebug","z":"eb4ead14.fd77f","name":"","x":374.5,"y":135,"wires":[["ed9596a0.eaa2b8"]]},{"id":"ed9596a0.eaa2b8","type":"debug","z":"eb4ead14.fd77f","name":"","active":false,"console":"false","complete":"false","x":561.5,"y":140,"wires":[]},{"id":"219cc581.f9b252","type":"serial-port","z":"","serialport":"/dev/ttyUSB0","serialbaud":"115200","databits":"8","parity":"none","stopbits":"1","newline":"\\n","bin":"false","out":"char","addchar":false}]
Fonction pour décoder un message (objet JSON) sans le plugin Node-RED
Le plugin contrib-mysensors est très efficace mais il ne permet (pour le moment du moins) que d’extraire le payload (contenu du message). Dans certains cas, il peut s’avérer nécessaire d’extraire des informations supplémentaire. Voici une petite fonction que vous pouvez ajouter à vos projets Node-RED. Elle remplace le plugin node-red-contrib-mysensors.
Pour une gateway Serial ou LAN
La fonction décode le message est décodé en renvoyant un objet JSON au format clé:valeur.
Elle renvoie un payload avec les informations suivantes :
- nodeId : Id du noeud publiant le message
- sensorId : Id de l’enfant
- mode : presentation, set, req, internal, stream
- type : numéro du sous-type de donnée (fonction du mode)
- typeLabel : libellé du type de données correspondant
- value : contenu du message (payload)
Vous pouvez également installer ce flow depuis le site officiel de Node-RED http://flows.nodered.org/flow/fa02078c160cb3e00e09f4980b534490
/* MySensors v2 Message Decoder * Payload : JSON object * www.projetsdiy.fr - oct. 2016 */ var mySensorsMessage = {} var newPayload = {}; var message = msg.payload.toString(); message = message.replace(/(\r\n|\n|\r)/gm, ""); var tokens = message.split(";") if(tokens.length == 6) { mySensorsMessage.nodeId = parseInt(tokens[0]); mySensorsMessage.childSensorId= parseInt(tokens[1]); mySensorsMessage.messageType = parseInt(tokens[2]); mySensorsMessage.ack = parseInt(tokens[3]); mySensorsMessage.subType = parseInt(tokens[4]); mySensorsMessage.value = Number(tokens[5]); var messageType = mySensorsMessage.messageType; var subType = mySensorsMessage.subType; 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"]; 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"] 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"] switch (messageType) { case 0: // Presentation newPayload.mode = "Presentation"; newPayload.type = labelPresentation[subType]; newPayload.value = mySensorsMessage.value; break; case 1: // Set newPayload.nodeId = mySensorsMessage.nodeId; newPayload.sensorId = mySensorsMessage.childSensorId; newPayload.mode= "Set"; newPayload.type= subType; newPayload.typeLabel= labelSet[subType]; newPayload.value= mySensorsMessage.value; break; case 2: // Req newPayload.nodeId= mySensorsMessage.nodeId; newPayload.sensorId= mySensorsMessage.childSensorId; newPayload.mode= "Req"; newPayload.type= subType; newPayload.typeLabel= labelSet[subType]; newPayload.value= mySensorsMessage.value; break; case 3: // Internal newPayload.nodeId= mySensorsMessage.nodeId; newPayload.sensorId= mySensorsMessage.childSensorId; newPayload.mode= "Internal"; newPayload.type= subType; newPayload.typeLabel= labelInternal[subType]; newPayload.value= mySensorsMessage.value; break; case 4: // Stream - OTA firmware update newPayload.nodeId= mySensorsMessage.nodeId; newPayload.mode= "stream"; break; default: break; } msg.payload = newPayload; } else { msg.payload = "Error! Nothing to decode" } return msg;
Voici ce que vous obtiendrez avec la fonction. Chaque message est maintenant explicite et formaté sous la forme d’un objet JSON plus facile à exploiter dans un projet.
Libre à vous de la modifier en fonction de vos besoins.
Pour une gateway MQTT
Si vous utilisez une gateway MQTT, utilisez ce Flow pour décoder les messages
/* MySensors v2.3.x Message Decoder * Payload : JSON object * www.projetsdiy.fr - 03/2020 */ var mySensorsMessage = {} var newPayload = {}; var tokens = msg.topic.split("/") console.log(msg.topic, "|", tokens); if(tokens.length == 6) { // 0 1 2 3 4 5 // prefix/node-id/child-sensor-id/message-type/ack/sub-type mySensorsMessage.nodeId = parseInt(tokens[1]); mySensorsMessage.childSensorId= parseInt(tokens[2]); mySensorsMessage.messageType = parseInt(tokens[3]); mySensorsMessage.ack = parseInt(tokens[3]); mySensorsMessage.subType = parseInt(tokens[5]); mySensorsMessage.value = msg.payload; var messageType = mySensorsMessage.messageType; var subType = mySensorsMessage.subType; 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"]; 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"] 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"] newPayload.topic = tokens[0] switch (messageType) { case 0: // Presentation newPayload.mode = "Presentation"; newPayload.type = labelPresentation[subType]; newPayload.value= mySensorsMessage.value; break; case 1: // Set newPayload.nodeId= mySensorsMessage.nodeId; newPayload.sensorId= mySensorsMessage.childSensorId; newPayload.mode= "Set"; newPayload.type= subType; newPayload.typeLabel= labelSet[subType]; newPayload.value= mySensorsMessage.value; break; case 2: // Req newPayload.nodeId= mySensorsMessage.nodeId; newPayload.sensorId= mySensorsMessage.childSensorId; newPayload.mode= "Req"; newPayload.type= subType; newPayload.typeLabel= labelSet[subType]; newPayload.value= mySensorsMessage.value; break; case 3: // Internal newPayload.nodeId= mySensorsMessage.nodeId; newPayload.sensorId= mySensorsMessage.childSensorId; newPayload.mode= "Internal"; newPayload.type= subType; newPayload.typeLabel= labelInternal[subType]; newPayload.value= mySensorsMessage.value; break; case 4: // Stream - OTA firmware update newPayload.nodeId= mySensorsMessage.nodeId; newPayload.mode= "stream"; break; default: break; } msg.payload = newPayload; } else { msg.payload = "Error! Nothing to decode. Lenght =" + tokens.length } return msg;
Code du flow
[{"id":"61bbd468.bddf9c","type":"tcp in","z":"eb4ead14.fd77f","name":"MySensors Gateway","server":"client","host":"192.168.1.20","port":"5003","datamode":"stream","datatype":"utf8","newline":"","topic":"","base64":false,"x":169.88886260986328,"y":226.92767333984375,"wires":[["f4fd4940.32ba8"]]},{"id":"f4fd4940.32ba8","type":"function","z":"eb4ead14.fd77f","name":"Decode MySensor Message","func":"/* MySensors v2 Message Decoder\n* Payload : JSON object\n* www.projetsdiy.fr - oct. 2016\n*/\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]);\n\n 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 case 0: // Presentation\n \n newPayload.mode = \"Presentation\";\n newPayload.type = labelPresentation[subType];\n break;\n case 1: // Set\n newPayload.nodeId= mySensorsMessage.nodeId;\n newPayload.sensorId= 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: // Req\n newPayload.nodeId= mySensorsMessage.nodeId;\n newPayload.sensorId= 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: // Internal\n newPayload.nodeId= mySensorsMessage.nodeId;\n newPayload.sensorId= mySensorsMessage.childSensorId;\n newPayload.mode= \"Internal\";\n newPayload.type= subType;\n newPayload.typeLabel= labelInternal[subType];\n newPayload.value= mySensorsMessage.value;\n break; \n case 4: // Stream - OTA firmware update\n newPayload.nodeId= mySensorsMessage.nodeId;\n newPayload.mode= \"stream\";\n break;\n default:\n break;\n }\n\n msg.payload = newPayload; \n} else {\n msg.payload = \"Error! Nothing to decode\"\n} \n\nreturn msg;","outputs":1,"noerr":0,"x":394.5555419921875,"y":279.5555725097656,"wires":[["22cb3401.ef7e24","2d12c5a2.7304aa","fd30fa09.244ce8"]]},{"id":"fd30fa09.244ce8","type":"debug","z":"eb4ead14.fd77f","name":"","active":true,"console":"false","complete":"false","x":628.5,"y":235,"wires":[]}]
La fonction mysencap
La dernière fonction mysencap proposée par le plugin permet de formater un message avant de le publier sur un noeud du réseau MySensors. On peut envoyer ce que l’on veut dans la limite de 25 bytes. Il faut également ajouter un retour à la ligne (\n) avant de l’injecter dans la fonction. Par exemple, on peut récupérer l’état d’un switch créé avec le plugin node-red-contrib-ui pour allumer ou éteindre une Led (ou une lampe via un relai). Nous verrons en détail ce plugin dans un prochain tutoriel.
Ajoutez un Node switch
Donnez lui un nom. Pour la valeur de sortie, indiquez 1 et 0 pour Off. Ce n’est pas très important, on peut très bien laisser True/False. Il faudra juste tester la bonne valeur dans le code Arduino du noeud MySensors.
Allez sur la page d’interface à l’adresse
http://IP_NODE-RED:1880/ui
Vous disposer maintenant d’un interrupteur à deux états.
Il ne reste plus qu’à préparer le message. Ajoutez une fonction et coller ce code pour ajouter un retour à la ligne.
msg.payload = msg.payload + "\n" return msg;
Ensuite ajoutez un Node mysencap et indiquez les paramètres du noeud de destination du message. Le type de message doit être Request. Voici un exemple :
Il ne reste plus qu’à injecter dans un Node mysdecenc avant d’envoyer le message sur une gateway (série ou réseau) MySensors.
Ajoutez ce code sur le noeud MySensor pour intercepter les messages envoyés à cet objet.
void receive(const MyMessage &message) { Serial.print("Message recu pour le capteur :"); Serial.print(message.sensor); Serial.print(", Nouveau statut : "); Serial.println(message.getBool()); }
Et voilà, si on appuie sur l’interrupteur, on reçoit bien les messages sur le noeud en provenance du flow Node-RED.
Code du flow
[{"id":"f34523e0.fa94a","type":"mysdecenc","z":"e1e0f04d.8c404","name":"","x":546.388916015625,"y":276,"wires":[["a9d71461.a61de8"]]},{"id":"45e9c56a.b8cdec","type":"mysencap","z":"e1e0f04d.8c404","name":"","nodeid":"3","childid":"0","subtype":"2","internal":0,"ack":false,"msgtype":"2","presentation":false,"presentationtype":0,"presentationtext":"","fullpresentation":false,"firmwarename":"","firmwareversion":"","x":400,"y":220.3333282470703,"wires":[["f34523e0.fa94a"]]},{"id":"a9d71461.a61de8","type":"tcp out","z":"e1e0f04d.8c404","host":"192.168.1.20","port":"5003","beserver":"client","base64":false,"end":false,"name":"to MySensors","x":738,"y":232.3333282470703,"wires":[]},{"id":"d253489c.087998","type":"function","z":"e1e0f04d.8c404","name":"slash n","func":"msg.payload = msg.payload + \"\\n\"\nreturn msg;","outputs":1,"noerr":0,"x":274,"y":276.3333282470703,"wires":[["45e9c56a.b8cdec"]]},{"id":"af4ddcee.88eaf","type":"ui_switch","z":"e1e0f04d.8c404","tab":"6df01db6.d8538c","name":"Switch","topic":"","group":"","order":1,"onvalue":"1","offvalue":"0","x":149,"y":224.3333282470703,"wires":[["d253489c.087998"]]},{"id":"6df01db6.d8538c","type":"ui_tab","z":"","name":"Salon","icon":"store","order":"1"}]
Mises à jour
[25/03/2020] Se connecter et décoder les messages MySensors MQTT
Avez-vous aimé cet article ?