Les objets connectés IoT envahissent notre monde chaque jour d’avantage. Bonne ou mauvaise chose ? je ne me prononcerai pas. Pour mieux comprendre comment ça fonctionne, je vous propose cet article de découverte de MQTT.
Créer un objet connecté IoT avec MQTT et des Raspberry Pi
Pourquoi cet article ?
Je ne sais pas vous (vous me direz), mais quand je cherche un article pour tester MQTT, j’en trouve plein. Super ! Mais quand il faut mettre en œuvre, on s’aperçoit que les articles sont écrits par des utilisateurs qui maitrisent ce protocole. Ils vous expliquent ce qu’il faut faire, ça oui. Mais ils ne disent pas COMMENT FAIRE. Plus clairement ? un mode opératoire détaillé, une recette qui fonctionne. De quoi démarrer avec un ensemble qui fonctionne et ensuite le modifier pour aller plus loin… Je vous mets dans les sources une partie des liens que j’ai explorés. Je vous laisse juge.
Du coup je me suis mis en tête de proposer une solution avec des Raspberry Pi.
Cahier des charges
Un premier Raspberry Pi capture des données Température + Humidité. Il les envoie en Wifi (protocole MQTT) à un deuxième Raspberry Pi, chargé de recevoir les messages, de les stocker dans une base de données, puis de les afficher en temps réel.
Solution retenue
Après de nombreuses (et longues) recherches, des essais (plus ou moins fructueux) j’ai finalement retenu la solution que je vous propose.
Émetteur :
- Un Raspberry Pi 2 sous Raspbian Stretch version 04-2018
- Une clé WiFi USB “officielle”
- Un capteur DHT22 – AM2302 monté sur une breadboard (plaque de prototypage)
Récepteur :
- Un Raspberry Pi 3 sous Raspbian Stretch version 04-2018
- Pour traiter les données MQTT le pack Telegraf / Influxdb / Chronograf
Il y avait bien entendu de nombreuses autres possibilités : MySQL, MariaDB… pour la base de données, Grafana pour l’affichage, tout écrire en Python ou en C au lieu d’utiliser des briques logicielles…
N’hésitez pas à faire part de votre expérience dans les commentaires de cet article, mais inutile de me dire que mes choix sont mauvais ils sont juste les miens et répondent à mon besoin de présenter un ensemble fonctionnel et rapidement mis en œuvre. C’est le principal.
Après si vous pensez que VOTRE solution est la meilleure (c’est certainement le cas, en fonction du problème que vous aviez à résoudre !), les pages de framboise314 vous sont ouvertes Contactez moi, je vous crée un compte d’auteur et vous nous rédigez un super article qui explique votre problématique, vos choix et comment réaliser tout ça. Vous en faites profiter la communauté, ce qui est bien plus enrichissant qu’une critique stérile
Bon… ceci étant dit, on y va ?
Le protocole MQTT
MQTT (Message Queuing Telemetry Transport) est un protocole de messagerie publication-souscription basé sur le protocole TCP/IP. Il a été initialement développé par Andy Stanford-Clark (IBM) et Arlen Nipper (EuroTech). (wikipedia)
Ce schéma montre le principe de fonctionnement de MQTT. A gauche figurent les “publieurs”. Ce sont des machines (Arduino, ESP8266, Raspberry Pi…) qui captent des valeurs (température, humidité, pression, consommation électrique, consommation d’eau…) et les envoient à un serveur appelé “Broker”.
Des clients “souscripteurs” sont connectés au “Broker”. Ils ont sollicité l’envoi de certaines données. Lorsque le Broker reçoit ces données, il les retransmet aux clients qui se sont abonnés à ce flux de données. Par exemple un des clients souscripteurs recevra la température et l’humidité pour en faire un graphe en temps réel. L’autre client recevra la consommation d’eau et déclenchera une alerte si elle dépasse une valeur déterminée.
Un premier test de MQTT en local
Pour ce premier test il n’était pas question d’envoyer des données… juste une chaîne de caractères, pour voir si “ça passe” entre les deux Raspberry Pi.
J’ai retenu cet article de Felix, sur tutorials-raspberrypi. Il propose d’installer Mosquitto qui est sans doute la solution la plus simple pour débuter.
Commencez par connecter vos deux Raspberry Pi en WiFi sur votre Box, et relevez leurs adresses IP (souris sur l’icône réseau ou ifconfig dans un terminal).
Installez d’abord Mosquitto sur les deux Raspberry Pi
sudo apt-get install -y mosquitto mosquitto-clients
Après l’installation, un serveur Mosquitto est démarré automatiquement. Ouvrez un abonné (subscriber) dans le canal “test_channel” en attente de messages sur un des Raspberry Pi. Dans un terminal tapez :
mosquitto_sub -h localhost -v -t test_channel
Mosquitto reste en attente de message sur ce canal.
Le canal est ici comme une fréquence en FM, sur laquelle on écoute une station. Par exemple, différentes données peuvent être envoyées sur différents canaux (température, humidité, luminosité, etc.).
Afin de transférer simplement les données, nous allons d’abord utiliser le même Raspberry Pi. Cela permet de tester que Mosquitto fonctionne sur ce Raspberry Pi. Ouvrez un nouveau terminal / une nouvelle connexion SSH sur le même Raspberry Pi et tapez :
mosquitto_pub -h localhost -t test_channel -m "Hello Raspberry Pi"
Ici les données partent d’un publisher test_channel, rejoignent le broker et sont envoyées au subscriber. Dans la première fenêtre de terminal (ou dans votre première session SSH) vous devez voir apparaître Hello Raspberry Pi. Ceci prouve que votre broker Mosquitto fonctionne correctement sur cette machine.
Si ce n’est pas le cas, inutile d’aller plus loin. Il faut faire fonctionner cette manip d’abord !
Sur l’exemple ci-dessus vous voyez deux sessions putty ouvertes sur la même machine. Lancez en premier le subscriber (récepteur) dans la fenêtre du bas. La fenêtre supérieure reçoit le publisher (émetteur). Quand vous validez la ligne de commande mosquitto_pub, le texte apparait dans la fenêtre du bas. C’est la preuve que MQTT fonctionne sur cette machine.
Nota : localhost remplace l’adresse IP de la machine sur laquelle on intervient.
Faites la même chose sur l’autre Raspberry Pi. Vous confirmerez ainsi que les deux Raspberry Pi fonctionnent en local, chacun avec son propre Mosquitto.
Envoyer des données avec MQTT entre deux Raspberry Pi
Maintenant que nous sommes certain(e)s que MQTT est opérationnel sur les deux Raspberry Pi, voici venu le moment d’envoyer les données d’un Raspberry Pi vers l’autre.
Pas de grand changement. Mes Raspberry Pi ont respectivement comme adresse 192.168.1.16 pour le publisher et 192.168.1.20 pour le subscriber. Lances d’abord le subscriber (fenêtre du bas) pour qu’il se mette en attente de réception. Il faudra ensuite indiquer au publisher (fenêtre du haut) l’adresse du broker (serveur) au lieu de localhost. Le publisher enverra le message au deuxième Raspberry Pi, vers le broker. Le broker constate la présence d’un subscriber sur le même canal. Il lui envoie les données et le subscriber affiche le texte.
Voilà, vous êtes maintenant capable d’envoyer des données en MQTT d’un Raspberry Pi à l’autre. Pour une utilisation moins primaire, on voudra envoyer des valeurs de température, pression, humidité… Pour gagner en souplesse et varier nos contenus, il va falloir utiliser un langage de programmation, par exemple Python.
Manip : Éteignez le Raspberry Pi avec le Broker et le subscriber. Démarrez ensuite le publisher. Regardez ce qui se passe…
Transmettre des données avec MQTT : le publisher
Le capteur
C’est un article de thingsboard.io qui m’a servi de base de départ pour la mise en place du publisher. Dans cet article l’auteur utilise un capteur DHT22 ou AM2302 pour mesurer la température et l’humidité relative. Ces valeurs sont ensuite envoyées en JSON via MQTT vers le broker. JSON permet de transporter des valeurs avec un intitulé pour les identifier.
Le montage
Le circuit DHT22 utilisé ainsi que son brochage (Image Thingsboard.io)
Câblage du DHT22 sur le Raspberry Pi (image thingsboard.io). Résistance 4K7 environ.
Le Raspberry Pi 2 utilisé en publisher. Le DHT22 est monté sur une breadboard et le Pi2 est connecté au réseau WiFi grâce à une clé WiFi USB “officielle”.
Câblage du circuit DHT22.
Le Raspberry Pi 3 utilisé en broker, publisher et autres…
Le programme Python de publication
Voici le programme Python extrait de cet article et modifié pour répondre au cahier des charges et au fonctionnement souhaité. Dans cette utilisation le broker sera sur le Raspberry Pi 3B+ (adresse 192.168.1.16) avec le subscriber. Le Raspberry Pi 2 à l’adresse 192.168.1.20 sera le publisher. Il utilise paho-mqtt. C’est une bibliothèque client Paho MQTT pour Python, qui implémente les versions 3.1 et 3.1.1.1 du protocole MQTT. Ce code fournit une classe client qui permet aux applications de se connecter à un broker MQTT pour publier des messages (c’est ce qu nous allons utiliser), s’abonner à des canaux et recevoir des messages publiés. Il supporte Python 2.7.9+ ou 3.4+.
Commencez par installer paho-mqtt :
sudo pip install paho-mqtt
puis la librairie Adafruit qui gère les capteurs :
sudo apt-get install python-dev git clone https://github.com/adafruit/Adafruit_Python_DHT.git cd Adafruit_Python_DHT sudo python setup.py install
Ensuite saisissez ce programme (ou téléchargez le)
Voici le programme Python sous forme d’image (WordPress a une fâcheuse tendance à supprimer les espaces inutiles, et il enlève l’indentation pourtant très utile (indispensable) en Python. Vous pouvez télécharger le programme en cliquant sur ce lien.
Si on regarde ce que fait ce programme, on importe un certain nombre de librairies, dont la librairie Adafruit de gestion des DHTxx
Ensuite on donne l’adresse du broker à laquelle le programme doit se connecter.
J’ai mis un intervalle de temps de 5s pour les mesures, mais vous pouvez régler comme vous le souhaitez.
Le programme lit les données dht.read_retry puis les données sont rangées dans sensor_data avec les intitulés ‘temperature’ et ‘humidity’
Les données sont envoyées au broker par client_publish sur le canal test_channel.
Pour tester lancez mosquitto sur l’autre Raspberry Pi, vous verrez arriver les données :
Nous sommes prêt(e)s côté publication, on va passer au côté broker.
Le broker, son client, la base de données et l’affichage
C’est cette architecture que j’ai choisie pour le broker. Elle est présentée sur le site influxdata.com. Pour mon cahier des charges, je n’ai besoin que de Telegraf pour recevoir les données, InfluxDB pour les stocker et Chronograf pour les afficher sur une page web.
A gauche de cette image, on voit le Pi2 que nous venons de configurer, avec sa sonde DHT22. Il est connecté en WiFi à la box. Le deuxième Raspberry Pi est un Raspberry Pi 3. Il est également connecté en WiFI à la Box.
Telegraf est chargé de récupérer les données émises par le Pi2, et reçues par le broker. Il les stocke dans InfluxDB dont la particularité est d’enregistrer les données avec un “timestamp“, un horodatage. C’est très utile quand on enregistre des données climatiques, par exemple. Chaque donnée est précisément datée.
Chronograf génère une page web permettant d’administrer influxdb et de gérer les tableaux (dashboards) présentant les données.
Installation de TIC (Telegraf, InfluxDB, Chronograf)
sudo apt-get update sudo apt-get upgrade sudo apt-get install apt-transport-https sudo apt-get install curl curl -sL https://repos.influxdata.com/influxdb.key | sudo apt-key add - echo "deb https://repos.influxdata.com/debian stretch stable" | sudo tee /etc/apt/sources.list.d/influxdb.list sudo apt-get update sudo apt-get install influxdb sudo nano /etc/influxdb/influxdb.conf
InfluxDB est installé (d’après bentek.fr). Pour des tests on n’a pas besoin de sécurité (pensez y par la suite si vous utilisez ce système en réel ! ).
Nota : Il est possible que apt-transport-https et curl soient déjà installés dans leur dernière version sur votre système.
Dans /etc/influxdb/influxdb.conf nous allons activer le port HTTP sans authentification en modifiant les lignes de la rubrique [HTTP] du fichier comme suit :
[http]
# Determines whether HTTP endpoint is enabled.
enabled = true
# The bind address used by the HTTP service.
bind-address = “:8086”
# Determines whether user authentication is enabled over HTTP/HTTPS.
auth-enabled = false
Il suffit de décommenter les lignes qui ont un # en première position, en supprimant ce #.
sudo service influxdb restart sudo service influxdb status
Installez maintenant Telegraf :
sudo apt-get install telegraf sudo systemctl start telegraf
et modifiez son fichier de configuration pour qu’il reçoive les data du publisher (test_channel) et les envoie à la BDD InfluxDB :
[code lang="bash"]sudo nano /etc/telegraf/telegraf.conf[/code]
###############################################################################
# OUTPUT PLUGINS #
###############################################################################
# Configuration for sending metrics to InfluxDB
[[outputs.influxdb]]
## The full HTTP or UDP URL for your InfluxDB instance.
##
## Multiple URLs can be specified for a single cluster, only ONE of the
## urls will be written to each interval.
# urls = [“unix:///var/run/influxdb.sock”]
# urls = [“udp://127.0.0.1:8089”]
# urls = [“http://127.0.0.1:8086”]
## The target database for metrics; will be created as needed.
database = “michelin”
## If true, no CREATE DATABASE queries will be sent. Set to true when using
## Telegraf with a user without permissions to create databases or when the
## database already exists.
# skip_database_creation = false
Name of existing retention policy to write to. Empty string writes to
## the default retention policy. Only takes effect when using HTTP.
retention_policy = “”
ainsi que
# # Read metrics from MQTT topic(s)
[[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://localhost: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 = [
“test_channel/#”,
]
…
# ## 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 = “json”
tag_keys = [
“Temperature”,
“Humidity”
]
J’ai ici indiqué à Telegraf de récupérer les données du canal test_channel. Ces données au format JSON comportent deux champs : temperature et humidity. Les données seront rangées dans la base de données michelin.
Enregistrez vos modifications puis redémarrez telegraf.
Par défaut Telegraf enregistre les données locales (CPU, charge disque etc.) vous pouvez vérifier son fonctionnement avec cette commande qui devrait vous afficher une quantité de données…
[code lang="bash"]curl "http://localhost:8086/query?q=select+*+from+telegraf..cpu"[/code]
On va maintenant pouvoir installer Chronograf qui sera utilisé pour afficher une page web avec les données reçues, mais aussi pour gérer la BDD influxDB.
sudo apt-get install chronograf sudo systemctl start chronograf
Automatiser le lancement des logiciels
Pour que influxdb, telegraf et chronograf soient lancés au démarrage / redémarrage du Raspberry Pi, tapez
<pre>sudo systemctl enable influxdb
sudo systemctl enable telegraf
sudo systemctl enable chronograf</pre>
Mosquitto sera relancé sans que vous ayez à intervenir.
Utiliser Chronograf
Se connecter à Chronograf
Ouvrez un navigateur (sur le Raspberry Pi ou sur un PC) et entrez l’adresse de la machine sur laquelle vous avez installé la suite TIC, indiquez le port : 8888
Créer une base de données
Sur la page web de Chronograf, allez sur InfluxDB Admin dans le menu de gauche.
Il existe déjà des bases de données Internal et telegraf. J’en ai précédemment créé une pour des besoins de tests, j’ai flouté son nom
Cliquez sur Create Database.
Donnez un nom à votre base de données (je l’ai appelée mesures… quelle inspiration !) Puis enregistrez la (coche verte sur la droite)
Votre BDD apparait maintenant dans la liste
Ouvrez Data Explorer. Par défaut votre BDD enregistre tout un tas de paramètres locaux. Ça peut s’arranger en modifiant le fichier de configuration pour qu’elle n’enregistre que vos données. Mais ici on teste et ça ne gêne pas qu’il y ait des données en plus. Ce qui nous intéresse c’est le flux mqtt_consumer que nous avons déclaré dans la config. de telegraf.
Ouvrez mqtt_consumer. Il reçoit bien test_channel et ses deux champs : temperature et humidity.
Sélectionnez ces deux champs
En bas de la page vous voyez apparaitre un graphique représentant vos données. Passez la souris dessus, un curseur vous indique la date et l’heure de la mesure, ainsi que les valeurs relevées.
On peut maintenant créer un nouveau Dashboard (panneau d’affichage). Cliquez sur Create Dashboard. Dans la fenêtre qui s’ouvre, cliquez sur Add Data et allez sélectionner la température dans mqtt_consumer. Validez en cliquant sur la coche verte.
Si vous voulez ajouter un nouveau graphique cliquez sur Add Cell en haut à droite. Vous pouvez par exemple sélectionner Humidity.
Si vous passez la souris sur la barre haute d’un graphique, votre curseur se transforme en croix. Déplacez la fenêtre pour la positionner sous la précédente. Ensuite cliquez sur le coin inférieur gauche pour redimensionner vos graphiques…
Vous pouvez choisir la durée que représente votre graphique : les 5 dernières minutes, les 15 dernières minutes etc.
Voici un relevé de température dans mon atelier sur 24 heures.
Conclusion
Voilà vous devriez maintenant avoir une installation transmettant des mesures climatiques depuis un Raspberry Pi vers un autre en utilisant le protocole MQTT.
Vous pouvez vous amuser et commencer les modifs (c’est ça qu’est bon !) Pensez quand même (quand c’est opérationnel) à faire une image de chacune des deux cartes SD, pour pouvoir redémarrer rapidement en cas de plantage
Il resterait à transformer le Raspberry Pi récepteur en point d’accès pour que le (ou les) autre(s) Raspberry Pi (ESP8266) se connectent directement à lui sans passer par une box.
Mais là je vous laisse faire il suffit de cliquer sur le lien ci-dessus pour accéder à l’article sur raspAP.
N’hésitez pas à faire un retour dans les commentaires de cet article, c’est toujours enrichissant (et pour l’auteur et pour les autres lecteurs)
Sources
- https://fr.wikipedia.org/wiki/MQTT
- http://ticksurraspberrypi3.blogspot.com/
- https://docs.influxdata.com/chronograf/v1.5/introduction/getting-started/
- https://thingsboard.io/docs/samples/raspberry/temperature/
- https://blog.groupe-sii.com/le-protocole-mqtt-dans-liot/
- http://www.steves-internet-guide.com/logging-mqtt-sensor-data-to-sql-database-with-python/
- http://thefreephysicist.com/writing-mqtt-data-sqlite3-database-raspberry-pi/
- https://github.com/bsmaat/mqtt/blob/master/sql/sqlwriter.py
- http://raspberrywebserver.com/cgiscripting/rpi-temperature-logger/building-an-sqlite-temperature-logger.html
- https://github.com/Pyplate/rpi_temp_logger
- Simple (Browser Based) graphical display of MQTT data
Wireless communication between Raspberry Pi’s via MQTT broker/client
Raspberry Pi: Measure Humidity and Temperature with DHT11/DHT22
MQTT 101 – How to Get Started with the lightweight IoT Protocol
Cet article Utiliser le protocole MQTT pour communiquer des données entre 2 Raspberry Pi a été publié en premier sur Framboise 314, le Raspberry Pi à la sauce française.....