Connettere il dispositivo alla soluzione preconfigurata per il monitoraggio remoto (Linux)Connect your device to the remote monitoring preconfigured solution (Linux)

In questa esercitazione viene implementato un dispositivo Chiller che invia i dati di telemetria seguenti alla soluzione di monitoraggio remoto preconfigurata:In this tutorial, you implement a Chiller device that sends the following telemetry to the remote monitoring preconfigured solution:

  • TemperaturaTemperature
  • PressionePressure
  • UmiditàHumidity

Per semplicità, il codice genera valori di telemetria di esempio per il chiller.For simplicity, the code generates sample telemetry values for the Chiller. È possibile estendere l'esempio connettendo sensori reali al dispositivo e inviando dati di telemetria reali.You could extend the sample by connecting real sensors to your device and sending real telemetry.

Il dispositivo di esempio inoltre:The sample device also:

  • Invia i metadati alla soluzione per descrivere le proprie funzionalità.Sends metadata to the solution to describe its capabilities.
  • Risponde alle azioni attivate dalla pagina Dispositivi della soluzione.Responds to actions triggered from the Devices page in the solution.
  • Risponde alle modifiche di configurazione inviate dalla pagina Dispositivi della soluzione.Responds to configuration changes send from the Devices page in the solution.

Per completare l'esercitazione, è necessario un account Azure attivo.To complete this tutorial, you need an active Azure account. Se non si dispone di un account Azure, è possibile creare un account di valutazione gratuito in pochi minuti.If you don't have an account, you can create a free trial account in just a couple of minutes. Per informazioni dettagliate, vedere la pagina relativa alla versione di valutazione gratuita di Azure.For details, see Azure Free Trial.

Prima di iniziareBefore you start

Prima di scrivere il codice per il dispositivo, distribuire la soluzione preconfigurata di monitoraggio remoto e aggiungere un nuovo dispositivo fisico alla soluzione.Before you write any code for your device, deploy your remote monitoring preconfigured solution and add a new physical device to the solution.

Distribuire la soluzione preconfigurata per il monitoraggio remotoDeploy your remote monitoring preconfigured solution

Il dispositivo Chiller creato in questa esercitazione invia dati a un'istanza della soluzione preconfigurata per il monitoraggio remoto.The Chiller device you create in this tutorial sends data to an instance of the remote monitoring preconfigured solution. Se nel proprio account Azure non è già stato effettuato il provisioning della soluzione preconfigurata per il monitoraggio remoto, vedere Distribuire la soluzione preconfigurata di monitoraggio remotoIf you haven't already provisioned the remote monitoring preconfigured solution in your Azure account, see Deploy the remote monitoring preconfigured solution

Al termine del processo di distribuzione della soluzione di monitoraggio remoto, fare clic su Avvia per aprire il dashboard della soluzione nel browser.When the deployment process for the remote monitoring solution finishes, click Launch to open the solution dashboard in your browser.

Dashboard della soluzione

Aggiungere il dispositivo alla soluzione di monitoraggio remotoAdd your device to the remote monitoring solution

Nota

Se è già stato aggiunto un dispositivo nella soluzione, è possibile saltare questo passaggio. Per il passaggio successivo sarà però necessaria la stringa di connessione del dispositivo. È possibile recuperare la stringa di connessione di un dispositivo dal portale di Azure oppure usando lo strumento az iot dell'interfaccia della riga di comando.

Per connettere un dispositivo alla soluzione preconfigurata, è necessario che identifichi se stesso nell'hub IoT mediante delle credenziali valide.For a device to connect to the preconfigured solution, it must identify itself to IoT Hub using valid credentials. Quando si aggiunge il dispositivo alla soluzione, si ha la possibilità di salvare la stringa di connessione del dispositivo che contiene queste credenziali.You have the opportunity to save the device connection string that contains these credentials when you add the device the solution. Le istruzioni per includere la stringa di connessione del dispositivo nell'applicazione client sono illustrate più avanti in questa esercitazione.You include the device connection string in your client application later in this tutorial.

