You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
IoT-For-Beginners/translations/fr/2-farm/lessons/4-migrate-your-plant-to-the.../wio-terminal-connect-hub.md

13 KiB

Connectez votre appareil IoT au cloud - Wio Terminal

Dans cette partie de la leçon, vous allez connecter votre Wio Terminal à votre IoT Hub pour envoyer des données de télémétrie et recevoir des commandes.

Connectez votre appareil à IoT Hub

L'étape suivante consiste à connecter votre appareil à IoT Hub.

Tâche - se connecter à IoT Hub

  1. Ouvrez le projet soil-moisture-sensor dans VS Code.

  2. Ouvrez le fichier platformio.ini. Supprimez la dépendance de la bibliothèque knolleary/PubSubClient. Cette bibliothèque était utilisée pour se connecter au broker MQTT public, mais elle n'est pas nécessaire pour se connecter à IoT Hub.

  3. Ajoutez les dépendances de bibliothèque suivantes :

    seeed-studio/Seeed Arduino RTC @ 2.0.0
    arduino-libraries/AzureIoTHub @ 1.6.0
    azure/AzureIoTUtility @ 1.6.1
    azure/AzureIoTProtocol_MQTT @ 1.6.0
    azure/AzureIoTProtocol_HTTP @ 1.6.0
    azure/AzureIoTSocket_WiFi @ 1.0.2
    

    La bibliothèque Seeed Arduino RTC fournit du code pour interagir avec une horloge temps réel dans le Wio Terminal, utilisée pour suivre l'heure. Les autres bibliothèques permettent à votre appareil IoT de se connecter à IoT Hub.

  4. Ajoutez ce qui suit en bas du fichier platformio.ini :

    build_flags =
        -DDONT_USE_UPLOADTOBLOB
    

    Cela définit un drapeau de compilation nécessaire lors de la compilation du code Arduino IoT Hub.

  5. Ouvrez le fichier d'en-tête config.h. Supprimez tous les paramètres MQTT et ajoutez la constante suivante pour la chaîne de connexion de l'appareil :

    // IoT Hub settings
    const char *CONNECTION_STRING = "<connection string>";
    

    Remplacez <connection string> par la chaîne de connexion de votre appareil que vous avez copiée précédemment.

  6. La connexion à IoT Hub utilise un jeton basé sur le temps. Cela signifie que l'appareil IoT doit connaître l'heure actuelle. Contrairement aux systèmes d'exploitation comme Windows, macOS ou Linux, les microcontrôleurs ne synchronisent pas automatiquement l'heure actuelle via Internet. Vous devrez donc ajouter du code pour obtenir l'heure actuelle à partir d'un serveur NTP. Une fois l'heure récupérée, elle peut être stockée dans une horloge temps réel du Wio Terminal, permettant de demander l'heure correcte ultérieurement, à condition que l'appareil ne perde pas d'alimentation. Ajoutez un nouveau fichier appelé ntp.h avec le code suivant :

    #pragma once
    
    #include "DateTime.h"
    #include <time.h>
    #include "samd/NTPClientAz.h"
    #include <sys/time.h>
    
    static void initTime()
    {
        WiFiUDP _udp;
        time_t epochTime = (time_t)-1;
        NTPClientAz ntpClient;
    
        ntpClient.begin();
    
        while (true)
        {
            epochTime = ntpClient.getEpochTime("0.pool.ntp.org");
    
            if (epochTime == (time_t)-1)
            {
                Serial.println("Fetching NTP epoch time failed! Waiting 2 seconds to retry.");
                delay(2000);
            }
            else
            {
                Serial.print("Fetched NTP epoch time is: ");
    
                char buff[32];
                sprintf(buff, "%.f", difftime(epochTime, (time_t)0));
                Serial.println(buff);
                break;
            }
        }
    
        ntpClient.end();
    
        struct timeval tv;
        tv.tv_sec = epochTime;
        tv.tv_usec = 0;
    
        settimeofday(&tv, NULL);
    }
    

    Les détails de ce code sont hors du cadre de cette leçon. Il définit une fonction appelée initTime qui obtient l'heure actuelle d'un serveur NTP et l'utilise pour régler l'horloge du Wio Terminal.

  7. Ouvrez le fichier main.cpp et supprimez tout le code MQTT, y compris le fichier d'en-tête PubSubClient.h, la déclaration de la variable PubSubClient, les méthodes reconnectMQTTClient et createMQTTClient, ainsi que tous les appels à ces variables et méthodes. Ce fichier ne doit contenir que du code pour se connecter au WiFi, obtenir l'humidité du sol et créer un document JSON avec ces données.

  8. Ajoutez les directives #include suivantes en haut du fichier main.cpp pour inclure les fichiers d'en-tête des bibliothèques IoT Hub et pour régler l'heure :

    #include <AzureIoTHub.h>
    #include <AzureIoTProtocol_MQTT.h>
    #include <iothubtransportmqtt.h>
    #include "ntp.h"
    
  9. Ajoutez l'appel suivant à la fin de la fonction setup pour régler l'heure actuelle :

    initTime();
    
  10. Ajoutez la déclaration de variable suivante en haut du fichier, juste en dessous des directives d'inclusion :

    IOTHUB_DEVICE_CLIENT_LL_HANDLE _device_ll_handle;
    

    Cela déclare un IOTHUB_DEVICE_CLIENT_LL_HANDLE, un handle pour une connexion à IoT Hub.

  11. En dessous, ajoutez le code suivant :

    static void connectionStatusCallback(IOTHUB_CLIENT_CONNECTION_STATUS result, IOTHUB_CLIENT_CONNECTION_STATUS_REASON reason, void *user_context)
    {
        if (result == IOTHUB_CLIENT_CONNECTION_AUTHENTICATED)
        {
            Serial.println("The device client is connected to iothub");
        }
        else
        {
            Serial.println("The device client has been disconnected");
        }
    }
    

    Cela déclare une fonction de rappel qui sera appelée lorsque la connexion à IoT Hub change de statut, comme lors de la connexion ou de la déconnexion. Le statut est envoyé au port série.

  12. En dessous, ajoutez une fonction pour se connecter à IoT Hub :

    void connectIoTHub()
    {
        IoTHub_Init();
    
        _device_ll_handle = IoTHubDeviceClient_LL_CreateFromConnectionString(CONNECTION_STRING, MQTT_Protocol);
    
        if (_device_ll_handle == NULL)
        {
            Serial.println("Failure creating Iothub device. Hint: Check your connection string.");
            return;
        }
    
        IoTHubDeviceClient_LL_SetConnectionStatusCallback(_device_ll_handle, connectionStatusCallback, NULL);
    }
    

    Ce code initialise le code de la bibliothèque IoT Hub, puis crée une connexion en utilisant la chaîne de connexion dans le fichier d'en-tête config.h. Cette connexion est basée sur MQTT. Si la connexion échoue, cela est envoyé au port série - si vous voyez cela dans la sortie, vérifiez la chaîne de connexion. Enfin, la fonction de rappel de statut de connexion est configurée.

  13. Appelez cette fonction dans la fonction setup sous l'appel à initTime :

    connectIoTHub();
    
  14. Comme avec le client MQTT, ce code fonctionne sur un seul thread et nécessite du temps pour traiter les messages envoyés par le hub et au hub. Ajoutez ce qui suit en haut de la fonction loop pour le faire :

    IoTHubDeviceClient_LL_DoWork(_device_ll_handle);
    
  15. Compilez et téléchargez ce code. Vous verrez la connexion dans le moniteur série :

    Connecting to WiFi..
    Connected!
    Fetched NTP epoch time is: 1619983687
    Sending telemetry {"soil_moisture":391}
    The device client is connected to iothub
    

    Dans la sortie, vous pouvez voir l'heure NTP récupérée, suivie de la connexion du client de l'appareil. La connexion peut prendre quelques secondes, donc vous pourriez voir l'humidité du sol dans la sortie pendant que l'appareil se connecte.

    💁 Vous pouvez convertir l'heure UNIX du NTP en une version plus lisible en utilisant un site web comme unixtimestamp.com

