Partager via


Connexion de votre appareil à la solution préconfigurée de surveillance à distance (Windows)

Présentation du scénario

Dans ce scénario, vous allez créer un appareil qui envoie la télémétrie suivante à la solution préconfigurée de surveillance à distance :

  • Température externe
  • Température interne
  • Humidité

Par souci de simplicité, le code sur l’appareil génère des valeurs d’exemple, mais nous vous encourageons à étendre l'exemple en connectant des capteurs réels à votre appareil et en envoyant une télémétrie réelle.

L’appareil est également en mesure de répondre aux méthodes appelées à partir du tableau de bord de la solution et aux valeurs de propriétés souhaitées définies dans le tableau de bord de la solution.

Pour effectuer ce didacticiel, vous avez besoin d’un compte Azure actif. Si vous ne possédez pas de compte, vous pouvez créer un compte d’évaluation gratuit en quelques minutes. Pour plus d’informations, consultez Essai gratuit Azure.

Avant de commencer

Avant d’écrire du code pour votre appareil, vous devez approvisionner votre solution préconfigurée de surveillance à distance et approvisionner un nouvel appareil personnalisé dans cette solution.

Approvisionner la solution préconfigurée de surveillance à distance

L’appareil que vous créez dans ce didacticiel envoie des données à une instance de la solution préconfigurée de surveillance à distance. Si vous n’avez pas déjà approvisionné la solution préconfigurée de surveillance à distance dans votre compte Azure, procédez comme suit :

  1. Sur la page https://www.azureiotsolutions.com/, cliquez sur + pour créer une solution.
  2. Cliquez sur Sélectionner dans le panneau Surveillance à distance pour créer votre solution.
  3. Sur la page Create Remote monitoring solution (Créer une solution de supervision à distance), entrez le nom de votre choix dans la zone Nom de solution, sélectionnez la Région dans laquelle vous souhaitez procéder au déploiement, puis sélectionnez l’abonnement Azure à utiliser. Cliquez ensuite sur Créer la solution.
  4. Attendez la fin du processus de configuration.

Avertissement

Les solutions préconfigurées utilisent des services Azure facturables. Veillez à supprimer la solution préconfigurée de votre abonnement lorsque vous avez terminé pour éviter toute facturation inutile. Vous pouvez supprimer complètement une solution préconfigurée de votre abonnement sur la page https://www.azureiotsolutions.com/.

Au terme du processus d’approvisionnement de la solution de supervision à distance, cliquez sur Lancer pour ouvrir le tableau de bord de la solution dans votre navigateur.

Tableau de bord de solution

Configurer votre appareil dans la solution de supervision à distance

Notes

Si vous avez déjà approvisionné un appareil dans votre solution, vous pouvez ignorer cette étape. Vous devez connaître les informations d'identification de l’appareil lorsque vous créez l'application cliente.

Pour qu’un appareil puisse se connecter à la solution préconfigurée, il doit s’identifier auprès d’IoT Hub à l’aide d’informations d’identification valides. Vous pouvez récupérer les informations d’identification de l’appareil à partir du tableau de bord de la solution. Les informations d’identification de l’appareil seront ajoutées dans votre application cliente dans la suite de ce didacticiel.

Pour ajouter un appareil à votre solution de supervision à distance, procédez comme suit dans le tableau de bord de la solution :

  1. Dans le coin inférieur gauche du tableau de bord, cliquez sur Ajouter un périphérique.

    Ajout d’un appareil

  2. Dans le panneau Appareil personnalisé, cliquez sur Ajouter nouveau.

    Ajout d’un appareil personnalisé

  3. Choisissez Me laisser définir mon propre ID d'appareil. Entrez un ID d’appareil comme monappareil, cliquez sur Vérifier l’ID pour vous assurer que ce nom n’est pas déjà utilisé, puis cliquez sur Créer pour approvisionner l’appareil.

    Ajouter ID d’appareil

  4. Prenez note des informations d’identification de l’appareil (ID d’appareil, nom d’hôte IoT Hub et clé d’appareil). Votre application cliente a besoin de ces valeurs pour se connecter à la solution de supervision à distance. Cliquez ensuite sur Terminé.

    Afficher les informations d’identification d’un appareil

  5. Sélectionnez votre appareil dans la liste d’appareils du tableau de bord de la solution. Ensuite, dans le panneau Détails de l’appareil, cliquez sur Activer l’appareil. L’état de votre appareil est maintenant En cours d’exécution. La solution de supervision à distance peut désormais recevoir des données de télémétrie à partir de votre appareil et appeler des méthodes sur l’appareil.