Per aggiungere un dispositivo alla soluzione per il monitoraggio remoto, completare i passaggi seguenti nella pagina Dispositivi della soluzione:To add a device to your remote monitoring solution, complete the following steps on the Devices page in the solution:

  1. Scegliere Nuovo dispositivo e quindi come Tipo di dispositivo scegliere Fisico:Choose + New device, and then choose Physical as the Device type:

    Aggiungere un dispositivo fisico

  2. Immettere Fisico-chiller come ID del dispositivo.Enter Physical-chiller as the Device ID. Scegliere le opzioni Chiave simmetrica e Genera chiavi automaticamente:Choose the Symmetric Key and Auto generate keys options:

    Scegliere le opzioni per il dispositivo

  3. Scegliere Applica.Choose Apply. Prendere quindi nota dei valori di ID dispositivo, Chiave primaria, e Connection string primary key (Chiave primaria della stringa di connessione):Then make a note of the Device ID, Primary Key, and Connection string primary key values:

    Recuperare le credenziali

A questo punto è stato aggiunto un dispositivo fisico alla soluzione preconfigurata di monitoraggio remoto e ne è stata annotata la stringa di connessione.You've now added a physical device to the remote monitoring preconfigured solution and noted its device connection string. Nelle sezioni seguenti si implementerà l'applicazione client che usa la stringa di connessione del dispositivo per connettersi alla soluzione.In the following sections, you implement the client application that uses the device connection string to connect to your solution.

L'applicazione client implementa il modello di dispositivo Chiller predefinito.The client application implements the built-in Chiller device model. Un modello di dispositivo per la soluzione preconfigurata specifica le informazioni seguenti per il dispositivo:A preconfigured solution device model specifies the following about a device:

  • Le proprietà che il dispositivo segnala alla soluzione.The properties the device reports to the solution. Ad esempio, un dispositivo Chiller segnala informazioni su firmware e posizione.For example, a Chiller device reports information about its firmware and location.
  • Tipi di dati di telemetria che il dispositivo invia alla soluzione.The types of telemetry the device sends to the solution. Ad esempio, un dispositivo Chiller invia valori di temperatura, umidità e pressione.For example, a Chiller device sends temperature, humidity, and pressure values.
  • I metodi che possono essere pianificati nella soluzione per l'esecuzione nel dispositivo.The methods you can schedule from the solution to run on the device. Un dispositivo Chiller, ad esempio, deve implementare i metodi Reboot, FirmwareUpdate, EmergencyValveRelease e IncreasePressure.For example, a Chiller device must implement Reboot, FirmwareUpdate, EmergencyValveRelease, and IncreasePressure methods.

Questa esercitazione mostra come connettere un dispositivo fisico alla soluzione preconfigurata di monitoraggio remoto.This tutorial shows you how to connect a physical device to the remote monitoring preconfigured solution.

Creare un progetto client C in LinuxCreate a C client project on Linux

Come per la maggior parte delle applicazioni incorporate in esecuzione su dispositivi vincolati, il codice client per l'applicazione del dispositivo è scritto in C. In questa esercitazione si compilerà l'applicazione in un computer che esegue Ubuntu (Linux).As with most embedded applications that run on constrained devices, the client code for the device application is written in C. In this tutorial, you build the application on a machine running Ubuntu (Linux).

Per completare questi passaggi, è necessario un dispositivo che esegue Ubuntu 15.04 o versioni successive.To complete these steps, you need a device running Ubuntu version 15.04 or later. Prima di continuare, installare i pacchetti dei prerequisiti nel dispositivo Ubuntu usando il comando seguente:Before proceeding, install the prerequisite packages on your Ubuntu device using the following command:

sudo apt-get install cmake gcc g++

Installare le librerie client sul dispositivoInstall the client libraries on your device

Le librerie client dell'hub IoT di Azure sono disponibili in forma di pacchetto da installare sul dispositivo Ubuntu tramite il comando apt-get .The Azure IoT Hub client libraries are available as a package you can install on your Ubuntu device using the apt-get command. Completare la procedura seguente per installare il pacchetto che contiene la libreria del client dell'hub IoT e i file d'intestazione nel computer Ubuntu:Complete the following steps to install the package that contains the IoT Hub client library and header files on your Ubuntu computer:

  1. In una shell, aggiungere il repository AzureIoT al computer:In a shell, add the AzureIoT repository to your computer:

    sudo add-apt-repository ppa:aziotsdklinux/ppa-azureiot
    sudo apt-get update
    
  2. Installare il pacchetto azure-iot-sdk-c-devInstall the azure-iot-sdk-c-dev package

    sudo apt-get install -y azure-iot-sdk-c-dev
    

Installare il parser JSON ParsonInstall the Parson JSON parser

Le librerie client di hub IoT usano il parser JSON per analizzare il payload dei messaggi.The IoT Hub client libraries use the Parson JSON parser to parse message payloads. In una cartella appropriata nel computer, clonare il repository Parson GitHub usando il comando seguente:In a suitable folder on your computer, clone the Parson GitHub repository using the following command:

