Tutorial: Desenvolver um módulo java IoT Edge com contentores do Linux

Aplica-se a:IoT Edge marca de verificação 1.4 IoT Edge 1.4

Pode utilizar os módulos do Azure IoT Edge para implementar código que aplica a sua lógica de negócio diretamente aos seus dispositivos IoT Edge. Este tutorial explica-lhe como criar e implementar um módulo do IoT Edge que filtra dados de sensores. Irá utilizar o dispositivo IoT Edge simulado que criou no artigo Deploy Azure IoT Edge on a simulated device (Implementar o Azure IoT Edge num dispositivo simulado). Neste tutorial, ficará a saber como:

  • Usar o Visual Studio Code para criar um módulo Java IoT Edge baseado no pacote de modelos maven Azure IoT Edge e no SDK de dispositivos Java Azure IoT.
  • Utilize o Visual Studio Code e o Docker para criar uma imagem do Docker e publicá-la no seu registo.
  • Implemente o módulo no seu dispositivo IoT Edge.
  • Veja os dados gerados.

O módulo do IoT Edge que criou neste tutorial filtra os dados de temperatura que são gerados pelo seu dispositivo. Envia apenas mensagens de origem caso a temperatura seja superior a um limiar especificado. Este tipo de análise no Edge é útil para reduzir a quantidade de dados que são comunicados e armazenados na cloud.

Se não tiver uma subscrição do Azure, crie uma conta gratuita do Azure antes de começar.

Pré-requisitos

Este tutorial demonstra como desenvolver um módulo em Java com o Visual Studio Code e como implementá-lo num dispositivo IoT Edge. IoT Edge não suporta módulos Java criados como contentores do Windows.

Utilize a tabela seguinte para compreender as suas opções para desenvolver e implementar módulos Java:

Java Visual Studio Code Visual Studio 2017/2019
Linux AMD64 Utilizar o VS Code para módulos Java no Linux AMD64
Linux ARM32 Utilizar o VS Code para módulos Java no Arm32 do Linux
Linux ARM64 Utilizar o VS Code para módulos Java no Arm64 do Linux

Antes de iniciar este tutorial, deve ter percorrido o tutorial anterior para configurar o seu ambiente de desenvolvimento para o desenvolvimento de contentores do Linux: Desenvolver módulos de IoT Edge para dispositivos Linux. Ao concluir um desses tutoriais, deverá ter os seguintes pré-requisitos em vigor:

Para desenvolver um módulo IoT Edge em Java, instale os seguintes pré-requisitos adicionais no seu computador de desenvolvimento:

  • Pacote de Extensão do Java para o Visual Studio Code.

  • Java SE Development Kit 11 e defina a variável de JAVA_HOME ambiente para apontar para a instalação do JDK.

  • Maven

    Dica

    Os processos de instalação de Java e Maven adicionam variáveis de ambiente ao seu sistema. Reinicie qualquer terminal do Visual Studio Code aberto, o PowerShell ou as instâncias da linha de comandos após concluir a instalação. Este passo garante que estes utilitários conseguem reconhecer os comandos Java e Maven no futuro.

Criar um projeto de módulo

Os passos seguintes criam um projeto de módulo IoT Edge baseado no pacote de modelos maven IoT Edge do Azure e no SDK de dispositivo Java do Azure IoT. Pode criar o projeto com o Visual Studio Code e a extensão IoT Edge do Azure.

Criar um novo projeto

Crie um modelo de solução Java que pode personalizar com o seu próprio código.

  1. No Visual Studio Code, selecione Ver>Paleta de Comandos para abrir a paleta de comandos do VS Code.

  2. Na paleta de comandos, introduza e execute o comando Azure IoT Edge: Nova solução do IoT Edge. Siga as instruções na paleta de comandos para criar a sua solução.

    Campo Valor
    Selecionar pasta Escolha a localização no computador de desenvolvimento na qual o VS Code vai criar os ficheiros da solução.
    Indicar um nome para a solução Introduza um nome descritivo para a sua solução ou aceite a predefinição EdgeSolution.
    Selecionar modelo de módulo Selecione Módulo Java.
    Indicar um nome para o módulo Dê o nome JavaModule ao módulo.
    Indicar o repositório de imagens do Docker para o módulo Os repositórios de imagens incluem o nome do seu registo de contentor e o nome da sua imagem de contentor. A imagem de contentor é pré-preenchida a partir do nome que indicou no último passo. Substitua localhost:5000 pelo valor do servidor de início de sessão do seu registo de contentor do Azure. Pode obter o servidor de Início de Sessão a partir da página Descrição geral do seu registo de contentor no portal do Azure.

    O repositório de imagem final é semelhante <a registry name.azurecr.io/javamodule>.
    Indique o valor para groupId Introduza um valor de ID de grupo ou aceite a predefinição com.edgemodule.

    Fornecer repositório de imagens do Docker