Création d’un exemple de solution C sur Windows

Les étapes suivantes vous montrent comment créer une application cliente qui communique avec la solution préconfigurée de surveillance à distance. Cette application est écrite en C, générée et exécutée sur Windows.

Créez un projet de démarrage dans Visual Studio 2015 ou Visual Studio 2017 et ajoutez les packages NuGet clients de l’appareil IoT Hub :

  1. Dans Visual Studio, créez une application console C à l’aide du modèle Application console Win32 de Visual C++. Nommez le projet RMDevice.

  2. Sur la page Paramètres de l’application dans l’Assistant Application Win32, assurez-vous que l’option Application console est sélectionnée et décochez les cases En-tête précompilé et Vérifications SDL (Security Development Lifecycle).

  3. Dans l’ Explorateur de solutions, supprimez les fichiers stdafx.h, targetver.h et stdafx.cpp.

  4. Dans l’ Explorateur de solutions, renommez le fichier RMDevice.cpp en RMDevice.c.

  5. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet RMDevice, puis cliquez sur Gérer les packages NuGet. Cliquez sur Parcourir, puis recherchez et installez les packages NuGet suivants :

    • Microsoft.Azure.IoTHub.Serializer
    • Microsoft.Azure.IoTHub.IoTHubClient
    • Microsoft.Azure.IoTHub.MqttTransport
  6. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet RMDevice, puis cliquez sur Propriétés pour ouvrir la boîte de dialogue Pages de propriétés du projet. Pour plus d’informations, consultez Setting Visual C++ Project Properties (Définition des propriétés de projet Visual C++).

  7. Cliquez sur le dossier Linker, puis cliquez sur la page de propriétés d’entrée.

  8. Ajoutez crypt32.lib à la propriété Dépendances supplémentaires. Cliquez sur OK, puis de nouveau sur OK pour enregistrer les valeurs des propriétés du projet.

Ajoutez la bibliothèque JSON Parson au projet RMDevice ainsi que les instructions #include requises :

  1. Dans un dossier approprié sur votre ordinateur, clonez le référentiel GitHub Parson à l’aide de la commande suivante :

    git clone https://github.com/kgabis/parson.git
    
  2. Copiez les fichiers parson.h et parson.c de la copie locale du référentiel Parson dans le dossier de votre projet RMDevice.

  3. Dans Visual Studio, cliquez avec le bouton droit sur le projet RMDevice, cliquez sur Ajouter, puis sur Élément existant.

  4. Dans la boîte de dialogue Ajouter un élément existant, sélectionnez les fichiers parson.h et parson.c dans le dossier du projet RMDevice. Cliquez ensuite sur Ajouter pour ajouter ces deux fichiers à votre projet.

  5. Dans Visual Studio, ouvrez le fichier RMDevice.c. Remplacez les instructions existantes #include par ce qui suit :

    #include "iothubtransportmqtt.h"
    #include "schemalib.h"
    #include "iothub_client.h"
    #include "serializer_devicetwin.h"
    #include "schemaserializer.h"
    #include "azure_c_shared_utility/threadapi.h"
    #include "azure_c_shared_utility/platform.h"
    #include "parson.h"
    

    Notes

    À présent, vous pouvez vérifier que votre projet contient les dépendances appropriées définies en le générant.

Spécification du comportement de l’appareil IoT