Envoyer des données de télémétrie

Maintenant que votre appareil est connecté, vous pouvez envoyer des données de télémétrie à IoT Hub au lieu du broker MQTT.

Tâche - envoyer des données de télémétrie

  1. Ajoutez la fonction suivante au-dessus de la fonction setup :

    void sendTelemetry(const char *telemetry)
    {
        IOTHUB_MESSAGE_HANDLE message_handle = IoTHubMessage_CreateFromString(telemetry);
        IoTHubDeviceClient_LL_SendEventAsync(_device_ll_handle, message_handle, NULL, NULL);
        IoTHubMessage_Destroy(message_handle);
    }
    

    Ce code crée un message IoT Hub à partir d'une chaîne passée en paramètre, l'envoie au hub, puis nettoie l'objet message.

  2. Appelez ce code dans la fonction loop, juste après la ligne où la télémétrie est envoyée au port série :

    sendTelemetry(telemetry.c_str());
    

Gérer les commandes

Votre appareil doit gérer une commande provenant du code serveur pour contrôler le relais. Cela est envoyé sous forme de requête de méthode directe.

Tâche - gérer une requête de méthode directe

  1. Ajoutez le code suivant avant la fonction connectIoTHub :

    int directMethodCallback(const char *method_name, const unsigned char *payload, size_t size, unsigned char **response, size_t *response_size, void *userContextCallback)
    {
        Serial.printf("Direct method received %s\r\n", method_name);
    
        if (strcmp(method_name, "relay_on") == 0)
        {
            digitalWrite(PIN_WIRE_SCL, HIGH);
        }
        else if (strcmp(method_name, "relay_off") == 0)
        {
            digitalWrite(PIN_WIRE_SCL, LOW);
        }
    }
    

    Ce code définit une méthode de rappel que la bibliothèque IoT Hub peut appeler lorsqu'elle reçoit une requête de méthode directe. La méthode demandée est envoyée dans le paramètre method_name. Cette fonction imprime la méthode appelée sur le port série, puis active ou désactive le relais en fonction du nom de la méthode.

    💁 Cela pourrait également être implémenté dans une seule requête de méthode directe, en passant l'état souhaité du relais dans une charge utile qui peut être transmise avec la requête de méthode et disponible à partir du paramètre payload.

  2. Ajoutez le code suivant à la fin de la fonction directMethodCallback :

    char resultBuff[16];
    sprintf(resultBuff, "{\"Result\":\"\"}");
    *response_size = strlen(resultBuff);
    *response = (unsigned char *)malloc(*response_size);
    memcpy(*response, resultBuff, *response_size);
    
    return IOTHUB_CLIENT_OK;
    

    Les requêtes de méthode directe nécessitent une réponse, et la réponse est en deux parties - une réponse sous forme de texte et un code de retour. Ce code créera un résultat sous forme du document JSON suivant :

    {
        "Result": ""
    }
    

    Cela est ensuite copié dans le paramètre response, et la taille de cette réponse est définie dans le paramètre response_size. Ce code retourne ensuite IOTHUB_CLIENT_OK pour indiquer que la méthode a été correctement gérée.

  3. Configurez le rappel en ajoutant ce qui suit à la fin de la fonction connectIoTHub :

    IoTHubClient_LL_SetDeviceMethodCallback(_device_ll_handle, directMethodCallback, NULL);
    
  4. La fonction loop appellera la fonction IoTHubDeviceClient_LL_DoWork pour traiter les événements envoyés par IoT Hub. Cela n'est appelé que toutes les 10 secondes en raison du delay, ce qui signifie que les méthodes directes ne sont traitées que toutes les 10 secondes. Pour rendre cela plus efficace, le délai de 10 secondes peut être implémenté sous forme de nombreux délais plus courts, appelant IoTHubDeviceClient_LL_DoWork à chaque fois. Pour ce faire, ajoutez le code suivant au-dessus de la fonction loop :

    void work_delay(int delay_time)
    {
        int current = 0;
        do
        {
            IoTHubDeviceClient_LL_DoWork(_device_ll_handle);
            delay(100);
            current += 100;
        } while (current < delay_time);
    }
    

    Ce code bouclera de manière répétée, appelant IoTHubDeviceClient_LL_DoWork et retardant de 100 ms à chaque fois. Il le fera autant de fois que nécessaire pour retarder pendant le temps donné dans le paramètre delay_time. Cela signifie que l'appareil attend au maximum 100 ms pour traiter les requêtes de méthode directe.

  5. Dans la fonction loop, supprimez l'appel à IoTHubDeviceClient_LL_DoWork, et remplacez l'appel delay(10000) par ce qui suit pour appeler cette nouvelle fonction :

    work_delay(10000);
    

💁 Vous pouvez trouver ce code dans le dossier code/wio-terminal.

😀 Votre programme de capteur d'humidité du sol est connecté à votre IoT Hub !

Avertissement :
Ce document a été traduit à l'aide du service de traduction automatique Co-op Translator. Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.