Se for a primeira vez que cria o módulo Java, poderá demorar vários minutos a transferir os pacotes maven. Quando a solução estiver pronta, a janela do VS Code carrega a área de trabalho IoT Edge solução. A área de trabalho da solução contém cinco componentes de nível superior:

  • A pasta modules contém o código Java para o módulo e os ficheiros do Docker para criar o módulo como uma imagem de contentor.
  • O ficheiro .env armazena as credenciais do registo de contentor.
  • O ficheiro deployment.template.json contém as informações que o runtime do IoT Edge utiliza para implementar módulos num dispositivo.
  • O ficheiro deployment.debug.template.json contentores da versão de depuração dos módulos.
  • Não irá editar a pasta .vscode ou o ficheiro .gitignore neste tutorial.

Se não especificou um registo de contentor ao criar a sua solução, mas aceitou o valor localhost:5000 predefinido, não terá um ficheiro .env.

Adicionar as credenciais do registo

O ficheiro de ambiente armazena as credenciais do seu registo de contentor e partilha-as com o runtime do IoT Edge. O runtime precisa destas credenciais para solicitar as imagens privadas para o dispositivo IoT Edge.

A extensão IoT Edge tenta extrair as credenciais do registo de contentor do Azure e preenchê-las no ficheiro de ambiente. Verifique se as suas credenciais já estão incluídas. Caso contrário, adicione-os agora:

  1. No explorador do VS Code, abra o ficheiro .env.
  2. Atualize os campos com os valores nome de utilizador e palavra-passe que copiou do seu Azure Container Registry.
  3. Guarde este ficheiro.

Nota

Este tutorial utiliza credenciais de início de sessão de administrador para Azure Container Registry, que são convenientes para cenários de desenvolvimento e teste. Quando estiver pronto para cenários de produção, recomendamos uma opção de autenticação com menos privilégios, como principais de serviço. Para obter mais informações, veja Gerir o acesso ao seu registo de contentor.

Selecione a arquitetura de destino

Atualmente, o Visual Studio Code pode desenvolver módulos Java para dispositivos LINux AMD64 e Linux ARM32v7. Tem de selecionar a arquitetura que está a filtrar com cada solução, uma vez que o contentor é criado e executado de forma diferente para cada tipo de arquitetura. A predefinição é LINux AMD64.

  1. Abra a paleta de comandos e procure Azure IoT Edge: Definir Plataforma de Destino Predefinida para Solução edge ou selecione o ícone de atalho na barra lateral na parte inferior da janela.

  2. Na paleta de comandos, selecione a arquitetura de destino na lista de opções. Neste tutorial, estamos a utilizar uma máquina virtual do Ubuntu como dispositivo IoT Edge, pelo que manteremos o amd64 predefinido.

