Publié le 26 mars 2015 - par

L’Internet des Objets (IoT) sur Raspberry Pi avec MQTT

mqtt_logo_250pxMichel est un fidèle de framboise314 et il intervient en particulier sur le forum à propos de MQTT.
MQTT est un protocole machine à machine (M2M) utilisé pour l’IoT (Internet des objets). Il a été conçu pour être très léger et pour utiliser une bande passante réseau minime.
Michel nous propose dans cet article la mise en œuvre de MQTT sur Raspberry PI.

L’Internet des objets, le protocole MQTT, le Raspberry PI Mosquitto et la puce ESP8266.

IoT_logoOn entend de plus en plus parler l’Internet des objets (IoT : Internet Of Things).
Ces objets peuvent communiquer sans fil (Radio, Bluetooth ou Wifi).
Un des protocoles utilisable pour faire dialoguer ces objets est MQTT (M2M Machine to Machine).

MQTT

mqtt_logo_250px

  • MQTT est un service de messagerie TCP/IP simple
  • Les messages sont envoyés par des publieurs (les publishers) sur un canal (une chaîne d’information) appelé Topic. Ces messages peuvent être lus par les souscripteurs (les subscribers) qui surveillent certains Topics.
  • Un serveur (Broker) se charge de faire la liaison entre les publieurs et les souscripteurs.
  • On peut évidemment installer un Broker sur notre Framboise, par exemple Mosquitto.

Mosquitto sur la Framboise.

Installation par :

sudo apt-get install mosquitto mosquitto-clients python-mosquitto
  • Mosquitto est le serveur MQTT (Broker).
  • Mosquitto-clients installe les clients MQTT « mosquitto_sub » , « mosquitto_pub » , « mosquitto_passwd »
  • Python-mosquitto ajoute la partie Python avec des API permettant de créer des clients et d’interroger des serveurs.
  • Pour commencer avant de configurer Mosquitto sur le Rasberry, on peut simplement d’utiliser le serveur de test de Mosquitto « test.mosquitto.org ».
  • Il n’y a pas de compte à créer sur mosquito.org et aucun paramétrage n’est nécessaire pour lancer des tests.

Exemples d’appels de Mosquitto.

