Introdução ao gerenciamento de dispositivos (Java)

Os aplicativos de back-end podem usar primitivos do Hub IoT do Azure, como dispositivos gêmeos e métodos diretos, para iniciar e monitorar remotamente as ações de gerenciamento de dispositivo nos dispositivos. Este artigo mostra como um aplicativo de back-end e um dispositivo podem trabalhar juntos para permitir que você inicie e monitore uma reinicialização remota por meio do Hub IoT.

Observação

Os recursos descritos neste artigo estão disponíveis apenas na camada padrão do Hub IoT. Para obter mais informações sobre as camadas básica e padrão/gratuita do Hub IoT, confira Escolher a camada certa do Hub IoT para a sua solução.

Use um método direto para iniciar as ações de gerenciamento do dispositivo (como a reinicialização, redefinição de fábrica e atualização do firmware) a partir de um aplicativo de back-end na nuvem. O dispositivo é responsável por:

  • Lidar com a solicitação do método enviada a partir do Hub IoT.

  • Iniciar a ação específica do dispositivo correspondente no dispositivo.

  • Fornecimento de atualizações de status por meio das propriedades relatadas para o Hub IoT.

Você pode usar um aplicativo de back-end na nuvem para executar consultas do dispositivo gêmeo para relatar o progresso de suas ações de gerenciamento do dispositivo.

Este artigo mostra como criar:

  • simulated-device: um aplicativo de dispositivo simulado com um método direto que reinicializa o dispositivo e relata a hora da última reinicialização. Métodos diretos são invocados da nuvem.

  • trigger-reboot: um aplicativo Java que chama o método direto no aplicativo de dispositivo simulado por meio do Hub IoT. Ele exibe a resposta e as propriedades relatadas atualizadas.

Observação

Para obter informações sobre os SDKs que você pode usar para criar aplicativos para serem executados em dispositivos e seu back-end da solução, consulte SDKs do IoT do Azure.

Pré-requisitos

  • Um hub IoT. Crie um com a CLI ou o portal do Azure.

  • Um dispositivo registrado. Registre um no portal do Azure.

  • Java SE Development Kit 8. Certifique-se de selecionar Java 8 em Suporte de longo prazo para obter downloads do JDK 8.

  • Maven 3

  • Verifique se a porta 8883 está aberta no firewall. O exemplo de dispositivo deste artigo usa o protocolo MQTT, que se comunica pela porta 8883. Essa porta poderá ser bloqueada em alguns ambientes de rede corporativos e educacionais. Para obter mais informações e maneiras de resolver esse problema, confira Como se conectar ao Hub IoT (MQTT).

Criar um aplicativo de dispositivo com um método direto

