Delen via


Uw apparaat verbinden met de vooraf geconfigureerde oplossing voor externe bewaking (Linux)

Overzicht van scenario's

In dit scenario maakt u een apparaat dat de volgende telemetrie verzendt naar de vooraf geconfigureerde oplossing voor externe controle:

  • Externe temperatuur
  • Interne temperatuur
  • Vochtigheid

Om het eenvoudig te houden, genereert de code op het apparaat voorbeeldwaarden, maar we moedigen u aan om het voorbeeld uit te breiden door echte sensoren met het apparaat te verbinden en echte telemetrie te verzenden.

Het apparaat kan ook reageren op methoden die zijn aangeroepen vanuit het oplossingsdashboard en op waarden van gewenste eigenschappen die in het oplossingsdashboard zijn ingesteld.

U hebt een actief Azure-account nodig om deze zelfstudie te voltooien. Als u geen account hebt, kunt u binnen een paar minuten een gratis proefaccount maken. Zie Gratis proefversie van Azure voor meer informatie.

Voordat u begint

Voordat u code voor het apparaat gaat schrijven, moet u de vooraf geconfigureerde oplossing voor externe controle inrichten en een nieuw aangepast apparaat in die oplossing inrichten.

De vooraf geconfigureerde oplossing voor externe controle inrichten

Het apparaat dat u in deze zelfstudie maakt, verzendt gegevens naar een exemplaar van de vooraf geconfigureerde oplossing voor externe controle. Als u de vooraf geconfigureerde oplossing voor externe controle in uw Azure-account nog niet hebt ingericht, voer dan de volgende stappen uit:

  1. Klik op + de https://www.azureiotsolutions.com/ pagina om een oplossing te maken.
  2. Klik in het deelvenster Externe controle op Selecteren om de oplossing te maken.
  3. Voer op de pagina Externe bewakingsoplossing een zelfgekozen Oplossingsnaam in, selecteer de Regio waarin u deze wilt implementeren en selecteer het Azure-abonnement dat u wilt gebruiken. Klik vervolgens op Oplossing maken.
  4. Wacht tot het inrichtingsproces is voltooid.

Waarschuwing

De vooraf geconfigureerde oplossingen maken gebruik van factureerbare Azure-services. Zorg dat u de vooraf geconfigureerde oplossing uit uw abonnement verwijdert wanneer u klaar bent, om overbodige kosten te voorkomen. U kunt een vooraf geconfigureerde oplossing volledig uit uw abonnement verwijderen door naar de https://www.azureiotsolutions.com/ pagina te gaan.

Wanneer het inrichtingsproces voor de externe bewakingsoplossing is voltooid, klikt u op Starten om het dashboard van de oplossing in uw browser te openen.

Oplossingsdashboard

Het apparaat inrichten in de externe bewakingsoplossing

Notitie

Als u al een apparaat in uw oplossing hebt ingericht, kunt u deze stap overslaan. U moet de referenties van het apparaat weten wanneer u de clienttoepassing maakt.

Een apparaat kan alleen verbinding maken met de vooraf geconfigureerde oplossing als het zichzelf met geldige referenties kan identificeren bij IoT Hub. U kunt de apparaatreferenties ophalen via het dashboard van de oplossing. Verderop in deze zelfstudie neemt u de referenties van het apparaat op in de clienttoepassing.

Als u een apparaat aan de externe bewakingsoplossing wilt toevoegen, voert u de volgende stappen uit in het dashboard van de oplossing:

  1. Klik in de linkerbenedenhoek van het dashboard op Een apparaat toevoegen.

    Een apparaat toevoegen

  2. Klik in het deelvenster Aangepast apparaat op Nieuw toevoegen.

    Een aangepast apparaat toevoegen

  3. Kies Laat mij mijn eigen apparaat-id definiëren. Voer een apparaat-id in, bijvoorbeeld mijnapparaat, en klik op Id controleren om te controleren of de naam nog niet wordt gebruikt. Klik tot slot op Maken om het apparaat in te richten.

    Apparaat-id toevoegen

  4. Noteer de referenties van het apparaat (apparaat-id, hostnaam van IoT Hub en apparaatsleutel). De clienttoepassing heeft deze waarden nodig om verbinding te maken met de externe bewakingsoplossing. Klik vervolgens op Gereed.

    Apparaatreferenties weergeven

  5. Selecteer uw apparaat in de lijst met apparaten in het oplossingsdashboard. Klik vervolgens in het deelvenster Apparaatdetails op Apparaat inschakelen. De status van het apparaat is nu Wordt uitgevoerd. De externe bewakingsoplossing kan nu telemetrie ontvangen van uw apparaat en methoden op het apparaat aanroepen.

Een C-voorbeeldclient bouwen en uitvoeren op Linux

