Accueil / Objets Connectés / Node-RED / Node-RED module Dashboard : ajouter une interface graphique (Partie 1)

Node-RED module Dashboard : ajouter une interface graphique (Partie 1)

Le module Dashboard permet d’ajouter très facilement une (très belle) interface graphique à un projet Node-RED. Le module Dashboard succède au module UI. Avec ce module on peut ajouter des afficheurs pour visualiser sous différentes formes des mesures : gauges, graphique, texte, notification, ou du code HTML libre. On peut aussi ajouter des champs permettant de interactions : bouton, interrupteur, slider (potentiomètre linéaire), champ de saisie (texte ou numérique), liste de choix et des formulaires.

Installer le module Dashboard

node-red dashboard library
Si vous utilisez le module UI (node-red-contrib-ui), vous devez déjà le désinstaller. Depuis le Terminal

cd ~/.node-red
npm uninstall node-red-contrib-ui

Vous pouvez aussi le désinstaller depuis de gestionnaire de palette.

Remarque. Il faut supprimer tous les Nodes du module UI. Commencez par supprimer tous les tableaux (Tab) avant de supprimer les Nodes, sinon il est impossible de désinstaller le module.

Ouvrez le gestionnaire de palette et cherchez le module à l’aide du mot clé dashboard.

node-red dashboard installation palette manager

Puis cliquez sur install pour installer le module. A la fin de l’installation, actualisez l’affichage du navigateur.

Eléments graphiques proposés par Dashboard

node-red dashboard paletteLe module Dashboard propose les commandes graphiques suivantes (entrées) :

  • Bouton (button)
  • Liste de choix (dropdown)
  • Interrupteur à 2 états (switch)
  • Potentiomètre horizontal (slider)
  • Sélecteur numérique (numeric)
  • Champ de saisie de texte (text input)
  • Formulaire (form)

Ainsi que les afficheurs suivants (sorties) :

  • Texte (text)
  • Gauge (gauge)
  • Graphique (chart)
  • Notification furtive (notification)
  • Changer de page (tab) (ui control)
  • Affichage de code HTML (template)

On accède à l’interface graphique par l’URL

http://IP_NODERED:1880/dashboard

 

 

1ère partie : découverte des commandes du Dashboard

Dans ce tutoriel nous allons découvrir les commandes proposées par ce module Dashboard.

Comment personnaliser les icônes

Avant de rentrer dans le vif du sujet, voyons d’abord comment utiliser des icônes. Plusieurs librairies d’icônes Open Source peuvent être utilisées pour personnaliser l’affichage des composants.