Nesta seção, você cria um aplicativo de console Java que simula um dispositivo. O aplicativo escuta a chamada de método direto de reinicialização do hub IoT e responde imediatamente à chamada. Em seguida, o aplicativo é suspenso durante algum tempo para simular o processo de reinicialização antes de usar uma propriedade relatada para notificar o aplicativo de back-end trigger-reboot de que a reinicialização foi concluída.

  1. Na pasta dm-get-started, crie um projeto Maven denominado simulated-device usando o seguinte comando no prompt de comando:

    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=simulated-device -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    
  2. No prompt de comando, navegue até a pasta simulated-device.

  3. Usando um editor de texto, abra o arquivo pom.xml na pasta simulated-device e adicione a dependência a seguir ao nó dependências. Essa dependência permite que você use o pacote iot-service-client em seu aplicativo para se comunicar com seu hub IoT:

    <dependency>
      <groupId>com.microsoft.azure.sdk.iot</groupId>
      <artifactId>iot-device-client</artifactId>
      <version>1.17.5</version>
    </dependency>
    

    Observação

    Você pode verificar a versão mais recente do iot-device-client usando a pesquisa do Maven.

  4. Adicione a dependência a seguir ao nó dependências. Essa dependência configura um NOP para a fachada de log do Apache SLF4J, que é usada pelo SDK do cliente do dispositivo para implementar o registro em log. Essa configuração é opcional, mas, se você omiti-la, poderá ver um aviso no console ao executar o aplicativo. Para obter mais informações sobre o registro em log no SDK de cliente do dispositivo, consulte Registro em log no arquivo Leiame Exemplos do SDK do dispositivo IoT do Azure para Java.

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-nop</artifactId>
      <version>1.7.28</version>
    </dependency>
    
  5. Adicione o seguinte nó buid após o nó dependencies. Esta configuração instrui o Maven a usar Java 1.8 para compilar o aplicativo:

    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.3</version>
          <configuration>
            <source>1.8</source>
            <target>1.8</target>
          </configuration>
        </plugin>
      </plugins>
    </build>
    
  6. Salve e feche o arquivo pom.xml.

  7. Usando um editor de texto, abra o arquivo de origem simulated-device\src\main\java\com\mycompany\app\App.java.

  8. Adicione as seguintes instruções import ao arquivo:

    import com.microsoft.azure.sdk.iot.device.*;
    import com.microsoft.azure.sdk.iot.device.DeviceTwin.*;
    
    import java.io.IOException;
    import java.net.URISyntaxException;
    import java.time.LocalDateTime;
    import java.util.Scanner;
    import java.util.Set;
    import java.util.HashSet;
    
  9. Adicione as seguintes variáveis no nível da classe à classe App . Substitua {yourdeviceconnectionstring} pela cadeia de conexão de dispositivo que você viu quando registrou um dispositivo no Hub IoT:

    private static final int METHOD_SUCCESS = 200;
    private static final int METHOD_NOT_DEFINED = 404;
    
    private static IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;
    private static String connString = "{yourdeviceconnectionstring}";
    private static DeviceClient client;
    
  10. Para implementar um manipulador de retorno de chamada para eventos de status do método direto, adicione a seguinte classe aninhada à classe de Aplicativo:

    protected static class DirectMethodStatusCallback implements IotHubEventCallback
    {
      public void execute(IotHubStatusCode status, Object context)
      {
        System.out.println("IoT Hub responded to device method operation with status " + status.name());
      }
    }
    
  11. Para implementar um manipulador de retorno de chamada para eventos de status de dispositivo gêmeo, adicione a seguinte classe aninhada à classe de Aplicativo:

    protected static class DeviceTwinStatusCallback implements IotHubEventCallback
    {
        public void execute(IotHubStatusCode status, Object context)
        {
            System.out.println("IoT Hub responded to device twin operation with status " + status.name());
        }
    }
    
  12. Para implementar um manipulador de retorno de chamada para eventos de propriedade, adicione a seguinte classe aninhada à classe de Aplicativo:

    protected static class PropertyCallback implements PropertyCallBack<String, String>
    {
      public void PropertyCall(String propertyKey, String propertyValue, Object context)
      {
        System.out.println("PropertyKey:     " + propertyKey);
        System.out.println("PropertyKvalue:  " + propertyKey);
      }
    }
    
  13. Para implementar um thread para simular a reinicialização do dispositivo, adicione a seguinte classe aninhada à classe de Aplicativo. O thread é suspenso por cinco segundos e define a propriedade relatada lastReboot:

    protected static class RebootDeviceThread implements Runnable {
      public void run() {
        try {
          System.out.println("Rebooting...");
          Thread.sleep(5000);
          Property property = new Property("lastReboot", LocalDateTime.now());
          Set<Property> properties = new HashSet<Property>();
          properties.add(property);
          client.sendReportedProperties(properties);
          System.out.println("Rebooted");
        }
        catch (Exception ex) {
          System.out.println("Exception in reboot thread: " + ex.getMessage());
        }
      }
    }
    
  14. Para implementar o método direto no dispositivo, adicione a seguinte classe aninhada à classe de Aplicativo. Quando o aplicativo simulado recebe uma chamada para o método direto reboot, ele retorna uma confirmação para o chamador e inicia um thread para processar a reinicialização:

    protected static class DirectMethodCallback implements com.microsoft.azure.sdk.iot.device.DeviceTwin.DeviceMethodCallback
    {
      @Override
      public DeviceMethodData call(String methodName, Object methodData, Object context)
      {
        DeviceMethodData deviceMethodData;
        switch (methodName)
        {
          case "reboot" :
          {
            int status = METHOD_SUCCESS;
            System.out.println("Received reboot request");
            deviceMethodData = new DeviceMethodData(status, "Started reboot");
            RebootDeviceThread rebootThread = new RebootDeviceThread();
            Thread t = new Thread(rebootThread);
            t.start();
            break;
          }
          default:
          {
            int status = METHOD_NOT_DEFINED;
            deviceMethodData = new DeviceMethodData(status, "Not defined direct method " + methodName);
          }
        }
        return deviceMethodData;
      }
    }
    
  15. Modifique a assinatura do método principal para lançar as seguintes exceções:

    public static void main(String[] args) throws IOException, URISyntaxException
    
  16. Para criar uma instância de um DeviceClient, substitua o código no método main pelo código a seguir:

    System.out.println("Starting device client sample...");
    client = new DeviceClient(connString, protocol);
    
  17. Para começar a escutar chamadas de método diretas, adicione o seguinte código ao método principal:

    try
    {
      client.open();
      client.subscribeToDeviceMethod(new DirectMethodCallback(), null, new DirectMethodStatusCallback(), null);
      client.startDeviceTwin(new DeviceTwinStatusCallback(), null, new PropertyCallback(), null);
      System.out.println("Subscribed to direct methods and polling for reported properties. Waiting...");
    }
    catch (Exception e)
    {
      System.out.println("On exception, shutting down \n" + " Cause: " + e.getCause() + " \n" +  e.getMessage());
      client.close();
      System.out.println("Shutting down...");
    }
    
  18. Para desligar o simulador de dispositivo, adicione o seguinte código ao método principal:

    System.out.println("Press any key to exit...");
    Scanner scanner = new Scanner(System.in);
    scanner.nextLine();
    scanner.close();
    client.close();
    System.out.println("Shutting down...");
    
  19. Salve e feche o arquivo simulated-device\src\main\java\com\mycompany\app\App.java.

  20. Compile o aplicativo simulated-device e corrija os erros. No prompt de comando, navegue até a pasta simulated-device e execute o seguinte comando:

    mvn clean package -DskipTests
    

