Dela via


Ansluta enheten till den förkonfigurerade fjärrövervakningslösningen (Linux)

Översikt över scenario

I det här scenariot skapar du en enhet som skickar följande telemetri till den förkonfigurerade lösningen för fjärrövervakning:

  • Extern temperatur
  • Intern temperatur
  • Luftfuktighet

För enkelhetens skull genererar koden på enheten exempelvärden men vi rekommenderar att du utökar exemplet genom att ansluta riktiga sensorer till enheten och skicka riktig telemetri.

Enheten kan även svara på metoderna som anropas från lösningens instrumentpanel och de önskade egenskapsvärden som är angivna i lösningens instrumentpanel.

Du behöver ett Azure-konto för att slutföra den här självstudiekursen. Om du inte har något konto kan skapa du ett kostnadsfritt utvärderingskonto på bara några minuter. Mer information om den kostnadsfria utvärderingsversionen av Azure finns Kostnadsfri utvärderingsversion av Azure.

Innan du börjar

Innan du kan skriva kod för enheten måste du etablera din förkonfigurerade lösning för fjärrövervakning och etablera en ny anpassad enhet i lösningen.

Etablera din förkonfigurerade lösning för fjärrövervakning

Enheten som du skapar i den här självstudien skickar data till en instans av den förkonfigurerade lösningen för fjärrövervakning. Om du inte redan har etablerat den förkonfigurerade lösningen för fjärrövervakning i ditt Azure-konto använder du följande steg:

  1. På sidan https://www.azureiotsolutions.com/ klickar du för + att skapa en lösning.
  2. Klicka på Välj på panelen Fjärrövervakning för att skapa din lösning.
  3. På sidan Create Remote monitoring solution (Skapa fjärrövervakningslösning) anger du ett Lösningsnamn och väljer den Region du vill distribuera till samt väljer den Azure-prenumerationen som du vill använda. Klicka på Skapa lösning.
  4. Vänta tills etableringsprocessen har slutförts.

Varning

De förkonfigurerade lösningarna använder fakturerbara Azure-tjänster. Se till att ta bort den förkonfigurerade lösningen från prenumerationen när du är färdig med den för att undvika onödiga kostnader. Du kan ta bort en förkonfigurerad lösning helt från din prenumeration genom att besöka sidan https://www.azureiotsolutions.com/ .

När etableringen av fjärrövervakningslösningen är klar klickar du på Starta för att öppna lösningens instrumentpanel i webbläsaren.

Instrumentpanel för lösningen

Etablera enheten i fjärrövervakningslösningen

Anteckning

Om du redan har etablerat en enhet i din lösning kan du hoppa över det här steget. Du behöver känna till enhetens autentiseringsuppgifter när du skapar klientprogrammet.

För att en enhet ska kunna ansluta till den förkonfigurerade lösningen måste den identifiera sig för IoT Hub med giltiga autentiseringsuppgifter. Du kan hämta enhetens autentiseringsuppgifter från lösningens instrumentpanel. Du kan inkludera enhetsautentiseringsuppgifterna i klientprogrammet senare i den här självstudien.

Om du vill lägga till en enhet till din fjärrövervakningslösning utför du följande steg i lösningens instrumentpanel:

  1. Klicka på Lägg till en enhet i det nedre vänstra hörnet på instrumentpanelen.

    Lägg till en enhet

  2. I panelen Anpassad enhet klickar du på Lägg till ny.

    Lägg till en anpassad enhet

  3. Välj Låt mig ange mitt eget enhets-ID. Ange ett enhets-ID, t.ex. mydevice och klicka på Kontrollera ID för att kontrollera att namnet inte redan används. Klicka sedan på Skapa för att etablera enheten.

    Lägg till enhets-ID

  4. Notera enhetsautentiseringsuppgifterna (Enhets-ID, IoT Hub-värdnamn och Enhetsnyckel). Klientprogrammet behöver dessa värden för att ansluta till fjärrövervakningslösningen. Klicka sedan på Klar.

    Visa enhetsautentiseringsuppgifter

  5. Välj enheten i enhetslistan i lösningens instrumentpanel. Klicka sedan på Aktivera enhet i panelen Enhetsinformation. Statusen för din enhet är nu Körs. Fjärrövervakningslösningen kan nu ta emot telemetri från enheten och anropa metoder på enheten.