In de volgende stappen ziet u hoe u een clienttoepassing maakt die communiceert met de vooraf geconfigureerde oplossing voor externe bewaking. Deze toepassing is geschreven in C en gebouwd en uitgevoerd op Ubuntu Linux.

Als u deze stappen wilt uitvoeren, hebt u een apparaat met Ubuntu versie 15.04 of 15.10 nodig. Voordat u doorgaat, installeert u de vereiste pakketten op uw Ubuntu-apparaat met behulp van de volgende opdracht:

sudo apt-get install cmake gcc g++

De clientbibliotheken op uw apparaat installeren

De Azure IoT Hub-clientbibliotheken zijn beschikbaar als een pakket dat u op uw Ubuntu-apparaat kunt installeren met behulp van de apt-get-opdracht. Voer de volgende stappen uit om het pakket met de IoT Hub-clientbibliotheek en headerbestanden op uw Ubuntu-computer te installeren:

  1. Voeg in een shell de AzureIoT-opslagplaats toe aan uw computer:

    sudo add-apt-repository ppa:aziotsdklinux/ppa-azureiot
    sudo apt-get update
    
  2. Het pakket azure-iot-sdk-c-dev installeren

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

De Parson JSON-parser installeren

De IoT Hub-clientbibliotheken gebruiken de Parson JSON-parser om nettoladingen van berichten te parseren. Kloon in een geschikte map op uw computer de Parson GitHub-opslagplaats met behulp van de volgende opdracht:

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

Uw project voorbereiden

Maak op uw Ubuntu-computer een map met de naam remote_monitoring. In de map remote_monitoring :

  • Maak de vier bestanden main.c, remote_monitoring.c, remote_monitoring.h en CMakeLists.txt.
  • Maak een map met de naam parson.

Kopieer de bestanden parson.c en parson.h van uw lokale kopie van de Parson-opslagplaats naar de map remote_monitoring/parson .

Open het bestand remote_monitoring.c in een teksteditor. Voeg de volgende #include instructies toe:

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

Het gedrag van het IoT-apparaat opgeven

De clientbibliotheek van de IoT Hub-serialisatiefunctie maakt gebruik van een model om de opmaak op te geven van de berichten die het apparaat uitwisselt met IoT Hub.

  1. Voeg de volgende variabelendeclaraties achter de #include-instructies toe. Vervang de tijdelijke aanduidingen [Apparaat-id] en [Apparaatsleutel] door waarden die u voor uw apparaat hebt genoteerd in het dashboard van de externe bewakingsoplossing. Gebruik de hostnaam van de IoT Hub uit het oplossingsdashboard om [IoTHub-naam] te vervangen. Als uw IoT Hub-hostnaam bijvoorbeeld contoso.azure devices.net is, vervangt u [IoTHub-naam] door contoso:

    static const char* deviceId = "[Device Id]";
    static const char* connectionString = "HostName=[IoTHub Name].azure-devices.net;DeviceId=[Device Id];SharedAccessKey=[Device Key]";
    
  2. Voeg de volgende code toe om het model te definiëren dat het apparaat in staat stelt om met IoT Hub te communiceren. Dit model bepaalt dat het apparaat:

    • Kan temperatuur, externe temperatuur, vochtigheid en een apparaat-id als telemetrie verzenden.
    • Metagegevens over het apparaat naar IoT Hub kan verzenden. Het apparaat verzendt bij het opstarten basismetagegevens in een DeviceInfo-object.
    • Gerapporteerde eigenschappen naar de apparaatdubbel in IoT Hub kan verzenden. Deze gerapporteerde eigenschappen zijn gegroepeerd in configuratie-, apparaat- en systeemeigenschappen.
    • Gewenste eigenschappen die in de apparaatdubbel in IoT Hub zijn ingesteld, kan ontvangen en hierop kan reageren.
    • Kan reageren op de directe methoden Reboot en InitiateFirmwareUpdate die via de oplossingsportal worden aangeroepen. Met behulp van gerapporteerde eigenschappen stuurt het apparaat informatie over de ondersteunde directe methoden.
    // 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);
    

Het gedrag van het apparaat implementeren