git clone https://github.com/kgabis/parson.git

Preparare il progettoPrepare your project

Nel computer Ubuntu creare una cartella denominata remote_monitoring.On your Ubuntu machine, create a folder called remote_monitoring. Nella cartella remote_monitoring:In the remote_monitoring folder:

  • Creare i quattro file main.c, remote_monitoring.c, remote_monitoring.h e CMakeLists.txt.Create the four files main.c, remote_monitoring.c, remote_monitoring.h, and CMakeLists.txt.
  • Creare una cartella denominata parson.Create folder called parson.

Copiare i file parson.c e parson.h dalla copia locale del repository Parson alla cartella remote_monitoring/parson.Copy the files parson.c and parson.h from your local copy of the Parson repository into the remote_monitoring/parson folder.

Aprire il file remote_monitoring.c in un editor di testo.In a text editor, open the remote_monitoring.c file. Aggiungere le istruzioni #include seguenti:Add the following #include statements:

#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 <string.h>

Specificare il comportamento del dispositivo IoTSpecify the behavior of the IoT device

La libreria client serializzatrice di hub IoT usa un modello per specificare il formato dei messaggi che il dispositivo scambia con hub IoT.The IoT Hub serializer client library uses a model to specify the format of the messages the device exchanges with IoT Hub.

  1. Aggiungere le seguenti dichiarazioni di variabili dopo le istruzioni #include .Add the following variable declarations after the #include statements. Sostituire i valori segnaposto [Device Id] e [Device connection string] con i valori annotati per il dispositivo fisico aggiunto alla soluzione di monitoraggio remoto:Replace the placeholder values [Device Id] and [Device connection string] with the values you noted for the physical device you added to the remote monitoring solution:

    static const char* deviceId = "[Device Id]";
    static const char* connectionString = "[Device connection string]";
    
  2. Aggiungere il codice seguente per definire il modello che consente al dispositivo di comunicare con l'hub IoT.Add the following code to define the model that enables the device to communicate with IoT Hub. Questo modello consente di specificare che il dispositivo:This model specifies that the device:

    • Può inviare umidità, temperatura e pressione come dati di telemetria.Can send temperature, pressure, and humidity as telemetry.
    • Può inviare proprietà segnalate al dispositivo gemello nell'hub IoT.Can send reported properties, to the device twin in IoT Hub. Queste proprietà segnalate includono informazioni sullo schema di telemetria e sui metodi supportati.These reported properties include information about the telemetry schema and supported methods.
    • Può ricevere e agire sulle proprietà desiderate impostate nel dispositivo gemello nell'hub IoT.Can receive and act on desired properties set in the device twin in IoT Hub.
    • Può rispondere ai metodi diretti Reboot, FirmwareUpdate, EmergencyValveRelease e IncreasePressure richiamati dall'interfaccia utente.Can respond to the Reboot, FirmwareUpdate, EmergencyValveRelease, and IncreasePressure direct methods invoked from the UI. Il dispositivo invia le informazioni sui metodi diretti che supporta usando le proprietà segnalate.The device sends information about the direct methods it supports using reported properties.

      // Define the Model
      BEGIN_NAMESPACE(Contoso);
      
      DECLARE_STRUCT(MessageSchema,
      ascii_char_ptr, Name,
      ascii_char_ptr, Format,
      ascii_char_ptr_no_quotes, Fields
      )
      
      DECLARE_STRUCT(TelemetrySchema,
      ascii_char_ptr, Interval,
      ascii_char_ptr, MessageTemplate,
      MessageSchema, MessageSchema
      )
      
      DECLARE_STRUCT(TelemetryProperties,
      TelemetrySchema, TemperatureSchema,
      TelemetrySchema, HumiditySchema,
      TelemetrySchema, PressureSchema
      )
      
      DECLARE_DEVICETWIN_MODEL(Chiller,
      /* Telemetry (temperature, external temperature and humidity) */
      WITH_DATA(double, temperature),
      WITH_DATA(ascii_char_ptr, temperature_unit),
      WITH_DATA(double, pressure),
      WITH_DATA(ascii_char_ptr, pressure_unit),
      WITH_DATA(double, humidity),
      WITH_DATA(ascii_char_ptr, humidity_unit),
      
      /* Manage firmware update process */
      WITH_DATA(ascii_char_ptr, new_firmware_URI),
      WITH_DATA(ascii_char_ptr, new_firmware_version),
      
      /* Device twin properties */
      WITH_REPORTED_PROPERTY(ascii_char_ptr, Protocol),
      WITH_REPORTED_PROPERTY(ascii_char_ptr, SupportedMethods),
      WITH_REPORTED_PROPERTY(TelemetryProperties, Telemetry),
      WITH_REPORTED_PROPERTY(ascii_char_ptr, Type),
      WITH_REPORTED_PROPERTY(ascii_char_ptr, Firmware),
      WITH_REPORTED_PROPERTY(ascii_char_ptr, FirmwareUpdateStatus),
      WITH_REPORTED_PROPERTY(ascii_char_ptr, Location),
      WITH_REPORTED_PROPERTY(double, Latitiude),
      WITH_REPORTED_PROPERTY(double, Longitude),
      
      WITH_DESIRED_PROPERTY(ascii_char_ptr, Interval, onDesiredInterval),
      
      /* Direct methods implemented by the device */
      WITH_METHOD(Reboot),
      WITH_METHOD(FirmwareUpdate, ascii_char_ptr, Firmware, ascii_char_ptr, FirmwareUri),
      WITH_METHOD(EmergencyValveRelease),
      WITH_METHOD(IncreasePressure)
      );
      
      END_NAMESPACE(Contoso);
      

