Share via


Ligue o seu dispositivo à solução pré-configurada de monitorização remota (Windows)

Scenario overview (Descrição geral do cenário)

Neste cenário, vai criar um dispositivo que envia a seguinte telemetria para solução pré-configurada de monitorização remota:

  • Temperatura externa
  • Temperatura interna
  • Humidade

Para simplificar, o código no dispositivo gera valores de exemplo, mas incentivamo-lo a alargar a amostra ao ligar sensores reais ao dispositivo e enviar telemetria real.

O dispositivo também é capaz de responder a métodos invocados a partir do dashboard da solução e a valores de propriedades pretendidas definidos no dashboard da solução.

Para concluir este tutorial, precisa de uma conta ativa do Azure. Se não tiver uma conta, pode criar uma de avaliação gratuita em apenas alguns minutos. Para obter mais detalhes, consulte Avaliação Gratuita do Azure.

Antes de começar

Antes de escrever qualquer código para o seu dispositivo, terá de aprovisionar a sua solução pré-configurada de monitorização remota e aprovisionar um novo dispositivo personalizado nessa solução.

Aprovisionar a solução pré-configurada de monitorização remota

O dispositivo que vai criar neste tutorial envia dados para uma instância da solução pré-configurada de monitorização remota. Se ainda não aprovisionou a solução pré-configurada de monitorização remota na sua conta do Azure, utilize os seguintes passos:

  1. https://www.azureiotsolutions.com/ Na página, clique + para criar uma solução.
  2. Clique em Selecionar no painel Monitorização remota para criar a solução.
  3. Na página Criar solução de monitorização remota, introduza um Nome da solução à sua escolha, selecione a Região onde pretende implementar e selecione a subscrição do Azure que pretende utilizar. Em seguida, clique em Criar solução.
  4. Aguarde até à conclusão do processo de aprovisionamento.

Aviso

As soluções pré-configuradas utilizam serviços do Azure faturáveis. Certifique-se de que remove a solução pré-configurada da sua subscrição quando terminar para evitar eventuais encargos desnecessários. Pode remover completamente uma solução pré-configurada da sua subscrição visitando a https://www.azureiotsolutions.com/ página.

Quando o processo de aprovisionamento para a solução de monitorização remota terminar, clique em Iniciar para abrir o dashboard da solução no seu browser.

Dashboard de soluções

Aprovisionar o dispositivo na solução de monitorização remota

Nota

Se já tiver aprovisionado um dispositivo na sua solução, pode ignorar este passo. Precisa de saber as credenciais do dispositivo quando criar a aplicação cliente.

Para que um dispositivo ligue à solução pré-configurada, este tem de se identificar no Hub IoT utilizando credenciais válidas. Pode obter as credenciais do dispositivo a partir do dashboard da solução. Vai incluir as credenciais do dispositivo na sua aplicação cliente mais à frente neste tutorial.

Para adicionar um dispositivo à sua solução de monitorização remota, execute os passos seguintes no dashboard da solução:

  1. No canto inferior esquerdo do dashboard, clique em Adicionar um dispositivo.

    Adicionar um dispositivo

  2. No painel Dispositivo Personalizado, clique em Adicionar novo.

    Adicionar um dispositivo personalizado

  3. Escolha Definir o meu próprio ID do Dispositivo. Introduza um ID do Dispositivo, como, por exemplo, mydevice, clique em Verificar ID para verificar se o nome já não está a ser utilizado e, em seguida, clique em Criar para aprovisionar o dispositivo.

    Adicionar ID do dispositivo

  4. Anote as credenciais do dispositivo (ID do Dispositivo, Nome do Anfitrião do Hub IoT e Chave do Dispositivo). A aplicação cliente precisa destes valores para ligar à solução de monitorização remota. Em seguida, clique em Fazer.

    Ver as credenciais do dispositivo

  5. Selecione o seu dispositivo na lista de dispositivos no dashboard da solução. Em seguida, no painel Detalhes do Dispositivo, clique em Ativar Dispositivo. O estado do seu dispositivo é agora Em execução. A solução de monitorização remota pode agora receber telemetria do seu dispositivo e invocar métodos no dispositivo.

Criar uma solução de amostra C no Windows

Os passos a seguir mostram como criar uma aplicação do cliente que comunica com a solução pré-configurada de monitorização remota. Esta aplicação está escrita em C e construída e executada no Windows.

