J’ai entrepris un voyage pour explorer Azure IoT et transférer les milliers d’événements diffusés via mon courtier MQTT local (Mosquitto) dans Azure IoT. Après mon dernier message utilisant le SDK Azure IoT pour Python avec Paho MQTT, je pensais que mon travail ici était terminé, mais j’ai récemment été informé de leur prise en charge d’origine pour divers appareils Arduino de Microsoft et Espressif.

Avant que vous ne soyez trop excité compte tenu des exigences de ces bibliothèques, cela ne fonctionnera pas sur votre Arduino Uno, Arduino Mega 2560, etc. La prise en charge d’Azure IoT Hub est réservée à la nouvelle génération de cartes Espressif (ESP32, ESP8266) et Realtek Ameba D. Ces cartes peuvent contenir des mégaoctets, et non des kilooctets de RAM, des processeurs multicœurs et sont capables de se charger dans une pile TCP/IP. , MQTT et ainsi de suite.

S’il y a un thème dans ma maison, il est fiable et il est donc temps de ranger mon Raspberry Pi monté en rack et de prendre un microcontrôleur. Un Raspberry Pi, aussi étonnant soit-il, est un SBC (Single Board Computer) qui a besoin d’être mis à jour, arrosé et alimenté. Il utilise un système de fichiers, un sous-système de mémoire flash. Qu’en est-il de la fiabilité, et avez-vous déjà eu un système de fichiers corrompu sur un microcontrôleur ?

Donc, comme tout bon architecte sérieux, je vous encourage à arrêter, à ranger votre Raspberry Pi et à adopter une approche différente. Un microcontrôleur.

Aujourd’hui, j’utilise environ 30 sorties sur un Arduino Mega 2560 avec un blindage Ethernet et PoE utilisant le MQTT (Pub/Sub Client Library), mais il est temps de moderniser, et à cause de mon amour pour les appareils ESP avec Tasmota, j’ai décidé d’acheter un ESP32 pour cette tâche même.

Dans cet article, je vais illustrer comment créer un pont entre Mosquitto MQTT et Azure IoT Hub à l’aide d’un appareil ESP32.

J’ai expliqué dans un article précédent pourquoi j’emprunte cette voie de publication de la télémétrie pour Azure IoT Hub, ainsi que les différentes façons dont j’ai illustré comment aller de l’avant pour atteindre cet objectif. De la connexion directe à Azure IoT Hub (via des jetons MQTT et SAS) à Azure IoT Edge exécuté localement avec MQTT et enfin les SDK.

J’ai pu atteindre mes objectifs avec plus ou moins de succès, mais j’ai quelques inquiétudes concernant les approches que j’ai essayées jusqu’à présent.

  • La connexion directe à Azure-IoT Hub introduit une latence dans le cloud.
  • L’approbation, des jetons SAS aux certificats X509, n’est pas anonyme et certains de mes petits appareils (Tasmota) n’augurent rien de bon.
  • Objet structuré, il est défini (devices/{DeviceID}/messsages/events/) et non sous forme libre. Cela signifie une reconfiguration, ce qui n’est pas difficile, mais beaucoup de frictions.
  • Fiabilité, toutes les solutions jusqu’à présent reposaient sur un système d’exploitation qui nécessite des correctifs, des mises à jour et même une petite charge administrative.

Mes objectifs pour construire une solution

  1. Aucune reconfiguration de mes appareils MQTT (Home Assistant, PLC, Arduino Mega 2560, ~ 75 appareils Tasmota).
  2. Utiliser mon courtier MQTT existant (Mosquitto) pour Azure IoT.
  3. Exécuter sur microcontrôleur car je veux être fiable.

Des objectifs assez élevés, vous pouvez même dire que je suis paresseux, mais la réalité est que je veux une faible friction pour tirer une intelligence opérationnelle des milliers d’événements chaque jour (lire ci-dessous, c’est plus de 10 000 par jour !)

Ce que nous allons construire

Pour surmonter les limitations décrites ci-dessus, nous utiliserons un microcontrôleur ESP32 avec du code C ++ et quelques bibliothèques. Parlons rapidement de ces deux éléments.

ESP32
Par où commencer, qu’est-ce qui n’est pas amoureux de cette puce ? ESP32 est un microcontrôleur moderne et puissant compatible Arduino qui pilote de nombreux appareils de mon contrôleur d’irrigation (Opensprinkler) au robot d’apprentissage de mes enfants (MBot), ils utilisent soit un ESP32, soit un dérivé plus ancien, tel qu’un ESP8266.