Implementare il comportamento del dispositivoImplement the behavior of the device

Aggiungere il codice che implementa il comportamento definito nel modello.Now add code that implements the behavior defined in the model.

  1. Aggiungere il gestore di callback seguente che viene eseguito quando il dispositivo ha inviato i nuovi valori di proprietà segnalati alla soluzione preconfigurata:Add the following callback handler that runs when the device has sent new reported property values to the preconfigured solution:

    /* 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);
    }
    
  2. Aggiungere la funzione seguente che simula un processo di aggiornamento del firmware:Add the following function that simulates a firmware update process:

    static int do_firmware_update(void *param)
    {
      Chiller *chiller = (Chiller *)param;
      printf("do_firmware_update('URI: %s, Version: %s')\r\n", chiller->new_firmware_URI, chiller->new_firmware_version);
    
      printf("Simulating download phase...\r\n");
      chiller->FirmwareUpdateStatus = "downloading";
      /* Send reported properties to IoT Hub */
      if (IoTHubDeviceTwin_SendReportedStateChiller(chiller, deviceTwinCallback, NULL) != IOTHUB_CLIENT_OK)
      {
        printf("Failed sending serialized reported state\r\n");
      }
      ThreadAPI_Sleep(5000);
    
      printf("Simulating applying phase...\r\n");
      chiller->FirmwareUpdateStatus = "applying";
      /* Send reported properties to IoT Hub */
      if (IoTHubDeviceTwin_SendReportedStateChiller(chiller, deviceTwinCallback, NULL) != IOTHUB_CLIENT_OK)
      {
        printf("Failed sending serialized reported state\r\n");
      }
      ThreadAPI_Sleep(5000);
    
      printf("Simulating reboot phase...\r\n");
      chiller->FirmwareUpdateStatus = "rebooting";
      /* Send reported properties to IoT Hub */
      if (IoTHubDeviceTwin_SendReportedStateChiller(chiller, deviceTwinCallback, NULL) != IOTHUB_CLIENT_OK)
      {
        printf("Failed sending serialized reported state\r\n");
      }
      ThreadAPI_Sleep(5000);
    
      chiller->Firmware = _strdup(chiller->new_firmware_version);
      chiller->FirmwareUpdateStatus = "waiting";
      /* Send reported properties to IoT Hub */
      if (IoTHubDeviceTwin_SendReportedStateChiller(chiller, deviceTwinCallback, NULL) != IOTHUB_CLIENT_OK)
      {
        printf("Failed sending serialized reported state\r\n");
      }
    
      return 0;
    }
    
  3. Aggiungere la funzione seguente che gestisce le proprietà desiderate impostate nel dashboard della soluzione.Add the following function that handles the desired properties set in the solution dashboard. Tali proprietà desiderate sono definite nel modello:These desired properties are defined in the model:

    void onDesiredInterval(void* argument)
    {
      /* By convention 'argument' is of the type of the MODEL */
      Chiller* chiller = argument;
      printf("Received a new desired Interval value: %s \r\n", chiller->Interval);
    }
    
  4. Aggiungere le funzioni seguenti che gestiscono i metodi diretti richiamati tramite l'hub IoT.Add the following functions that handle the direct methods invoked through the IoT hub. Questi metodi diretti sono definiti nel modello:These direct methods are defined in the model:

    /* Handlers for direct methods */
    METHODRETURN_HANDLE Reboot(Chiller* chiller)
    {
      (void)(chiller);
    
      METHODRETURN_HANDLE result = MethodReturn_Create(201, "\"Rebooting\"");
      printf("Received reboot request\r\n");
      return result;
    }
    
    METHODRETURN_HANDLE FirmwareUpdate(Chiller* chiller, ascii_char_ptr Firmware, ascii_char_ptr FirmwareUri)
    {
      printf("Recieved firmware update request request\r\n");
      METHODRETURN_HANDLE result = NULL;
      if (chiller->FirmwareUpdateStatus != "waiting")
      {
        LogError("Attempting to initiate a firmware update out of order");
        result = MethodReturn_Create(400, "\"Attempting to initiate a firmware update out of order\"");
      }
      else
      {
        chiller->new_firmware_version = _strdup(Firmware);
        chiller->new_firmware_URI = _strdup(FirmwareUri);
        THREAD_HANDLE thread_apply;
        THREADAPI_RESULT t_result = ThreadAPI_Create(&thread_apply, do_firmware_update, chiller);
        if (t_result == THREADAPI_OK)
        {
          result = MethodReturn_Create(201, "\"Starting firmware update thread\"");
        }
        else
        {
          LogError("Failed to start firmware update thread");
          result = MethodReturn_Create(500, "\"Failed to start firmware update thread\"");
        }
      }
    
      return result;
    }
    
    METHODRETURN_HANDLE EmergencyValveRelease(Chiller* chiller)
    {
      (void)(chiller);
    
      METHODRETURN_HANDLE result = MethodReturn_Create(201, "\"Releasing Emergency Valve\"");
      printf("Recieved emergency valve release request\r\n");
      return result;
    }
    
    METHODRETURN_HANDLE IncreasePressure(Chiller* chiller)
    {
      (void)(chiller);
    
      METHODRETURN_HANDLE result = MethodReturn_Create(201, "\"Increasing Pressure\"");
      printf("Received increase pressure request\r\n");
      return result;
    }
    
  5. Aggiungere la funzione seguente che aggiunge una proprietà a un messaggio da dispositivo a cloud:Add the following function that adds a property to a device-to-cloud message:

    /* Add message property */
    static void addProperty(MAP_HANDLE propMap, char* propName, char* propValue)
    {
      if (Map_AddOrUpdate(propMap, propName, propValue) != MAP_OK)
      {
        (void)printf("ERROR: Map_AddOrUpdate Failed on %s!\r\n", propName);
      }
    }
    
  6. Aggiungere la funzione seguente che invia un messaggio con proprietà alla soluzione preconfigurata:Add the following function that sends a message with properties to the preconfigured solution:

    static void sendMessage(IOTHUB_CLIENT_HANDLE iotHubClientHandle, const unsigned char* buffer, size_t size, char* schema)
    {
      IOTHUB_MESSAGE_HANDLE messageHandle = IoTHubMessage_CreateFromByteArray(buffer, size);
      if (messageHandle == NULL)
      {
        printf("unable to create a new IoTHubMessage\r\n");
      }
      else
      {
        // Add properties
        MAP_HANDLE propMap = IoTHubMessage_Properties(messageHandle);
        addProperty(propMap, "$$MessageSchema", schema);
        addProperty(propMap, "$$ContentType", "JSON");
        time_t now = time(0);
        struct tm* timeinfo;
        #pragma warning(disable: 4996)
        timeinfo = gmtime(&now);
        char timebuff[50];
        strftime(timebuff, 50, "%Y-%m-%dT%H:%M:%SZ", timeinfo);
        addProperty(propMap, "$$CreationTimeUtc", timebuff);
    
        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);
    }
    
  7. Aggiungere la funzione seguente per connettere il dispositivo alla soluzione preconfigurata nel cloud e scambiare dati.Add the following function to connect your device to the preconfigured solution in the cloud, and exchange data. Questa funzione esegue questa procedura:This function performs the following steps:

    • Inizializza la piattaforma.Initializes the platform.
    • Registra lo spazio dei nomi Contoso con la libreria di serializzazione.Registers the Contoso namespace with the serialization library.
    • Inizializza il client con la stringa di connessione del dispositivo.Initializes the client with the device connection string.
    • Creare un'istanza del modello Chiller.Create an instance of the Chiller model.
    • Crea e invia i valori delle proprietà segnalate.Creates and sends reported property values.
    • Crea un ciclo per inviare dati di telemetria ogni cinque secondi mentre lo stato degli aggiornamenti del firmware è in attesa.Creates a loop to send telemetry every five seconds while the firmware update status is waiting.
    • Deinizializza tutte le risorse.Deinitializes all resources.

      void remote_monitoring_run(void)
      {
      if (platform_init() != 0)
      {
        printf("Failed to initialize the platform.\r\n");
      }
      else
      {
        if (SERIALIZER_REGISTER_NAMESPACE(Contoso) == NULL)
        {
          printf("Unable to SERIALIZER_REGISTER_NAMESPACE\r\n");
        }
        else
        {
          IOTHUB_CLIENT_HANDLE iotHubClientHandle = IoTHubClient_CreateFromConnectionString(connectionString, MQTT_Protocol);
          if (iotHubClientHandle == NULL)
          {
            printf("Failure in IoTHubClient_CreateFromConnectionString\r\n");
          }
          else
          {
            Chiller* chiller = IoTHubDeviceTwin_CreateChiller(iotHubClientHandle);
            if (chiller == NULL)
            {
              printf("Failure in IoTHubDeviceTwin_CreateChiller\r\n");
            }
            else
            {
              /* Set values for reported properties */
              chiller->Protocol = "MQTT";
              chiller->SupportedMethods = "Reboot,FirmwareUpdate,EmergencyValveRelease,IncreasePressure";
              chiller->Telemetry.TemperatureSchema.Interval = "00:00:05";
              chiller->Telemetry.TemperatureSchema.MessageTemplate = "{\"temperature\":${temperature},\"temperature_unit\":\"${temperature_unit}\"}";
              chiller->Telemetry.TemperatureSchema.MessageSchema.Name = "chiller-temperature;v1";
              chiller->Telemetry.TemperatureSchema.MessageSchema.Format = "JSON";
              chiller->Telemetry.TemperatureSchema.MessageSchema.Fields = "{\"temperature\":\"Double\",\"temperature_unit\":\"Text\"}";
              chiller->Telemetry.HumiditySchema.Interval = "00:00:05";
              chiller->Telemetry.HumiditySchema.MessageTemplate = "{\"humidity\":${humidity},\"humidity_unit\":\"${humidity_unit}\"}";
              chiller->Telemetry.HumiditySchema.MessageSchema.Name = "chiller-humidity;v1";
              chiller->Telemetry.HumiditySchema.MessageSchema.Format = "JSON";
              chiller->Telemetry.HumiditySchema.MessageSchema.Fields = "{\"humidity\":\"Double\",\"humidity_unit\":\"Text\"}";
              chiller->Telemetry.PressureSchema.Interval = "00:00:05";
              chiller->Telemetry.PressureSchema.MessageTemplate = "{\"pressure\":${pressure},\"pressure_unit\":\"${pressure_unit}\"}";
              chiller->Telemetry.PressureSchema.MessageSchema.Name = "chiller-pressure;v1";
              chiller->Telemetry.PressureSchema.MessageSchema.Format = "JSON";
              chiller->Telemetry.PressureSchema.MessageSchema.Fields = "{\"pressure\":\"Double\",\"pressure_unit\":\"Text\"}";
              chiller->Type = "Chiller";
              chiller->Firmware = "1.0.0";
              chiller->FirmwareUpdateStatus = "waiting";
              chiller->Location = "Building 44";
              chiller->Latitiude = 47.638928;
              chiller->Longitude = -122.13476;
      
              /* Send reported properties to IoT Hub */
              if (IoTHubDeviceTwin_SendReportedStateChiller(chiller, deviceTwinCallback, NULL) != IOTHUB_CLIENT_OK)
              {
                printf("Failed sending serialized reported state\r\n");
              }
              else
              {
                /* Send telemetry */
                chiller->temperature_unit = "F";
                chiller->pressure_unit = "psig";
                chiller->humidity_unit = "%";
      
                srand((unsigned int)time(NULL));
                while (1)
                {
                  chiller->temperature = 50 + ((rand() % 10) - 5);
                  chiller->pressure = 55 + ((rand() % 10) - 5);
                  chiller->humidity = 30 + ((rand() % 10) - 5);
                  unsigned char*buffer;
                  size_t bufferSize;
      
                  if (chiller->FirmwareUpdateStatus == "waiting")
                  {
                    (void)printf("Sending sensor value Temperature = %f %s,\r\n", chiller->temperature, chiller->temperature_unit);
      
                    if (SERIALIZE(&buffer, &bufferSize, chiller->temperature, chiller->temperature_unit) != CODEFIRST_OK)
                    {
                      (void)printf("Failed sending sensor value\r\n");
                    }
                    else
                    {
                      sendMessage(iotHubClientHandle, buffer, bufferSize, chiller->Telemetry.TemperatureSchema.MessageSchema.Name);
                    }
      
                    (void)printf("Sending sensor value Humidity = %f %s,\r\n", chiller->humidity, chiller->humidity_unit);
      
                    if (SERIALIZE(&buffer, &bufferSize, chiller->humidity, chiller->humidity_unit) != CODEFIRST_OK)
                    {
                      (void)printf("Failed sending sensor value\r\n");
                    }
                    else
                    {
                      sendMessage(iotHubClientHandle, buffer, bufferSize, chiller->Telemetry.HumiditySchema.MessageSchema.Name);
                    }
      
                    (void)printf("Sending sensor value Pressure = %f %s,\r\n", chiller->pressure, chiller->pressure_unit);
      
                    if (SERIALIZE(&buffer, &bufferSize, chiller->pressure, chiller->pressure_unit) != CODEFIRST_OK)
                    {
                      (void)printf("Failed sending sensor value\r\n");
                    }
                    else
                    {
                      sendMessage(iotHubClientHandle, buffer, bufferSize, chiller->Telemetry.PressureSchema.MessageSchema.Name);
                    }
                  }
      
                  ThreadAPI_Sleep(5000);
                }
      
                IoTHubDeviceTwin_DestroyChiller(chiller);
              }
          }
            IoTHubClient_Destroy(iotHubClientHandle);
        }
          serializer_deinit();
        }
      }
      platform_deinit();
      }
      

      Per riferimento, ecco un esempio di messaggio di Telemetria inviato alla soluzione preconfigurata:For reference, here is a sample Telemetry message sent to the preconfigured solution:

      Device: [myCDevice],
      Data:[{"humidity":50.000000000000000, "humidity_unit":"%"}]
      Properties:
      '$$MessageSchema': 'chiller-humidity;v1'
      '$$ContentType': 'JSON'
      '$$CreationTimeUtc': '2017-09-12T09:17:13Z'
      