Skapa och köra en C-exempelklient i Linux

Följande steg visar hur du skapar ett klientprogram som kommunicerar med den förkonfigurerade fjärrövervakningslösningen. Det här programmet är skrivet i C och har skapats och körts på Ubuntu Linux.

För att slutföra de här stegen behöver du en enhet som kör Ubuntu version 15.04 eller 15.10. Innan du fortsätter installerar du nödvändiga paket på Ubuntu-enheten med följande kommando:

sudo apt-get install cmake gcc g++

Installera klientbiblioteken på enheten

De Azure IoT Hub klientbiblioteken är tillgängliga som ett paket som du kan installera på Ubuntu-enheten med hjälp av kommandot apt-get. Utför följande steg för att installera paketet som innehåller IoT Hub-klientbiblioteket och huvudfilerna på Ubuntu-datorn:

  1. I ett gränssnitt lägger du till AzureIoT-lagringsplatsen på datorn:

    sudo add-apt-repository ppa:aziotsdklinux/ppa-azureiot
    sudo apt-get update
    
  2. Installera paketet azure-iot-sdk-c-dev

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

Installera Parson JSON-parsern

IoT Hub-klientbiblioteken använder Parson JSON-parsern för att parsa meddelandenyttolaster. I en lämplig mapp på datorn klonar du Parson GitHub-lagringsplatsen med följande kommando:

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

Förbereda projektet

På din Ubuntu-dator skapar du en mapp med namnet remote_monitoring. I mappen remote_monitoring :

  • Skapa de fyra filerna main.c, remote_monitoring.c, remote_monitoring.h och CMakeLists.txt.
  • Skapa mapp med namnet parson.

Kopiera filerna parson.c och parson.h från din lokala kopia av Parson-lagringsplatsen till mappen remote_monitoring/parson .

Öppna filen remote_monitoring.c i en textredigerare. Lägg till följande #include-uttryck:

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

Ange beteende för IoT-enheten

Klientbiblioteket för IoT Hub-serialiseraren använder en modell för att ange formatet på de meddelanden som enheten utbyter med IoT Hub.

  1. Lägg till följande variabeldeklarationer efter #include-instruktionerna. Ersätt platshållarvärdena [Enhets-ID] och [Enhetsnyckel] med värden som du antecknade för enheten på instrumentpanelen för fjärrövervakningslösningen. Använd värdnamnet för IoT Hub från lösningens instrumentpanel för att ersätta [IoTHub-namn]. Om ditt värdnamn för IoT Hub exempelvis är contoso.azure-devices.net ersätter du [IoTHub-namn] med contoso:

    static const char* deviceId = "[Device Id]";
    static const char* connectionString = "HostName=[IoTHub Name].azure-devices.net;DeviceId=[Device Id];SharedAccessKey=[Device Key]";
    
  2. Lägg till följande kod för att definiera den modell som aktiverar enheten till att kommunicera med IoT Hub. Modellen anger att enheten kan göra följande:

    • Kan skicka temperatur, extern temperatur, luftfuktighet och ett enhets-ID som telemetri.
    • Skicka metadata om enheten till IoT Hub. Enheten skickar grundläggande metadata i ett DeviceInfo-objekt vid start.
    • Skicka rapporterade egenskaper till enhetstvillingen i IoT Hub. De rapporterade egenskaperna grupperas i konfigurations-, enhets- och systemegenskaper.
    • Ta emot och arbeta med önskade egenskaper som angetts i enhetstvillingen i IoT Hub.
    • Svara på de direkta metoderna Reboot och InitiateFirmwareUpdate som anropas via lösningsportalen. Enheten använder rapporterade egenskaper för att skicka information om direkta metoder som stöds.
    // 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);
    

Implementera enhetens beteende

