# Les sujets En MQTT, un **sujet** (ou *topic* en anglais) est une chaîne de caractères qui identifie une catégorie ou un canal de communication. Les clients MQTT peuvent s'abonner à un ou plusieurs sujets pour recevoir les messages publiés sur ces sujets. Lorsqu'un client publie un message sur un sujet particulier, tous les clients qui se sont abonnés à ce sujet recevront ce message. Les sujets sont organisés sous forme de hiérarchie à l'aide de barres obliques (`/`) pour séparer les différents niveaux. Prenons un exemple concret. Un capteur de température dans la chambre 1 publie sa mesure sur le sujet `maison/chambre1/temperature` avec pour charge utile `19.8`. Au même moment, un autre capteur publie l'humidité de la cuisine sur `maison/cuisine/humidite` avec la valeur `62`. Home Assistant, abonné à `maison/chambre1/temperature`, recevra uniquement la première information ; un dashboard Grafana abonné aux deux sujets recevra les deux. Quelques bonnes pratiques pour nommer les sujets : - **Toujours en minuscules**, sans accents ni espaces — `maison/chambre1/temperature` plutôt que `Maison/Chambre 1/Température`. - **Du plus général au plus spécifique**, de gauche à droite — `maison/etage1/chambre1/capteur3` se lit naturellement. - **Pas de `/` en début de sujet** : `/maison/chambre1` crée un premier niveau vide, source d'erreurs subtiles. - **Préférer des noms parlants à des identifiants opaques** — `chambre1` plutôt que `dev_8a3f`. Les sujets sont un élément clé de la flexibilité et de l'extensibilité de MQTT, permettant une communication efficace et ciblée entre les différents clients de l'écosystème. ## Sujets réservés MQTT définit plusieurs sujets réservés (ou *reserved topics*) qui ont une signification particulière et qui ne doivent pas être utilisés pour la publication de messages personnalisés. Tous les sujets réservés commencent par le caractère `$`, ce qui permet de les distinguer immédiatement des sujets applicatifs. Voici quelques exemples : - `$SYS/#` : utilisé par le broker pour publier des informations système le concernant — statistiques de performance, informations de connexion des clients, etc. - `$SYS/broker/version` : version du broker MQTT. - `$SYS/broker/uptime` : temps d'activité du broker depuis son dernier démarrage. - `$SYS/broker/clients/connected` : nombre de clients actuellement connectés. - `$SYS/broker/messages/received` : nombre total de messages reçus depuis le démarrage. Concrètement, on peut s'abonner à `$SYS/#` depuis un client MQTT pour superviser la santé du broker en temps réel. Avec `mosquitto_sub` : ```bash mosquitto_sub -h localhost -t '$SYS/#' -v ``` renverra en continu des lignes comme : ``` $SYS/broker/uptime 12453 seconds $SYS/broker/clients/connected 7 $SYS/broker/load/messages/received/1min 142 ``` Il ne faut pas utiliser ces sujets réservés pour publier des messages personnalisés, car cela peut perturber le fonctionnement normal du broker ou des clients MQTT qui s'attendent à y recevoir des informations système spécifiques. ## Caractère générique # En MQTT, le symbole `#` est un caractère générique utilisé comme joker pour s'abonner à tous les sous-sujets d'un certain niveau **et de tous les niveaux inférieurs**. Il ne peut apparaître qu'en **dernière position** d'un filtre d'abonnement. Par exemple, si un client s'abonne au sujet `maison/chambre1/#`, il recevra les messages publiés sur : - `maison/chambre1/temperature` - `maison/chambre1/humidite` - `maison/chambre1/lumiere/plafond` - `maison/chambre1/lumiere/chevet/etat` …et tous les autres sous-sujets, quelle que soit leur profondeur. À noter : `maison/chambre1/#` inclut aussi le sujet `maison/chambre1` lui-même s'il existe. Un cas d'usage typique : un logger qui veut archiver toute l'activité de la maison s'abonne simplement à `maison/#` et capte l'intégralité des messages échangés sur cette branche. L'utilisation du joker `#` peut avoir des conséquences importantes sur le trafic réseau et la charge de travail du broker, en particulier pour les hiérarchies importantes avec de nombreux sous-sujets. S'abonner à `#` tout court (autorisé par la plupart des brokers, à confirmer dans la doc) reviendrait à recevoir absolument tous les messages — utile pour du débogage ponctuel, à proscrire en production. Quelques règles à respecter pour que le filtre soit valide : - `#` doit être **seul dans son niveau** : `maison/chambre1#` est invalide, il faut écrire `maison/chambre1/#`. - `#` doit être **le dernier caractère** : `maison/#/temperature` est invalide. - On ne peut **pas publier** sur un sujet contenant `#` — les jokers sont réservés aux abonnements. ## Caractère générique + MQTT définit un autre caractère générique, le symbole `+`, qui correspond à **exactement un seul niveau** de la hiérarchie. Contrairement à `#`, il peut être placé à n'importe quel niveau du filtre, et même apparaître plusieurs fois. Par exemple, si un client s'abonne au sujet `maison/+/temperature`, il recevra les messages publiés sur : - `maison/chambre1/temperature` ✓ - `maison/cuisine/temperature` ✓ - `maison/salon/temperature` ✓ - `maison/chambre1/capteur1/temperature` ✗ *(deux niveaux entre `maison` et `temperature`)* - `maison/temperature` ✗ *(aucun niveau entre les deux)* C'est exactement ce qu'on attend pour récupérer toutes les températures de la maison, sans capter au passage l'humidité ou la luminosité. On peut combiner plusieurs `+` dans un même filtre. Par exemple, `maison/+/+/etat` capte l'état de tous les équipements de toutes les pièces : `maison/salon/lampe1/etat`, `maison/cuisine/four/etat`, etc. Et on peut associer `+` et `#` dans un même abonnement. Par exemple, `maison/+/capteurs/#` capte tout ce qui concerne les capteurs de n'importe quelle pièce, à n'importe quelle profondeur : - `maison/salon/capteurs/temperature` ✓ - `maison/cuisine/capteurs/humidite/valeur` ✓ - `maison/chambre1/lampe/etat` ✗ Comme pour `#`, le symbole `+` ne peut être utilisé que dans un abonnement, jamais dans une publication. ## Récapitulatif | Filtre | Correspond à | |---|---| | `maison/chambre1/temperature` | exactement ce sujet | | `maison/+/temperature` | les températures de chaque pièce (un seul niveau) | | `maison/chambre1/#` | tout ce qui est publié sous `chambre1` (profondeur quelconque) | | `maison/+/+/etat` | l'état des équipements de chaque pièce | | `#` | tous les sujets applicatifs (à utiliser avec parcimonie) | | `$SYS/#` | toutes les infos système du broker |