Site : tvaira.free.fr

Node-Red

Node-RED est un outil de programmation graphique par assemblage de nodes (blocs fonctionnels). Il est notamment utiliser pour développer des applications de l’Internet des Objets (IoT).

Il fournit un éditeur basé sur un navigateur qui facilite l’assemblage des noeuds constituant un flow qui sera déployé en un clic. Il existe une vaste gamme de nœuds dans la palette.

Node-Red est un projet Open Source basé sur Node.js et soutenu par IBM.

La communauté Node-Red propose de très nombreux nodes dans tous les domaines : objets connectés (ZWave, Sonos..), services en ligne (météo, twitter…), bases de données…

Liens :

Installation

Raspberry Pi

Lien : Node-Red sur Raspberry Pi

bash <(curl -sL https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/update-nodejs-and-nodered)

sudo wget https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/nodered.service -O /lib/systemd/system/nodered.service
sudo wget https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/node-red-start -O /usr/bin/node-red-start
sudo wget https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/node-red-stop -O /usr/bin/node-red-stop
sudo chmod +x /usr/bin/node-red-st*

sudo systemctl daemon-reload
sudo systemctl enable nodered.service

sudo apt-get install python-rpi.gpio

Vérification :

sudo systemctl status nodered.service

Accès : http://127.0.0.1:1880/

Linux

curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -

sudo apt-get install -y nodejs

sudo npm install -g --unsafe-perm node-red

node-red

Accès : http://127.0.0.1:1880/

Windows

Télécharger Node.js

Lien : nodered.org/docs/platforms/windows

Avec cmd.exe :

C:> node --version && npm --version

C:> npm install -g --unsafe-perm node-red

C:> node-red

Accès : http://127.0.0.1:1880/

Exemple

Ajouter des nodes : dans Menu → Manage Palette

Il vous faut installer les nodes dashboard (pour les boutons, sliders, gauge, graphiques, …) et serialport.

Vous disposez maintenant de nouveaux blocs :

Dans le flow, créer un tab à partir de l’onglet layout :

Puis créer des groups :

Ils contiendront ensuite les éléments à afficher (pour les boutons, sliders, gauge, graphiques, …) :

Sur le flow, déposer un bloc serial (input) pour recevoir des trames du port série :

Double-cliquer sur le bloc pour le configurer avec edit :

Déposer maintenant un bloc debug et le relier au bloc serial :

Pour visualiser les trames dans le debugger :

Il faut savoir que les blocs se transmettent un flux nommé msg qui contient les données dans payload.

On va ajouter un bloc function et le relier aussi au bloc serial :

Éditer le code de la fonction en double cliquant sur le bloc :

On programme en JavaScript. La fonction reçoit en entrée le flux msg et elle retournera en sortie un flux du même type. Les données contenues dans msg.payload sont de type String.

// en entrée on reçoit msg
// la trame est dans payload

msg.payload.replace("\r", "");
// les données sont séparées par un ';'
var datas = msg.payload.split(";");
// on crée un message pour l'affichage
var message = "Trame : " + msg.payload + " -> Type : " + datas[0] + " [Data 1 = " + datas[1] + "] [Data 2 = " + datas[2] + "] [ Data 3 = " + datas[3] + "]";
// on réinitialise msg
var msg={};
// on met le message dans payload pour le bloc suivant
msg.payload = message;

// en sortie on retourne msg
return msg;

Pour finir on ajoute un bloc text du dashboard qui nous permettra d’afficher la trame. Vous pouvez l’éditer afin de la placer dans un group, fixer sa taille et son positionnement :

Au final, on obtient le flow suivant :

Pour tester, il faut déployer (deploy) :

Puis ouvrir l’URL : http://127.0.0.1:1880/ui

Ici, la trame contient 3 valeurs : la température, l’humidité et un angle.

On va compléter le flow pour afficher ces données dans une gauge et on ajoutera un graphique. Pour “alimenter” ces bloc, on placera une fonction pour extraire les données de la trame.

