tutos:mqtt

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
tutos:mqtt [2018/10/25 07:26] ygangattutos:mqtt [2020/11/02 11:45] (Version actuelle) – [Raspberry Pi : Installation du broker] mdelsaut
Ligne 1: Ligne 1:
 ====== MQTT (mosquitto) ====== ====== MQTT (mosquitto) ======
  
-A faire+Fait :
   -  [x] Comparatif   -  [x] Comparatif
   -  [x] MQTT sur Raspberry Pi   -  [x] MQTT sur Raspberry Pi
   -  [x] MQTT sur Arduino   -  [x] MQTT sur Arduino
   -  [x] Relay + Capteur courant   -  [x] Relay + Capteur courant
-  -  [x] MQTT et Node-Red (en cours) +  -  [x] MQTT et Node-Red 
-  -  [ ] MQTT & InfluxDB +  -  [X] MQTT & InfluxDB 
 +   [X] MQTT & Java
  
 +<WRAP center round important 60%>
 +L'original est sur : https://gist.github.com/gyassine/a5eda1c64557baa60cd563f22ac96c0d
 +</WRAP>
  
 //(Note : ces informations ont été compilées à partir de différentes sources anglaises/françaises)// //(Note : ces informations ont été compilées à partir de différentes sources anglaises/françaises)//
Ligne 16: Ligne 19:
  
 Il existe deux types d'architectures les plus courantes : Il existe deux types d'architectures les plus courantes :