La plus connue, Font Awesome (http://fontawesome.io/icons/). Les versions les plus récentes ne sont pas supportées (4.7 et 5), mais il en reste beaucoup d’autres ! Pour utilisez une fonte Awesome, ajoutez fa- devant le nom de l’icône. Par exemple fa-fire.

node-red dashboard font awesome
Material Design (https://material.io/icons/) est un projet Open Source soutenu par Google. Pour utiliser une icône, remplacez les espaces par _, par exemple pour « account balance wallet », saisissez « account_balance_wallet ».

node-red dashboard icons material design google

Enfin, vous pouvez utiliser la librairie d’icônes Open Source pour projets AngularJS de Klarsys (https://klarsys.github.io/angular-material-icons/). Utilisez le nom icon.

node-red dashboard icone klarsys

Préparation des pages (tabs)

Il est possible de créer des groupes et des pages directement depuis le panneau de configuration de chaque Node du dashboard. Lorsqu’on découvre le module, c’est beaucoup plus facile et plus clair de passer par la palette de configuration qui s’ajoute à coté de la console (debug). Si le panneau n’est pas visible(ou si vous l’avez fermé), allez dans le menu puis View et enfin dashboard.

node-red affichage onglet dashboard

Choisissez un titre (title). Il sera affiché comme titre de la page dans l’entête du navigateur internet. On peut choisir entre deux thèmes, sombre avec un fond noir (Dark) ou clair avec un fond blanc, les éléments graphiques en bleu (Light).

Cliquez sur +tab pour ajouter une page.

node-red dashboard onglet ajout tab

Ouvrez la fenêtre d’édition en appuyant sur edit.

https://i2.wp.com/www.projetsdiy.fr/wp-content/uploads/2016/11/2-node-red-dashboard-edit-tab.png?resize=298%2C66

Donnez un nom (name) et éventuellement une icône (voir plus haut comment faire). Enregistrez avec Done ou Update. Ici on donnera le nom Ecran Principale et l’icône home.

node-red-dashboard-edition-tab-ecran-principal

Ajoutez maintenant 3 groupes

node-red-dashboard-ecran-ajouter-groupe

Et ouvrez la fenêtre d’édition

node-red-dashboard-edit-group

Donnez les noms suivants aux groupes :

  • Eléments d’entrées
  • Formulaire
  • Journal d’événement du Dashboard

node-red-dashboard-edition-groupe

On peut laisser la taille de chaque widget se régler automatiquement mais dans certains cas vous devrez la changer à la main avec le paramètre Width (largeur).

node-red-dashboard-taille-groupe

On peut réordonner les groupes dans une Tab, les déplacer d’une Tab à une autre et réordonner les Tab et utilisant la poignée.

node-red-dashboard-reorganisation-ordre-groupes

Le groupe est maintenant prêt.

node-red-dashboard-groupes-configures

Maintenant, nous allons ajouter un à un les éléments de contrôle proposés par le module et découvrir ce qu’ils permettent de réaliser ainsi que les paramètres disponibles. On assignera chaque élément au groupe « Eléments d’entrée », sauf le formulaire que l’on assignera au groupe « Formulaire ».

Bouton (Button)

Paramètres du bouton

  • Group : groupe d’affichage.
  • Size : taille de l’élément. Auto par défaut
  • Icon : permet d’afficher un icône à gauche du libellé
  • Label : libellé du bouton
  • Colour : couleur du libellé (en hexa, pr exemple #8000ff)
  • Payload : valeur de sortie lorsqu’on presse sur le bouton (true, false)
  • Topic : étiquette
  • Name : nom du Node affiché sur le flow Node-RED

node-red dashboard button bouton

Le bouton obtenu

node-red dashboard bouton

Liste de choix (dropdown)

L’élément Dropdown (liste de choix) permet à l’utilisateur de renvoyer 3 types de données :

  • Une chaine de caractère
  • Une valeur numérique entière
  • Un booléen

Le Node peut aussi être transparent et laisser passer un message entrant. Pour cela, il faut cocher la case « If msg arrives on input, pass trough to output ».

node-red dashboard liste de choix dropdown

La liste de choix obtenue

node-red dashboard dropdown

Interrupteur (switch)

L’interrupteur horizontal permet de renvoyer un booléen lorsqu’il change d’état. Il est possible d’inverser la valeur du booléen en sélectionnant en inversant les valeur de sortie en fonction de l’état On et Off.

node-red dashboard switch interrupteur

Il est également possible d’avoir d’autres types de sortie (autre que le payload) :

  • Un Flow
  • Stocker l’état dans une variable globale (Global)
  • Une chaîne de caractères (String)
  • Un nombre (Number)
  • Un objet JSON
  • La date et l’heure de l’action (timestamp)

node-red dashboard switch autres types

Le switch obtenu

node-red dashboard switch

Potentiomètre linéaire (Slider)

Tout comme le switch, le slider peut laisser passer un message entrant en toute transparence (cocher if msg arrives…).

Le slider prend comme paramètre la valeur minimum (min), maximum (max) et le pas (step).

node-red dashboard slider potentiometre

Le slider obtenu

node-red dashboard slider

Champ de saisie numérique (Numeric)

On doit définir une gamme de saisie (min, max).

node-red dashboard numeric numerique

Le champ numérique obtenu

node-red dashboard numeric

Champ de saisie texte (Text) :

Ce champ propose 4 masques de saisie. Si un délai (delay) est indiqué (par défaut 300ms), le Node renvoie la valeur saisie automatiquement. C’est pratique pour un usage sur tablette. Si le délai est nul (0), il faudra valider la saisie par un appui sur la touche Enter.

node-red dashboard saisie texte

Texte

Rien de plus à dire dessus.

node-red dashboard text saisie texte

Mot de passe (password)

Dans ce cas les caractères sont masqués.

node-red dashboard saisie mot de passe password

Sélecteur de couleur (color picker)

Il renvoie le code couleur au format hexadecimal. Il utilise le sélecteur de couleur du système.

node-red dashboard selecteur couleur color picker.

Adresse Email

Pratique, ce champ vérifie que l’email saisi est correct.

node-red dashboard saisie email textFormulaire (form)

Dernier gros morceau du Dashbord, le formulaire. C’est un composant vraiment très puissant et très simple à mettre en oeuvre.

Comme d’habitude, un libellé (Label) permet de lui donner un type qui sera affiché en entête. On ’empile’ ensuite les éléments dans le formulaire (Form elements). On dispose des choix suivants :

  • Texte (text)
  • Nombre (Number)
  • Email (E-mail)
  • Mot de passe (Password)
  • Case à cocher (Checkbox)
  • Interrupteur (Switch)

On peut rendre chaque élément obligatoire (Required) avant la sortie du formulaire.

node-red dashboard form formulaire

Voici le formulaire obtenu.

node-red dashboard formulaire form

Bonus : créer un journal des événements

Voyons maintenant à quoi ça ressemble. Je vous propose un petit morceau de code qui stocke dans une variable globale tous les événements et les affiches sous la forme d’un journal d’événement (log).

Ajoutez un Node function et collez ce code. On stocke dans une variable globale les événements sur l’interface. On supprime les messages au delà de 20 enregistrements.

// Créé une variable pour stocker le journal du dashboard si inexistante
// initialise the counter to 0 if it doesn't exist already
var dashboardLog = context.get('dashboardLog')|| [];

dashboardLog.push(msg);
if (dashboardLog.length > 20){
    // Supprime le plus anciens message si > 20
    // Delete oldest message if > 20
    dashboardLog.shift();
    dashboardLog.length = 20;
} 

// Enregistre les messages du dashboard pour le prochain affichage
// store the value back
context.set('dashboardLog',dashboardLog);

// Affiche le journal des messages
// make it part of the outgoing msg object
msg = {};
msg.payload = dashboardLog;
return msg;

Ajoutez ensuite un Node HTML et collez ce code. On utilise la classe AngularJS ng-repeat pour parcourir le tableau renvoyé par la fonction précédente. On créé un libellé en rouge à l’aide du topic. A coté d’une puce (ul), on affiche la valeur renvoyée par l’événement du Dashboard.

<ul>
 <li ng-repeat="x in msg.payload">
 <font color="red">{{x.topic}}</font>
    <ul>
        <li>{{x.payload}}</li>
    </ul>
 </li>
</ul>

Maintenant, vous pouvez allez sur le Dashboard en saisissant l’adresse http://IP_NODERED:1880/ui

A vous de tester maintenant !

32-node-red-dashboard-test

Code du flow

Coller le code de ce flow pour tester rapidement cet exemple.

[{"id":"6eecf682.454f38","type":"ui_button","z":"df9159f.e304ea8","name":"Boutton","group":"2a5abbd3.afa284","order":0,"width":0,"height":0,"label":"Boutton","color":"#fffff","icon":"fa-star","payload":"true","payloadType":"bool","topic":"Button","x":360,"y":100,"wires":[["1e96adb5.fd25e2"]]},{"id":"2a0c052c.dfe4ca","type":"ui_dropdown","z":"df9159f.e304ea8","name":"Liste de choix","label":"Choisissez ce que vous voulez","group":"2a5abbd3.afa284","order":0,"width":0,"height":0,"passthru":true,"options":[{"label":"Choix 1 : chaine","value":"Choix1","type":"str"},{"label":"Choix 2 : numérique","value":4,"type":"num"},{"label":"Choix 3 : bool","value":true,"type":"bool"}],"payload":"","topic":"Liste de choix","x":340,"y":140,"wires":[["1e96adb5.fd25e2"]]},{"id":"61be9b53.3a5ff4","type":"debug","z":"df9159f.e304ea8","name":"Dashboard Log","active":true,"console":"false","complete":"payload","x":900,"y":220,"wires":[]},{"id":"e7869632.cb19b8","type":"ui_switch","z":"df9159f.e304ea8","name":"Interrupteur","label":"switch","group":"2a5abbd3.afa284","order":0,"width":0,"height":0,"passthru":true,"topic":"Interrupteur","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":350,"y":180,"wires":[["1e96adb5.fd25e2"]]},{"id":"6f4d5597.73fb0c","type":"ui_slider","z":"df9159f.e304ea8","name":"Slider","label":"slider","group":"2a5abbd3.afa284","order":0,"width":0,"height":0,"passthru":true,"topic":"Slider","min":0,"max":10,"step":1,"x":370,"y":220,"wires":[["1e96adb5.fd25e2"]]},{"id":"93c06deb.61b61","type":"ui_numeric","z":"df9159f.e304ea8","name":"","label":"numeric","group":"2a5abbd3.afa284","order":0,"width":0,"height":0,"passthru":true,"topic":"Numérique","format":"{{value}}","min":0,"max":10,"x":360,"y":260,"wires":[["1e96adb5.fd25e2"]]},{"id":"8f5cb4d9.8208a8","type":"ui_text_input","z":"df9159f.e304ea8","name":"","label":"Champ saisie de Texte","group":"2a5abbd3.afa284","order":0,"width":0,"height":0,"passthru":true,"mode":"text","delay":"0","topic":"Champ saisie de Texte","x":320,"y":300,"wires":[["1e96adb5.fd25e2"]]},{"id":"3375a2e.57b475e","type":"ui_form","z":"df9159f.e304ea8","name":"","label":"Un formulaire Node-RED","group":"febe591f.8ca1f8","order":0,"width":0,"height":0,"options":[{"label":"Du texte","value":"Texte","type":"text","required":true},{"label":"Un nombre","value":"Nombre","type":"number","required":false},{"label":"Un email","value":"email","type":"email","required":false},{"label":"Un mot de passe","value":"Mot de passe","type":"password","required":false},{"label":"Une case à cocher","value":"Case à cocher","type":"checkbox","required":false},{"label":"Un interrupteur","value":"Interrupteur","type":"switch","required":false}],"formValue":{"Texte":"","Nombre":"","email":"","Mot de passe":"","Case à cocher":false,"Interrupteur":false},"payload":"","topic":"Formulaire","x":310,"y":460,"wires":[["1e96adb5.fd25e2"]]},{"id":"1e96adb5.fd25e2","type":"function","z":"df9159f.e304ea8","name":"Enregistre les événements","func":"// Créé une variable pour stocker le journal du dashboard si inexistante\n// initialise the counter to 0 if it doesn't exist already\nvar dashboardLog = context.get('dashboardLog')|| [];\n\ndashboardLog.push(msg);\nif (dashboardLog.length > 20){\n    // Supprime le plus anciens message si > 20\n    // Delete oldest message if > 20\n    dashboardLog.shift();\n    dashboardLog.length = 20;\n} \n\n// Enregistre les messages du dashboard pour le prochain affichage\n// store the value back\ncontext.set('dashboardLog',dashboardLog);\n\n// Affiche le journal des messages\n// make it part of the outgoing msg object\nmsg = {};\nmsg.payload = dashboardLog;\nreturn msg;\n","outputs":1,"noerr":0,"x":660,"y":280,"wires":[["61be9b53.3a5ff4","7a421874.47f638"]]},{"id":"7a421874.47f638","type":"ui_template","z":"df9159f.e304ea8","group":"842b8d23.22294","name":"Journal des événement du Dashboard","order":1,"width":"8","height":"10","format":"<ul>\n <li ng-repeat=\"x in msg.payload\">\n <font color=\"red\">{{x.topic}}</font>\n    <ul>\n        <li>{{x.payload}}</li>\n    </ul>\n </li>\n</ul>","storeOutMessages":true,"fwdInMessages":true,"x":970,"y":320,"wires":[[]]},{"id":"87bf88d.1fbd678","type":"ui_text_input","z":"df9159f.e304ea8","name":"","label":"Champ saisie email","group":"2a5abbd3.afa284","order":0,"width":0,"height":0,"passthru":true,"mode":"email","delay":300,"topic":"Champ saisie email","x":330,"y":340,"wires":[["1e96adb5.fd25e2"]]},{"id":"55e7b58f.cafe6c","type":"ui_text_input","z":"df9159f.e304ea8","name":"","label":"Champ saisie mot de passe","group":"2a5abbd3.afa284","order":0,"width":0,"height":0,"passthru":true,"mode":"password","delay":300,"topic":"Champ saisie mot de passe","x":300,"y":380,"wires":[["1e96adb5.fd25e2"]]},{"id":"21feb1b7.018a5e","type":"ui_text_input","z":"df9159f.e304ea8","name":"","label":"Sélecteur de couleur","group":"2a5abbd3.afa284","order":0,"width":0,"height":0,"passthru":true,"mode":"color","delay":300,"topic":"Sélecteur de couleur","x":320,"y":420,"wires":[["1e96adb5.fd25e2"]]},{"id":"2a5abbd3.afa284","type":"ui_group","z":"","name":"Eléments d'entrée","tab":"99f501d2.56c31","order":1,"disp":true,"width":"8"},{"id":"febe591f.8ca1f8","type":"ui_group","z":"","name":"Formulaire","tab":"99f501d2.56c31","order":2,"disp":true,"width":"8"},{"id":"842b8d23.22294","type":"ui_group","z":"df9159f.e304ea8","name":"Journal des événements du Dashboard","tab":"99f501d2.56c31","order":3,"disp":true,"width":"8"},{"id":"99f501d2.56c31","type":"ui_tab","z":"","name":"Ecran Principal","icon":"home","order":2}]

Dans la seconde partie, nous verrons comment intégrer des éléments de sortie (gauges, graphs, notifications…).