Aggiungere il codice per eseguire l'appAdd code to run the app

Aprire il file remote_monitoring.h in un editor di testo.In a text editor, open the remote_monitoring.h file. Aggiungere il codice seguente:Add the following code:

void remote_monitoring_run(void);

Aprire il file main.c in un editor di testo.In a text editor, open the main.c file. Aggiungere il codice seguente:Add the following code:

#include "remote_monitoring.h"

int main(void)
{
  remote_monitoring_run();

  return 0;
}

Compilare ed eseguire l'applicazioneBuild and run the application

La procedura seguente descrive i metodi d'uso di CMake per compilare l'applicazione client.The following steps describe how to use CMake to build your client application.

  1. Aprire il file CMakeLists.txt nella cartella remote_monitoring in un editor di testo.In a text editor, open the CMakeLists.txt file in the remote_monitoring folder.

  2. Aggiungere le istruzioni seguenti per definire la modalità di compilazione dell'applicazione client:Add the following instructions to define how to build your client application:

    macro(compileAsC99)
      if (CMAKE_VERSION VERSION_LESS "3.1")
        if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
          set (CMAKE_C_FLAGS "--std=c99 ${CMAKE_C_FLAGS}")
          set (CMAKE_CXX_FLAGS "--std=c++11 ${CMAKE_CXX_FLAGS}")
        endif()
      else()
        set (CMAKE_C_STANDARD 99)
        set (CMAKE_CXX_STANDARD 11)
      endif()
    endmacro(compileAsC99)
    
    cmake_minimum_required(VERSION 2.8.11)
    compileAsC99()
    
    set(AZUREIOT_INC_FOLDER "${CMAKE_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/parson" "/usr/include/azureiot" "/usr/include/azureiot/inc")
    
    include_directories(${AZUREIOT_INC_FOLDER})
    
    set(sample_application_c_files
        ./parson/parson.c
        ./remote_monitoring.c
        ./main.c
    )
    
    set(sample_application_h_files
        ./parson/parson.h
        ./remote_monitoring.h
    )
    
    add_executable(sample_app ${sample_application_c_files} ${sample_application_h_files})
    
    target_link_libraries(sample_app
        serializer
        iothub_client
        iothub_client_mqtt_transport
        aziotsharedutil
        umqtt
        pthread
        curl
        ssl
        crypto
        m
    )
    
  3. Nella cartella remote_monitoring creare una cartella per archiviare i file make generati da CMake.In the remote_monitoring folder, create a folder to store the make files that CMake generates. Eseguire quindi i comandi cmake e make in questo modo:Then run the cmake and make commands as follows:

    mkdir cmake
    cd cmake
    cmake ../
    make
    
  4. Eseguire l'applicazione client e inviare dati di telemetria all'hub IoT:Run the client application and send telemetry to IoT Hub:

    ./sample_app
    