Obter a cadeia de conexão do hub IoT

Neste artigo, você cria um serviço de back-end que invoca um método direto em um dispositivo. Para invocar um método direto em um dispositivo por meio do Hub IoT, o seu serviço precisa da permissão conexão de serviço. Por padrão, todo Hub IoT é criado com uma política de acesso compartilhado chamada serviço que concede essa permissão.

Para obter a cadeia de conexão do Hub IoT para a política de serviço, siga estas etapas:

  1. No portal do Azure, selecione Grupos de recursos. Selecione o grupo de recursos em que o Hub está localizado e, em seguida, selecione o seu hub na lista de recursos.

  2. No painel do lado esquerdo do hub IoT, selecione Políticas de acesso compartilhado.

  3. Na lista de políticas, selecione a política de serviço.

  4. Copie a Cadeia de conexão primária e salve o valor.

Captura de tela que mostra como recuperar a cadeia de conexão do seu Hub IoT no portal do Azure.

Para obter mais informações sobre permissões e políticas de acesso compartilhado do Hub IoT, consulte Controle de acesso e permissões.

Criar um aplicativo de serviço para disparar uma reinicialização

Nesta seção, você cria um aplicativo de console Java que:

  1. Invoca um método direto de reinicialização no aplicativo de dispositivo simulado.

  2. Exibe a resposta.

  3. Sonda as propriedades relatadas enviadas do dispositivo para determinar quando a reinicialização está concluída.

