Dela via


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

Ö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 gå till 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 en C-exempellösning i Windows

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

Skapa ett startprojekt i Visual Studio 2015 eller Visual Studio 2017 och lägg till nuGet-paketen för IoT Hub-enhetsklienten:

  1. I Visual Studio skapar du ett C-konsolprogram med hjälp av mallen Visual C++ Win32-konsolprogram . Ge projektet namnet RMDevice.

  2. På sidan Programinställningar i Win32-programguiden kontrollerar du att Konsolprogram är markerat och avmarkerar förkompilerade rubrik- och SDL-kontroller (Security Development Lifecycle).

  3. I Solution Explorer tar du bort filerna stdafx.h, targetver.h och stdafx.cpp.

  4. I Solution Explorer byter du namn på filen RMDevice.cpp till RMDevice.c.

  5. I Solution Explorer högerklickar du på RMDevice-projektet och klickar sedan på Hantera NuGet-paket. Klicka på Bläddra och sök sedan efter och installera följande NuGet-paket:

    • Microsoft.Azure.IoTHub.Serializer
    • Microsoft.Azure.IoTHub.IoTHubClient
    • Microsoft.Azure.IoTHub.MqttTransport
  6. I Solution Explorer högerklickar du på RMDevice-projektet och klickar sedan på Egenskaper för att öppna projektets dialogruta Egenskapssidor. Mer information finns i Ange egenskaper för Visual C++-projekt.

  7. Klicka på mappen Linker och klicka sedan på egenskapssidan Indata .

  8. Lägg till crypt32.lib i egenskapen Ytterligare beroenden . Klicka på OK och sedan på OK igen för att spara projektets egenskapsvärden.

Lägg till Parson JSON-biblioteket i RMDevice-projektet och lägg till nödvändiga #include instruktioner:

  1. I en lämplig mapp på datorn klonar du Parson GitHub-lagringsplatsen med följande kommando:

    git clone https://github.com/kgabis/parson.git
    
  2. Kopiera filerna parson.h och parson.c från den lokala kopian av Parson-lagringsplatsen till rmDevice-projektmappen .

  3. Högerklicka på RMDevice-projektet i Visual Studio, klicka på Lägg till och klicka sedan på Befintligt objekt.

  4. I dialogrutan Lägg till befintligt objekt väljer du filerna parson.h och parson.c i projektmappen RMDevice . Klicka sedan på Lägg till för att lägga till dessa två filer i projektet.

  5. Öppna filen RMDevice.c i Visual Studio. Ersätt de befintliga #include -instruktionerna med följande kod:

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

    Anteckning

    Nu kan du kontrollera att projektet har rätt beroenden konfigurerade genom att skapa det.

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}
    

Skapa och köra exempelappen

Lägg till kod för att anropa funktionen remote_monitoring_run och skapa och köra enhetsappen.

  1. Ersätt huvudfunktionen med följande kod för att anropa funktionen remote_monitoring_run :

    int main()
    {
      remote_monitoring_run();
      return 0;
    }
    
  2. Klicka på Skapa och sedan på Skapa lösning för att skapa enhetsappen.

  3. I Solution Explorer högerklickar du på RMDevice-projektet, klickar på Felsök och klickar sedan på Starta ny instans för att köra exemplet. Konsolen visar meddelanden när programmet skickar exempeltelemetri till den förkonfigurerade lösningen, tar emot önskade egenskapsvärden som angetts på lösningsinstrumentpanelen och svarar på metoder som anropas från lösningens instrumentpanel.

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.