Voeg nu code toe om het gedrag te implementeren dat in het model is gedefinieerd.

  1. Voeg de volgende functies toe die de gewenste eigenschappen verwerken die in het oplossingsdashboard zijn ingesteld. De volgende gewenste eigenschappen zijn in het model gedefinieerd:

    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. Voeg de volgende functies toe die de directe methoden verwerken die via de IoT Hub worden aangeroepen. De volgende directe methoden zijn in het model gedefinieerd:

    /* 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. Voeg de volgende functie toe die een bericht naar de vooraf geconfigureerde oplossing verzendt:

    /* 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. Voeg de volgende callbackhandler toe die wordt uitgevoerd wanneer het apparaat nieuwe gerapporteerde eigenschapswaarden naar de vooraf geconfigureerde oplossing heeft verzonden:

    /* 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. Voeg de volgende functie toe om het apparaat te verbinden met de vooraf geconfigureerde oplossing in de cloud, en gegevens uit te wisselen. Deze functie voert de volgende stappen uit:

    • Initialiseert het platform.
    • Registreert de Contoso-naamruimte bij de serialisatiebibliotheek.
    • Initialiseert de client met de verbindingsreeks van het apparaat.
    • Maakt een exemplaar van het thermostaatmodel.
    • Maakt en verzendt gerapporteerde eigenschapswaarden.
    • Verzendt een DeviceInfo-object.
    • Maakt een lus om elke seconde telemetrie te verzenden.
    • Deïnitialiseert alle resources.
    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();
    }
    

    Ter referentie volgt hier een voorbeeld van een telemetriebericht dat naar de vooraf geconfigureerde oplossing is verzonden:

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

De functie remote_monitoring_run aanroepen

Open het bestand remote_monitoring.h in een teksteditor. Voeg de volgende code toe:

void remote_monitoring_run(void);

Open in een teksteditor het bestand main.c . Voeg de volgende code toe:

#include "remote_monitoring.h"

int main(void)
{
    remote_monitoring_run();

    return 0;
}

De toepassing bouwen en uitvoeren.

In de volgende stappen wordt beschreven hoe u CMake gebruikt om uw clienttoepassing te bouwen.

  1. Open in een teksteditor het CMakeLists.txt bestand in de map remote_monitoring .

  2. Voeg de volgende instructies toe om te definiëren hoe u uw clienttoepassing bouwt:

    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. Maak in de remote_monitoring map een map om de make-bestanden op te slaan die door CMake worden gegenereerd en voer de cmake uit en voer de opdrachten als volgt uit:

    mkdir cmake
    cd cmake
    cmake ../
    make
    
  4. Voer de clienttoepassing uit en verzend telemetrie naar IoT Hub:

    ./sample_app
    

Telemetrie van apparaten weergeven in het dashboard

Via het dashboard van de externe bewakingsoplossing kunt u de telemetrie bekijken die uw apparaten naar IoT Hub verzenden.

  1. Ga in de browser terug naar het dashboard van de externe bewakingsoplossing en klik in het linkerdeelvenster op Apparaten om naar de Lijst met apparaten te navigeren.

  2. In de Lijst met apparaten zou de status van uw apparaat nu Wordt uitgevoerd moeten zijn. Als dat niet zo is, klikt u in het deelvenster Apparaatdetails op Apparaat inschakelen.

    Apparaatstatus weergeven

  3. Klik op Dashboard om terug te keren naar het dashboard en selecteer het apparaat in de vervolgkeuzelijst Weer te geven apparaat om de telemetrie ervan weer te geven. De telemetrie uit de voorbeeldtoepassing is 50 eenheden voor de interne temperatuur, 55 eenheden voor de externe temperatuur en 50 eenheden voor de vochtigheid.

    Telemetrie van apparaten weergeven

Een methode op het apparaat aanroepen

Via het dashboard van de externe bewakingsoplossing kunt u methoden op uw apparaten aanroepen via IoT Hub. U kunt in de externe bewakingsoplossing bijvoorbeeld een methode aanroepen om het opnieuw opstarten van een apparaat te simuleren.

  1. Klik op het dashboard van de externe bewakingsoplossing in het linkerdeelvenster op Apparaten om naar de Lijst met apparaten te navigeren.

  2. Klik in de Lijst met apparaten op Apparaat-id voor uw apparaat.

  3. Klik in het deelvenster Apparaatdetails op Methoden.

    Apparaatmethoden

  4. Selecteer in de vervolgkeuzelijst Methode de methode InitiateFirmwareUpdate en voer in FWPACKAGEURI een dummy URL in. Klik op Methode aanroepen om de methode op het apparaat aan te roepen.

    Een apparaatmethode aanroepen

  5. In de console waarin de apparaatcode wordt uitgevoerd, wordt een bericht weergegeven wanneer het apparaat de methode afhandelt. De resultaten van de methode worden toegevoegd aan de geschiedenis in de portal van de oplossing:

    Geschiedenis van methoden weergeven

Volgende stappen

In het artikel Customizing preconfigured solutions (Vooraf geconfigureerde oplossingen aanpassen) worden enkele manieren beschreven waarop u dit voorbeeld kunt uitbreiden. Mogelijke uitbreidingen zijn het gebruik van echte sensoren en de implementatie van aanvullende opdrachten.

Zie Permissions on the azureiotsuite.com site (Machtigingen op de site azureiotsuite.com) voor meer informatie.