IoT personnalisé, partie 6 – Présentation de MQTT

IoT personnalisé, partie 6 - Présentation de MQTT

Les projets précédents sur la conception d’une plate-forme Internet des objets (IoT) personnalisée ont examiné le périphérique IoT que nous utiliserons ainsi qu’une simple démonstration d’une plate-forme HTTP. Cependant, dans ce projet, nous examinerons le démarrage de notre plate-forme «MQTT-like» afin de pouvoir créer une puissante plate-forme IoT pour n’importe quel projet à l’avenir.

Solutions IoT personnalisées Partie 1 – Introduction à l’Internet des objets

Solutions IoT personnalisées, partie 2 – ESP32 vs ESP8266

Solutions IoT personnalisées, partie 3 – HTTP vs MQTT

Solutions IoT personnalisées, partie 4 – Créer un système de publication HTTP

IoT personnalisé, partie 5 – Comment faire des requêtes HTTP GET

Topologie MQTT

iot personnalisé partie 6 - présentation de mqtt

Alors que nous avons regardé ce qu’est MQTT dans un projet précédent, pour rafraîchir nos souvenirs, nous l’examinerons brièvement à nouveau. MQTT signifie Message Queue Telemetry Transport et est un protocole qui définit la manière dont les clients et les serveurs se connectent, envoient des messages et se comportent. Contrairement à HTTP, les clients MQTT se connectent à un serveur et la connexion est maintenue active aussi longtemps que le client le souhaite. Les clients peuvent s’abonner à une variable dont la valeur leur est envoyée par le serveur chaque fois qu’elle change sur le serveur et les clients peuvent publier des valeurs dans une variable sur le serveur (tous les autres clients qui sont abonnés à cette variable recevront la dernière valeur).

Cependant, il convient de préciser que notre plate-forme implémentera un protocole personnalisé qui se comportera un peu comme MQTT mais qui aura des fonctionnalités supplémentaires ainsi que l’utilisation de messages texte au lieu de messages binaires. La messagerie textuelle facilite la correction des erreurs et permet de distinguer les commandes des données. Une fonctionnalité que nous ajouterons, en particulier, est la messagerie d’appareil à appareil par laquelle un client peut envoyer un message à un autre client en utilisant l’identifiant unique de cet appareil.

Notre protocole

Ainsi, avant de pouvoir examiner la structure du serveur et la manière dont les appareils communiqueront, nous devons d’abord établir notre protocole et sa structure.

  1. Relier – Un périphérique client lance une demande de connexion au serveur
  2. Autoriser – Le serveur peut choisir d’accepter ou de refuser cette demande. Cela peut être fait en utilisant un identifiant unique ou un bouton-poussoir physique qu’un opérateur de serveur doit appuyer
  3. Lié – De là, les messages peuvent être envoyés vers et depuis le client / serveur

Tous les messages entre le client et le serveur seront en texte brut ASCII pour les commandes et les données. Cela signifie que non seulement la correction d’erreurs est plus simple, mais que nous pouvons également être sûrs que des messages entiers sont envoyés et reçus correctement ainsi que l’utilisation de caractères de contrôle ASCII (sauts de ligne par exemple) comme terminateurs de lignes. Pour notre protocole, nous utiliserons la structure de commande suivante:

START | COMMAND=CMD | END

Tous les messages commencent par le mot START et se terminent par END, ce qui est utile pour s’assurer qu’un paquet a été reçu correctement. Tous les paramètres sont séparés par un ‘|’ caractère (ce n’est pas la lettre I mais une ligne verticale) et le premier paramètre est toujours une commande. En fonction de la commande, d’autres paramètres devront être passés tels que le nom de la variable et la valeur des données.

Messages client-serveur

Ce sont les messages que nos appareils clients peuvent envoyer au serveur.

Message

Fonction

START | COMMANDE = BONJOUR! | FIN

Réponse Keep Alive