La bibliothèque cliente du sérialiseur IoT Hub utilise un modèle pour spécifier le format des messages que l’appareil échange avec IoT Hub.

  1. Ajoutez les déclarations de variables suivantes après les instructions #include . Remplacez les valeurs d’espace réservé [ID d’appareil] et [Clé d’appareil] par les valeurs que vous avez notées pour votre appareil provenant du tableau de bord de la solution de supervision à distance. Utilisez le nom d’hôte IoT Hub du tableau de bord de la solution pour remplacer [Nom IoTHub]. Par exemple, si votre nom d’hôte IoT Hub est contoso.azure-devices.net, remplacez [Nom Hub IoT] par contoso :

    static const char* deviceId = "[Device Id]";
    static const char* connectionString = "HostName=[IoTHub Name].azure-devices.net;DeviceId=[Device Id];SharedAccessKey=[Device Key]";
    
  2. Ajoutez le code suivant pour définir le modèle qui permet à l’appareil de communiquer avec IoT Hub. Ce modèle spécifie que l’appareil :

    • Peut envoyer la température, la température externe, l’humidité et un ID d’appareil en tant que données de télémétrie.
    • Peut envoyer des métadonnées concernant l’appareil à IoT Hub. L’appareil envoie des métadonnées de base dans un objet DeviceInfo au démarrage.
    • Peut envoyer des propriétés signalées à la représentation d’appareil dans IoT Hub. Ces propriétés signalées sont regroupées par configuration, appareil et système.
    • Peut recevoir et agir sur les propriétés souhaitées définies sur la représentation d’appareil dans IoT Hub.
    • Peut répondre aux méthodes directes Redémarrer et InitiateFirmwareUpdate appelées sur le portail de la solution. L’appareil envoie des informations sur les méthodes directes prises en charge en utilisant les propriétés signalées.
    // Define the Model
    BEGIN_NAMESPACE(Contoso);
    
    /* Reported properties */
    DECLARE_STRUCT(SystemProperties,
      ascii_char_ptr, Manufacturer,
      ascii_char_ptr, FirmwareVersion,
      ascii_char_ptr, InstalledRAM,
      ascii_char_ptr, ModelNumber,
      ascii_char_ptr, Platform,
      ascii_char_ptr, Processor,
      ascii_char_ptr, SerialNumber
    );
    
    DECLARE_STRUCT(LocationProperties,
      double, Latitude,
      double, Longitude
    );
    
    DECLARE_STRUCT(ReportedDeviceProperties,
      ascii_char_ptr, DeviceState,
      LocationProperties, Location
    );
    
    DECLARE_MODEL(ConfigProperties,
      WITH_REPORTED_PROPERTY(double, TemperatureMeanValue),
      WITH_REPORTED_PROPERTY(uint8_t, TelemetryInterval)
    );
    
    /* Part of DeviceInfo */
    DECLARE_STRUCT(DeviceProperties,
      ascii_char_ptr, DeviceID,
      _Bool, HubEnabledState
    );
    
    DECLARE_DEVICETWIN_MODEL(Thermostat,
      /* Telemetry (temperature, external temperature and humidity) */
      WITH_DATA(double, Temperature),
      WITH_DATA(double, ExternalTemperature),
      WITH_DATA(double, Humidity),
      WITH_DATA(ascii_char_ptr, DeviceId),
    
      /* DeviceInfo */
      WITH_DATA(ascii_char_ptr, ObjectType),
      WITH_DATA(_Bool, IsSimulatedDevice),
      WITH_DATA(ascii_char_ptr, Version),
      WITH_DATA(DeviceProperties, DeviceProperties),
    
      /* Device twin properties */
      WITH_REPORTED_PROPERTY(ReportedDeviceProperties, Device),
      WITH_REPORTED_PROPERTY(ConfigProperties, Config),
      WITH_REPORTED_PROPERTY(SystemProperties, System),
    
      WITH_DESIRED_PROPERTY(double, TemperatureMeanValue, onDesiredTemperatureMeanValue),
      WITH_DESIRED_PROPERTY(uint8_t, TelemetryInterval, onDesiredTelemetryInterval),
    
      /* Direct methods implemented by the device */
      WITH_METHOD(Reboot),
      WITH_METHOD(InitiateFirmwareUpdate, ascii_char_ptr, FwPackageURI),
    
      /* Register direct methods with solution portal */
      WITH_REPORTED_PROPERTY(ascii_char_ptr_no_quotes, SupportedMethods)
    );
    
    END_NAMESPACE(Contoso);
    