Atualizar o módulo com o código personalizado

  1. No explorador do VS Code, abra os módulos>JavaModule>src>java>principal>com>edgemodule>App.java.

  2. Adicione o seguinte código na parte superior do ficheiro para importar novas as novas classes referenciadas.

    import java.io.StringReader;
    import java.util.concurrent.atomic.AtomicLong;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.json.Json;
    import javax.json.JsonObject;
    import javax.json.JsonReader;
    
    import com.microsoft.azure.sdk.iot.device.DeviceTwin.Pair;
    import com.microsoft.azure.sdk.iot.device.DeviceTwin.Property;
    import com.microsoft.azure.sdk.iot.device.DeviceTwin.TwinPropertyCallBack;
    
  3. Adicione a seguinte definição à classe App. Esta variável define um limiar de temperatura. A temperatura da máquina medida não será comunicada a Hub IoT até ultrapassar este valor.

    private static final String TEMP_THRESHOLD = "TemperatureThreshold";
    private static AtomicLong tempThreshold = new AtomicLong(25);
    
  4. Substitua o método de execução de MessageCallbackMqtt pelo seguinte código. Este método é chamado sempre que o módulo recebe uma mensagem MQTT do hub do IoT Edge. Ele filtra as mensagens que comunicam temperaturas inferiores ao limiar de temperatura definido através do módulo duplo.

    protected static class MessageCallbackMqtt implements MessageCallback {
        private int counter = 0;
        @Override
        public IotHubMessageResult execute(Message msg, Object context) {
            this.counter += 1;
    
            String msgString = new String(msg.getBytes(), Message.DEFAULT_IOTHUB_MESSAGE_CHARSET);
            System.out.println(
                   String.format("Received message %d: %s",
                            this.counter, msgString));
            if (context instanceof ModuleClient) {
                try (JsonReader jsonReader = Json.createReader(new StringReader(msgString))) {
                    final JsonObject msgObject = jsonReader.readObject();
                    double temperature = msgObject.getJsonObject("machine").getJsonNumber("temperature").doubleValue();
                    long threshold = App.tempThreshold.get();
                    if (temperature >= threshold) {
                        ModuleClient client = (ModuleClient) context;
                        System.out.println(
                            String.format("Temperature above threshold %d. Sending message: %s",
                            threshold, msgString));
                        client.sendEventAsync(msg, eventCallback, msg, App.OUTPUT_NAME);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return IotHubMessageResult.COMPLETE;
        }
    }
    
  5. Adicione as seguintes duas classes internas estáticas à classe App. Estas classes atualizam a variável tempThreshold quando a propriedade pretendida do módulo duplo é alterada. Todos os módulos têm o seu próprio módulo duplo, que lhe permite configurar o código em execução no interior de um módulo diretamente a partir da cloud.

    protected static class DeviceTwinStatusCallBack implements IotHubEventCallback {
        @Override
        public void execute(IotHubStatusCode status, Object context) {
            System.out.println("IoT Hub responded to device twin operation with status " + status.name());
        }
    }
    
    protected static class OnProperty implements TwinPropertyCallBack {
        @Override
        public void TwinPropertyCallBack(Property property, Object context) {
            if (!property.getIsReported()) {
                if (property.getKey().equals(App.TEMP_THRESHOLD)) {
                    try {
                        long threshold = Math.round((double) property.getValue());
                        App.tempThreshold.set(threshold);
                    } catch (Exception e) {
                        System.out.println("Faile to set TemperatureThread with exception");
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
  6. Adicione as seguintes linhas ao método main após client.open() para subscrever as atualizações do módulo duplo.

    client.startTwin(new DeviceTwinStatusCallBack(), null, new OnProperty(), null);
    Map<Property, Pair<TwinPropertyCallBack, Object>> onDesiredPropertyChange = new HashMap<Property, Pair<TwinPropertyCallBack, Object>>() {
        {
            put(new Property(App.TEMP_THRESHOLD, null), new Pair<TwinPropertyCallBack, Object>(new OnProperty(), null));
        }
    };
    client.subscribeToTwinDesiredProperties(onDesiredPropertyChange);
    client.getTwin();
    
  7. Guarde o ficheiro App.java.

  8. No explorador do VS Code, abra o ficheiro deployment.template.json na área de trabalho IoT Edge solução.

  9. Adicione o módulo JavaModule ao manifesto da implementação. Insira o seguinte conteúdo JSON na parte inferior da secção moduleContent, após o módulo duplo $edgeHub:

      "JavaModule": {
          "properties.desired":{
              "TemperatureThreshold":25
          }
      }
    

    Adicionar o módulo duplo ao modelo de implementação

  10. Guarde o ficheiro deployment.template.json.

Criar e emitir o módulo

Na secção anterior, criou uma solução IoT Edge e adicionou código ao JavaModule para filtrar mensagens em que a temperatura comunicada da máquina é inferior ao limite aceitável. Agora, crie a solução como uma imagem de contentor e envie-a para o seu registo de contentor.

  1. Abra o terminal integrado do VS Code ao selecionar Ver>Terminal.

  2. Inicie sessão no Docker ao introduzir o seguinte comando no terminal. Inicie sessão com o nome de utilizador, palavra-passe e servidor de início de sessão do seu registo de contentor do Azure. Pode obter estes valores a partir da secção Chaves de acesso do seu registo no portal do Azure.

    docker login -u <ACR username> -p <ACR password> <ACR login server>
    

    Poderá receber um aviso de segurança a recomendar a utilização de --password-stdin. Embora essa melhor prática seja recomendada para cenários de produção, está fora do âmbito deste tutorial. Para obter mais informações, veja a referência de início de sessão do docker .

  3. No explorador do VS Code, clique com o botão direito do rato no ficheiro deployment.template.json e selecione Compilar e Emitir IoT Edge Solução.

    O comando build and push inicia três operações. Em primeiro lugar, cria uma nova pasta na solução denominada configuração que contém o manifesto de implementação completo, que é criado a partir de informações no modelo de implementação e noutros ficheiros de solução. Em segundo lugar, é executada docker build para criar a imagem de contentor com base no dockerfile adequado para a arquitetura de destino. Em seguida, é executado docker push para enviar o repositório de imagens para o registo de contentor.

    Este processo pode demorar vários minutos da primeira vez, mas é mais rápido da próxima vez que executar os comandos.

Implementar módulos no dispositivo

Utilize o explorador do Visual Studio Code e a extensão IoT Edge do Azure para implementar o projeto do módulo no seu dispositivo IoT Edge. Já tem um manifesto de implementação preparado para o seu cenário, o ficheiro deployment.amd64.json na pasta de configuração. Agora tudo o que precisa de fazer é selecionar um dispositivo para receber a implementação.

Certifique-se de que o dispositivo IoT Edge está operacional.

  1. No explorador do Visual Studio Code, na secção Hub IoT do Azure, expanda Dispositivos para ver a sua lista de dispositivos IoT.

  2. Carregue com o botão direito do rato no nome do seu dispositivo do IoT Edge e, em seguida, selecione Criar Implementação para o Dispositivo Único.

  3. Selecione o ficheiro deployment.amd64.json na pasta config e, em seguida, clique em Selecionar Manifesto de Implementação do Edge. Não utilize o ficheiro deployment.template.json.

  4. No seu dispositivo, expanda Módulos para ver uma lista de módulos implementados e em execução. Clique no botão Atualizar. Deverá ver o novo JavaModule em execução juntamente com o módulo SimulatedTemperatureSensor e o $edgeAgent e $edgeHub.

    Os módulos podem demorar alguns minutos a começar. O IoT Edge runtime precisa de receber o seu novo manifesto de implementação, extrair as imagens do módulo do runtime do contentor e, em seguida, iniciar cada novo módulo.

Ver os dados gerados

Depois de aplicar o manifesto de implementação no seu dispositivo IoT Edge, o runtime do IoT Edge no dispositivo recolhe as novas informações de implementação e começa a ser executado no mesmo. Quaisquer módulos em execução no dispositivo que não estão incluídos no manifesto de implementação são parados. Quaisquer módulos em falta do dispositivo são iniciados.

  1. No explorador do Visual Studio Code, clique com o botão direito do rato no nome do seu dispositivo IoT Edge e selecione Iniciar Monitorização do Ponto Final de Evento Incorporado.

  2. Veja as mensagens que chegam ao seu Hub IoT. A chegada das mensagens poderá demorar algum tempo. O dispositivo IoT Edge tem de receber a nova implementação e iniciar todos os módulos. Em seguida, as alterações efetuadas ao código JavaModule aguardam até que a temperatura da máquina atinja os 25 graus antes de enviar mensagens. Também adiciona o tipo de mensagem Alerta a quaisquer mensagens que atinjam esse limiar de temperatura.

Editar o módulo duplo

Utilizámos o módulo duplo JavaModule no manifesto de implementação para definir o limiar de temperatura em 25 graus. Pode utilizar o módulo duplo para alterar a funcionalidade sem ter de atualizar o código do módulo.

  1. No Visual Studio Code, expanda os detalhes no seu dispositivo IoT Edge para ver os módulos em execução.

  2. Clique com o botão direito do rato em JavaModule e selecione Editar módulo duplo.

  3. Localize TemperatureThreshold nas propriedades pretendidas. Altere o seu valor para uma nova temperatura 5 graus para 10 graus superior à temperatura reportada mais recente.

  4. Guarde o ficheiro duplo do módulo.

  5. Clique com o botão direito do rato em qualquer parte do painel de edição do módulo duplo e selecione Atualizar módulo duplo.

  6. Monitorize as mensagens de entrada do dispositivo para a cloud. Deverá ver as mensagens pararem até que o novo limiar de temperatura seja atingido.

Limpar os recursos

Se planeia avançar para o próximo artigo recomendado, pode manter os recursos e as configurações que criou e reutilizá-los. Também pode continuar a utilizar o mesmo dispositivo IoT Edge como um dispositivo de teste.

Caso contrário, pode eliminar as configurações locais e os recursos do Azure que criou neste artigo para evitar custos.

Eliminar recursos do Azure

A eliminação de recursos e grupos de recursos do Azure é irreversível. Confirme que não elimina acidentalmente o grupo de recursos ou recursos errados. Se tiver criado o hub IoT dentro de um grupo de recursos existente que tenha recursos que pretende manter, elimine apenas o próprio recurso do hub IoT e não o grupo de recursos.

Para eliminar os recursos:

  1. Inicie sessão no Portal do Azure e selecione Grupos de recursos.

  2. Selecione o nome do grupo de recursos que contém os recursos de teste do IoT Edge.

  3. Reveja a lista de recursos contidos no seu grupo de recursos. Se quiser eliminá-los todos, pode selecionar Eliminar grupo de recursos. Se quiser eliminar apenas alguns dos recursos, pode clicar em cada um para eliminá-los individualmente.

Passos seguintes

Neste tutorial, criou um módulo de IoT Edge que filtra dados não processados gerados pelo seu dispositivo IoT Edge.

Avance para os próximos tutoriais para saber como o Azure IoT Edge o ajuda a implementar serviços cloud do Azure para processar e analisar dados no Edge.