Crie um projeto inicial no Visual Studio 2015 ou visual Studio 2017 e adicione os pacotes nuGet do cliente Hub IoT dispositivo:

  1. No Visual Studio, crie uma aplicação de consola C utilizando o modelo de aplicação de consola Visual C++ Win32 . Nomeie o projeto RMDevice.

  2. Na página Definições de Aplicação no Assistente de Aplicação Win32, certifique-se de que a aplicação da Consola está selecionada e verifica o cabeçalho pré-comprometido e verificações de ciclo de vida de desenvolvimento de segurança (SDL).

  3. Em Explorador de Soluções, elimine os ficheiros stdafx.h, targetver.h e stdafx.cpp.

  4. Em Explorador de Soluções, mude o nome do ficheiro RMDevice.cpp para RMDevice.c.

  5. Em Explorador de Soluções, clique à direita no projeto RMDevice e, em seguida, clique em Gerir pacotes NuGet. Clique em procurar e instalar os seguintes pacotes NuGet:

    • Microsoft.Azure.IoTHub.Serializer
    • Microsoft.Azure.ioTHub.ioTHubClient
    • Microsoft.Azure.ioTHub.MqttTransport
  6. Em Explorador de Soluções, clique à direita no projeto RMDevice e, em seguida, clique em Propriedades para abrir a caixa de diálogo de Páginas de Propriedade do projeto. Para mais detalhes, consulte a Definição de Propriedades do Projeto Visual C++.

  7. Clique na pasta Linker e, em seguida, clique na página da propriedade Entrada .

  8. Adicione cript32.lib à propriedade Dependências Adicionais . Clique em OK e, em seguida, OK novamente para guardar os valores de propriedade do projeto.

Adicione a biblioteca Parson JSON ao projeto RMDevice e adicione as declarações necessárias #include :

  1. Numa pasta adequada no seu computador, clone o repositório Parson GitHub utilizando o seguinte comando:

    git clone https://github.com/kgabis/parson.git
    
  2. Copie os ficheiros parson.h e parson.c da cópia local do repositório parson para a sua pasta de projeto RMDevice .

  3. No Visual Studio, clique à direita no projeto RMDevice , clique em Adicionar e, em seguida, clique em Item Existente.

  4. No diálogo de produto existente , selecione os ficheiros parson.h e parson.c na pasta do projeto RMDevice . Em seguida, clique em Adicionar para adicionar estes dois ficheiros ao seu projeto.

  5. No Visual Studio, abra o ficheiro RMDevice.c. Substitua as declarações existentes #include pelo seguinte código:

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

    Nota

    Agora pode verificar se o seu projeto tem as dependências corretas configurando-o construindo-o.

Especificar o comportamento do dispositivo IoT

A biblioteca de clientes do serializador do Hub IoT utiliza um modelo para especificar o formato das mensagens que o dispositivo troca com o Hub IoT.

  1. Adicione as seguintes declarações de variáveis a seguir às instruções #include. Substitua os valores do espaço reservado [ID do dispositivo] e [Tecla do dispositivo] pelos valores que notou para o seu dispositivo no painel de instrumentos de monitorização remota. Utilize o Nome de anfitrião do Hub IoT no dashboard da solução para substituir [IoTHub Name]. Por exemplo, se o Nome de anfitrião do seu Hub IoT for contoso.azure devices.net, substitua [IoTHub Name] por contoso:

    static const char* deviceId = "[Device Id]";
    static const char* connectionString = "HostName=[IoTHub Name].azure-devices.net;DeviceId=[Device Id];SharedAccessKey=[Device Key]";
    
  2. Adicione o código seguinte para definir o modelo que permite que o dispositivo comunique com o Hub IoT. Este modelo especifica que o dispositivo:

    • Pode enviar temperatura, temperatura externa, humidade e um dispositivo de identificação como telemetria.
    • Pode enviar metadados sobre o dispositivo para o Hub IoT. O dispositivo envia metadados básicos num objeto DeviceInfo no arranque.
    • Pode enviar propriedades comunicadas para o dispositivo duplo no Hub IoT. Estas propriedades comunicadas são agrupadas em propriedades de configuração, de dispositivo e de sistema.
    • Pode receber uma ação sobre as propriedades pretendidas definidas no dispositivo duplo no Hub IoT.
    • Pode responder aos métodos diretos Reboot e InitiateFirmwareUpdate invocados através do portal da solução. O dispositivo envia informações sobre os métodos diretos que suporta utilizando propriedades comunicadas.
    // 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);
    

