Publier et souscrire à des messages MQTT

Le protocole MQTT est largement utilisé dans les systèmes distribués et IoT pour la communication légère entre appareils et applications. Souvent, une application doit être capable à la fois de publier des messages vers un topic MQTT et de s’abonner à des topics pour recevoir des messages.

Ce tutoriel explique en détail comment, avec la bibliothèque Python paho-mqtt, réaliser un client MQTT qui publie et souscrit simultanément, en détaillant chaque étape, ainsi que la gestion des callbacks et des boucles réseau.


Préparation

Avant de commencer, assurez-vous que :


Principes clés à comprendre

Pour utiliser MQTT efficacement, voici quelques concepts fondamentaux à garder en tête :


Créer un client MQTT capable de publier et de souscrire

Le client MQTT doit :

Écrire le code complet

import paho.mqtt.client as mqtt
import time

# Fonction appelée quand la connexion au broker est établie
def on_connect(client, userdata, flags, rc):
    if rc == 0:
        print("Connecté au broker MQTT avec succès")
        # S'abonner à un topic à la connexion
        client.subscribe("maison/salon/temperature", qos=1)
    else:
        print(f"Échec de connexion, code {rc}")

# Fonction appelée quand un message est reçu sur un topic abonné
def on_message(client, userdata, message):
    payload = message.payload.decode('utf-8')
    print(f"Message reçu sur {message.topic} : {payload}")

# Création d’un client MQTT
client = mqtt.Client()

# Assignation des callbacks
client.on_connect = on_connect
client.on_message = on_message

# Connexion au broker public test.mosquitto.org
client.connect("test.mosquitto.org", 1883, 60)

# Démarrage de la boucle réseau dans un thread séparé (non bloquant)
client.loop_start()

# Publier un message toutes les 5 secondes
try:
    while True:
        message = "23.5°C"
        result = client.publish("maison/salon/temperature", message, qos=1)
        status = result[0]
        if status == 0:
            print(f"Message publié : {message}")
        else:
            print(f"Erreur lors de la publication du message : {status}")
        time.sleep(5)
except KeyboardInterrupt:
    print("Arrêt du client MQTT")

# Arrêter proprement la boucle réseau
client.loop_stop()
client.disconnect()

Explications approfondies


Pourquoi utiliser loop_start() au lieu de loop_forever() ?

La méthode loop_forever() bloque le programme tant que la connexion MQTT est active, ce qui empêche d’exécuter d’autres tâches dans le même script. Ici, nous voulons pouvoir publier des messages périodiquement tout en écoutant les messages reçus.

loop_start() démarre la boucle réseau en arrière-plan, dans un thread distinct, et laisse le contrôle au script principal. Cela permet d’avoir un client MQTT capable de publier et recevoir en même temps.


Gestion des erreurs et reconnexions

Il est important dans une application réelle de gérer les erreurs et reconnexions automatiques. Paho-MQTT supporte cette gestion mais il faut parfois ajouter des callbacks additionnels, notamment on_disconnect et on_subscribe, pour gérer proprement ces cas. Le tutoriel de base n’en traite pas mais c’est une étape importante pour la robustesse.


Les QoS en MQTT

Le Quality of Service définit la garantie de livraison du message :

Dans notre exemple, nous utilisons généralement QoS 1 pour un bon compromis entre fiabilité et performance.


Résumé


Pour aller plus loin

Voici quelques pistes pour améliorer ce client MQTT :

Ce tutoriel vous offre une base solide pour maîtriser la publication et la souscription MQTT en Python et vous invite à expérimenter et étendre ces principes pour vos projets.