Esse aplicativo de console se conecta ao Hub IoT para invocar o método direto e ler as propriedades relatadas.

  1. Crie uma pasta vazia chamada dm-get-started.

  2. Na pasta dm-get-started, crie um projeto Maven chamado trigger-reboot usando o seguinte comando no prompt de comando:

    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=trigger-reboot -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    
  3. No prompt de comando, navegue até a pasta trigger-reboot.

  4. Usando um editor de texto, abra o arquivo pom.xml na pasta trigger-reboot e adicione a dependência a seguir ao nó dependências. Essa dependência permite que você use o pacote iot-service-client em seu aplicativo para se comunicar com seu hub IoT:

    <dependency>
      <groupId>com.microsoft.azure.sdk.iot</groupId>
      <artifactId>iot-service-client</artifactId>
      <version>1.17.1</version>
      <type>jar</type>
    </dependency>
    

    Observação

    Você pode verificar a versão mais recente do iot-service-client usando a pesquisa do Maven.

  5. Adicione o seguinte nó buid após o nó dependencies. Esta configuração instrui o Maven a usar Java 1.8 para compilar o aplicativo:

    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.3</version>
          <configuration>
            <source>1.8</source>
            <target>1.8</target>
          </configuration>
        </plugin>
      </plugins>
    </build>
    
  6. Salve e feche o arquivo pom.xml.

  7. Usando um editor de texto, abra o arquivo de origem trigger-reboot\src\main\java\com\mycompany\app\App.java.

  8. Adicione as seguintes instruções import ao arquivo:

    import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceMethod;
    import com.microsoft.azure.sdk.iot.service.devicetwin.MethodResult;
    import com.microsoft.azure.sdk.iot.service.exceptions.IotHubException;
    import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceTwin;
    import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceTwinDevice;
    
    import java.io.IOException;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ExecutorService;
    
  9. Adicione as seguintes variáveis no nível da classe à classe App . Substitua {youriothubconnectionstring} pela cadeia de conexão do Hub IoT que você copiou anteriormente em Obter a cadeia de conexão do hub IoT:

    public static final String iotHubConnectionString = "{youriothubconnectionstring}";
    public static final String deviceId = "myDeviceId";
    
    private static final String methodName = "reboot";
    private static final Long responseTimeout = TimeUnit.SECONDS.toSeconds(30);
    private static final Long connectTimeout = TimeUnit.SECONDS.toSeconds(5);
    
  10. Para implementar um thread que lê as propriedades relatadas do dispositivo gêmeo a cada 10 segundos, adicione a seguinte classe aninhada à classe de Aplicativo:

    private static class ShowReportedProperties implements Runnable {
      public void run() {
        try {
          DeviceTwin deviceTwins = DeviceTwin.createFromConnectionString(iotHubConnectionString);
          DeviceTwinDevice twinDevice = new DeviceTwinDevice(deviceId);
          while (true) {
            System.out.println("Get reported properties from device twin");
            deviceTwins.getTwin(twinDevice);
            System.out.println(twinDevice.reportedPropertiesToString());
            Thread.sleep(10000);
          }
        } catch (Exception ex) {
          System.out.println("Exception reading reported properties: " + ex.getMessage());
        }
      }
    }
    
  11. Modifique a assinatura do método principal para lançar a seguinte exceção:

    public static void main(String[] args) throws IOException
    
  12. Para invocar o método direto de reinicialização no dispositivo simulado, substitua o código no método main pelo seguinte código:

    System.out.println("Starting sample...");
    DeviceMethod methodClient = DeviceMethod.createFromConnectionString(iotHubConnectionString);
    
    try
    {
      System.out.println("Invoke reboot direct method");
      MethodResult result = methodClient.invoke(deviceId, methodName, responseTimeout, connectTimeout, null);
    
      if(result == null)
      {
        throw new IOException("Invoke direct method reboot returns null");
      }
      System.out.println("Invoked reboot on device");
      System.out.println("Status for device:   " + result.getStatus());
      System.out.println("Message from device: " + result.getPayload());
    }
    catch (IotHubException e)
    {
        System.out.println(e.getMessage());
    }
    
  13. Para iniciar o thread para sondar as propriedades relatadas do dispositivo simulado, adicione o seguinte código ao método principal:

    ShowReportedProperties showReportedProperties = new ShowReportedProperties();
    ExecutorService executor = Executors.newFixedThreadPool(1);
    executor.execute(showReportedProperties);
    
  14. Para que você possa interromper o aplicativo, adicione o seguinte código ao método principal:

    System.out.println("Press ENTER to exit.");
    System.in.read();
    executor.shutdownNow();
    System.out.println("Shutting down sample...");
    
  15. Salve e feche o arquivo trigger-reboot\src\main\java\com\mycompany\app\App.java.

  16. Criar o aplicativo de back-end trigger-reboot e corrigir os erros. No prompt de comando, navegue até a pasta trigger-reboot e execute o seguinte comando:

    mvn clean package -DskipTests
    

