Condividi tramite


Connettere il dispositivo alla soluzione preconfigurata di monitoraggio remoto (Linux)

Panoramica dello scenario

In questo scenario viene creato un dispositivo che invia i dati di telemetria seguenti al monitoraggio remoto soluzione preconfigurata:

  • Temperatura esterna
  • Temperatura interna
  • Umidità

Per semplicità, il codice nel dispositivo genera valori di esempio, ma è consigliabile estendere l'esempio connettendo sensori reali al dispositivo e inviando dati di telemetria reali.

Il dispositivo è anche in grado di rispondere ai metodi richiamati dal dashboard della soluzione e i valori delle proprietà desiderati impostati nel dashboard della soluzione.

Per completare questa esercitazione, è necessario un account Azure attivo. Se non si dispone di un account, è possibile creare un account di valutazione gratuita in pochi minuti. Per informazioni dettagliate, vedere Versione di valutazione gratuita di Azure.

Prima di iniziare

Prima di scrivere codice per il dispositivo, è necessario effettuare il provisioning della soluzione preconfigurata di monitoraggio remoto ed effettuare il provisioning di un nuovo dispositivo personalizzato in tale soluzione.

Configurare la soluzione preconfigurata di monitoraggio remoto

Il dispositivo creato in questa esercitazione invia i dati a un'istanza della soluzione preconfigurata di monitoraggio remoto. Se non è già stato effettuato il provisioning della soluzione preconfigurata di monitoraggio remoto nell'account Azure, seguire questa procedura:

  1. Nella pagina https://www.azureiotsolutions.com/ fare clic su + per creare una soluzione.
  2. Fare clic su Selezionare sul pannello monitoraggio remoto per creare la propria soluzione.
  3. Nella pagina Crea soluzione di monitoraggio remoto immettere un Nome della soluzione di propria scelta, selezionare la Regione in cui si vuole eseguire la distribuzione e selezionare la sottoscrizione di Azure che si desidera usare. Fare quindi clic su Crea soluzione.
  4. Attendere il completamento del processo di provisioning.

Avvertimento

Le soluzioni preconfigurate usano servizi di Azure fatturabili. Assicurarsi di rimuovere la soluzione preconfigurata dalla sottoscrizione al termine dell'operazione per evitare addebiti non necessari. È possibile rimuovere completamente una soluzione preconfigurata dalla sottoscrizione visitando la pagina https://www.azureiotsolutions.com/.

Al termine del processo di provisioning per la soluzione di monitoraggio remoto, fare clic su Avvia per aprire il dashboard della soluzione nel browser.

dashboard della soluzione

Configura il dispositivo nella soluzione di monitoraggio remoto

Nota

Se è già stato effettuato il provisioning di un dispositivo nella soluzione, è possibile ignorare questo passaggio. È necessario conoscere le credenziali del dispositivo quando si crea l'applicazione client.

Affinché un dispositivo si connetta alla soluzione preconfigurata, deve identificarsi all'hub IoT usando credenziali valide. È possibile recuperare le credenziali del dispositivo dal dashboard della soluzione. Le credenziali del dispositivo vengono incluse nell'applicazione client più avanti in questa esercitazione.