START | COMMANDE = SUB | VARIABLE = VAR | FIN

Abonnez-vous à la variable VAR

START | COMMAND = UNSUB | VARIABLE = VAR | FIN

Se désabonner de la variable VAR

START | COMMAND = UNSUBALL | FIN

Se désabonner de TOUTES les variables

START | COMMANDE = PUB | VARIABLE = VAR | VALEUR = DONNÉES | FIN

Publier la valeur DATA dans la variable VAR

START | COMMANDE = DEL | VARIABLE = VAR | FIN

Supprimer la variable VAR

START | COMMANDE = MSG | DEVICE = ID | VALEUR = DONNÉES | FIN

Envoyer le message DATA à l’ID de l’appareil

START | COMMANDE = ID | ID = VALUE | FIN

Définir l’ID d’appareil sur VALUE

START | COMMAND = CLOSE | FIN

Fermer la connexion

Messages de serveur à client

Ce sont les messages que le serveur enverra au périphérique client.

Message

Fonction

START | COMMANDE = BONJOUR? | FIN

Es-tu toujours en vie? / Répondez avec Hello!

START | COMMANDE = OK | FIN

La réponse de la dernière commande était OK

START | COMMANDE = MAUVAIS | FIN

La réponse de la dernière commande était mauvaise

START | COMMANDE = SUB | VARIABLE = VAR | VALEUR = DONNÉES | FIN

La nouvelle valeur de la variable VAR souscrite est DATA

START | COMMANDE = MSG | DEVICE = ID | VALEUR = DONNÉES | FIN

L’ID de l’appareil a envoyé un message DATA

START | COMMAND = CLOSE | FIN

Fermer la connexion

Code serveur

Notre serveur pourrait être écrit dans un large éventail de langages tels que C ++, C # et Java, mais le langage que nous utiliserons sera Python. Bien que Python ne soit pas aussi rapide que les langages compilés, il présente des avantages majeurs, notamment la prise en charge multiplateforme, la simplicité et la bibliothèque avec prise en charge d’exemples de code. La programmation de socket en Python est beaucoup plus facile que celle des langages compilés et la possibilité d’écrire des applications multi-thread signifie que chaque appareil client connecté à notre serveur peut fonctionner dans son propre thread. Cela ne veut pas dire que notre serveur ne peut pas être écrit en C ++, mais cela ajouterait de la complexité ainsi que des spécificités du système d’exploitation. Le code que nous allons créer pourra fonctionner sur Windows, Mac et Linux qui intègre des ordinateurs monocarte tels que le Raspberry Pi.

Notre serveur sera construit en utilisant la disposition suivante:

  • Boucle de code principale
    • Cette boucle principale ouvrira un port et permettra aux appareils de se connecter. Une fois qu’un périphérique s’est connecté, il sera envoyé à son propre objet de classe qui exécute son propre thread
  • Fil client
    • Ce thread client gérera un client spécifique. Toutes les demandes entrantes sont traitées et les réponses appropriées renvoyées au client
    • Les valeurs publiées dans sont stockées dans un fichier texte global (dont le nom est le nom de la variable) qui est accessible à tous les autres threads client. La date et l’heure de publication de la variable sont également enregistrées dans le fichier texte
    • Tous les threads clients stockent la liste des variables souscrites, leur dernière valeur et l’heure à laquelle ces valeurs ont été obtenues. Si une nouvelle entrée est trouvée, elle est envoyée au client connecté afin qu’il puisse recevoir la dernière valeur

Conclusion

Alors maintenant que nous avons vu comment notre serveur fonctionnera, la structure du message et comment le code sera construit, la tâche suivante est de construire la chose! Dans le prochain projet, nous ferons fonctionner notre code de boucle principale en Python ainsi que les threads clients pour accepter les demandes de connexion entrantes ainsi que du code de connexion de base sur l’ESP32.

Photo de Robin Mitchell