On lance en premier sur le Rasberry le client MQTT : mosquitto_sub en lui demandant de se mettre à l’écoute d’un ensemble de Topics dans l’exemple, SMBA38 et les sous Topics de SMBA38 (en utilisant le #):

$mosquitto_sub -h test.mosquitto.org -t "SMBA38/#" –v

Ensuite on lance dans une autre console, plusieurs fois le client MQTT pour publier des valeurs sur ce même Topic (option –m).

pi@raspberrypi:~$ mosquitto_pub -h test.mosquitto.org -t SMBA38/temps/Ext -m 17

pi@raspberrypi:~$ mosquitto_pub -h test.mosquitto.org -t SMBA38/temps/Ext -m 15

pi@raspberrypi:~$ mosquitto_pub -h test.mosquitto.org -t SMBA38/temps/Int -m 21

Et voici les données affichées par le subscripteur (option –v), les données arrivent immédiatement après leur publication.

pi@raspberrypi:~$ mosquitto_sub -h test.mosquitto.org -t
"SMBA38/#" -v
SMBA38/temps/Ext 17
SMBA38/temps/Ext 15
SMBA38/temps/Int 21

Le port utilisé par défaut est le 1883.

Dans cet exemple on n’utilise pas de nom d’utilisateur et de mot de passe, les transmissions ne sont pas codées.
La QoS (qualité de service n’est pas utilisée).

Si on lance la commande :

mosquitto_sub -h test.mosquitto.org -t "#" –v

On récupère tous les topics du serveur de test de Mosquitto ( même ceux non créés par nous même).
Et avec :

pi@raspberrypi:~$ mosquitto_sub -h test.mosquitto.org -t "+/temp/#" -v
random/temp 22
project4fun/temp typeA
ccdata/temp 19.3

On récupère les tests sur des capteurs de température car c’est en général ce genre de test quel les développeurs affectionnent.

Fonctionnalités de MQTT.

Le protocole MQTT dispose d’autres fonctionnalités.

  • La notion de QoS dans les messages qui transitent via MQTT.
    • =0 Le message envoyé n’est pas stocké par le Broker, il n’y a pas d’accusé de réception, perte du message si arrêt du serveur ou du client.
    • =1 message livré au moins une fois le client renvoi le message jusqu’à ce que le broker envoi en retour un accusé de réception.
    • =2 le broker sauvegarde le message et le transmettra jusqu’a ce que les souscripteurs connectés le reçoive (avec un mécanisme évitant la duplication de messages).
  • Persistance des messages, si la persistance est demandée sur un Topic, les messages sont conservés sur le Broker.
  • On peut configurer un message testament (Last Will Testament), si un client perd la connexion au Broker le message testament pourra être récupéré par les souscripteurs à l’écoute du topic LWT.
  • On peut définir qui a le droit de publier sur tel ou tel Topic et également qui a le droit de s’y abonner.
  • La sécurité peut se faire au niveau transport en SSL/TLS, et au niveau authentification, par certificats SSL/TLS ou couple user/mot de passe.
  • On peut utiliser les jokers ‘+’ et ’#’ dans les Topics pour s’abonner à un ensemble de Topics. Par exemple « SMBA38/+/# »
  • On peut laisser le choix aux publieurs de définir l’arborescence des Topics et dans ce cas, il n’y a rien à configurer sur le Broker, le publieur indique les Topics qu’il renseigne et le souscripteur indique les Topics qu’il veut surveiller.

Une fois installé sur le Raspberry, Mosquitto fonctionne sans problème.

  • On peut utiliser « mosquitto_passwd » pour configurer les utilisateurs et les mots de passe.
  • L’exemple suivant interroge le Broker sur les pertes de connexion des clients, on indique un utilisateur (-u) et un mot de passe (-P)
pi@raspberrypi:~$ mosquitto_sub -q 2 -h 192.168.1.22 -u util -P motdepasse -t "lwt/#" -v

Il existe plusieurs Clients MQTT pour, Linux, Apple, Smartphones et même pour Windows .

MQTT.fx sous Windows.

Voici un exemple avec le client Windows MQTT.fx (Programmé en Java).

mqtt_screenshot

On peut avec MQTT.fx Publier , souscrire, écrire des scripts (En java) Avoir des informations sur le Broker ou lire les logs.

Conclusions.

A la différence d’un serveur avec une base de données relationnelle qui conserve les données d’une façon permanente, un Broker est surtout prévu pour mettre en relation des objets, les messages ne sont en général pas conservés sur la base (Sauf demande de messages persistants).

C’est un peu le même principe que les flux RSS.

Par contre la création et la consultation des Topics est très simple et aucune configuration n’est nécessaire pour ajouter un Topic. (Sauf demande explicite de contrôles par le Broker de l’utilisation des Topics).

On peut facilement faire communiquer plusieurs Framboises sans trop d’efforts de programmation, une simple ligne de commande suffit.

Mais on peut également développer en Python pour des projets plus complexes.

Toutes sortes d’objets disposant d’une interface Wifi peuvent également utiliser le protocole MQTT, c’est le cas de puces ESP8266 d’Espressif.

PUCE ESP8266 Nodemcu, Lua et MQTT.

mqtt_esp8266Puce ESP8266 ESP-01 (14,3 mn x 24.8 mn)

mqtt_nodemcu_devAvec Puce ESP8266 ESP-12 avec ADC.

Puce ESP8266.

  • La société Espressif propose une puce ESP8266 disposant de deux interfaces réseau Wifi.
    L’ESP8266 :
  •  Dispose de 32Kbytes de Ram, 96Kbytes de data RAM, 64 KBytes de BOOT ROM.
  • Le Processeur 32 bits a une architecture Harward, La fréquence est de 80MHZ.
  • La puce est généralement accompagnée d’une mémoire Flash SPI de 512MO à 4GO.
  • L’alimentation est de 3V.
  • La puce peut se mettre en sommeil pour ne pas trop tirer sur l’alimentation.

On trouve ces puces sur Ebay à partir de 2€, Il existe des cartes de développement à 10€, par exemple Nodemcu.

Il existe plusieurs implémentations de ces puces sur des PCB ESP-01 à ESP-12 l’antenne Wifi peut être sur le PCB, céramique ou externe.

Firmwares utilisables :

On peut Flasher plusieurs firmwares sur cette puce :

  • Commandes AT (la puce se comporte comme un modem Wifi), il existe des librairies pour utiliser le protocole MQTT à partir d’un Arduino.
  • Serveur WEB développés en C.
  • Micro Python.
  • Nodemcu embarquant le langage orienté réseau Lua avec des fonctions MQTT.

La société Espressif propose une machine virtuelle sous VirtualBox avec l’environnement de développement déjà installé (ToolChain) , il suffit de rajouté le SDK livré également par Espressif.

Nodemcu et Lua.

La carte de tests Nodemcu est reliée par USB à un ordinateur (Nodemcu embarque un convertisseur USB / Série).
La mémoire flash est organisée en fichiers (format SLIP).
On dispose de fonctions pour piloter les GPIO (SPI, I2C, oneWire, ADC, PWM).

Lua est un langage orienté réseau.

  • On peut en Lua envoyer des mails d’une façon autonome.
  • Développer des clients et des serveurs UDP ou TCP.
  • On peut également programmer un serveur Telnet en une douzaine de lignes de code pour pouvoir prendre la main à distance via le Wifi sur la console de l’interpréteur Lua.

MQTT et Lua.

Exemple de code d’appels à MQTT en Lua sur le la carte de développement Nodemcu.

m=mqtt.Client("test", 30,"","") -- création du client

--Evénements
m:on("connect", function(con) print ("Connexion OK") end)
m:on("offline", function(con) print ("offline") m:close() end)
m:on("message", function(conn, topic, data)
if data ~= nil then
print("réception topic: ".. topic .. ":" .. data) end end)

-- Connexion + écoute + envoi
m:connect("test.mosquitto.org", 1883, 0, function(conn) print("Connexion lancée")
m:subscribe("SMBA38/#",1, function(conn) print("Subscription OK, je suis à l'écoute")
m:publish( "SMBA38/temps/ext",15,0, 0,function(conn) print ("SMBA38/temps/ext publié")
end)
end)
end)

Et la trace dans la console Lua

>dofile("mqtt_mosquitto.lua")
Connexion lancée
Subscription OK, je suis à l'écoute
SMBA38/temps/ext publié
réception topic: SMBA38/temps/ext:15
réception topic: SMBA38/temps/Int:21
offline

Dans le même code on teste :

  • La Connexion au BroKer.
  • Le souscripteur (mis en premier pour recevoir les données du publieur).
  • Le publieur.

La valeur : « réception topic: SMBA38/temps/Int:21 »
Correspond à une valeur publiée en même temps que le test avec Lua depuis le Raspberry par :

mosquitto_pub -h test.mosquitto.org -t SMBA38/temps/Int -m 21

Dans la vraie vie, il y aura plusieurs ESP8266, un qui envoie des données et un (ou plusieurs) qui les traite.

Conclusions

Il est donc très facile en quelques lignes de Lua de mettre à jour la base de données d’un Broker MQTT , ce broker publiant immédiatement les données.

Et pour une puce à deux euros, c’est pas mal et cette puce peut gérer les communications réseau d’une façon autonome avec une alimentation de deux piles de 1,5V.

J’ai publié sur le Forum de Framboise 314 plusieurs exemples en code Lua.

SMBA38.

Merci à Michel pour cet article très intéressant

À propos François MOCQ

Électronicien d'origine, devenu informaticien, et passionné de nouvelles technologies, formateur en maintenance informatique puis en Réseau et Télécommunications. Dès son arrivée sur le marché, le potentiel offert par Raspberry Pi m’a enthousiasmé j'ai rapidement créé un blog dédié à ce nano-ordinateur (www.framboise314.fr) pour partager cette passion. Auteur de plusieurs livres sur le Raspberry Pi publiés aux Editions ENI.

9 réflexions au sujet de « L’Internet des Objets (IoT) sur Raspberry Pi avec MQTT »

  1. StEx

    Excellente intro !
    Moi qui justement envisage de m’initier à la domotique et aux IOT, c’est parfait. Je n’ai plus qu’à recevoir mon ESP8266 pour tester tout ça. J’aimerais aussi me bricoler un interrupteur sans fils le plus simple et le moins coûteux possible, cela me parait être une bonne voie.

    Répondre
    1. smba38

      L’utilisation de MQTT n’est intéressante que si l’on veut gérer plusieurs capteurs / actionneurs dans un système domotique centralisé.

      Avec une télécommande à base d’esp8266 il y a les contraintes suivantes :
      L’esp8266 ne doit être alimentée que durant l’envoi d’un ordre pour préserver les piles.
      L’esp8266 va rebooter à chaque fois et il faut environ 3 secondes pour que le Wifi soit activé et que le message arrive au récepteur.
      Si il n’y a qu’une seule télécommande on peut se passer de MQTT et utiliser le protocole TCP pour envoyer les messages et dans ce cas, le récepteur peut être une autre puce esp8266.
      SMBA38.

      Répondre
  2. Ping : L’Internet des Objets (IoT) sur Raspberry Pi avec MQTT | Veille techno de Hotfirenet

  3. Martin

    L’esp8266 résout vraiment pas mal de soucis grâce à son prix et sa taille, merci de le partager(pour ceux qu’il ne le connaisse pas). Par contre je ne comprends toujours pas le fonctionnement du MQTT dans la plus part des projets. Le principe du TCP/UDP est simple, l’un envoie à l’autre et le contraire. Mais par exemple, l’esp8266 peut t-il recevoir des ordres(activer un relais par ex) et envoyer des donnés en même temps(comme température) avec le MQTT ?

    Répondre
    1. smba38

      Oui par exemple avec deux esp8266 on peut réaliser une télécommande d’un portail.
      l’esp8266 de la télécommande publie le topic « maison/portail ouverture » (ou fermeture).
      l’esp8266 qui pilote le portail est à l’écoute (souscripteur) du même topic « /maison/portail ».
      et en fonction de l’ordre, il ouvre ou ferme le portail via un relais commandé par un GPIO de l’esp8266.
      Le serveur Broker ne sert qu’a relayer le message entre le publieur et le souscripteur.

      Si l’on veut prendre des décisions par exemple pour interdire l’ouverture du portail en fonction d’un horaire, on peut par exemple en python écouter le topic « maison/portail » et publier seulement si l’horaire est valide un topic « /maison/portail arrêt » (ou marche).
      Dans se cas le souscripteur qui pilote le portail teste l’ordre arrêt ou marche du topic « maison/portail »

      Si l’on veut changer la logique de commande, seul le programme python est à modifier.

      SMBA38.

      Répondre
  4. Cédric

    Génial, merci pour l’article qui a permis à plusieurs utilisateurs Jeedom d’avoir une belle présentation claire de MQTT. Et également qui a permis à ceux utilisant de l’ESP8266 de voir à quoi ca pouvait servir.

    J’avais vu que c’était normalement possible ESP8266 et MQTT, là c’est clair et facile. Go pour en mettre un peu partout.

    Répondre
  5. Franck

    Bonjour,
    Merci pour cet Article je ne connaissais pas l’ESP8266 et je pense que c’est vraiment ce qu’il me faut.
    Je souhaite relevé les données d’un capteur de température en I2C, le capteur est en 3,3v. Est-ce qu’avec un ESP-01 + Capteur I2C + Alim, Il est possible de faire quelque chose de totalement autonome qui transmettrai à un serveur (RPI en WIFI bien sûr) toutes les x minutes le relevé de ce capteur ? Dans ce cas je pense qu’il est nécessaire de passer par LUA ?

    Répondre
    1. smba38

      Sur l’esp8266, on peut flasher plusieurs firmwares.
      Avec celui des commandes AT, il faut un microprocesseur pour piloter l’esp8266 via des commandes AT: L’esp8266 se comporte comme un modem Wifi.

      Avec Nodemcu et Lua l’esp8266 est autonome et on peut communiquer avec un serveur par exemple un Raspberry en utilisant le protocole MQTT, TCP, HTTP ou même un simple mail (SMTP).

      L’esp8266 dispose de deux interfaces Wifi (une interface qui peut se connecter sur un routeur en mode station et une interface qui peut être configurée en mode AP : point d’accès) on peut avoir les deux interfaces actives en même temps.

      En mode AP, c’est par exemple le Raspberry qui devient client, le serveur DHCP de l’esp8266 lui affecte une adresse IP sur le réseau 192.168.4.0 , le Raspberry peut interroger quand bon lui semble l’esp8266, celui ci via l’I2C lui envoi en retour la valeur du capteur.

      Avec le mode AP on peut séparer le réseau local ( par exemple 192.168.1.0) et le réseau des capteurs (192.168.4.0)

      SMBA38.

      Répondre
  6. tmunzer

    Bonjour et merci pour cette présentation. Je pense qu’il y a un souci sur la taille mémoire de l’ESP8266, c’est plutôt 512 Ko à 4Mo.

    Répondre
  7. Ping : Programmez N° 190 : à Maker vaillant, rien d’impossible ! | Framboise 314, le Raspberry Pi à la sauce française….

  8. Ping : Tuto Domotique, Technologie - Mes réfrigérateur & congélateur en mode connecté

  9. Ping : Tuto Microcontrôleurs, Technologie - Les croquettes du Chat en iot

  10. Ludovic

    Salut,
    Je ne suis pas certain de bien avoir compris la mécanique de QoS :
    Dans le cas d’un QoS=2, qui est en charge de renvoyer les trames ?
    Exemple :
    Le noeud B est abonné au sujet « /monTopic » avec un QoS 2
    Le noeud A publie vers le sujet « /monTopic » avec un QoS 2.
    Dans tous les cas, le noeud A publie vers le broker.
    Si le noeud B n’a pas été en mesure de recevoir la publication (deconnexion wifi au moment inopportun), qui devra renvoyer le message ? le broker ? ou le noeud A ?
    Si j’ai bien compris, le noeud A ne fait que publier vers le broker, donc c’est au broker de gérer les souscriptions des autres noeuds (dont le noeud A ignore l’existence !) et de renvoyer le message vers ceux (ou celui) qui a souscrit avec QoS=2 ?

    Répondre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Complétez ce captcha SVP *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.