Per aggiungere un dispositivo alla soluzione di monitoraggio remoto, completare i passaggi seguenti nel dashboard della soluzione:

  1. Nell'angolo inferiore sinistro del dashboard fare clic su Aggiungi un dispositivo.

    Aggiungere un dispositivo

  2. Nel pannello dispositivo personalizzato , fare clic su Aggiungi nuovo.

    Aggiungidispositivo personalizzato

  3. Scegliere Permettimi di definire il mio ID dispositivo. Immettere un ID dispositivo, ad esempio mydevice, fare clic su Controlla ID per verificare che il nome non sia già in uso e quindi fare clic su Crea per effettuare il provisioning del dispositivo.

    Aggiungi ID dispositivo

  4. Prendere nota delle credenziali del dispositivo (ID dispositivo, nome host dell'hub IoT e Chiave del dispositivo). L'applicazione client richiede questi valori per connettersi alla soluzione di monitoraggio remoto. Fare quindi clic su Done (Chiudi).

    Visualizzare le credenziali del dispositivo

  5. Selezionare il dispositivo nell'elenco dei dispositivi nel dashboard della soluzione. Quindi, nel pannello Dettagli Dispositivo, fare clic su Abilita Dispositivo. Lo stato del tuo dispositivo è attualmente in esecuzione. La soluzione di monitoraggio remoto può ora ricevere dati di telemetria dal dispositivo e richiamare i metodi nel dispositivo.

Compilare ed eseguire un client C di esempio Linux

I passaggi seguenti illustrano come creare un'applicazione client che comunica con la soluzione preconfigurata di monitoraggio remoto. Questa applicazione è scritta in C ed è stata compilata ed eseguita in Ubuntu Linux.

Per completare questi passaggi, è necessario un dispositivo che esegue Ubuntu versione 15.04 o 15.10. Prima di procedere, installare i pacchetti prerequisiti nel dispositivo Ubuntu usando il comando seguente:

sudo apt-get install cmake gcc g++

Installare le librerie client nel dispositivo

Le librerie client dell'hub IoT di Azure sono disponibili come pacchetto che è possibile installare nel dispositivo Ubuntu usando il comando apt-get. Completare i passaggi seguenti per installare il pacchetto che contiene la libreria client dell'hub IoT e i file di intestazione nel computer Ubuntu:

  1. In una shell aggiungere il repository AzureIoT al computer:

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

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

Installare il parser JSON "Parson"

Le librerie client dell'hub IoT usano il parser JSON Parson per analizzare i payload dei messaggi. In una cartella appropriata sul tuo computer, per clonare il repository GitHub Parson, usa il comando seguente:

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

Preparare il progetto

Nel computer Ubuntu creare una cartella denominata remote_monitoring. Nella cartella remote_monitoring:

  • Creare i quattro file main.c, remote_monitoring.c, remote_monitoring.he CMakeLists.txt.
  • Creare una cartella denominata parson.

Copiare i file parson.c e parson.h dalla copia locale del repository Parson nella cartella remote_monitoring/parson.

In un editor di testo aprire il file remote_monitoring.c. Aggiungere le istruzioni #include seguenti:

#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"

Specificare il comportamento del dispositivo IoT

La libreria client del serializzatore dell'hub IoT usa un modello per specificare il formato dei messaggi che scambiano i dispositivi con l'hub IoT.

  1. Aggiungere le dichiarazioni di variabili seguenti dopo le istruzioni #include. Sostituire i valori segnaposto [ID dispositivo] e [Chiave dispositivo] con i valori annotati per il dispositivo nel dashboard della soluzione di monitoraggio remoto. Usare il nome host dell'hub IoT dal dashboard della soluzione per sostituire [Nome IoTHub]. Ad esempio, se il nome host dell'hub IoT è contoso.azure-devices.net, sostituire [Nome IoTHub] con contoso:

    static const char* deviceId = "[Device Id]";
    static const char* connectionString = "HostName=[IoTHub Name].azure-devices.net;DeviceId=[Device Id];SharedAccessKey=[Device Key]";
    
  2. Aggiungere il codice seguente per definire il modello che consente al dispositivo di comunicare con l'hub IoT. Questo modello specifica che il dispositivo:

    • Può inviare temperatura, temperatura esterna, umidità e UN ID dispositivo come dati di telemetria.
    • Può inviare metadati sul dispositivo all'hub IoT. Il dispositivo invia metadati di base in un oggetto DeviceInfo all'avvio.
    • Può inviare le proprietà segnalate al dispositivo gemello nell'hub IoT. Queste proprietà segnalate vengono raggruppate in proprietà di configurazione, dispositivo e sistema.
    • Può ricevere e agire sulle proprietà desiderate impostate nel dispositivo gemello nell'hub IoT.
    • Può rispondere ai metodi diretti Reboot e InitiateFirmwareUpdate richiamati tramite il portale della soluzione. Il dispositivo invia informazioni sui metodi diretti supportati attraverso le proprietà riportate.
    // 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);
    

Implementare il comportamento del dispositivo

Aggiungere ora il codice che implementa il comportamento definito nel modello.

  1. Aggiungere le funzioni seguenti che gestiscono le proprietà desiderate impostate nel dashboard della soluzione. Queste proprietà desiderate sono definite nel modello:

    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. Aggiungere le funzioni seguenti che gestiscono i metodi diretti richiamati tramite l'hub IoT. Questi metodi diretti sono definiti nel modello:

    /* 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. Aggiungere la funzione seguente che invia un messaggio alla soluzione preconfigurata:

    /* 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. Aggiungere il seguente gestore di callback che è eseguito quando il dispositivo invia nuovi valori delle proprietà segnalate alla soluzione preconfigurata:

    /* 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. Aggiungere la funzione seguente per connettere il dispositivo alla soluzione preconfigurata nel cloud e scambiare dati. Questa funzione esegue i passaggi seguenti:

    • Inizializza la piattaforma.
    • Registra lo spazio dei nomi Contoso con la libreria di serializzazione.
    • Inizializza il client con la stringa di connessione del dispositivo.
    • Creare un'istanza del modello del termostato.
    • Crea e invia i valori delle proprietà segnalate.
    • Invia un oggetto DeviceInfo.
    • Crea un ciclo per inviare dati di telemetria ogni secondo.
    • Deinizializza tutte le risorse.
    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();
    }
    

    Per riferimento, di seguito è riportato un esempio messaggio di telemetria inviato alla soluzione preconfigurata:

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

Chiamare la funzione remote_monitoring_run

In un editor di testo aprire il file remote_monitoring.h. Aggiungere il codice seguente:

void remote_monitoring_run(void);

In un editor di testo aprire il file main.c. Aggiungere il codice seguente:

#include "remote_monitoring.h"

int main(void)
{
    remote_monitoring_run();

    return 0;
}

Compilare ed eseguire l'applicazione

I passaggi seguenti descrivono come usare CMake per compilare l'applicazione client.

  1. In un editor di testo aprire il file CMakeLists.txt nella cartella remote_monitoring.

  2. Aggiungere le istruzioni seguenti per definire come compilare l'applicazione client:

    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 e quindi eseguire i comandi cmake e make come indicato di seguito:

    mkdir cmake
    cd cmake
    cmake ../
    make
    
  4. Eseguire l'applicazione client e inviare dati di telemetria all'hub IoT:

    ./sample_app
    

Visualizzare i dati di telemetria del dispositivo nel dashboard

Il dashboard nella soluzione di monitoraggio remoto consente di visualizzare i dati di telemetria inviati dai dispositivi all'hub IoT.

  1. Nel tuo browser, torna al dashboard della soluzione di monitoraggio remoto, fai clic su Dispositivi nel pannello a sinistra per passare all'elenco dei dispositivi .

  2. Nell'elenco Dispositivi, dovresti vedere che lo stato del tuo dispositivo è In esecuzione. Fare clic su Abilita dispositivo nel pannello Dettagli dispositivo in caso contrario.

    Visualizzare lo stato del dispositivo

  3. Fare clic su Dashboard per tornare al dashboard, selezionare il dispositivo nell'elenco a discesa Dispositivo da visualizzare per visualizzarne i dati di telemetria. I dati di telemetria dell'applicazione di esempio sono 50 unità per la temperatura interna, 55 unità per la temperatura esterna e 50 unità per l'umidità.

    Visualizzare i dati di telemetria dei dispositivi

Richiamare un metodo nel dispositivo

Il dashboard nella soluzione di monitoraggio remoto consente di richiamare metodi nei dispositivi tramite l'hub IoT. Ad esempio, nella soluzione di monitoraggio remoto è possibile richiamare un metodo per simulare il riavvio di un dispositivo.

  1. Nel dashboard della soluzione di monitoraggio remoto fare clic su Dispositivi nel pannello a sinistra per passare all'elenco Dispositivi .

  2. Fare clic su ID dispositivo per il tuo dispositivo nell'elenco dei dispositivi .

  3. Nel pannello dettagli dispositivo fare clic su Metodi.

    metodi dispositivo

  4. Nel menu a tendina Method, selezionare InitiateFirmwareUpdatee quindi in FWPACKAGEURI inserire un URL fittizio. Fare clic su Invoke Method per chiamare il metodo nel dispositivo.

    Richiamare un metodo del dispositivo

  5. Viene visualizzato un messaggio nella console che esegue il codice del dispositivo quando il dispositivo gestisce il metodo. I risultati del metodo vengono aggiunti alla cronologia nel portale della soluzione:

    Visualizzare la cronologia dei metodi

Passaggi successivi

L'articolo Personalizzazione di soluzioni preconfigurate descrive alcuni modi in cui è possibile estendere questo esempio. Le possibili estensioni includono l'uso di sensori reali e l'implementazione di comandi aggiuntivi.

Altre informazioni sulle autorizzazioni di nel sito azureiotsuite.com.