L’ESP32 est une série de systèmes peu coûteux et à faible consommation d’énergie sur des microcontrôleurs à puce avec Wi-Fi intégré et Bluetooth bimode. La série ESP32 utilise soit un microprocesseur Tensilica Xtensa LX6 dans les variantes double cœur et monocœur, le microprocesseur double cœur Xtensa LX7 ou un microprocesseur RISC-V monocœur et comprend des connecteurs d’antenne intégrés, un balun RF, un amplificateur de puissance. , amplificateur récepteur à faible bruit, amplificateur de fichier et modules de gestion de l’alimentation. ESP32 est créé et développé par Espressif Systems, une société chinoise basée à Shanghai, et est fabriqué par TSMC à l’aide de son procédé 40 nm. Il succède au microcontrôleur ESP8266.

ESP32 – Wikipédia

Construisons.

Présentation des codes

Regardez les étapes ci-dessous pendant que je taquine cette solution ou mon référentiel GitHub pour l’esquisse complète d’Arduino. Pour vous donner une meilleure compréhension de la façon dont cela fonctionne, je vais le décomposer en étapes logiques ci-dessous nécessaires pour recevoir des messages de Mosquitto sur MQTT en utilisant « PubSubClient », puis les republier dans Azure IoT Hub en utilisant « Esp32MQTTClient ».

Étape 1 – Arduino IDE – Ajouter ESP32 à la carte
Arduino IDE n’est pas familier avec ESP32, donc la toute première étape que nous devons prendre est d’exploiter les capacités du gestionnaire de carte d’Arduino IDE pour fournir un support pour ESP32.

Dans l’IDE Arduino, ouvrez « Préférences » et entrez l’une des URL suivantes

Ouvrez ‘Boards Manager’ dans le menu ‘Outils’> ‘Tableau blanc’ et installez esp32 Plate-forme. Sélectionnez votre carte ESP32 spécifique dans le menu après l’installation.

Redémarrez l’IDE Arduino.

Étape 2 – Nous avons besoin d’une bibliothèque – PubSubClient
Bien que nous ayons maintenant un support pour ESP32, nous devons ajouter une bibliothèque qui nous permet de nous abonner et de recevoir des messages MQTT de notre courtier Mosquitto. Pour cela, nous avons besoin d’une bibliothèque MQTT. Il y en a beaucoup, mais j’ai déjà utilisé ‘PubSubClient’ sur d’autres projets sans aucun problème.

Pour installer, ‘Outils’> ‘Gérer les bibliothèques’> ‘PubSubClient’

Étape 3 – Créer du code (bibliothèques et variables)
Après avoir validé que votre carte fonctionne (je vous suggérerais de télécharger un croquis Blink), nous pouvons commencer à coder. Cet exemple est basé sur ‘Examples’> ‘ESP32 Azure IoT Arduino’> ‘Simple MQTT’, que j’ai beaucoup changé

Nous devons inclure certaines bibliothèques, nous voulons utiliser le Wi-Fi (pour la connexion), PubSubClient (pour Mosquitto MQTT) et ESP32MQTTClient (pour Azure IoT Hub), et nous voulons définir des variables pour le sujet MQTT et la charge utile que nous voulons utiliser entre les fonctions.

#include <WiFi.h>
#include <PubSubClient.h>
#include "Esp32MQTTClient.h"
 
const char* ssid = "Wifi SSID";
const char* password =  "Wifi Password
const char* mqttServer = "IP Address of MQTT Server";
const int mqttPort = 1883;
String MQTTTopic;
String MQTTPayload;

Pour Azure IoT Hub, vous devez définir votre chaîne de connexion. Cet article ne concerne pas la création d’un hub IoT ou la création d’un appareil et suppose que vous en avez déjà créé un. Voir Utilisation du portail Azure pour créer un hub IoT | Microsoft Docs pour plus d’informations sur la configuration d’un Azure IoT Hub, l’ajout d’un appareil et l’obtention d’une chaîne de connexion d’appareil.


//Azure IOT Hub Setup
static const char* connectionString = "*******************=";
static bool hasIoTHub = false;

Étape 4 – Créez du code (fonctionnalité de configuration : connexion au Wi-Fi, Azure et Mosquitto MQTT)
Notre fonctionnalité de « configuration » se connectera à notre LAN via Wi-Fi, puis se connectera à Azure, où la fonctionnalité « MQTTConnect » se connecte non seulement à notre courtier MQTT local, mais définit également les éléments MQTT auxquels s’abonner. Vous pouvez vous abonner à plusieurs sujets MQTT en ayant plusieurs lignes d’abonnement. Vous pouvez également utiliser des filtres génériques MQTT pour faire correspondre les événements avec moins d’abonnements que j’utilise dans ce scénario.