-  -  **Request/Response** (ReqRep) : Qui ressemble à la technologie client/serveur (comme HTTP) +  - **Request/Response** (ReqRep) : Qui ressemble à la technologie client/serveur (comme HTTP) 
-  -  **Publish/Subscribe** (PubSub) : Des entités "//publishers//" publient un message (dans un "//topic//") sur le réseau sans se soucier des destinataires du message. Les "//subscribers//" s'abonnent à un "//topic//" et reçoit tous les messages du "//topic//". Le "//broker//" fait office de centralisateur des messages des "//publishers//" et se charge des envoyés aux "//subscribers//". Le gros désavantage de cette architecture est la présence du "//broker//" qui est en fait un SPoF (Single point of Failure).+  - **Publish/Subscribe** (PubSub) : Des entités "//publishers//" publient un message (dans un "//topic//") sur le réseau sans se soucier des destinataires du message. Les "//subscribers//" s'abonnent à un "//topic//" et reçoit tous les messages du "//topic//". Le "//broker//" fait office de centralisateur des messages des "//publishers//" et se charge des envoyés aux "//subscribers//". Le gros désavantage de cette architecture est la présence du "//broker//" qui est en fait un SPoF (Single point of Failure).
  
 Avantages et Inconvénients : [[https://blog.opto22.com/optoblog/request-response-vs-pub-sub-part-2|Request-response vs. publish-subscribe]] Avantages et Inconvénients : [[https://blog.opto22.com/optoblog/request-response-vs-pub-sub-part-2|Request-response vs. publish-subscribe]]
Ligne 30: Ligne 33:
  
 **Points clefs**: **Points clefs**:
-  -  Request/Response Architecture +  - Request/Response Architecture 
-  -  UDP/IP Based +  - UDP/IP Based 
-  -  QoS Support +  - QoS Support 
-  -  Supports Unicast as well as Multicast +  - Supports Unicast as well as Multicast 
-  -  Uses DTLS for Security +  - Uses DTLS for Security 
-  -  Supports Resource Discovery +  - Supports Resource Discovery 
-  -  CoAP Node plays Server Role too (NAT Issues) +  - CoAP Node plays Server Role too (NAT Issues) 
-  -  Decentralised (No Single Point of Failure) +  - Decentralised (No Single Point of Failure)
-  -  dedsdf+
  
 === REST/HTTP === === REST/HTTP ===
Ligne 49: Ligne 51:
  
 **Points clés**: **Points clés**:
-  -  Request/Response Architecture +  - Request/Response Architecture 
-  -  TCP/IP Based +  - TCP/IP Based 
-  -  No QoS Support +  - No QoS Support 
-  -  Complex Implementation at Client Side +  - Complex Implementation at Client Side 
-  -  Larger Header compared to other IoT Protocols (Higher Bandwidth Requirement) +  - Larger Header compared to other IoT Protocols (Higher Bandwidth Requirement) 
-  -  Uses SSL/TLS for Security+  - Uses SSL/TLS for Security
  
 ==== Publish/Subscribe ==== ==== Publish/Subscribe ====
Ligne 65: Ligne 67:
  
 MQTT offre une Qualité de service (QoS) à 3 niveaux : MQTT offre une Qualité de service (QoS) à 3 niveaux :
-  -  **QoS 0** : transmission de message sans accusé de réception +  - **QoS 0** : transmission de message sans accusé de réception 
-  -  **QoS 1** : transmission de message avec accusé de réception +  - **QoS 1** : transmission de message avec accusé de réception 
-  -  **QoS 2** : transmission de message avec accusé de réception et vérification du message transmis afin d’éviter qu’un même message ne soit pas transmis de nombreuses fois.+  - **QoS 2** : transmission de message avec accusé de réception et vérification du message transmis afin d’éviter qu’un même message ne soit pas transmis de nombreuses fois.
  
 MQTT-SN (MQTT for Sensor Network) est une version optimisée pour les objets à très faibles ressources communiquant sans fil. MQTT-SN (MQTT for Sensor Network) est une version optimisée pour les objets à très faibles ressources communiquant sans fil.
  
 **Points clés** : **Points clés** :
-  -  Publish/Subscribe Architecture +  - Publish/Subscribe Architecture 
-  -  Light Weight (Min Header Size: 2 Bytes) +  - Light Weight (Min Header Size: 2 Bytes) 
-  -  TCP/IP Based +  - TCP/IP Based 
-  -  QoS Support +  - QoS Support 
-  -  Payload Agnostic +  - Payload Agnostic 
-  -  Uses SSL/TLS for Security +  - Uses SSL/TLS for Security 
-  -  Broker could be Single Point of Failure+  - Broker could be Single Point of Failure
  
 === XMPP (Extensible Messaging and Presence Protocol) === === XMPP (Extensible Messaging and Presence Protocol) ===
Ligne 96: Ligne 98:
  
 **Points clés** : **Points clés** :
-  -  Point to Point Message Exchange (Server to Server) +  - Point to Point Message Exchange (Server to Server) 
-  -  Flexible Messaging Patterns +  - Flexible Messaging Patterns 
-  -  TCP/IP Based +  - TCP/IP Based 
-  -  Smallest Packet Size: 60 Bytes +  - Smallest Packet Size: 60 Bytes 
-  -  QoS Support +  - QoS Support 
-  -  Uses SSL/TLS for Security+  - Uses SSL/TLS for Security
  
 ==== Autres types de communications ==== ==== Autres types de communications ====
Ligne 110: Ligne 112:
  
 **Points clés** : **Points clés** :
-  -  Publish/Subscribe and Request/Response Architecture +  - Publish/Subscribe and Request/Response Architecture 
-  -  Relational data modeling +  - Relational data modeling 
-  -  QoS Support +  - QoS Support 
-  -  Multicast support over plain UDP sockets +  - Multicast support over plain UDP sockets 
-  -  Leverages both TCP/IP and UDP/IP Transport +  - Leverages both TCP/IP and UDP/IP Transport 
-  -  Uses TLS and DTLS for Security +  - Uses TLS and DTLS for Security 
-  -  Decentralised (No Single Point of Failure)+  - Decentralised (No Single Point of Failure) 
 + 
 +==== Résumé ==== 
 + 
 +{{https://adlinkblogist.files.wordpress.com/2015/04/dds-comparison-v2.png|Resume}} //Source : https:%%//%%istblog.adlinktech.com/tag/messaging-protocol///
  
 ===== Le choix ===== ===== Le choix =====
Ligne 125: Ligne 131:
  
 Pour rappel, dans un système MQTT complet nous retrouvons quatre notions importantes : Pour rappel, dans un système MQTT complet nous retrouvons quatre notions importantes :
-  -  Les publishers : L’origine des messages +  - Les publishers : L’origine des messages 
-  -  Les subscribers : La destination des messages +  - Les subscribers : La destination des messages 
-  -  Le broker : L’élément qui fait le lien entre les publishers et les subscribers +  - Le broker : L’élément qui fait le lien entre les publishers et les subscribers 
-  -  Les topics : Canaux de communications.+  - Les topics : Canaux de communications.
  
 > Message Queue Telemetry Transport, MQTT pour abréger, est un protocole de messagerie utile dans la communication entre les dispositifs de l'Internet des objets. Fait intéressant, le protocole a été développé en 1999, alors que l'IdO, qui connaît une croissance rapide, en était à ses balbutiement. > Message Queue Telemetry Transport, MQTT pour abréger, est un protocole de messagerie utile dans la communication entre les dispositifs de l'Internet des objets. Fait intéressant, le protocole a été développé en 1999, alors que l'IdO, qui connaît une croissance rapide, en était à ses balbutiement.
Ligne 163: Ligne 169:
  
 Pour une configuration "Headless", c.-à-d. sans écran et sans clavier, pour que celle-ci puisse démarrer et se connecter en Wifi à votre réseau internet : Pour une configuration "Headless", c.-à-d. sans écran et sans clavier, pour que celle-ci puisse démarrer et se connecter en Wifi à votre réseau internet :
-  -  **Activer la connexion SSH** en créant un fichier ''%%ssh%%'' (sans extension) dans la partition boot +  - **Activer la connexion SSH** en créant un fichier ''%%ssh%%'' (sans extension) dans la partition boot 
-  -  **Créer un fichier ''%%wpa_supplicant.conf%%''**, situé à la racine de la partition boot de la carte avec :+  - **Créer un fichier ''%%wpa_supplicant.conf%%''**, situé à la racine de la partition boot de la carte avec :
  
 <code> <code>
Ligne 177: Ligne 183:
 } }
 </code> </code>
-<HTML><ul></HTML> +Remarque : 
-<HTML><li></HTML>//[Optionnel]// **Fixer l'adresse IP de la machine** si besoin pour le wifi<HTML></li></HTML> +  //[Optionnel]// **Fixer l'adresse IP de la machine** si besoin pour le wifi 
-<HTML><li></HTML><HTML><p></HTML>Faire ''%%sudo nano /etc/dhcpcd.conf%%'' et mettre ceci<HTML></p></HTML>+  Faire ''%%sudo nano /etc/dhcpcd.conf%%'' et mettre ceci 
 <code> <code>
 interface wlan0 interface wlan0
Ligne 185: Ligne 192:
 static routers=192.168.1.1 static routers=192.168.1.1
 static domain_name_servers=192.168.1.1 static domain_name_servers=192.168.1.1
-</code><HTML></li></HTML+</code> 
-<HTML><li></HTML><HTML></li></HTML> +   
-<HTML><li></HTML>Au besoin désactiver le ipV6 en éditant le faisant ''%%sudo nano /etc/sysctl.d/local.conf%%'' et en mettant la ligne suivante ''%%net.ipv6.conf.all.disable_ipv6=1%%''<HTML></li></HTML> +  Au besoin désactiver le ipV6 en éditant le faisant ''%%sudo nano /etc/sysctl.d/local.conf%%'' et en mettant la ligne suivante ''%%net.ipv6.conf.all.disable_ipv6=1%%'' 
-<HTML><li></HTML>Faire ensuite ''%%sudo ifconfig wlan0 down && sudo ifconfig wlan0 up%%''<HTML></li></HTML> +  Faire ensuite ''%%sudo ifconfig wlan0 down && sudo ifconfig wlan0 up%%'' 
-<HTML><li></HTML>**Configurer raspberry** avec ''%%sudo raspi-config%%''<HTML></li></HTML> +  **Configurer raspberry** avec ''%%sudo raspi-config%%'' 
-<HTML><li></HTML>Changer les options de localisations (FR etc.)<HTML></li></HTML> +  Changer les options de localisations (FR etc.) 
-<HTML><li></HTML>''%%sudo apt-get update && sudo apt-get upgrade%%''<HTML></li></HTML> +  ''%%sudo apt-get update && sudo apt-get upgrade%%'' 
-<HTML><li></HTML>''%%sudo apt-get install ntpdate%%''<HTML></li></HTML> +  ''%%sudo apt-get install ntpdate%%'' 
-<HTML><li></HTML>**Changer le mot de passe** par défaut : ''%%passwd%%''<HTML></li></HTML> +  **Changer le mot de passe** par défaut : ''%%passwd%%'' 
-<HTML><li></HTML>**Mettre à jour la date du Raspberry** :<HTML></li></HTML> +  **Mettre à jour la date du Raspberry** : 
-<HTML><li></HTML>Faire ''%%sudo apt-get install ntp%%''<HTML></li></HTML> +  Faire ''%%sudo apt-get install ntp%%'' 
-<HTML><li></HTML>//Editer le fichier ''%%sudo nano /etc/ntp.conf%%'' et dans les pools rajouter ntp.univ.run// (uniquement dans le cas d'un serveur interne à L'université de la Réunion)<HTML></li></HTML> +  //Editer le fichier ''%%sudo nano /etc/ntp.conf%%'' et dans les pools rajouter ntp.univ.run// (uniquement dans le cas d'un serveur interne à L'université de la Réunion) 
-<HTML><li></HTML>//[Optionnel]// **Créer un username différent** :<HTML></li></HTML> +  //[Optionnel]// **Créer un username différent** : 
-<HTML><li></HTML>Faire ''%%sudo adduser house001%%'' et entrer le mot de passante<HTML></li></HTML> +  Faire ''%%sudo adduser house001%%'' et entrer le mot de passante 
-<HTML><li></HTML>Faire ''%%sudo adduser house001 sudo%%'' pour l'ajouter au groupe sudo<HTML></li></HTML> +  Faire ''%%sudo adduser house001 sudo%%'' pour l'ajouter au groupe sudo 
-<HTML><li></HTML>Au besoin, supprimer l'utilisateur pi en faisant ''%%sudo deluser +  Au besoin, supprimer l'utilisateur pi en faisant ''%%sudo deluser 
-  - remove-home pi%%'' ou encore le désactiver en faisant ''%%sudo passwd +  -remove-home pi%%'' ou encore le désactiver en faisant ''%%sudo passwd 
-  -  -lock pi%%''<HTML></li></HTML> +  --lock pi%%'' 
-<HTML><li></HTML>//[Optionnel]// **Pour plus de sécurité, il est possible ensuite** (tuto sur [[https://www.raspberrypi.org/documentation/configuration/security.md|ce site]]) :<HTML></li></HTML> +  //[Optionnel]// **Pour plus de sécurité, il est possible ensuite** (tuto sur [[https://www.raspberrypi.org/documentation/configuration/security.md|ce site]]) : 
-<HTML><li></HTML>Interdire l'accès root en SSH<HTML></li></HTML> +  Interdire l'accès root en SSH 
-<HTML><li></HTML>Obliger le mot de passe pour les ''%%sudo%%''<HTML></li></HTML> +  Obliger le mot de passe pour les ''%%sudo%%'' 
-<HTML><li></HTML>Forcer l'utilisation de clés SSH<HTML></li></HTML> +  Forcer l'utilisation de clés SSH 
-<HTML><li></HTML>Installer un firewall (''%%ufw%%'' ou ''%%iptables%%'')<HTML></li></HTML> +  Installer un firewall (''%%ufw%%'' ou ''%%iptables%%''
-<HTML><li></HTML><HTML><p></HTML>Installer ''%%fail2ban%%''<HTML></p></HTML><HTML></li></HTML><HTML></ul></HTML>+  Installer ''%%fail2ban%%''
  
 ==== Raspberry Pi : Installation du broker ==== ==== Raspberry Pi : Installation du broker ====
 +
 +L'installation se fait comme suit :
  
 <HTML><ul></HTML> <HTML><ul></HTML>
Ligne 218: Ligne 227:
 <HTML><li></HTML>//[Optionnel]// **Créer un accès par mot de passe**<HTML></li></HTML> <HTML><li></HTML>//[Optionnel]// **Créer un accès par mot de passe**<HTML></li></HTML>
 <HTML><li></HTML>''%%sudo mosquitto_passwd <HTML><li></HTML>''%%sudo mosquitto_passwd
-  - c /etc/mosquitto/passwd user%%''<HTML></li></HTML>+  -c /etc/mosquitto/passwd user%%''<HTML></li></HTML>
 <HTML><li></HTML><HTML><p></HTML>Dans ''%%/etc/mosquitto/mosquitto.conf%%'', rajouter les lignes<HTML></p></HTML> <HTML><li></HTML><HTML><p></HTML>Dans ''%%/etc/mosquitto/mosquitto.conf%%'', rajouter les lignes<HTML></p></HTML>
 <code> <code>
 allow_anonymous false allow_anonymous false
 password_file /etc/mosquitto/passwd password_file /etc/mosquitto/passwd
-</code><HTML></li></HTML> +</code> 
-<HTML><li></HTML><HTML><ul></HTML> +Ensuite il faut faire : <HTML></li></HTML> 
-<HTML><li></HTML>Faire ''%%systemctl restart mosquitto%%''<HTML></li></HTML><HTML></ul></HTML>+<HTML><li></HTML> 
 +Faire ''%%systemctl restart mosquitto%%'' 
 <HTML></li></HTML><HTML></ul></HTML> <HTML></li></HTML><HTML></ul></HTML>
  
 Nous interdisons l’accès en anonyme et nous allons autoriser les connexions uniquement avec un identifiant mot de passe (dont la liste se trouve le fichier ''%%passwd%%'' que nous avons créé et est de la forme user:motdepasse). Il est possible aussi pour plus de sécurité de changer le port par défaut (1883), mais dans ce cas, on s'éloigne du standard. Nous interdisons l’accès en anonyme et nous allons autoriser les connexions uniquement avec un identifiant mot de passe (dont la liste se trouve le fichier ''%%passwd%%'' que nous avons créé et est de la forme user:motdepasse). Il est possible aussi pour plus de sécurité de changer le port par défaut (1883), mais dans ce cas, on s'éloigne du standard.
 +
 +//**Remarque : **// la commande ''%%-c%%'' permet de créer le fichier orignal (ou d'écraser l'ancien). Si nous voulons rajouter d'autres utilisateurs, il est faut utiliser la commande ''%%mosquitto_passwd
 +  -b passwordfile user password%%''
  
   * Pour tester la connexion depuis un autre appareil, il est possible d'utiliser le client Java (fichier jar) [[https://github.com/eclipse/paho.mqtt-spy/wiki/Downloads|mqtt-spy]] à fois comme publisher et subscribers ([[https://www.hivemq.com/blog/mqtt-toolbox-mqtt-spy|Infos sur l'appli]]) ou encore [[https://play.google.com/store/apps/details?id=at.tripwire.mqtt.client&hl=fr_FR|MyMQTT]] sur Android   * Pour tester la connexion depuis un autre appareil, il est possible d'utiliser le client Java (fichier jar) [[https://github.com/eclipse/paho.mqtt-spy/wiki/Downloads|mqtt-spy]] à fois comme publisher et subscribers ([[https://www.hivemq.com/blog/mqtt-toolbox-mqtt-spy|Infos sur l'appli]]) ou encore [[https://play.google.com/store/apps/details?id=at.tripwire.mqtt.client&hl=fr_FR|MyMQTT]] sur Android
Ligne 244: Ligne 257:
  
 Lors du débogage de la communication avec un serveur MQTT, il peut s'avérer utile de s'abonner à toutes les rubriques en faisant ''%%mosquitto_sub Lors du débogage de la communication avec un serveur MQTT, il peut s'avérer utile de s'abonner à toutes les rubriques en faisant ''%%mosquitto_sub
-  - h 192.168.0.22 +  -h 192.168.0.22 
-  - v +  -v 
-  - t "#"%%''+  -t "#"%%''
  
 ==== Arduino : Matériel ==== ==== Arduino : Matériel ====
  
 Dans notre cas, nous avons utilisé : Dans notre cas, nous avons utilisé :
-  -  Un [[https://store.arduino.cc/arduino-uno-rev3|Arduino Uno R3]] +  - Un [[https://store.arduino.cc/arduino-uno-rev3|Arduino Uno R3]] 
-  -  Un [[https://www.seeedstudio.com/Base-Shield-V2-p-1378.html|Grove Base Shield]] +  - Un [[https://www.seeedstudio.com/Base-Shield-V2-p-1378.html|Grove Base Shield]] 
-  -  Un [[http://wiki.seeedstudio.com/Grove-LCD_RGB_Backlight/|Grove +  - Un [[http://wiki.seeedstudio.com/Grove-LCD_RGB_Backlight/|Grove 
-  -  LCD RGB Backlight]] +  - LCD RGB Backlight]] 
-  -  Un [[https://www.adafruit.com/product/3653|Adafruit ATWINC1500 WiFi Shield]]+  - Un [[https://www.adafruit.com/product/3653|Adafruit ATWINC1500 WiFi Shield]]
  
 Le //Grove Le //Grove
-  -  LCD RGB Backlight// est branché sur le 1er port //I2C// du //Grove Base Shield//. Ce dernier (mis sous 5V) a été placé entre le //WiFi Shield// et l'//Arduino//.+  - LCD RGB Backlight// est branché sur le 1er port //I2C// du //Grove Base Shield//. Ce dernier (mis sous 5V) a été placé entre le //WiFi Shield// et l'//Arduino//.
  
-L'//Arduino// est alimenté par une source externe par connecteur Jack, à 7V, en respectant la polarité (le + est à l’intérieur et le  à l’extérieur).+L'//Arduino// est alimenté par une source externe par connecteur Jack, à 7V, en respectant la polarité (le + est à l’intérieur et le 
 +  à l’extérieur).
  
 Les //Adafruit ATWINC1500 WiFi Shield// ont été mis à jour avec le dernier firmware (Voir [[https://learn.adafruit.com/adafruit-winc1500-wifi-shield-for-arduino?view=all#updating-firmware|Site officiel]]). Les //Adafruit ATWINC1500 WiFi Shield// ont été mis à jour avec le dernier firmware (Voir [[https://learn.adafruit.com/adafruit-winc1500-wifi-shield-for-arduino?view=all#updating-firmware|Site officiel]]).
Ligne 269: Ligne 283:
  
 Il est important de bien configurer l'IDE et d'importer les bibliothèques nécessaires : Il est important de bien configurer l'IDE et d'importer les bibliothèques nécessaires :
-  -  Librairies : +  - Librairies : 
-  -  WiFi101 +  - WiFi101 
-  -  Adafruit IO Arduino +  - Adafruit IO Arduino 
-  -  Grove +  - Grove 
-  -  LCD RGB Backlight +  - LCD RGB Backlight 
-  -  Pubsubclient //<- non utilisé// +  - Pubsubclient //<- non utilisé// 
-  -  Configuration : +  - Configuration : 
-  -  Type de carte : **Arduino/Genuino Uno** +  - Type de carte : **Arduino/Genuino Uno** 
-  -  Serial : **9600 baud**+  - Serial : **9600 baud**
  
 ==== Arduino : Code ==== ==== Arduino : Code ====
  
 Le déroulement du programme est le suivant : Le déroulement du programme est le suivant :
-  -  Imports & Initialisations +  - Imports & Initialisations 
-  -  Connexion au WiFi +  - Connexion au Wifi 
-  -  Inscription au flux ''%%user/feeds/onoff%%'' +  - Inscription au flux ''%%user/feeds/onoff%%'' 
-  -  Boucle : +  - Boucle : 
-  -  Connection au serveur MQTT (si non connecté ou si déconnexion) +  - Connexion au serveur MQTT (si non connecté ou si déconnexion) 
-  -  Ecoute au flux ''%%user/feeds/onoff%%'' et affiche sur le LCD s'il y ON ou OFF reçus. +  - Ecoute au flux ''%%user/feeds/onoff%%'' et affiche sur le LCD s'il y ON ou OFF reçus. 
-  -  Publication d'un entier (croissant au fur et à mesure) sur le flux ''%%user/feeds/numbers%%''+  - Publication d'un entier (croissant au fur et à mesure) sur le flux ''%%user/feeds/numbers%%''
  
 Le code du programme ''%%MQTT_Basic%%'' est : Le code du programme ''%%MQTT_Basic%%'' est :
Ligne 307: Ligne 321:
  
 // //
-  -  --------------------------- GROVE LCD Lib +  ---------------------------- GROVE LCD Lib 
-  -  ------------------------+  -------------------------
 //#include <Wire.h>           // i2c LIB to use LCD //#include <Wire.h>           // i2c LIB to use LCD
 #include "rgb_lcd.h"        // lcd LIB #include "rgb_lcd.h"        // lcd LIB
Ligne 348: Ligne 362:
  
 // //
-  -  -------------------------- Variables & others +  --------------------------- Variables & others 
-  -  -------------------------------+  --------------------------------
 rgb_lcd lcd; rgb_lcd lcd;
 byte heart[8] = { byte heart[8] = {
Ligne 364: Ligne 378:
 void setup() { void setup() {
     //     //
-  -  ------------------------ Initialization Serial +  ------------------------- Initialization Serial 
-  -  -----------------------------+  ------------------------------
     while (!Serial);  // wait for serial port to connect. Needed for native USB port only     while (!Serial);  // wait for serial port to connect. Needed for native USB port only
     Serial.begin(9600);     Serial.begin(9600);
Ligne 372: Ligne 386:
  
     //     //
-  -  --------------------- Initialization Wifi WINC1500 +  ---------------------- Initialization Wifi WINC1500 
-  -  -------------------------+  --------------------------
     // Initialise the Client     // Initialise the Client
     Serial.print(F("\nInit the WiFi module..."));     Serial.print(F("\nInit the WiFi module..."));
Ligne 385: Ligne 399:
  
     //     //
-  -  ----------------------------- Physical part +  ------------------------------ Physical part 
-  -  ---------------------------------+  ----------------------------------
  
     Serial.println(F("LCD Init"));     Serial.println(F("LCD Init"));
Ligne 403: Ligne 417:
  
     //     //
-  -  -------------------------- Variables & others +  --------------------------- Variables & others 
-  -  -------------------------------+  --------------------------------
     mqtt.subscribe(&onoffmsg);     mqtt.subscribe(&onoffmsg);
 } }
Ligne 412: Ligne 426:
 void loop() { void loop() {
     //     //
-  -  ----------------------------- MQTT Connection +  ------------------------------ MQTT Connection 
-  -  -------------------------------+  --------------------------------
     // Ensure the connection to the MQTT server is alive (this will make the first     // Ensure the connection to the MQTT server is alive (this will make the first
     // connection and automatically reconnect when disconnected).     // connection and automatically reconnect when disconnected).
Ligne 419: Ligne 433:
     lcd.setRGB(255,165,0);     lcd.setRGB(255,165,0);
     //     //
-  -  ----------------------------- Subscription +  ------------------------------ Subscription 
-  -  ----------------------------------+  -----------------------------------
     Adafruit_MQTT_Subscribe *subscription;     Adafruit_MQTT_Subscribe *subscription;
     while ((subscription = mqtt.readSubscription(5000))) {     while ((subscription = mqtt.readSubscription(5000))) {
Ligne 441: Ligne 455:
  
     //     //
-  -  ----------------------------- Publication +  ------------------------------ Publication 
-  -  ---------------------------------+  ----------------------------------
     Serial.print(F("\nSending "));     Serial.print(F("\nSending "));
     Serial.print(x);     Serial.print(x);
Ligne 497: Ligne 511:
 </code> </code>
 Remarques sur ce code : Remarques sur ce code :
-  -  Le ''%%USERNAME%%'' et ''%%PWD%%'' sont ceux qui ont été défini dans les **mosquitto_passwd** (voir précédemment). +  - Le ''%%USERNAME%%'' et ''%%PWD%%'' sont ceux qui ont été définis dans les **mosquitto_passwd** (voir précédemment). 
-  -  Le mot de passe du wifi est stocké dans ''%%arduino_secrets.h%%'' (mais celui du broker, volontairement) +  - Le mot de passe du wifi est stocké dans ''%%arduino_secrets.h%%'' (mais celui du broker, volontairement) 
-  -  Dès que la mémoire dynamique (vive) est utilisé à plus de 80%, il y a des soucis de connexion au wifi comme au MQTT. +  - Dès que la mémoire dynamique (vive) est utilisée à plus de 80%, il y a des soucis de connexion au wifi comme au MQTT. 
-  -  La solution la plus rapide pour diminuer ce nombre a été de remplacer ''%%Serial.println("Text")%%'' par ''%%Serial.println(F("Text"))%%''. Cela fonctionne aussi pour les ''%%lcd.print%%''+  - La solution la plus rapide pour diminuer ce nombre a été de remplacer ''%%Serial.println("Text")%%'' par ''%%Serial.println(F("Text"))%%''. Cela fonctionne aussi pour les ''%%lcd.print%%''
-  -  Une autre solution est de mettre ''%%const%%'' partout où celà est possible ! +  - Une autre solution est de mettre ''%%const%%'' partout où cela est possible ! 
-  -  Une solution plus complexe mais envisageable à la fin est d'utiliser ''%%PROGMEM%%''+  - Une solution plus complexemais envisageable à la fin est d'utiliser ''%%PROGMEM%%''
-  -  Sachant que les ''%%Serial.println%%'' utilise beaucoup cette SRAM, il est possible : +  - Sachant que les ''%%Serial.println%%'' utilisent beaucoup cette SRAM, il est possible : 
-  -  de le supprimer lorsque tout fonctionne +  - de le supprimer lorsque tout fonctionne 
-  -  d'utiliser ce genre d'astuce+  - d'utiliser ce genre d'astuce
  
 <code cpp> <code cpp>
Ligne 517: Ligne 531:
 #endif #endif
 </code> </code>
-Plus d'informations sur la fonction ''%%F()%%'' et sur la gestion de mémoire sont disponible +Plus d'informations sur la fonction ''%%F()%%'' et sur la gestion de mémoire sont disponibles 
-  -  en français sur [[https://www.carnetdumaker.net/articles/reduire-lempreinte-memoire-dun-programme-arduino-avec-progmem/|ce site]] et [[https://zestedesavoir.com/tutoriels/374/gestion-de-la-memoire-sur-arduino/|ce site]]. +  - En français sur [[https://www.carnetdumaker.net/articles/reduire-lempreinte-memoire-dun-programme-arduino-avec-progmem/|ce site]] et [[https://zestedesavoir.com/tutoriels/374/gestion-de-la-memoire-sur-arduino/|ce site]]. 
-  -  en anglais sur [[https://learn.adafruit.com/memories-of-an-arduino/optimizing-sram|ce site]] et [[https://forum.arduino.cc/index.php?topic=79436.0|ce forum]].+  - En anglais sur [[https://learn.adafruit.com/memories-of-an-arduino/optimizing-sram|ce site]] et [[https://forum.arduino.cc/index.php?topic=79436.0|ce forum]].
  
 +Le fichier ''%%arduino_secrets.h%%'' contient le code suivant :
 +
 +<code c>
 +#define SECRET_SSID "NOM-POINT-D-ACCES"
 +#define SECRET_PASS "MDP-WIFI"
 +</code>
 ===== Application ===== ===== Application =====
  
Ligne 526: Ligne 546:
  
 Pour la suite du test, nous avons fait le montage suivant sur le Arduino : Pour la suite du test, nous avons fait le montage suivant sur le Arduino :
-  -  Nous avons branché un [[https://www.elecfreaks.com/wiki/index.php?title=Octopus_Current_Sensor|Octopus Current Sensor]] en plaçant le signal reçu sur le PIN A0. Sur ce relay, nous avons branché une LED (et un résistance ainsi qu'un potentiomètre).+  - Nous avons branché un [[https://www.elecfreaks.com/wiki/index.php?title=Octopus_Current_Sensor|Octopus Current Sensor]] en plaçant le signal reçu sur le PIN A0. Sur ce relai, nous avons branché une LED (et une résistance ainsi qu'un potentiomètre).
  
-{{http://www.robitshop.com/octopus-current-sensor-10267-42-B.jpg%7Cwidth=100| Octopus Current Sensor}}+{{http://www.robitshop.com/octopus-current-sensor-10267-42-B.jpg| Octopus Current Sensor}}
  
-  * Nous avons utilisé un [[http://www.mantech.co.za/Datasheets/Products/IDUINO-ME114.pdf|4 Channel 12vdc Relay Module IDUINO Board]] en branchat le Relay sur le PIN 7+  * Nous avons utilisé un [[http://www.mantech.co.za/Datasheets/Products/IDUINO-ME114.pdf|4 Channel 12vdc Relay Module IDUINO Board]] en branchant le Relay sur le PIN 7
  
-{{https://www.jaycar.com.au/medias/sys_master/images/9105856659486/arduino-compatible-4-channel-12v-relay-moduleImageMain-515.jpg|4 Channel 12vdc Relay Module Board}}{:height="50%" width="50%"}+{{https://www.jaycar.com.au/medias/sys_master/images/9105856659486/arduino-compatible-4-channel-12v-relay-moduleImageMain-515.jpg|4 Channel 12vdc Relay Module Board}}
  
 <code c> <code c>
Ligne 548: Ligne 568:
   digitalWrite(RELAY1, LOW); // Turns ON Relays 1   digitalWrite(RELAY1, LOW); // Turns ON Relays 1
   Serial.println("---------------------- OFF   Serial.println("---------------------- OFF
-  -  ---------------------");+  ----------------------");
   delay(5000);   delay(5000);
   mesure(analogInPin);   mesure(analogInPin);
Ligne 555: Ligne 575:
   digitalWrite(RELAY1, HIGH); // Turns Relay Off   digitalWrite(RELAY1, HIGH); // Turns Relay Off
   Serial.println("---------------------- ON   Serial.println("---------------------- ON
-  -  ----------------------");+  -----------------------");
   delay(2000);   delay(2000);
   mesure(analogInPin);   mesure(analogInPin);
Ligne 573: Ligne 593:
   Serial.println(sensorValue);   Serial.println(sensorValue);
   sensorValue = ((sensorValue   sensorValue = ((sensorValue
-  -  506) * 5 / 1024 / 0.066);+  - 506) * 5 / 1024 / 0.066);
   // print the results to the serial monitor:   // print the results to the serial monitor:
   Serial.print("Converted = ");   Serial.print("Converted = ");
Ligne 585: Ligne 605:
  
 Ensuite nous avons modifié le code original de notre Arduino (voir [[#arduino-code|Arduino : Code]]) pour que : Ensuite nous avons modifié le code original de notre Arduino (voir [[#arduino-code|Arduino : Code]]) pour que :
-  -  Le relay s'actionne lorsque la valeur lut sur le flux ''%%user/feeds/onoff%%'' est **ON** et s'éteint lorsque la valeur est **OFF**. +  - Le relai s'actionne lorsque la valeur lut sur le flux ''%%user/feeds/onoff%%'' est **ON** et s'éteint lorsque la valeur est **OFF**. 
-  -  Le capteur permet de mesurer le courant que nous ferons varier avec un potentiomètre. L'Arduino renverra cette valeur sur le broker MQTT.+  - Le capteur permet de mesurer le courant que nous ferons varier avec un potentiomètre. L'Arduino renverra cette valeur sur le broker MQTT.
  
 Nous avons donc le code suivant : Nous avons donc le code suivant :
Ligne 605: Ligne 625:
  
 // //
-  -  --------------------------- GROVE LCD Lib +  ---------------------------- GROVE LCD Lib 
-  -  ------------------------+  -------------------------
 //#include <Wire.h>           // i2c LIB to use LCD //#include <Wire.h>           // i2c LIB to use LCD
 #include "rgb_lcd.h"        // lcd LIB #include "rgb_lcd.h"        // lcd LIB
Ligne 652: Ligne 672:
  
 // //
-  -  -------------------------- Variables & others +  --------------------------- Variables & others 
-  -  -------------------------------+  --------------------------------
 rgb_lcd lcd; rgb_lcd lcd;
 byte heart[8] = { byte heart[8] = {
Ligne 668: Ligne 688:
 void setup() { void setup() {
     //     //
-  -  ------------------------ Initialization Serial +  ------------------------- Initialization Serial 
-  -  -----------------------------+  ------------------------------
     while (!Serial);  // wait for serial port to connect. Needed for native USB port only     while (!Serial);  // wait for serial port to connect. Needed for native USB port only
     Serial.begin(9600);     Serial.begin(9600);
Ligne 676: Ligne 696:
  
     //     //
-  -  --------------------- Initialization Wifi WINC1500 +  ---------------------- Initialization Wifi WINC1500 
-  -  -------------------------+  --------------------------
     // Initialise the Client     // Initialise the Client
     Serial.print(F("\nInit the WiFi module..."));     Serial.print(F("\nInit the WiFi module..."));
Ligne 689: Ligne 709:
  
     //     //
-  -  ----------------------------- Physical part +  ------------------------------ Physical part 
-  -  ---------------------------------+  ----------------------------------
  
     Serial.println(F("LCD Init"));     Serial.println(F("LCD Init"));
Ligne 709: Ligne 729:
  
     //     //
-  -  -------------------------- Variables & others +  --------------------------- Variables & others 
-  -  -------------------------------+  --------------------------------
     mqtt.subscribe(&onoffmsg);     mqtt.subscribe(&onoffmsg);
 } }
Ligne 718: Ligne 738:
 void loop() { void loop() {
     //     //
-  -  ----------------------------- MQTT Connection +  ------------------------------ MQTT Connection 
-  -  -------------------------------+  --------------------------------
     // Ensure the connection to the MQTT server is alive (this will make the first     // Ensure the connection to the MQTT server is alive (this will make the first
     // connection and automatically reconnect when disconnected).     // connection and automatically reconnect when disconnected).
Ligne 725: Ligne 745:
     lcd.setRGB(255,165,0);     lcd.setRGB(255,165,0);
     //     //
-  -  ----------------------------- Subscription +  ------------------------------ Subscription 
-  -  ----------------------------------+  -----------------------------------
     Adafruit_MQTT_Subscribe *subscription;     Adafruit_MQTT_Subscribe *subscription;
     while ((subscription = mqtt.readSubscription(5000))) {     while ((subscription = mqtt.readSubscription(5000))) {
Ligne 749: Ligne 769:
  
     //     //
-  -  ----------------------------- Publication +  ------------------------------ Publication 
-  -  ---------------------------------+  ----------------------------------
  
     Serial.print(F("\nSending "));     Serial.print(F("\nSending "));
Ligne 811: Ligne 831:
   Voltage = (RawValue / 1024.0) * 5000; // Gets you mV   Voltage = (RawValue / 1024.0) * 5000; // Gets you mV
   Amps = ((Voltage   Amps = ((Voltage
-  -  ACSoffset) / mVperAmp);+  - ACSoffset) / mVperAmp);
   /*Serial.print("Raw Value = " ); // shows pre-scaled value   /*Serial.print("Raw Value = " ); // shows pre-scaled value
   Serial.print(RawValue);   Serial.print(RawValue);
Ligne 826: Ligne 846:
 </code> </code>
 Remarque : Remarque :
-  -  on est toujours confronté au problème de mémoire dynamique. Dans les logs de téléversement de Arduino, si dans la phrase ''%%Les variables globales utilisent 1614 octets (78%) de mémoire dynamique%%'', la mémoire utilisé arrive ou dépasse **80%** la connexion au wifi devient impossible...+  - on est toujours confronté au problème de mémoire dynamique. Dans les logs de téléversement de Arduino, si dans la phrase ''%%Les variables globales utilisent 1614 octets (78%) de mémoire dynamique%%'', la mémoire utilisée arrive ou dépasse **80%** la connexion au wifi devient impossible...
  
 ====== Bonus(es) ====== ====== Bonus(es) ======
Ligne 834: Ligne 854:
 Il est possible d'accéder au broker depuis l'extérieur en suivant une partie du tuto suivant : [[http://devotics.fr/installez-home-assistant/|Tuto IpDynamique]] Il est possible d'accéder au broker depuis l'extérieur en suivant une partie du tuto suivant : [[http://devotics.fr/installez-home-assistant/|Tuto IpDynamique]]
  
-===== Mosquitto et Node-RED =====+===== MQTT et Node-RED =====
  
-Node-RED est un outil puissant pour construire des applications de l'Internet des Objets (IoT) en mettant l'accent sur la simplification de la programmation qui se fait grâce à des blocs de code prédéfinis, appelés « nodes » ''%%pour%%'' effectuer des tâches. Il utilise une approche de programmation visuelle qui permet aux développeurs de connecter les blocs de code ensemble. Les nœuds connectés, généralement une combinaison de nœuds d'entrée, de nœuds de traitement et de nœuds de sortie, lorsqu'ils sont câblés ensemble, constituent un « flow ». [[http://silanus.fr/sin/?p=984|Tuto Node-Red]]+Node-RED est un outil puissant pour construire des applications de l'Internet des Objets (IoT) en mettant l'accent sur la simplification de la programmation qui se fait grâce à des blocs de code prédéfinis, appelés « nodes » ''%%pour%%'' effectuer des tâches. Il utilise une approche de programmation visuelle qui permet aux développeurs de connecter les blocs de code ensemble. Les nœuds connectés, généralement une combinaison de nœuds d'entrée, de nœuds de traitement et de nœuds de sortie, lorsqu'ils sont câblés ensemble, constituent un « flow ». [[http://silanus.fr/sin/?p=984|Tuto Node-RED]]
  
 La vocation de cette solution est de permettre de lier aisément des sources de données à des composants de traitement, locaux ou distants, et de créer des chaines de valeurs en quelques clics. La vocation de cette solution est de permettre de lier aisément des sources de données à des composants de traitement, locaux ou distants, et de créer des chaines de valeurs en quelques clics.
  
-Node-RED est compatible avec MQTT : [[https://bentek.fr/mosquitto-node-red-raspberry-pi/|Tuto MQTT Node-Red]]+Node-RED est compatible avec MQTT : [[https://bentek.fr/mosquitto-node-red-raspberry-pi/|Tuto MQTT Node-RED]]
  
-===== Installation Node-RED =====+==== Installation Node-RED ====
  
 Sur le raspberry-pi, allez dans le menu : **"Menu Sur le raspberry-pi, allez dans le menu : **"Menu
-  - > Preferences +  -> Preferences 
-  - > Recommended Software"**. Node-RED en fait partie depuis 2018.+  -> Recommended Software"**. Node-RED en fait partie depuis 2018.
  
 Si déjà installé, il est possible (voire préférable) de faire un ''%%sudo apt-get upgrade%%''. D'autres options d'installation sont disponibles sur [[https://nodered.org/docs/hardware/raspberrypi|le site officiel]]. Si déjà installé, il est possible (voire préférable) de faire un ''%%sudo apt-get upgrade%%''. D'autres options d'installation sont disponibles sur [[https://nodered.org/docs/hardware/raspberrypi|le site officiel]].
  
-Node-red peut fonctionner tel quel, cependant, pour pouvoir rajouter des modules, il faut avoir ''%%npm%%'' en faisant ''%%sudo apt-get install npm%%'' et en mettant à jour ''%%sudo npm i npm +Node-RED peut fonctionner tel quel, cependant, pour pouvoir rajouter des modules, il faut avoir ''%%npm%%'' en faisant ''%%sudo apt-get install npm%%'' et en mettant à jour ''%%sudo npm i npm 
-  - g%%''. (sinon, l'option //"Manage Palette"// sera absent)+  -g%%''. (sinon, l'option //"Manage Palette"// sera absente)
  
 Une autre possibilité est de lancer la commande suivante, qui permet de faire tout ce qu'il y a à faire : ''%%bash <(curl Une autre possibilité est de lancer la commande suivante, qui permet de faire tout ce qu'il y a à faire : ''%%bash <(curl
-  - sL https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/update-nodejs-and-nodered)%%''+  -sL https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/update-nodejs-and-nodered)%%'' 
 + 
 +{{https://wiki.mchobby.be/images/8/8d/Rasp-Node-RED-install-node-01.png| script}} 
 + 
 +==== Démarrage ==== 
 + 
 +Pour démarrer Node-RED dans **"Menu 
 +  -> Programmation 
 +  -> Node-RED"**. On peut également démarrer depuis le Terminal avec la commande ''%%sudo node-red-start%%''
 + 
 +Remarque : 
 +  - Pour permettre d'auto-start de node-red, il faut faire ''%%sudo systemctl enable nodered.service%%'' 
 +  - On accéde à Node-RED avec http:%%//%%localhost:1880/ ou encore http:%%//%%adresse-Ip-Du-Rpi:1880/ 
 + 
 +{{https://dennisschultz.files.wordpress.com/2015/06/node-red-startup.png| Ecran de démarrage}} 
 + 
 +==== Module Dashboard ==== 
 + 
 +=== Installation du module === 
 + 
 +Pour contrôler nos objets MQTT, nous allons utiliser le module Dashboard. Pour cela: 
 +  - Aller dans le menu de Node-RED en haut à droite 
 +  - Cliquer sur //"Manage Palette"// 
 +  - Dans l'onglet install, chercher et installer node-red-dashboard 
 + 
 +=== Configuration du module === 
 + 
 +  * Aller dans le menu de Node-RED en haut à droite 
 +  * Cliquer sur //"View 
 +  -> Dashboard"// 
 +  * Cliquer sur **+tab** pour rajouter un écran, dans lequel on mette ensuite 2 groupes avec **+group** Note : On accéde à Node-RED avec http:%%//%%localhost:1880/ui (après avoir déployé le flux) 
 + 
 +=== Création de Nodes === 
 + 
 +Une fois les nodes créés et liés, en cliquant sur **"deploy"** en haut à droite, on permet la mise en fonction de ces nodes. 
 + 
 +== Nodes MQTT == 
 + 
 +  * Faire un drag & drop d'un node MQTT **A** en input 
 +  * Le configurer : 
 +  * Configurer le serveur la première fois 
 +  * Configurer le topic %%//%%"user/feeds/numbers"%%//%% 
 +  * Faire un drag & drop d'un node MQTT **B** en output 
 +  * Le configurer : 
 +  * Résutiliser le même serveur 
 +  * Configurer le topic %%//%%"user/feeds/onff"%%//%% 
 + 
 +== Nodes Dashboard == 
 + 
 +  * Faire un drag & drop d'un node switch (input du dashboard) 
 +  * Le connecter avec l'entrée du node **B** 
 +  * Le configurer 
 +  * Mettre **ON** pour %%//%%"On Payload"%%//%% (sous forme de string) 
 +  * Mettre **OFF** pour %%//%%"Off Payload"%%//%% (sous forme de string) 
 +  * Faire un drag & drop d'un node text (output du dashboard) 
 +  * Le connecter avec la sortie du node **A** 
 +  * Le configurer (on peut laisser ce qu'il y a par défaut) 
 +  * Faire un drag & drop d'un node chart (output du dashboard) 
 +  * Le connecter avec la sortie du node **A** 
 +  * Le configurer (on peut laisser ce qu'il y a par défaut) 
 + 
 +== Pour test: == 
 + 
 +Pour aller plus rapidement, il est possible de faire directement un import du code json du flow au lieu de créer les nodes précédents : 
 + 
 +<code> 
 +
 +    { 
 +        "id": "798f513a.e8a04", 
 +        "type": "tab", 
 +        "label": "Mon 1er flow", 
 +        "disabled": false, 
 +        "info": "Flow de test pour :\n- Récupérer une donnée MQTT et afficher\n- Envoyer une valeur par MQTT" 
 +    }, 
 +    { 
 +        "id": "57a9ca2c.283154", 
 +        "type": "ui_base", 
 +        "theme":
 +            "name": "theme-dark", 
 +            "lightTheme":
 +                "default": "#0094CE", 
 +                "baseColor": "#0094CE", 
 +                "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif", 
 +                "edited": true, 
 +                "reset": false 
 +            }, 
 +            "darkTheme":
 +                "default": "#097479", 
 +                "baseColor": "#097479", 
 +                "baseFont": "Verdana,Verdana,Geneva,sans-serif", 
 +                "edited": true, 
 +                "reset": false 
 +            }, 
 +            "customTheme":
 +                "name": "Untitled Theme 1", 
 +                "default": "#4B7930", 
 +                "baseColor": "#4B7930", 
 +                "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif", 
 +                "reset": false 
 +            }, 
 +            "themeState":
 +                "base-color":
 +                    "default": "#097479", 
 +                    "value": "#097479", 
 +                    "edited": false 
 +                }, 
 +                "page-titlebar-backgroundColor":
 +                    "value": "#097479", 
 +                    "edited": false 
 +                }, 
 +                "page-backgroundColor":
 +                    "value": "#111111", 
 +                    "edited": false 
 +                }, 
 +                "page-sidebar-backgroundColor":
 +                    "value": "#000000", 
 +                    "edited": false 
 +                }, 
 +                "group-textColor":
 +                    "value": "#0eb8c0", 
 +                    "edited": false 
 +                }, 
 +                "group-borderColor":
 +                    "value": "#555555", 
 +                    "edited": false 
 +                }, 
 +                "group-backgroundColor":
 +                    "value": "#333333", 
 +                    "edited": false 
 +                }, 
 +                "widget-textColor":
 +                    "value": "#eeeeee", 
 +                    "edited": false 
 +                }, 
 +                "widget-backgroundColor":
 +                    "value": "#097479", 
 +                    "edited": false 
 +                }, 
 +                "widget-borderColor":
 +                    "value": "#333333", 
 +                    "edited": false 
 +                }, 
 +                "base-font":
 +                    "value": "Verdana,Verdana,Geneva,sans-serif" 
 +                } 
 +            } 
 +        }, 
 +        "site":
 +            "name": "Node-RED Dashboard", 
 +            "hideToolbar": "false", 
 +            "allowSwipe": "false", 
 +            "allowTempTheme": "true", 
 +            "dateFormat": "DD/MM/YYYY", 
 +            "sizes":
 +                "sx": 48, 
 +                "sy": 48, 
 +                "gx": 6, 
 +                "gy": 6, 
 +                "cx": 6, 
 +                "cy": 6, 
 +                "px": 0, 
 +                "py":
 +            } 
 +        } 
 +    }, 
 +    { 
 +        "id": "106a0892.4df7b7", 
 +        "type": "ui_tab", 
 +        "z": "", 
 +        "name": "Ecran principale", 
 +        "icon": "dashboard", 
 +        "order":
 +    }, 
 +    { 
 +        "id": "8e831ec7.d81eb", 
 +        "type": "ui_group", 
 +        "z": "", 
 +        "name": "Flux reçus", 
 +        "tab": "106a0892.4df7b7", 
 +        "order": 1, 
 +        "disp": true, 
 +        "width": "6", 
 +        "collapse": false 
 +    }, 
 +    { 
 +        "id": "279e1ad8.ebeae6", 
 +        "type": "ui_group", 
 +        "z": "", 
 +        "name": "Envoie infos", 
 +        "tab": "106a0892.4df7b7", 
 +        "order": 2, 
 +        "disp": true, 
 +        "width": "6", 
 +        "collapse": false 
 +    }, 
 +    { 
 +        "id": "f460a0.8fc35f6", 
 +        "type": "mqtt-broker", 
 +        "z": "", 
 +        "name": "Mon Broker", 
 +        "broker": "localhost", 
 +        "port": "1883", 
 +        "clientid": "", 
 +        "usetls": false, 
 +        "compatmode": true, 
 +        "keepalive": "60", 
 +        "cleansession": true, 
 +        "birthTopic": "", 
 +        "birthQos": "0", 
 +        "birthPayload": "", 
 +        "closeTopic": "", 
 +        "closeQos": "0", 
 +        "closePayload": "", 
 +        "willTopic": "", 
 +        "willQos": "0", 
 +        "willPayload": "" 
 +    }, 
 +    { 
 +        "id": "503ea954.5b97c8", 
 +        "type": "ui_switch", 
 +        "z": "798f513a.e8a04", 
 +        "name": "ON/OFF switch", 
 +        "label": "ON/OFF switch", 
 +        "group": "279e1ad8.ebeae6", 
 +        "order": 0, 
 +        "width": 0, 
 +        "height": 0, 
 +        "passthru": true, 
 +        "decouple": "false", 
 +        "topic": "switch", 
 +        "style": "", 
 +        "onvalue": "ON", 
 +        "onvalueType": "str", 
 +        "onicon": "", 
 +        "oncolor": "", 
 +        "offvalue": "OFF", 
 +        "offvalueType": "str", 
 +        "officon": "", 
 +        "offcolor": "", 
 +        "x": 225, 
 +        "y": 265, 
 +        "wires":
 +            [ 
 +                "8495340b.8c7758" 
 +            ] 
 +        ] 
 +    }, 
 +    { 
 +        "id": "e98fe402.458458", 
 +        "type": "ui_text", 
 +        "z": "798f513a.e8a04", 
 +        "group": "8e831ec7.d81eb", 
 +        "order": 0, 
 +        "width": 0, 
 +        "height": 0, 
 +        "name": "Valeur actuelle", 
 +        "label": "Valeur Actuelle", 
 +        "format": "{{msg.payload}}", 
 +        "layout": "row-spread", 
 +        "x": 220, 
 +        "y": 323, 
 +        "wires": [] 
 +    }, 
 +    { 
 +        "id": "9878823e.bbfaa", 
 +        "type": "mqtt in", 
 +        "z": "798f513a.e8a04", 
 +        "name": "Lecture user/feeds/numbers", 
 +        "topic": "user/feeds/numbers", 
 +        "qos": "2", 
 +        "broker": "f460a0.8fc35f6", 
 +        "x": 144, 
 +        "y": 455, 
 +        "wires":
 +            [ 
 +                "e98fe402.458458", 
 +                "a63e7897.d1d608" 
 +            ] 
 +        ] 
 +    }, 
 +    { 
 +        "id": "8495340b.8c7758", 
 +        "type": "mqtt out", 
 +        "z": "798f513a.e8a04", 
 +        "name": "Envoie vers user/feeds/onoff", 
 +        "topic": "user/feeds/onoff", 
 +        "qos": "", 
 +        "retain": "", 
 +        "broker": "f460a0.8fc35f6", 
 +        "x": 392, 
 +        "y": 175, 
 +        "wires": [] 
 +    }, 
 +    { 
 +        "id": "a63e7897.d1d608", 
 +        "type": "ui_chart", 
 +        "z": "798f513a.e8a04", 
 +        "name": "Valeur du courant", 
 +        "group": "8e831ec7.d81eb", 
 +        "order": 0, 
 +        "width": 0, 
 +        "height": 0, 
 +        "label": "Valeur du courant", 
 +        "chartType": "line", 
 +        "legend": "true", 
 +        "xformat": "HH:mm:ss", 
 +        "interpolate": "linear", 
 +        "nodata": "", 
 +        "dot": true, 
 +        "ymin": "", 
 +        "ymax": "", 
 +        "removeOlder": 1, 
 +        "removeOlderPoints": "", 
 +        "removeOlderUnit": "3600", 
 +        "cutout": 0, 
 +        "useOneColor": false, 
 +        "colors":
 +            "#1f77b4", 
 +            "#aec7e8", 
 +            "#ff7f0e", 
 +            "#2ca02c", 
 +            "#98df8a", 
 +            "#d62728", 
 +            "#ff9896", 
 +            "#9467bd", 
 +            "#c5b0d5" 
 +        ], 
 +        "useOldStyle": false, 
 +        "x": 339, 
 +        "y": 548, 
 +        "wires":
 +            [], 
 +            [] 
 +        ] 
 +    } 
 +
 +</code> 
 +===== MQTT et InfluxDB ===== 
 + 
 +En partant du principe que InfluxDB a été installé (voir [[https://gist.github.com/gyassine/27dd5bc1ff84bc3e98f6d0ec5cb549f4|mon tuto]]), la configuration de telegraf se fait comme suit : 
 + 
 +<code bash> 
 +[[inputs.mqtt_consumer]] 
 +   ## MQTT broker URLs to be used. The format should be scheme://host:port, 
 +   ## schema can be tcp, ssl, or ws. 
 +   servers = ["tcp://10.243.4.250:1883"
 + 
 +   ## MQTT QoS, must be 0, 1, or 2 
 +   qos = 0 
 +   ## Connection timeout for initial connection in seconds 
 +   connection_timeout = "30s" 
 + 
 +   ## Topics to subscribe to 
 +   topics = [ 
 +     "CtrlLoad/#", 
 +     "NetwEmul/#", 
 +     "SolarPan/#", 
 +   ] 
 + 
 +   # if true, messages that can't be delivered while the subscriber is offline 
 +   # will be delivered when it comes back (such as on service restart). 
 +   # NOTE: if true, client_id MUST be set 
 +   persistent_session = false 
 +   # If empty, a random client ID will be generated. 
 +   client_id = "" 
 + 
 +   ## username and password to connect MQTT server. 
 +   username = "Admin" 
 +   password = "apqm" 
 + 
 +   ## Optional SSL Config 
 +   # ssl_ca = "/etc/telegraf/ca.pem" 
 +   # ssl_cert = "/etc/telegraf/cert.pem" 
 +   # ssl_key = "/etc/telegraf/key.pem" 
 +   ## Use SSL but skip chain & host verification 
 +   # insecure_skip_verify = false 
 + 
 +   ## Data format to consume. 
 +   ## Each data format has its own unique set of configuration options, read 
 +   ## more about them here: 
 +   ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_INPUT.md 
 +   data_format = "value" 
 +   data_type= "integer" 
 + 
 +</code> 
 +Les valeurs sont ensuite stocké avec les tag appropriés (par exemple ''%%CtrlLoad/feeds/numbers%%'') dans ''%%telegraf.mqtt_consumer.topic%%''
 + 
 +//Exemple local de dashboard : http:%%//%%10.82.64.147/chronograf/sources/1/dashboards/3// 
 + 
 +===== MQTT et Java ===== 
 + 
 +L'implémentation de MQTT sous java est simple. Il suffit d'utiliser la [[https://www.eclipse.org/paho/clients/java/|libraire]] ''%%org.eclipse.paho%%'' avec **GRADLE** ''%%compile("org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0")%%'' ou **MAVEN** 
 + 
 +<code> 
 +<dependency> 
 +  <groupId>org.eclipse.paho</groupId> 
 +  <artifactId>org.eclipse.paho.client.mqttv3</artifactId> 
 +  <version>1.1.0</version> 
 +</dependency> 
 +</code> 
 +On utilisera les variables suivantes : 
 + 
 +<code java> 
 +           String topic        = "MQTT Examples"; 
 +           String content      = "Message from MqttPublishSample"; 
 +           int qos             = 2; 
 +           String broker       = "tcp://10.243.4.250:1883"; 
 +</code> 
 +La création de la connexion au broker se fait comme suit : 
 + 
 +<code java> 
 +           MqttClient client = new MqttClient(broker, MqttClient.generateClientId()); 
 +</code> 
 +On peut rajouter des options de connexions comme suit : 
 + 
 +<code java> 
 +           MqttConnectOptions options = new MqttConnectOptions(); 
 +           options.setAutomaticReconnect(true); 
 +           options.setCleanSession(true); 
 +           options.setConnectionTimeout(10); 
 +</code> 
 +puis on se connecte avec : 
 + 
 +<code java> 
 +           client.connect(options); // enlever options si aucune option configurée 
 +</code> 
 +Pour publier un message, il suffit de faire : 
 + 
 +<code java> 
 +           System.out.println("Publishing message: "+content); 
 +           MqttMessage message = new MqttMessage(content.getBytes()); 
 +           message.setQos(qos); 
 +           client.publish(topic, message); 
 +</code> 
 +Pour souscrire à un topic, il faut créer une classe qui reçoit et traite les messages : 
 + 
 +<code java> 
 +           // Latch used for synchronizing b/w threads 
 +           final CountDownLatch latch = new CountDownLatch(1); 
 + 
 +           // Topic filter the client will subscribe to 
 +           final String subTopic = "T/GettingStarted/pubsub"; 
 + 
 +           // Callback 
 +  - Anonymous inner-class for receiving messages 
 +           mqttClient.setCallback(new MqttCallback() { 
 + 
 +               public void messageArrived(String topic, MqttMessage message) throws Exception { 
 +                   // Called when a message arrives from the server that 
 +                   // matches any subscription made by the client 
 +                   String time = new Timestamp(System.currentTimeMillis()).toString(); 
 +                   System.out.println("\nReceived a Message!"
 +                           "\n\tTime:    " + time + 
 +                           "\n\tTopic:   " + topic + 
 +                           "\n\tMessage: " + new String(message.getPayload()) + 
 +                           "\n\tQoS:     " + message.getQos() + "\n"); 
 +                   latch.countDown(); // unblock main thread 
 +               } 
 + 
 +               public void connectionLost(Throwable cause) { 
 +                   System.out.println("Connection to Solace messaging lost!" + cause.getMessage()); 
 +                   latch.countDown(); 
 +               } 
 + 
 +               public void deliveryComplete(IMqttDeliveryToken token) { 
 +               } 
 + 
 +           }); 
 + 
 +           // Subscribe client to the topic filter and a QoS level of 0 
 +           System.out.println("Subscribing client to topic: " + subTopic); 
 +           mqttClient.subscribe(subTopic, 0); 
 +           System.out.println("Subscribed"); 
 + 
 +           // Wait for the message to be received 
 +           try { 
 +               latch.await(); // block here until message received, and latch will flip 
 +           } catch (InterruptedException e) { 
 +               System.out.println("I was awoken while waiting"); 
 +           } 
 +</code> 
 +Un [[https://github.com/SolaceSamples/solace-samples-mqtt/blob/master/src/main/java/com/solace/samples/TopicPublisher.java|publisher]] et [[https://github.com/SolaceSamples/solace-samples-mqtt/blob/master/src/main/java/com/solace/samples/TopicSubscriber.java|subscriber]] complet est disponible sur GitHub. 
 + 
 +//Source : https:%%//%%dev.solace.com/samples/solace-samples-mqtt/publish-subscribe/// 
 + 
 +====== Code final ====== 
 + 
 +===== Arduino ===== 
 + 
 +<code c> 
 +/*************************************************** 
 +  Adafruit MQTT Library WINC1500 Modified by Yassine 
 + 
 +  Demo written by Limor Fried/Ladyada for Adafruit Industries. 
 +  Modified by Yassine Gangat for LE²P. 
 + 
 +  MIT license, all text above must be included in any redistribution 
 + ****************************************************/ 
 +#include <SPI.h> 
 +#include "Adafruit_MQTT.h" 
 +#include "Adafruit_MQTT_Client.h" 
 +#include <WiFi101.h> 
 + 
 +// 
 +  ---------------------------- GROVE LCD Lib 
 +  ------------------------- 
 +//#include <Wire.h>           // i2c LIB to use LCD 
 +#include "rgb_lcd.h"        // lcd LIB 
 + 
 +#include "arduino_secrets.h" 
 +///////please enter your sensitive data in the Secret tab/arduino_secrets.h 
 +const char ssid[] = SECRET_SSID;        // your network SSID (name) 
 +const char pass[] = SECRET_PASS;       // your network password (use for WPA, or use as key for WEP) 
 +int status = WL_IDLE_STATUS;     // the WiFi radio's status 
 +// int keyIndex = 0;                // your network key Index number (needed only for WEP) 
 + 
 +// Initialise the Arduino data pins for INPUT/OUTPUT 
 +const int analogInPin = A0; 
 +const int RELAY2 = 8; 
 +const int mVperAmp = 185; // use 100 for 20A Module and 66 for 30A Module 
 + 
 + 
 +/************************* Broker Setup **********************************/ 
 + 
 +#define SERVER      "192.168.2.2" 
 +#define SERVERPORT  1883 
 +#define USERNAME    "SolarPan"   // NetwEmul 
 +  - CtrlLoad 
 +  - SolarPan 
 +#define PWD         "apqm" 
 + 
 +/******************************* Global State  ****************************/ 
 + 
 +//Set up the wifi client & Adafruit MQTT Client 
 +WiFiClient client; 
 +Adafruit_MQTT_Client mqtt(&client, SERVER, SERVERPORT, USERNAME, PWD); 
 + 
 +#define halt(s) { Serial.println(F( s )); while(1); 
 + 
 +/****************************** Feeds ***************************************/ 
 + 
 +// Setup a feed called 'photocell' for publishing. 
 +// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname> 
 +Adafruit_MQTT_Publish numbers = Adafruit_MQTT_Publish(&mqtt, USERNAME "/feeds/numbers"); 
 + 
 +// Setup a feed called 'onoff' for subscribing to changes. 
 +Adafruit_MQTT_Subscribe onoffmsg = Adafruit_MQTT_Subscribe(&mqtt, USERNAME "/feeds/onoff"); 
 + 
 + 
 + 
 +/*************************** Sketch Code ************************************/ 
 + 
 +// 
 +  --------------------------- Variables & others 
 +  -------------------------------- 
 +rgb_lcd lcd; 
 +byte heart[8] = { 
 +  0b00000, 
 +  0b01010, 
 +  0b11111, 
 +  0b11111, 
 +  0b11111, 
 +  0b01110, 
 +  0b00100, 
 +  0b00000 
 +}; 
 + 
 +void setup() { 
 +  // 
 +  ------------------------- Initialization Serial 
 +  ------------------------------ 
 +  while (!Serial);  // wait for serial port to connect. Needed for native USB port only 
 +  Serial.begin(9600); 
 + 
 +  //    Serial.println(F("Adafruit MQTT Library WINC1500 Modified by Yassine")); 
 + 
 +  // 
 +  ---------------------- Initialization Wifi WINC1500 
 +  -------------------------- 
 +  // Initialise the Client 
 +  //    Serial.print(F("\nInit the WiFi module...")); 
 +  // check for the presence of the breakout 
 +  if (WiFi.status() == WL_NO_SHIELD) { 
 +    Serial.println(F("WINC1500 not present")); 
 +    // don't continue: 
 +    while (true); 
 +  } 
 +  //    Serial.println(F("ATWINC OK!")); 
 + 
 +  // 
 +  ------------------------------ Physical part 
 +  ---------------------------------- 
 + 
 +  //    Serial.println(F("LCD Init")); 
 +  // set up the LCD's number of columns and rows: 
 +  lcd.begin(16, 2); 
 + 
 +  // Print a message to the LCD. 
 +#if 1 
 +  lcd.createChar(0, heart); 
 +#endif 
 +  lcd.setCursor(0, 0); 
 +  lcd.print(F("Made with ")); 
 +  lcd.write((unsigned char)0); 
 +  lcd.setCursor(0, 1); 
 +  lcd.print(F("     by Yassine")); 
 + 
 +  pinMode(RELAY2, OUTPUT); 
 + 
 +  // 
 +  --------------------------- Variables & others 
 +  -------------------------------- 
 +  mqtt.subscribe(&onoffmsg); 
 +
 + 
 +// uint32_t x = 0; 
 + 
 +void loop() { 
 +  // 
 +  ------------------------------ MQTT Connection 
 +  -------------------------------- 
 +  // Ensure the connection to the MQTT server is alive (this will make the first 
 +  // connection and automatically reconnect when disconnected). 
 +  MQTT_connect(); 
 +  // lcd.setRGB(255,165,0); 
 +  // 
 +  ------------------------------ Subscription 
 +  ----------------------------------- 
 +  Adafruit_MQTT_Subscribe *subscription; 
 +  while ((subscription = mqtt.readSubscription(5000))) { 
 +    if (subscription == &onoffmsg) { 
 +      Serial.print(F("Got: ")); 
 +      Serial.println((char *)onoffmsg.lastread); 
 + 
 +      if (0 == strcmp((char *)onoffmsg.lastread, "OFF")) { 
 +        lcd.setRGB(255, 0, 0); 
 +        lcd.setCursor(0, 1); 
 +        lcd.print(F("Closing ")); 
 +        lcd.print(F(USERNAME)); 
 +        digitalWrite(RELAY2, LOW); // Turns OFF Relays 1 
 +      } 
 +      if (0 == strcmp((char *)onoffmsg.lastread, "ON")) { 
 +        lcd.setRGB(0, 255, 0); 
 +        lcd.setCursor(0, 1); 
 +        lcd.print(F("Opening ")); 
 +        lcd.print(F(USERNAME)); 
 +        digitalWrite(RELAY2, HIGH); // Turns ON Relays 1 
 +      } 
 +    } 
 +  } 
 + 
 +  // 
 +  ------------------------------ Publication 
 +  ---------------------------------- 
 +  int32_t val = mesureSimple(analogInPin); 
 +  if (val < 0) { 
 +    lcd.setRGB(245, 130, 49); 
 +  } else { 
 +    lcd.setRGB(0, 0, 117); 
 +  } 
 + 
 + 
 +  // int32_t val = mesure(analogInPin) * 100; 
 + 
 +  Serial.print(F("\nSending ")); 
 +  Serial.print(val); 
 +  lcd.setCursor(0, 1); 
 +  lcd.print(F("                ")); 
 +  lcd.setCursor(0, 1); 
 +  lcd.print(F(USERNAME)); 
 +  lcd.setCursor(9, 1); 
 +  lcd.print(val); 
 + 
 +  // Si on met double au lieu de int32_t, plantage !!! 
 +  if (! numbers.publish(val)) { 
 +    Serial.println(F("...Failed")); 
 +  } else { 
 +    Serial.println(F("...OK!")); 
 +  } 
 + 
 +
 + 
 +// Function to connect and reconnect as necessary to the MQTT server. 
 +// Should be called in the loop function and it will take care if connecting. 
 +void MQTT_connect() { 
 +  int8_t ret; 
 + 
 +  // attempt to connect to Wifi network: 
 +  while (WiFi.status() != WL_CONNECTED) { 
 +    Serial.print(F("Attempting to connect to SSID: ")); 
 +    Serial.println(ssid); 
 +    // Connect to WPA/WPA2 network. Change this line if using open or WEP network: 
 +    status = WiFi.begin(ssid, pass); 
 + 
 +    // wait 10 seconds for connection: 
 +    uint8_t timeout = 10; 
 +    while (timeout && (WiFi.status() != WL_CONNECTED)) { 
 +      timeout--; 
 +      delay(1000); 
 +    } 
 +  } 
 + 
 +  // Stop if already connected. 
 +  if (mqtt.connected()) { 
 +    return; 
 +  } 
 + 
 +  Serial.print(F("Connecting to MQTT... ")); 
 + 
 +  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected 
 +    Serial.println(mqtt.connectErrorString(ret)); 
 +    Serial.println(ret); 
 +    Serial.println(F("Retrying MQTT connection in 5 seconds...")); 
 +    mqtt.disconnect(); 
 +    delay(5000);  // wait 5 seconds 
 +  } 
 +  Serial.println(F("MQTT Connected!")); 
 +
 +double mesure(int analogPin) { 
 + 
 +  const int ACSoffset = 2500; 
 +  double Amps = 0; 
 +  /*double Voltage = 0; 
 +    int RawValue= 0; 
 +    RawValue = analogRead(analogPin); 
 +    /*Voltage = (RawValue / 1024.0) * 5000; // Gets you mV 
 +    Amps = ((Voltage 
 +  - ACSoffset) / mVperAmp);*/ 
 + 
 +  Amps = (((analogRead(analogPin) / 1024.0) * 5000 
 +  - ACSoffset) / mVperAmp); 
 + 
 +  /*Serial.print("Raw Value = " ); // shows pre-scaled value 
 +    Serial.print(RawValue); 
 +    Serial.print("\t mV = "); // shows the voltage measured 
 +    Serial.print(Voltage,3); 
 +    // the '3' after voltage allows you to display 3 digits after decimal point 
 +    Serial.print("\t Amps = "); // shows the voltage measured 
 +    Serial.println(Amps,3); 
 +    // the '3' after voltage allows you to display 3 digits after decimal point 
 +    delay(2500); */ 
 +  return (Amps); 
 +
 +int mesureSimple(int analogPin) { 
 + 
 +  int Valeur = analogRead(analogPin); 
 + 
 +  return (Valeur); 
 +
 +</code> 
 +===== Node-RED ===== 
 + 
 +<code> 
 +
 +    { 
 +        "id": "798f513a.e8a04", 
 +        "type": "tab", 
 +        "label": "Mon 1er flow", 
 +        "disabled": false, 
 +        "info": "Flow de test pour :\n- Récupérer une donnée MQTT et afficher\n- Envoyer une valeur par MQTT" 
 +    }, 
 +    { 
 +        "id": "57a9ca2c.283154", 
 +        "type": "ui_base", 
 +        "theme":
 +            "name": "theme-dark", 
 +            "lightTheme":
 +                "default": "#0094CE", 
 +                "baseColor": "#0094CE", 
 +                "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif", 
 +                "edited": true, 
 +                "reset": false 
 +            }, 
 +            "darkTheme":
 +                "default": "#097479", 
 +                "baseColor": "#097479", 
 +                "baseFont": "Verdana,Verdana,Geneva,sans-serif", 
 +                "edited": true, 
 +                "reset": false 
 +            }, 
 +            "customTheme":
 +                "name": "Untitled Theme 1", 
 +                "default": "#4B7930", 
 +                "baseColor": "#4B7930", 
 +                "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif", 
 +                "reset": false 
 +            }, 
 +            "themeState":
 +                "base-color":
 +                    "default": "#097479", 
 +                    "value": "#097479", 
 +                    "edited": false 
 +                }, 
 +                "page-titlebar-backgroundColor":
 +                    "value": "#097479", 
 +                    "edited": false 
 +                }, 
 +                "page-backgroundColor":
 +                    "value": "#111111", 
 +                    "edited": false 
 +                }, 
 +                "page-sidebar-backgroundColor":
 +                    "value": "#000000", 
 +                    "edited": false 
 +                }, 
 +                "group-textColor":
 +                    "value": "#0eb8c0", 
 +                    "edited": false 
 +                }, 
 +                "group-borderColor":
 +                    "value": "#555555", 
 +                    "edited": false 
 +                }, 
 +                "group-backgroundColor":
 +                    "value": "#333333", 
 +                    "edited": false 
 +                }, 
 +                "widget-textColor":
 +                    "value": "#eeeeee", 
 +                    "edited": false 
 +                }, 
 +                "widget-backgroundColor":
 +                    "value": "#097479", 
 +                    "edited": false 
 +                }, 
 +                "widget-borderColor":
 +                    "value": "#333333", 
 +                    "edited": false 
 +                }, 
 +                "base-font":
 +                    "value": "Verdana,Verdana,Geneva,sans-serif" 
 +                } 
 +            } 
 +        }, 
 +        "site":
 +            "name": "Node-RED Dashboard", 
 +            "hideToolbar": "false", 
 +            "allowSwipe": "false", 
 +            "allowTempTheme": "true", 
 +            "dateFormat": "DD/MM/YYYY", 
 +            "sizes":
 +                "sx": 48, 
 +                "sy": 48, 
 +                "gx": 6, 
 +                "gy": 6, 
 +                "cx": 6, 
 +                "cy": 6, 
 +                "px": 0, 
 +                "py":
 +            } 
 +        } 
 +    }, 
 +    { 
 +        "id": "106a0892.4df7b7", 
 +        "type": "ui_tab", 
 +        "z": "", 
 +        "name": "Ecran principale", 
 +        "icon": "dashboard", 
 +        "order":
 +    }, 
 +    { 
 +        "id": "8e831ec7.d81eb", 
 +        "type": "ui_group", 
 +        "z": "", 
 +        "name": "Flux reçus", 
 +        "tab": "106a0892.4df7b7", 
 +        "order": 1, 
 +        "disp": true, 
 +        "width": "17", 
 +        "collapse": false 
 +    }, 
 +    { 
 +        "id": "279e1ad8.ebeae6", 
 +        "type": "ui_group", 
 +        "z": "", 
 +        "name": "Envoie infos", 
 +        "tab": "106a0892.4df7b7", 
 +        "order": 2, 
 +        "disp": true, 
 +        "width": "6", 
 +        "collapse": false 
 +    }, 
 +    { 
 +        "id": "f460a0.8fc35f6", 
 +        "type": "mqtt-broker", 
 +        "z": "", 
 +        "name": "Mon Broker", 
 +        "broker": "localhost", 
 +        "port": "1883", 
 +        "clientid": "", 
 +        "usetls": false, 
 +        "compatmode": true, 
 +        "keepalive": "60", 
 +        "cleansession": true, 
 +        "birthTopic": "", 
 +        "birthQos": "0", 
 +        "birthPayload": "", 
 +        "closeTopic": "", 
 +        "closeQos": "0", 
 +        "closePayload": "", 
 +        "willTopic": "", 
 +        "willQos": "0", 
 +        "willPayload": "" 
 +    }, 
 +    { 
 +        "id": "503ea954.5b97c8", 
 +        "type": "ui_switch", 
 +        "z": "798f513a.e8a04", 
 +        "name": "NetwEmul ON/OFF switch", 
 +        "label": "NetwEmul ON/OFF switch", 
 +        "group": "279e1ad8.ebeae6", 
 +        "order": 0, 
 +        "width": 0, 
 +        "height": 0, 
 +        "passthru": true, 
 +        "decouple": "false", 
 +        "topic": "switch", 
 +        "style": "", 
 +        "onvalue": "ON", 
 +        "onvalueType": "str", 
 +        "onicon": "", 
 +        "oncolor": "", 
 +        "offvalue": "OFF", 
 +        "offvalueType": "str", 
 +        "officon": "", 
 +        "offcolor": "", 
 +        "x": 188, 
 +        "y": 176, 
 +        "wires":
 +            [ 
 +                "8495340b.8c7758" 
 +            ] 
 +        ] 
 +    }, 
 +    { 
 +        "id": "e98fe402.458458", 
 +        "type": "ui_text", 
 +        "z": "798f513a.e8a04", 
 +        "group": "8e831ec7.d81eb", 
 +        "order": 0, 
 +        "width": 0, 
 +        "height": 0, 
 +        "name": "Valeur actuelle", 
 +        "label": "Valeur Actuelle", 
 +        "format": "{{msg.payload}}", 
 +        "layout": "row-spread", 
 +        "x": 480, 
 +        "y": 443, 
 +        "wires": [] 
 +    }, 
 +    { 
 +        "id": "9878823e.bbfaa", 
 +        "type": "mqtt in", 
 +        "z": "798f513a.e8a04", 
 +        "name": "Lecture de SolarPan", 
 +        "topic": "SolarPan/feeds/numbers", 
 +        "qos": "2", 
 +        "broker": "f460a0.8fc35f6", 
 +        "x": 151, 
 +        "y": 479, 
 +        "wires":
 +            [ 
 +                "e98fe402.458458", 
 +                "a63e7897.d1d608" 
 +            ] 
 +        ] 
 +    }, 
 +    { 
 +        "id": "8495340b.8c7758", 
 +        "type": "mqtt out", 
 +        "z": "798f513a.e8a04", 
 +        "name": "Envoie vers NetwEmul/feeds/onoff", 
 +        "topic": "NetwEmul/feeds/onoff", 
 +        "qos": "", 
 +        "retain": "", 
 +        "broker": "f460a0.8fc35f6", 
 +        "x": 502, 
 +        "y": 178, 
 +        "wires": [] 
 +    }, 
 +    { 
 +        "id": "a63e7897.d1d608", 
 +        "type": "ui_chart", 
 +        "z": "798f513a.e8a04", 
 +        "name": "Ensoleillement", 
 +        "group": "8e831ec7.d81eb", 
 +        "order": 0, 
 +        "width": 0, 
 +        "height": 0, 
 +        "label": "Ensoleillement", 
 +        "chartType": "line", 
 +        "legend": "true", 
 +        "xformat": "HH:mm:ss", 
 +        "interpolate": "linear", 
 +        "nodata": "", 
 +        "dot": false, 
 +        "ymin": "", 
 +        "ymax": "", 
 +        "removeOlder": "1", 
 +        "removeOlderPoints": "", 
 +        "removeOlderUnit": "60", 
 +        "cutout": 0, 
 +        "useOneColor": false, 
 +        "colors":
 +            "#1f77b4", 
 +            "#aec7e8", 
 +            "#ff7f0e", 
 +            "#2ca02c", 
 +            "#98df8a", 
 +            "#d62728", 
 +            "#ff9896", 
 +            "#9467bd", 
 +            "#c5b0d5" 
 +        ], 
 +        "useOldStyle": false, 
 +        "x": 472, 
 +        "y": 506, 
 +        "wires":
 +            [], 
 +            [] 
 +        ] 
 +    }, 
 +    { 
 +        "id": "c447fb5f.ce5208", 
 +        "type": "ui_switch", 
 +        "z": "798f513a.e8a04", 
 +        "name": "CtrlLoad ON/OFF switch", 
 +        "label": "CtrlLoad ON/OFF switch", 
 +        "group": "279e1ad8.ebeae6", 
 +        "order": 0, 
 +        "width": 0, 
 +        "height": 0, 
 +        "passthru": true, 
 +        "decouple": "false", 
 +        "topic": "switch", 
 +        "style": "", 
 +        "onvalue": "ON", 
 +        "onvalueType": "str", 
 +        "onicon": "", 
 +        "oncolor": "", 
 +        "offvalue": "OFF", 
 +        "offvalueType": "str", 
 +        "officon": "", 
 +        "offcolor": "", 
 +        "x": 178, 
 +        "y": 243, 
 +        "wires":
 +            [ 
 +                "4096fa94.514d14" 
 +            ] 
 +        ] 
 +    }, 
 +    { 
 +        "id": "4096fa94.514d14", 
 +        "type": "mqtt out", 
 +        "z": "798f513a.e8a04", 
 +        "name": "Envoie vers CtrlLoad/feeds/onoff", 
 +        "topic": "CtrlLoad/feeds/onoff", 
 +        "qos": "", 
 +        "retain": "", 
 +        "broker": "f460a0.8fc35f6", 
 +        "x": 502, 
 +        "y": 245, 
 +        "wires": [] 
 +    }, 
 +    { 
 +        "id": "33ce16a5.0352ca", 
 +        "type": "mqtt in", 
 +        "z": "798f513a.e8a04", 
 +        "name": "Lecture de NetwEmul", 
 +        "topic": "NetwEmul/feeds/numbers", 
 +        "qos": "2", 
 +        "broker": "f460a0.8fc35f6", 
 +        "x": 159, 
 +        "y": 552, 
 +        "wires":
 +            [ 
 +                "f185a9c5.e05d98" 
 +            ] 
 +        ] 
 +    }, 
 +    { 
 +        "id": "6020fc0e.f19df4", 
 +        "type": "mqtt in", 
 +        "z": "798f513a.e8a04", 
 +        "name": "Lecture de CtrlLoad", 
 +        "topic": "CtrlLoad/feeds/numbers", 
 +        "qos": "2", 
 +        "broker": "f460a0.8fc35f6", 
 +        "x": 148, 
 +        "y": 624, 
 +        "wires":
 +            [ 
 +                "f185a9c5.e05d98" 
 +            ] 
 +        ] 
 +    }, 
 +    { 
 +        "id": "f185a9c5.e05d98", 
 +        "type": "ui_chart", 
 +        "z": "798f513a.e8a04", 
 +        "name": "Valeur du courant", 
 +        "group": "8e831ec7.d81eb", 
 +        "order": 0, 
 +        "width": 0, 
 +        "height": 0, 
 +        "label": "Valeur du courant", 
 +        "chartType": "line", 
 +        "legend": "true", 
 +        "xformat": "HH:mm:ss", 
 +        "interpolate": "linear", 
 +        "nodata": "", 
 +        "dot": false, 
 +        "ymin": "", 
 +        "ymax": "", 
 +        "removeOlder": "1", 
 +        "removeOlderPoints": "", 
 +        "removeOlderUnit": "60", 
 +        "cutout": 0, 
 +        "useOneColor": false, 
 +        "colors":
 +            "#1f77b4", 
 +            "#aec7e8", 
 +            "#ff7f0e", 
 +            "#2ca02c", 
 +            "#98df8a", 
 +            "#d62728", 
 +            "#ff9896", 
 +            "#9467bd", 
 +            "#c5b0d5" 
 +        ], 
 +        "useOldStyle": false, 
 +        "x": 486, 
 +        "y": 599, 
 +        "wires":
 +            [], 
 +            [] 
 +        ] 
 +    } 
 +
 +</code>
  
-{{https://wiki.mchobby.be/images/8/8d/Rasp-Node-Red-install-node-01.png| script}} 
  • tutos/mqtt.1540452390.txt.gz
  • Dernière modification : 2018/10/25 07:26
  • de ygangat