Lägg till kod som implementerar det beteende som definierats i modellen.

  1. Lägg till följande funktioner som hanterar de önskade egenskaperna i lösningens instrumentpanel. Dessa önskade egenskaper definieras i modellen:

    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. Lägg till följande funktioner som hanterar de direkta metoder som anropas via IoT Hub. Dessa direkta metoder definieras i modellen:

    /* 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. Lägg till följande funktion som skickar ett meddelande till den förkonfigurerade lösningen:

    /* 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. Lägg till följande motringningshanterare som körs när enheten har skickat nya rapporterade egenskapsvärden till den förkonfigurerade lösningen:

    /* 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. Lägg till följande funktion för att ansluta enheten till den förkonfigurerade lösningen i molnet och utbyta data. Den här funktionen utför följande steg:

    • Initierar plattformen.
    • Registrerar namnområdet Contoso med serialiseringsbiblioteket.
    • Initierar klienten med enhetens anslutningssträng.
    • Skapar en instans av modellen Termostat.
    • Skapar och skickar rapporterade egenskapsvärden.
    • Skickar ett DeviceInfo-objekt.
    • Skapar en loop för att skicka telemetri varje sekund.
    • Avinitierar alla resurser.
    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();
    }
    

    Här är ett exempel på ett Telemetri-meddelande som skickats till den förkonfigurerade lösningen:

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

Anropa funktionen remote_monitoring_run

Öppna filen remote_monitoring.h i en textredigerare. Lägg till följande kod:

void remote_monitoring_run(void);

Öppna filen main.c i en textredigerare. Lägg till följande kod:

#include "remote_monitoring.h"

int main(void)
{
    remote_monitoring_run();

    return 0;
}

Skapa och kör appen

Följande steg beskriver hur du använder CMake för att skapa klientprogrammet.

  1. Öppna filenCMakeLists.txt i mappen remote_monitoring i en textredigerare.

  2. Lägg till följande instruktioner för att definiera hur du skapar klientprogrammet:

    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. I mappen remote_monitoring skapar du en mapp för att lagra filerna som CMake genererar och kör sedan cmake och gör kommandon på följande sätt:

    mkdir cmake
    cd cmake
    cmake ../
    make
    
  4. Kör klientprogrammet och skicka telemetri till IoT Hub:

    ./sample_app
    

Visa enhetstelemetri i instrumentpanelen

Instrumentpanelen i fjärrövervakningslösningen visar den telemetri som enheterna skickar till IoT Hub.

  1. Gå tillbaka till fjärrövervakningslösningens instrumentpanel i webbläsaren och klicka på Enheter i den vänstra panelen för att navigera till Enhetslistan.

  2. I enhetslistan bör du se att statusen för din enhet är Körs. Om den inte körs klickar du på Aktivera enhet i panelen Enhetsinformation.

    Visa enhetsstatus

  3. Klicka på Instrumentpanel för att gå tillbaka till instrumentpanelen och välj din enhet i listrutan Enhet att visa för att se dess telemetri. Telemetrin från exempelprogrammet är 50 enheter för intern temperatur, 55 enheter för extern temperatur och 50 enheter för fuktighet.

    Visa enhetstelemetri

Anropa en metod på enheten

Instrumentpanelen i fjärrövervakningslösningen låter dig anropa metoder på enheterna genom IoT Hub. Du kan till exempel anropa en metod för att simulera en omstart av en enhet i fjärrövervakningslösningen.

  1. I fjärrövervakningslösningens instrumentpanel klickar du på Enheter i den vänstra panelen för att navigera till Enhetslistan.

  2. Klicka på din enhets Enhets-ID i enhetslistan.

  3. I panelen Enhetsinformation klickar du på Metoder.

    Enhetsmetoder

  4. I listrutan Metodväljer du InitiateFirmwareUpdate och sedan anger du en dummy-URL i FWPACKAGEURI. Klicka på Anropa metod för att anropa metoden på enheten.

    Anropa en enhetsmetod

  5. Du ser ett meddelande i konsolen som kör enhetskoden när enheten hanterar metoden. Resultaten av metoden läggs till i historiken i lösningsportalen:

    Visa metodhistorik

Nästa steg

Artikeln Anpassning av förkonfigurerade lösningar beskriver några sätt du kan utöka det här exemplet. Möjliga tillägg kan vara att använda riktiga sensorer och att implementera ytterligare kommandon.

Du kan lära dig mer om behörigheter på webbplatsen azureiotsuite.com.