Plus (+) : il s’agit d’un caractère générique à un niveau qui correspond à n’importe quel nom pour un niveau de sujet spécifique. Nous pouvons utiliser ce caractère générique au lieu de spécifier un nom pour n’importe quel niveau de sujet dans le filtre de sujet.

Dièse (#) : il s’agit d’un caractère générique à plusieurs niveaux que nous ne pouvons utiliser qu’à la fin du filtre de sujet comme dernier niveau et correspond à tout sujet dont le premier niveau est le même que les niveaux de sujet indiqués sur le côté gauche du # symbole.

Comprendre les jokers | MQTT Essentials – Un protocole IoT léger (packtpub.com)

Le moniteur série est pratique pour résoudre les problèmes de Wi-Fi ou de connexion à Azure IoT Hub.

client.on_message = on_message  

void setup() {
  //Set baud rate
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("ESP32 : Connecting to WiFi...");
  }
  Serial.println("ESP32 : WiFi connected");
  Serial.println("ESP32 : IP address: ");
  Serial.println(WiFi.localIP());
  //Set MQTT details
  client.setServer(mqttServer, mqttPort);
  client.setCallback(callback);
 
  //Connect to Azure IOT
  if (!Esp32MQTTClient_Init((const uint8_t*)connectionString))
  {
    hasIoTHub = false;
    Serial.println("Azure IoT Hub : Initializing IoT hub failed.");
    return;
  }
  hasIoTHub = true;
 
}
    
void MQTTConnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("MQTT : Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP32Client")) {
      Serial.println("MQTT : Connected");
      // Once connected, publish an announcement...
      client.publish("stat/ESP32/IP_Address","10.0.0.203");
      //Subscribe to topics, one topic per line.
      client.subscribe("stat/+/POWER");      
    } else {
      Serial.print("MQTT : Failed to connect to MQTT , rc=");
      Serial.print(client.state());
      Serial.println("MQTT : Trying again to connect to MQTT in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

Étape 4 – Créer un code (Rappel MQTT & publier sur Azure)
Après les fonctions de configuration, nous devons maintenant créer une fonction qui écoute les messages MQTT entrants qui correspondent à notre abonnement (rappel), extraire l’élément et la charge utile avant de masser ces données et de les envoyer à Azure via une autre fonction (AzureIoTHub).

void callback(char* topic, byte* payload, unsigned int length) {

  MQTTTopic = String(topic);
  MQTTPayload = ""; 
  for (int i = 0; i < length; i++) {
    // Serial.print((char)payload[i]); - Use for debugging
    MQTTPayload = String(MQTTPayload + (char)payload[i]);
  }    
}


void AzureIoTHub() {
  if (hasIoTHub)
      {
        String tempString;
        tempString = "{" + MQTTTopic + ":" + MQTTPayload + "}";
        if (Esp32MQTTClient_SendEvent(tempString.c_str()))
        {
          Serial.println("Azure IoT Hub : Sending data to Azure IoT Hub succeed");
        }
        else
        {
          Serial.println("Azure IoT Hub : Failure...");
        }
      MQTTPayload = "";
      MQTTTopic = "";

   }
}

Étape 5 – Créer du code (notre boucle principale)
La boucle principale utilise toutes ces fonctionnalités, et sa logique peut être résumée en quelques points.
Connectez-vous à MQTT si vous n’êtes pas connecté

Si un élément/message MQTT a été décodé via notre « fonctionnalité de rappel », envoyez-le à Azure IoT Hub et reconnectez-vous s’il n’y a pas de connexion.

void loop() {
   //Connect to MQTT and reconnect if connection drops
   if (!client.connected()) {
     MQTTConnect();
   }
   //Respond to messages received
   if (MQTTTopic != "") { 
      Serial.println("MQTT : Topic is [" + MQTTTopic +"]");
      Serial.println("MQTT : Payload is [" + MQTTPayload + "]");
      AzureIoTHub(); 
  }
  client.loop();
}

Rassemble le tout
Voici une copie complète de ce qui précède plus un peu plus. Vous pouvez couper et coller ce qui suit ou cloner mon référentiel GitHub.

#include <WiFi.h>
#include <PubSubClient.h>
#include "Esp32MQTTClient.h"
 
const char* ssid = "****";
const char* password =  "****";
const char* mqttServer = "****";
const int mqttPort = 1883;
String MQTTTopic;
String MQTTPayload;

//Azure IOT Hub Setup
static const char* connectionString = "****";
static bool hasIoTHub = false;
 
WiFiClient espClient;
PubSubClient client(espClient);
 
void callback(char* topic, byte* payload, unsigned int length) {

  MQTTTopic = String(topic);
  MQTTPayload = ""; 
  for (int i = 0; i < length; i++) {
    // Serial.print((char)payload[i]); - Use for debugging
    MQTTPayload = String(MQTTPayload + (char)payload[i]);
  }    
}



void MQTTConnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("MQTT : Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP32Client")) {
      Serial.println("MQTT : Connected");
      // Once connected, publish an announcement...
      client.publish("stat/ESP32/IP_Address","10.0.0.203");
      //Subscribe to topics, one topic per line.
      client.subscribe("stat/+/POWER");      
    } else {
      Serial.print("MQTT : Failed to connect to MQTT , rc=");
      Serial.print(client.state());
      Serial.println("MQTT : Trying again to connect to MQTT in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  //Set baud rate
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("ESP32 : Connecting to WiFi...");
  }
  Serial.println("ESP32 : WiFi connected");
  Serial.println("ESP32 : IP address: ");
  Serial.println(WiFi.localIP());
  //Set MQTT details
  client.setServer(mqttServer, mqttPort);
  client.setCallback(callback);
 
  //Connect to Azure IOT
  if (!Esp32MQTTClient_Init((const uint8_t*)connectionString))
  {
    hasIoTHub = false;
    Serial.println("Azure IoT Hub : Initializing IoT hub failed.");
    return;
  }
  hasIoTHub = true;
 
}

void loop() {
   //Connect to MQTT and reconnect if connection drops
   if (!client.connected()) {
     MQTTConnect();
   }
   //Respond to messages received
   if (MQTTTopic != "") { 
      Serial.println("MQTT : Topic is [" + MQTTTopic +"]");
      Serial.println("MQTT : Payload is [" + MQTTPayload + "]");
      AzureIoTHub(); 
  }
  client.loop();
}

void AzureIoTHub() {
  if (hasIoTHub)
      {
        String tempString;
        tempString = "{" + MQTTTopic + ":" + MQTTPayload + "}";
        if (Esp32MQTTClient_SendEvent(tempString.c_str()))
        {
          Serial.println("Azure IoT Hub : Sending data to Azure IoT Hub succeed");
        }
        else
        {
          Serial.println("Azure IoT Hub : Failure...");
        }
      MQTTPayload = "";
      MQTTTopic = "";

   }
}

Pour voir cela en action
Passons à une vidéo pour voir que cela fonctionne de bout en bout, pour valider que les messages circulent dans Azure IoT Hub, je peux utiliser Azure CLI (AZ-CLI) pour surveiller la sortie couplée au moniteur série Arduino.

az iot hub monitor-events --output table --device-id devicename --hub-name hubname --output json

Pour les besoins de cette démo, j’ai laissé une poignée de messages au niveau QoS 2 et mis LWT (Last Will and Testament) au sable.

Après 24 heures de conduite, nous pouvons voir que j’ai publié 10,52 K de messages dans Azure IoT Hub et qu’il y a certains flux et reflux qui se produisent dans ma maison.

Période de 24 heures avec des messages circulant dans Azure IoT Hub

Conclusion
Il existe de nombreuses façons de décortiquer cette morue. Mes exigences étaient de publier des messages dans Azure et nous avons pu y parvenir de différentes manières (je suis sûr qu’il y en a d’autres). L’automatisation est un voyage, quel chemin souhaitez-vous emprunter ?

Nous avons illustré une approche side-car transparente qui écoute un courtier existant sur les sujets que vous souhaitez et les pousse dans Azure IoT, le tout sans apporter de modifications de configuration (la chose la plus importante pour ma mise en œuvre).

Cette méthode fonctionne sur un microcontrôleur, utilise moins de 5 W de puissance et fonctionne tout simplement. S’il y a des inconvénients, il y en a probablement, en ce moment c’est un moyen dans la direction (simplex) et me permet de pousser des messages dans Azure IoT, mais pas de recevoir des messages en retour.

Personnellement, j’aime cette approche, elle combine l’élégance d’un SDK comme mon code et couple la fiabilité d’un microcontrôleur. C’est mon code, mes choix sur ce que je fais, mais je comprends que ce n’est pas pour tout le monde.

Nous avons maintenant mes messages, mes événements dans Azure, et maintenant il est temps de se faire des amis et d’apprendre à dériver l’intelligence opérationnelle des visualisations à l’apprentissage automatique et au-delà.

Penser grand et construire heureux
Shane



Vues des publications :
648

Laisser un commentaire

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