Implementar o comportamento do dispositivo

Agora, adicione código que implementa o comportamento definido no modelo.

  1. Adicione as seguintes funções que processam as propriedades pretendidas definidas no dashboard da solução. Estas propriedades pretendidas são definidas no modelo:

    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. Adicione as seguintes funções que processam os métodos diretos invocados através do hub IoT. Estes métodos diretos são definidos no modelo:

    /* 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. Adicione a seguinte função que envia uma mensagem para a solução pré-configurada:

    /* 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. Adicione o seguinte processador de chamada de retorno que é executado quando o dispositivo envia novos valores de propriedades comunicadas para a solução pré-configurada:

    /* 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. Adicione a seguinte função para ligar o seu dispositivo à solução pré-configurada na cloud e trocar dados. Esta função executa os seguintes passos:

    • Inicializa a plataforma.
    • Regista o espaço de nomes Contoso na biblioteca de serialização.
    • Inicializa o cliente com a cadeia de ligação do dispositivo.
    • Cria uma instância do modelo Termóstato.
    • Cria e envia os valores das propriedades comunicadas.
    • Envia uma objeto DeviceInfo.
    • Cria um ciclo para enviar telemetria a cada segundo.
    • Desinicializa todos os recursos.
    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();
    }
    

    Para sua referência, eis um exemplo de mensagem de Telemetria enviada para a solução pré-configurada:

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

Criar e executar o exemplo

Adicione código para invocar a função remote_monitoring_run e, em seguida, construa e execute a aplicação do dispositivo.

  1. Substitua a função principal por seguir o código para invocar a função remote_monitoring_run :

    int main()
    {
      remote_monitoring_run();
      return 0;
    }
    
  2. Clique em Construir e, em seguida, Construa solução para construir a aplicação do dispositivo.

  3. Em Explorador de Soluções, clique à direita no projeto RMDevice, clique em Debug e, em seguida, clique em Iniciar nova instância para executar a amostra. A consola exibe mensagens à medida que a aplicação envia telemetria de amostra para a solução pré-configurada, recebe os valores de propriedade desejados definidos no painel de instrumentos de solução e responde aos métodos invocados do painel de instrumentos de solução.

Ver telemetria do dispositivo no dashboard

O dashboard na solução de monitorização remota permite-lhe ver a telemetria que os seus dispositivos enviam para o Hub IoT.

  1. No browser, regresse ao dashboard da solução de monitorização remota e clique em Dispositivos no painel à esquerda para navegar para a Lista de dispositivos.

  2. Na Lista de dispositivos, deverá ver que o estado do seu dispositivo é Em execução. Se não for, clique em Ativar Dispositivo no painel Detalhes do Dispositivo.

    Ver o estado do dispositivo

  3. Clique em Dashboard para voltar ao dashboard e selecione o seu dispositivo na lista pendente Dispositivo a Visualizar para ver a respetiva telemetria. A telemetria da aplicação de amostra é 50 unidades para temperatura interna, 55 unidades para temperatura externa e 50 unidades para humidade.

    Ver a telemetria do dispositivo

Invocar um método no seu dispositivo

O dashboard na solução de monitorização remota permite-lhe invocar os métodos nos seus dispositivos através do Hub IoT. Por exemplo, na solução de monitorização remota pode invocar um método para simular o reinício de um dispositivo.

  1. No dashboard da solução de monitorização remota, clique em Dispositivos no painel à esquerda para navegar para a Lista de dispositivos.

  2. Clique em ID do Dispositivo para o seu dispositivo na Lista de dispositivos.

  3. No painel Detalhes do dispositivo, clique em Métodos.

    Métodos do dispositivo

  4. Na lista pendente de Método, selecione InitiateFirmwareUpdate e, em seguida, em FWPACKAGEURI, introduza um URL fictício. Clique em Invocar Método para chamar o método no dispositivo.

    Invocar um método de dispositivo

  5. Verá uma mensagem na consola que está a executar o código do dispositivo quando o dispositivo processar o método. Os resultados do método são adicionados ao histórico no portal da solução:

    Ver o histórico do método

Passos seguintes

O artigo Personalizar soluções pré-configuradas descreve algumas formas através das quais pode expandir este exemplo. As extensões possíveis incluem a utilização de sensores reais e a implementação de comandos adicionais.

Pode saber mais sobre as permissões no site azureiotsuite.com.