Visualizzare la telemetria dei dispositiviView device telemetry

È possibile visualizzare i dati di telemetria inviati dal dispositivo nella pagina Dispositivi della soluzione.You can view the telemetry sent from your device on the Devices page in the solution.

  1. Selezionare il dispositivo del quale è stato effettuato il provisioning nell'elenco dei dispositivi della pagina Dispositivi.Select the device you provisioned in the list of devices on the Devices page. Un pannello visualizza le informazioni sul dispositivo, incluso un tracciato dei dati di telemetria del dispositivo:A panel displays information about your device including a plot of the device telemetry:

    Vedere i dettagli del dispositivo

  2. Scegliere Pressione per modificare la visualizzazione dei dati di telemetria:Choose Pressure to change the telemetry display:

    Visualizzare i dati di telemetria per la pressione

  3. Per visualizzare le informazioni di diagnostica sul dispositivo, scorrere fino a Diagnostica:To view diagnostic information about your device, scroll down to Diagnostics:

    Visualizzazione della diagnostica del dispositivo

Agire sul dispositivoAct on your device

Per richiamare i metodi nei dispositivi, usare la pagina Dispositivi della soluzione per il monitoraggio remoto.To invoke methods on your devices, use the Devices page in the remote monitoring solution. Nella soluzione per il monitoraggio remoto, i dispositivi Chiller implementano ad esempio un metodo FirmwareUpdate.For example, in the remote monitoring solution Chiller devices implement a FirmwareUpdate method.

  1. Scegliere Dispositivi per passare alla pagina Dispositivi della soluzione.Choose Devices to navigate to the Devices page in the solution.

  2. Selezionare il dispositivo del quale è stato effettuato il provisioning nell'elenco dei dispositivi della pagina Dispositivi:Select the device you provisioned in the list of devices on the Devices page:

    Selezionare il dispositivo fisico

  3. Per visualizzare un elenco dei metodi che è possibile chiamare in un dispositivo, scegliere Pianificazione.To display a list of the methods you can call on your device, choose Schedule. Per pianificare un metodo per l'esecuzione in più dispositivi, è possibile selezionare più dispositivi nell'elenco.To schedule a method to run on multiple devices, you can select multiple devices in the list. Il pannello Pianificazione mostra i tipi di metodi comuni a tutti i dispositivi selezionati.The Schedule panel shows the types of method common to all the devices you selected.

  4. Scegliere FirmwareUpdate, impostare il nome del processo su UpdatePhysicalChiller.Choose FirmwareUpdate, set the job name to UpdatePhysicalChiller. Impostare Firmware Version (Versione firmware) su 2.0.0, quindi impostare Firmware URI (URI firmware) su http://contoso.com/updates/firmware.bin e infine scegliere Apply (Applica):Set Firmware Version to 2.0.0, set Firmware URI to http://contoso.com/updates/firmware.bin, and then choose Apply:

    Pianificare l'aggiornamento del firmware

  5. Nella console che esegue il codice del dispositivo mentre il dispositivo simulato gestisce il metodo viene visualizzata una sequenza di messaggi.A sequence of messages displays in the console running your device code while the simulated device handles the method.

  6. A termine dell'aggiornamento, nella pagina Devices (Dispositivi) viene visualizzata la nuova versione del firmware:When the update is complete, the new firmware version displays on the Devices page:

    Aggiornamento completato

Nota

Per tenere traccia dello stato del processo nella soluzione, scegliere Visualizza.To track the status of the job in the solution, choose View.

Passaggi successiviNext steps

L'articolo Personalizzare la soluzione preconfigurata di monitoraggio remoto descrive alcuni modi per personalizzare la soluzione preconfigurata.The article Customize the remote monitoring preconfigured solution describes some ways to customize the preconfigured solution.