Executar os aplicativos

Agora você está pronto para executar os aplicativos.

  1. Em um prompt de comando, na pasta simulated-device, execute o seguinte comando para começar a escutar chamadas do método de reinicialização de seu hub IoT:

    mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
    

    Aplicativo de dispositivo simulado de Java do Hub IoT para escutar chamadas de método direto de reinicialização

  2. Em um prompt de comando na pasta trigger-reboot, execute o seguinte comando para chamar o método de reinicialização no dispositivo simulado do hub IoT:

    mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
    

    Serviço de aplicativo Java do Hub IoT para chamar o método de reinicialização direta

  3. O dispositivo simulado responde à chamada de método direto de reinicialização:

    O aplicativo de dispositivo simulado Java do Hub IoT responde à chamada de método direto

Personalizar e estender as ações de gerenciamento do dispositivo

As soluções de IoT podem expandir o conjunto definido de padrões de gerenciamento do dispositivo ou habilitar padrões personalizados usando o dispositivo gêmeo e os primitivos do método da nuvem para o dispositivo. Outros exemplos de ações de gerenciamento do dispositivo incluem a redefinição de fábrica, atualização do firmware, atualização do software, gerenciamento de energia, gerenciamento da rede e da conectividade, e criptografia dos dados.

Janelas de manutenção do dispositivo

Normalmente, você pode configurar os dispositivos para executar ações em um horário que minimiza as interrupções e a inatividade. As janelas de manutenção do dispositivo são um padrão usado para definir a hora em que um dispositivo deve atualizar sua configuração. As soluções de back-end podem usar as propriedades desejadas do dispositivo gêmeo para definir e ativar uma política no dispositivo que permite uma janela de manutenção. Quando um dispositivo recebe a política da janela de manutenção, ele pode usar a propriedade relatada do dispositivo gêmeo para informar o status da política. O aplicativo de back-end pode usar as consultas do dispositivo gêmeo para atestar a conformidade dos dispositivos e cada política.

Próximas etapas

Neste artigo, você usou um método direto para disparar uma reinicialização remota em um dispositivo. Você usou as propriedades relatadas para relatar a hora da última reinicialização do dispositivo e consultou o dispositivo gêmeo para descobrir a hora da última reinicialização do dispositivo na nuvem.

Para continuar a introdução aos padrões de Hub IoT e de gerenciamento de dispositivos, como a atualização baseada em imagem de ponta a ponta no artigo de Atualização de dispositivo para o Hub IoT do Azure usando a imagem de referência do Raspberry Pi 3 B+.

Para saber como estender a sua solução de IoT e agendar chamadas de método em vários dispositivos, consulte Agendar e difundir trabalhos.