Cette fonction aura la particularité de posséder trois sorties et donc de retourner 3 flux sous forme de tableau :

On déploie et on obtient maintenant :

On va s’occuper maintenant de la partie émission de trame sur le port série. On place un bloc serial (output) :

On complète le flow pour obtenir ceci :

La fonction ajoutée doit permettre de transmettre un flux msg au bloc serial. La trame à envoyer sera donc stockée dans payload, par exemple :

var trame = {};
trame.payload = ""

trame.payload += "$C;on";

return trame;

Le bloc switch est configuré pour transmettre trueou false dans son flux msg.payload qui sera reçu par la fonction. Le slider envoie lui directement sa valeur dans msg.payload.

On déploie et on obtient maintenant :

Vous pouvez paramétrer la page dans l’onglet Site :

Puis personnaliser le thème dans l’onglet Theme (ou Angular suivant le thème choisi) :

Avec un thème sombre, on obtient :

Il est possible d’exporter son flow et donc aussi de l’importer par le presse-paier (copier/coller) :

Le format est JSON :

[{"id":"44c31afb.21614c","type":"tab","label":"MonArduino","disabled":false,"info":"__Test__"},{"id":"26f8d34e.ac767c","type":"serial in","z":"44c31afb.21614c","name":"ttyUSB0","serial":"6c4adfa1.9f25c","x":100,"y":60,"wires":[["8897de98.f3be","5369894f.baee1","b6346da0.f98998"]]},{"id":"78858271.718be4","type":"ui_gauge","z":"44c31afb.21614c","name":"Data1","group":"d7a6a9dd.47f058","order":3,"width":"6","height":"5","gtype":"gage","title":"Température","label":"°C","format":"{{value}}","min":0,"max":"40","colors":["#00b500","#e6e600","#ca3838"],"seg1":"512","seg2":"768","x":590,"y":160,"wires":[]},{"id":"b6346da0.f98998","type":"function","z":"44c31afb.21614c","name":"Decode datas","func":"var datas;\nvar data1={};\nvar data2={};\nvar data3={};\n\nif(msg.payload.startsWith(\"$D;\"))\n//if(msg.payload.indexOf(\"$D\") != 1)\n{\n    msg.payload.replace(\"\\r\", \"\");\n    msg.payload.replace(\"$D;\", \"\");\n    datas = msg.payload.split(\";\");\n    data1.payload = datas[1];\n    data2.payload = datas[2];\n    data3.payload = datas[3];\n}\n\nreturn [data1,data2,data3]","outputs":3,"noerr":0,"x":340,"y":220,"wires":[["78858271.718be4"],["fde29434.b8e4c"],["fd50ead9.156808","72be3b8e.9720f4"]]},{"id":"cbb63da7.190438","type":"ui_text","z":"44c31afb.21614c","group":"62155dd4.2f1644","order":0,"width":"14","height":"1","name":"Affichage","label":"","format":"{{msg.payload}}","layout":"col-center","x":600,"y":60,"wires":[]},{"id":"8897de98.f3be","type":"function","z":"44c31afb.21614c","name":"Decode Trame","func":"var message;\nvar datas;\n\nmsg.payload.replace(\"\\r\", \"\");\nmsg.payload.replace(\"$D;\", \"\");\ndatas = msg.payload.split(\";\");\n\nmessage = \"Trame : \" + msg.payload + \" -> Type : \" + datas[0] + \" [Data 1 = \" + datas[1] + \"] [Data 2 = \" + datas[2] + \"] [ Data 3 = \" + datas[3] + \"]\";\n\nvar msg={};\n\nmsg.payload = message;\n\nreturn msg;","outputs":1,"noerr":0,"x":340,"y":60,"wires":[["cbb63da7.190438"]]},{"id":"93f85450.6f3ec","type":"ui_switch","z":"44c31afb.21614c","name":"Commande1","label":"Led","group":"1377207e.d88a58","order":1,"width":0,"height":0,"passthru":false,"decouple":"false","topic":"","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":110,"y":360,"wires":[["88b17cb0.1b78c"]]},{"id":"45634526.d6a13c","type":"serial out","z":"44c31afb.21614c","name":"ttyUSB0","serial":"6c4adfa1.9f25c","x":600,"y":380,"wires":[]},{"id":"88b17cb0.1b78c","type":"function","z":"44c31afb.21614c","name":"Fabrique trame","func":"var trame = {};\n\ntrame.payload = \"\"\n\nif (msg.payload === true) \n{\n    trame.payload += \"$C;on\";\n}\nelse if (msg.payload === false) \n{\n    trame.payload += \"$C;off\";\n}\nelse\n{\n    trame.payload += \"$C;\" + msg.payload;\n}\n\nreturn trame;","outputs":1,"noerr":0,"x":340,"y":400,"wires":[["7b23116a.db0a58","45634526.d6a13c"]]},{"id":"5369894f.baee1","type":"debug","z":"44c31afb.21614c","name":"","active":true,"console":"false","complete":"false","x":330,"y":120,"wires":[]},{"id":"a7853613.297c1","type":"ui_slider","z":"44c31afb.21614c","name":"Commande2","label":"Période","group":"1377207e.d88a58","order":0,"width":0,"height":0,"passthru":true,"outs":"end","topic":"","min":"1","max":"60","step":1,"x":110,"y":440,"wires":[["88b17cb0.1b78c"]]},{"id":"fde29434.b8e4c","type":"ui_gauge","z":"44c31afb.21614c","name":"Data2","group":"d7a6a9dd.47f058","order":0,"width":"6","height":"5","gtype":"gage","title":"Humidité","label":"%","format":"{{value}}","min":0,"max":"100","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":590,"y":200,"wires":[]},{"id":"7b23116a.db0a58","type":"debug","z":"44c31afb.21614c","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":610,"y":440,"wires":[]},{"id":"72be3b8e.9720f4","type":"ui_chart","z":"44c31afb.21614c","name":"Graphique","group":"62155dd4.2f1644","order":0,"width":0,"height":0,"label":"","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":true,"ymin":"0","ymax":"200","removeOlder":"15","removeOlderPoints":"","removeOlderUnit":"60","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":610,"y":280,"wires":[[],[]]},{"id":"fd50ead9.156808","type":"ui_gauge","z":"44c31afb.21614c","name":"Data3","group":"d7a6a9dd.47f058","order":0,"width":0,"height":0,"gtype":"gage","title":"Angle","label":"degrés","format":"{{value}}","min":0,"max":"200","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":590,"y":240,"wires":[]},{"id":"6c4adfa1.9f25c","type":"serial-port","z":"","serialport":"/dev/ttyUSB0","serialbaud":"115200","databits":"8","parity":"none","stopbits":"1","newline":"\\r","bin":"false","out":"char","addchar":true,"responsetimeout":""},{"id":"d7a6a9dd.47f058","type":"ui_group","z":"","name":"Datas","tab":"cb8f313f.f2c7d8","order":3,"disp":false,"width":"6","collapse":false},{"id":"62155dd4.2f1644","type":"ui_group","z":"","name":"Trame","tab":"cb8f313f.f2c7d8","order":5,"disp":false,"width":"14","collapse":false},{"id":"1377207e.d88a58","type":"ui_group","z":"","name":"Commande","tab":"cb8f313f.f2c7d8","order":2,"disp":false,"width":"6","collapse":false},{"id":"cb8f313f.f2c7d8","type":"ui_tab","z":"","name":"Mon Arduino","icon":"dashboard"}]

Pour tester, vous pouvez relier un Arduino à votre PC par le port série :

Cablage :

TX : Blanc
RX : Vert

Remarque : cet exemple utilise un capteur DHT12 (température et humidité), un capteur d’angle (grove) et une Led !

Retour au sommaire