Implémentation du comportement de l’appareil

Ajoutez à présent le code qui implémente le comportement défini dans le modèle.

  1. Ajoutez les fonctions suivantes qui gèrent les propriétés souhaitées définies dans le tableau de bord de solution. Ces propriétés souhaitées sont définies dans le modèle :

    void onDesiredTemperatureMeanValue(void* argument)
    {
      /* By convention 'argument' is of the type of the MODEL */
      Thermostat* thermostat = argument;
      printf("Received a new desired_TemperatureMeanValue = %f\r\n", thermostat->TemperatureMeanValue);
    
    }
    
    void onDesiredTelemetryInterval(void* argument)
    {
      /* By convention 'argument' is of the type of the MODEL */
      Thermostat* thermostat = argument;
      printf("Received a new desired_TelemetryInterval = %d\r\n", thermostat->TelemetryInterval);
    }
    
  2. Ajoutez les fonctions suivantes qui gèrent les méthodes directes appelées via IoT hub. Ces méthodes directes sont définies dans le modèle :

    /* Handlers for direct methods */
    METHODRETURN_HANDLE Reboot(Thermostat* thermostat)
    {
      (void)(thermostat);
    
      METHODRETURN_HANDLE result = MethodReturn_Create(201, "\"Rebooting\"");
      printf("Received reboot request\r\n");
      return result;
    }
    
    METHODRETURN_HANDLE InitiateFirmwareUpdate(Thermostat* thermostat, ascii_char_ptr FwPackageURI)
    {
      (void)(thermostat);
    
      METHODRETURN_HANDLE result = MethodReturn_Create(201, "\"Initiating Firmware Update\"");
      printf("Recieved firmware update request. Use package at: %s\r\n", FwPackageURI);
      return result;
    }
    
  3. Ajoutez la fonction suivante qui envoie un message à la solution préconfigurée :

    /* Send data to IoT Hub */
    static void sendMessage(IOTHUB_CLIENT_HANDLE iotHubClientHandle, const unsigned char* buffer, size_t size)
    {
      IOTHUB_MESSAGE_HANDLE messageHandle = IoTHubMessage_CreateFromByteArray(buffer, size);
      if (messageHandle == NULL)
      {
        printf("unable to create a new IoTHubMessage\r\n");
      }
      else
      {
        if (IoTHubClient_SendEventAsync(iotHubClientHandle, messageHandle, NULL, NULL) != IOTHUB_CLIENT_OK)
        {
          printf("failed to hand over the message to IoTHubClient");
        }
        else
        {
          printf("IoTHubClient accepted the message for delivery\r\n");
        }
    
        IoTHubMessage_Destroy(messageHandle);
      }
      free((void*)buffer);
    }
    
  4. Ajoutez le gestionnaire de rappel suivant, qui s’exécute lorsque l’appareil a envoyé les nouvelles valeurs des propriétés signalées à la solution préconfigurée :

    /* Callback after sending reported properties */
    void deviceTwinCallback(int status_code, void* userContextCallback)
    {
      (void)(userContextCallback);
      printf("IoTHub: reported properties delivered with status_code = %u\n", status_code);
    }
    
  5. Ajoutez la fonction suivante pour connecter votre appareil à la solution préconfigurée dans le cloud et échanger des données. Cette fonction effectue les étapes suivantes :

    • Initialise la plateforme.
    • Enregistre l’espace de noms Contoso sur la bibliothèque de sérialisation.
    • Initialise le client avec la chaîne de connexion à l’appareil.
    • Créez une instance du modèle Thermostat.
    • Crée et envoie les valeurs des propriétés signalées.
    • Envoie un objet DeviceInfo.
    • Crée une boucle pour envoyer des données de télémétrie chaque seconde.
    • Annule l’initialisation de toutes les ressources.
    void remote_monitoring_run(void)
    {
      if (platform_init() != 0)
      {
        printf("Failed to initialize the platform.\n");
      }
      else
      {
        if (SERIALIZER_REGISTER_NAMESPACE(Contoso) == NULL)
        {
          printf("Unable to SERIALIZER_REGISTER_NAMESPACE\n");
        }
        else
        {
          IOTHUB_CLIENT_HANDLE iotHubClientHandle = IoTHubClient_CreateFromConnectionString(connectionString, MQTT_Protocol);
          if (iotHubClientHandle == NULL)
          {
            printf("Failure in IoTHubClient_CreateFromConnectionString\n");
          }
          else
          {
    #ifdef MBED_BUILD_TIMESTAMP
            // For mbed add the certificate information
            if (IoTHubClient_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
            {
                printf("Failed to set option \"TrustedCerts\"\n");
            }
    #endif // MBED_BUILD_TIMESTAMP
            Thermostat* thermostat = IoTHubDeviceTwin_CreateThermostat(iotHubClientHandle);
            if (thermostat == NULL)
            {
              printf("Failure in IoTHubDeviceTwin_CreateThermostat\n");
            }
            else
            {
              /* Set values for reported properties */
              thermostat->Config.TemperatureMeanValue = 55.5;
              thermostat->Config.TelemetryInterval = 3;
              thermostat->Device.DeviceState = "normal";
              thermostat->Device.Location.Latitude = 47.642877;
              thermostat->Device.Location.Longitude = -122.125497;
              thermostat->System.Manufacturer = "Contoso Inc.";
              thermostat->System.FirmwareVersion = "2.22";
              thermostat->System.InstalledRAM = "8 MB";
              thermostat->System.ModelNumber = "DB-14";
              thermostat->System.Platform = "Plat 9.75";
              thermostat->System.Processor = "i3-7";
              thermostat->System.SerialNumber = "SER21";
              /* Specify the signatures of the supported direct methods */
              thermostat->SupportedMethods = "{\"Reboot\": \"Reboot the device\", \"InitiateFirmwareUpdate--FwPackageURI-string\": \"Updates device Firmware. Use parameter FwPackageURI to specify the URI of the firmware file\"}";
    
              /* Send reported properties to IoT Hub */
              if (IoTHubDeviceTwin_SendReportedStateThermostat(thermostat, deviceTwinCallback, NULL) != IOTHUB_CLIENT_OK)
              {
                printf("Failed sending serialized reported state\n");
              }
              else
              {
                printf("Send DeviceInfo object to IoT Hub at startup\n");
    
                thermostat->ObjectType = "DeviceInfo";
                thermostat->IsSimulatedDevice = 0;
                thermostat->Version = "1.0";
                thermostat->DeviceProperties.HubEnabledState = 1;
                thermostat->DeviceProperties.DeviceID = (char*)deviceId;
    
                unsigned char* buffer;
                size_t bufferSize;
    
                if (SERIALIZE(&buffer, &bufferSize, thermostat->ObjectType, thermostat->Version, thermostat->IsSimulatedDevice, thermostat->DeviceProperties) != CODEFIRST_OK)
                {
                  (void)printf("Failed serializing DeviceInfo\n");
                }
                else
                {
                  sendMessage(iotHubClientHandle, buffer, bufferSize);
                }
    
                /* Send telemetry */
                thermostat->Temperature = 50;
                thermostat->ExternalTemperature = 55;
                thermostat->Humidity = 50;
                thermostat->DeviceId = (char*)deviceId;
    
                while (1)
                {
                  unsigned char*buffer;
                  size_t bufferSize;
    
                  (void)printf("Sending sensor value Temperature = %f, Humidity = %f\n", thermostat->Temperature, thermostat->Humidity);
    
                  if (SERIALIZE(&buffer, &bufferSize, thermostat->DeviceId, thermostat->Temperature, thermostat->Humidity, thermostat->ExternalTemperature) != CODEFIRST_OK)
                  {
                    (void)printf("Failed sending sensor value\r\n");
                  }
                  else
                  {
                    sendMessage(iotHubClientHandle, buffer, bufferSize);
                  }
    
                  ThreadAPI_Sleep(1000);
                }
    
                IoTHubDeviceTwin_DestroyThermostat(thermostat);
              }
            }
            IoTHubClient_Destroy(iotHubClientHandle);
          }
          serializer_deinit();
        }
      }
      platform_deinit();
    }
    

    Pour référence, voici un exemple de message Telemetry envoyé à la solution préconfigurée :

    {"DeviceId":"mydevice01", "Temperature":50, "Humidity":50, "ExternalTemperature":55}
    

Créer et exécuter l’exemple.

Ajoutez du code pour appeler la fonction remote_monitoring_run , puis générez et exécutez l’application d’appareil.

  1. Remplacez la fonction principale par le code suivant pour appeler la fonction remote_monitoring_run :

    int main()
    {
      remote_monitoring_run();
      return 0;
    }
    
  2. Cliquez sur Générer, puis sur Générer la solution pour générer l’application de l’appareil.

  3. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet RMDevice, cliquez sur Déboguer, puis cliquez sur Démarrer une nouvelle instance pour exécuter l’exemple. La console affiche des messages, car l’application envoie un échantillon de données de télémétrie à la solution préconfigurée, reçoit les valeurs de propriété souhaitées définies dans le tableau de bord de la solution et répond aux méthodes appelées à partir du tableau de bord de la solution.

Affichage de la télémétrie des appareils dans le tableau de bord

Le tableau de bord de la solution de supervision à distance permet d’afficher la télémétrie que vos appareils envoient au IoT Hub.

  1. Dans votre navigateur, revenez au tableau de bord de la solution de supervision à distance, cliquez sur Périphériques dans le panneau de gauche pour accéder à la Liste de périphériques.

  2. Dans la Liste d’appareils, vous devez voir que l’état de votre appareil est maintenant En cours d’exécution. Sinon, cliquez sur Activer l’appareil dans le panneau Détails de l’appareil.

    Afficher l’état de l’appareil

  3. Cliquez sur Tableau de bord pour revenir au tableau de bord, sélectionnez votre périphérique dans la liste déroulante Périphérique à afficher pour afficher sa télémétrie. La télémétrie de l’exemple d’application est configurée pour envoyer 50 unités correspondant à la température interne, 55 unités correspondant à la température externe et 50 à l’humidité.

    Visualiser la télémétrie d’un appareil

Appel d’une méthode sur votre appareil

Le tableau de bord de la solution de supervision à distance vous permet d’appeler des méthodes sur vos appareils via IoT Hub. Par exemple, dans la solution de supervision à distance, vous pouvez appeler une méthode pour simuler le redémarrage d’un appareil.

  1. Dans le tableau de bord de la solution de supervision à distance, cliquez sur Périphériques dans le panneau de gauche pour accéder à la Liste de périphériques.

  2. Cliquez sur ID de périphérique pour votre périphérique dans la Liste de périphériques.

  3. Dans le panneau Détails de l’appareil, cliquez sur Méthodes.

    Méthodes d’appareil

  4. Dans la liste déroulante Méthode, sélectionnez InitiateFirmwareUpdate, puis dans FWPACKAGEURI, saisissez une URL factice. Cliquez sur Appeler une méthode pour appeler la méthode sur l’appareil.

    Appeler une méthode d’appareil

  5. Vous voyez un message dans la console exécutant votre code d’appareil lorsque l’appareil traite la méthode. Les résultats de la méthode sont ajoutés à l’historique dans le portail de solution :

    Affichage de l’historique des méthodes

Étapes suivantes

L'article Personnalisation des solutions préconfigurées décrit quelques méthodes pour étendre cet exemple. Les extensions incluent l'utilisation de capteurs réels et l'implémentation de commandes supplémentaires.

Vous pouvez en savoir plus sur les autorisations sur le site azureiotsuite.com.