Compartilhar via


Tutorial: Configurar seus dispositivos de um serviço de back-end

Como parte do ciclo de vida dos dispositivos, talvez seja necessário configurar seus dispositivos IoT a partir do serviço de back-end. Ao enviar uma configuração desejada para seus dispositivos, você também deseja receber atualizações de status e conformidade desses dispositivos. Por exemplo, você pode definir um intervalo de temperatura operacional de destino para um dispositivo ou coletar informações de versão do firmware de seus dispositivos.

Para sincronizar informações de estado entre um dispositivo e um Hub IoT, você usa dispositivos gêmeos. Um dispositivo gêmeo é um documento JSON, associado a um dispositivo específico e armazenado pelo Hub IoT na nuvem em que você pode consultá-los . Um dispositivo gêmeo contém propriedades desejadas, propriedades relatadas e etiquetas.

  • Uma propriedade desejada é definida por um aplicativo de back-end e lida por um dispositivo.
  • Uma propriedade relatada é definida por um dispositivo e lida por um aplicativo de back-end.
  • Um tag é definido por um aplicativo de back-end e nunca é enviado para um dispositivo. Você usa etiquetas para organizar seus dispositivos.

Este tutorial mostra como usar as propriedades desejadas e relatadas para sincronizar informações de estado.

Diagrama de dispositivos gêmeos no dispositivo e na nuvem.

Neste tutorial, você executará as seguintes tarefas:

  • Crie um hub IoT e adicione um dispositivo de teste ao registro de identidade.
  • Use as propriedades desejadas para enviar informações de estado para o dispositivo simulado.
  • Use as propriedades relatadas para receber informações de estado do dispositivo simulado.

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

Pré-requisitos

  • Este tutorial usa a CLI do Azure para criar recursos de nuvem. Se você já tiver um hub IoT com um dispositivo registrado nele, poderá ignorar essas etapas. Há duas maneiras de executar comandos da CLI:

  • Os dois aplicativos de exemplo executados neste tutorial são escritos usando Node.js. Você precisa Node.js v10.x.x ou posterior em seu computador de desenvolvimento.

    • Você pode baixar Node.js para várias plataformas de nodejs.org.

    • Você pode verificar a versão atual do Node.js em seu computador de desenvolvimento usando o seguinte comando:

      node --version
      
  • Clone ou baixe o projeto de Node.js de exemplo em Exemplos de Internet das Coisas do Azure para Node.js.

  • Verifique se a porta 8883 está aberta no firewall. O exemplo de dispositivo neste tutorial usa o protocolo MQTT, que se comunica pela porta 8883. Essa porta pode ser bloqueada em alguns ambientes de rede corporativa e educacional. Para obter mais informações e maneiras de solucionar esse problema, consulte Conectar-se ao Hub IoT (MQTT).

Configurar recursos do Azure

Para concluir este tutorial, sua assinatura do Azure deve conter um hub IoT com um dispositivo adicionado ao registro de identidade do dispositivo. A entrada no registro de identidade do dispositivo permite que o dispositivo simulado executado neste tutorial se conecte ao hub.

Se você ainda não tiver um hub IoT configurado em sua assinatura, poderá configurar um com o script da CLI a seguir. Esse script usa o nome tutorial-iot-hub com um número aleatório acrescentado ao nome do hub IoT. Você pode substituir esse nome por seu próprio nome globalmente exclusivo ao executá-lo. O script cria o grupo de recursos e o hub na região Central dos EUA , que você pode alterar para uma região mais próxima de você. O script recupera a cadeia de conexão de serviço do Hub IoT, que é usado no exemplo de back-end para conectar ao Hub IoT:

let "randomIdentifier=$RANDOM*$RANDOM"  
hubname="tutorial-iot-hub-$randomIdentifier"
___location=centralus

# Install the IoT extension if it's not already installed:
az extension add --name azure-iot

# Create a resource group:
az group create --name tutorial-iot-hub-rg --___location $___location

# Create your free-tier IoT hub. You can only have one free IoT hub per subscription.
# Change the sku to S1 to create a standard-tier hub if necessary.
az iot hub create --name $hubname --___location $___location --resource-group tutorial-iot-hub-rg --partition-count 2 --sku F1

# Make a note of the service connection string, you need it later:
az iot hub connection-string show --hub-name $hubname --policy-name service -o table

Este tutorial usa um dispositivo simulado chamado MyTwinDevice. O script a seguir adiciona esse dispositivo ao registro de identidade e recupera sua cadeia de conexão:

# Create the device in the identity registry:
az iot hub device-identity create --device-id MyTwinDevice --hub-name $hubname --resource-group tutorial-iot-hub-rg

# Retrieve the device connection string, you need this later:
az iot hub device-identity connection-string show --device-id MyTwinDevice --hub-name $hubname --resource-group tutorial-iot-hub-rg -o table

Enviar informações de estado para um dispositivo

Você usa as propriedades desejadas para enviar informações de estado de um aplicativo de back-end para um dispositivo. Nesta seção, você verá como:

  • Configure um dispositivo para receber e processar as propriedades desejadas.
  • Enviar propriedades desejadas de um aplicativo back-end para um dispositivo.

exemplo de propriedades desejadas

Você pode estruturar suas propriedades desejadas de qualquer maneira conveniente para seu aplicativo. Este exemplo usa uma propriedade de nível superior chamada fanOn e agrupa as propriedades restantes em componentes separados. O snippet JSON a seguir mostra a estrutura das propriedades desejadas que este tutorial usa. O JSON está no arquivo desired.json.

{
  "fanOn": "true",
  "components": {
    "system": {
      "id": "17",
      "units": "farenheit",
      "firmwareVersion": "9.75"
    },
    "wifi" : { 
      "channel" : "6",
      "ssid": "my_network"
    },
    "climate" : {
      "minTemperature": "68",
      "maxTemperature": "76"
    }
  }
}

Receber propriedades desejadas em um aplicativo de dispositivo

Para exibir o código de exemplo de dispositivo simulado que recebe as propriedades desejadas, navegue até a pasta iot-hub/Tutorials/DeviceTwins no exemplo Node.js projeto que você baixou. Em seguida, abra o arquivo SimulatedDevice.js em um editor de texto.

As seções a seguir descrevem o código executado no dispositivo simulado que responde às alterações de propriedade desejadas enviadas do aplicativo de back-end.

Recuperar o objeto de dispositivo gêmeo

Quando você registrou seu dispositivo com o hub IoT, você recebeu uma cadeia de conexão do dispositivo como saída. Uma cadeia de conexão de dispositivo é usada pelo dispositivo para autenticar com sua identidade registrada na nuvem. O código a seguir se conecta ao seu hub IoT usando uma cadeia de conexão de dispositivo:

// Get the device connection string from a command line argument
var connectionString = process.argv[2];

O código a seguir obtém um gêmeo do objeto cliente:

// Get the device twin
client.getTwin(function(err, twin) {
  if (err) {
    console.error(chalk.red('Could not get device twin'));
  } else {
    console.log(chalk.green('Device twin created'));

Criar manipuladores

Você pode criar manipuladores para atualizações de propriedade desejadas que respondem a atualizações em diferentes níveis na hierarquia JSON. Por exemplo, esse manipulador detecta todas as alterações desejadas nas propriedades que são enviadas para o dispositivo a partir de um aplicativo de back-end. A variável delta contém as propriedades desejadas enviadas do back-end da solução:

// Handle all desired property updates
twin.on('properties.desired', function(delta) {
    console.log(chalk.yellow('\nNew desired properties received in patch:'));

O manipulador a seguir só reage às alterações feitas na propriedade desejada fanOn :

// Handle changes to the fanOn desired property
twin.on('properties.desired.fanOn', function(fanOn) {
    console.log(chalk.green('\nSetting fan state to ' + fanOn));

    // Update the reported property after processing the desired property
    reportedPropertiesPatch.fanOn = fanOn ? fanOn : '{unknown}';
});

Manipuladores para várias propriedades

No JSON de exemplo de propriedades desejadas deste tutorial, o nó clima em componentes contém duas propriedades, minTemperature and maxTemperature.

O objeto gêmeo local de um dispositivo armazena um conjunto completo de propriedades desejadas e relatadas. O delta enviado do back-end pode atualizar apenas um subconjunto de propriedades desejadas. No snippet de código a seguir, se o dispositivo simulado receber uma atualização apenas para um dos valores minTemperature e maxTemperature, ele usará o valor no gêmeo local para o outro valor para configurar o dispositivo:

// Handle desired properties updates to the climate component
twin.on('properties.desired.components.climate', function(delta) {
    if (delta.minTemperature || delta.maxTemperature) {
      console.log(chalk.green('\nUpdating desired tempertures in climate component:'));
      console.log('Configuring minimum temperature: ' + twin.properties.desired.components.climate.minTemperature);
      console.log('Configuring maximum temperture: ' + twin.properties.desired.components.climate.maxTemperature);

      // Update the reported properties and send them to the hub
      reportedPropertiesPatch.minTemperature = twin.properties.desired.components.climate.minTemperature;
      reportedPropertiesPatch.maxTemperature = twin.properties.desired.components.climate.maxTemperature;
      sendReportedProperties();
    }
});

Manipular operações de inserção, atualização e exclusão

As propriedades desejadas enviadas do back-end não indicam qual operação está sendo executada em uma propriedade desejada específica. Seu código precisa inferir a operação do conjunto atual de propriedades desejadas armazenadas localmente e as alterações enviadas do hub.

O snippet a seguir mostra como o dispositivo simulado lida com operações de inserção, atualização e exclusão na lista de componentes nas propriedades desejadas. Você pode ver como usar valores nulos para indicar que um componente deve ser excluído:

// Keep track of all the components the device knows about
var componentList = {};

// Use this componentList list and compare it to the delta to infer
// if anything was added, deleted, or updated.
twin.on('properties.desired.components', function(delta) {
  if (delta === null) {
    componentList = {};
  }
  else {
    Object.keys(delta).forEach(function(key) {

      if (delta[key] === null && componentList[key]) {
        // The delta contains a null value, and the
        // device has a record of this component.
        // Must be a delete operation.
        console.log(chalk.green('\nDeleting component ' + key));
        delete componentList[key];

      } else if (delta[key]) {
        if (componentList[key]) {
          // The delta contains a component, and the
          // device has a record of it.
          // Must be an update operation.
          console.log(chalk.green('\nUpdating component ' + key + ':'));
          console.log(JSON.stringify(delta[key]));
          // Store the complete object instead of just the delta
          componentList[key] = twin.properties.desired.components[key];

        } else {
          // The delta contains a component, and the
          // device has no record of it.
          // Must be an add operation.
          console.log(chalk.green('\nAdding component ' + key + ':'));
          console.log(JSON.stringify(delta[key]));
          // Store the complete object instead of just the delta
          componentList[key] = twin.properties.desired.components[key];
        }
      }
    });
  }
});

Enviar propriedades desejadas de um aplicativo de back-end

Você viu como um dispositivo implementa manipuladores para receber atualizações de propriedade desejadas. Esta seção mostra como enviar alterações de propriedade desejadas a um dispositivo a partir de um aplicativo de back-end.

Para exibir o código de exemplo de dispositivo simulado que recebe as propriedades desejadas, navegue até a pasta iot-hub/Tutorials/DeviceTwins no exemplo Node.js projeto que você baixou. Em seguida, abra o arquivo ServiceClient.js em um editor de texto.

O snippet de código a seguir mostra como conectar o registro de identidade do dispositivo e acessar o gêmeo para um dispositivo específico:

// Create a device identity registry object
var registry = Registry.fromConnectionString(connectionString);

// Get the device twin and send desired property update patches at intervals.
// Print the reported properties after some of the desired property updates.
registry.getTwin(deviceId, async (err, twin) => {
  if (err) {
    console.error(err.message);
  } else {
    console.log('Got device twin');

O snippet de código a seguir mostra diferentes patches de propriedade desejada que o aplicativo de back-end envia ao dispositivo:

// Turn the fan on
var twinPatchFanOn = {
  properties: {
    desired: {
      patchId: "Switch fan on",
      fanOn: "false",
    }
  }
};

// Set the maximum temperature for the climate component
var twinPatchSetMaxTemperature = {
  properties: {
    desired: {
      patchId: "Set maximum temperature",
      components: {
        climate: {
          maxTemperature: "92"
        }
      }
    }
  }
};

// Add a new component
var twinPatchAddWifiComponent = {
  properties: {
    desired: {
      patchId: "Add WiFi component",
      components: {
        wifi: { 
          channel: "6",
          ssid: "my_network"
        }
      }
    }
  }
};

// Update the WiFi component
var twinPatchUpdateWifiComponent = {
  properties: {
    desired: {
      patchId: "Update WiFi component",
      components: {
        wifi: { 
          channel: "13",
          ssid: "my_other_network"
        }
      }
    }
  }
};

// Delete the WiFi component
var twinPatchDeleteWifiComponent = {
  properties: {
    desired: {
      patchId: "Delete WiFi component",
      components: {
        wifi: null
      }
    }
  }
};

O snippet a seguir mostra como o aplicativo de back-end envia uma atualização de propriedade desejada para um dispositivo:

// Send a desired property update patch
async function sendDesiredProperties(twin, patch) {
  twin.update(patch, (err, twin) => {
    if (err) {
      console.error(err.message);
    } else {
      console.log(chalk.green(`\nSent ${twin.properties.desired.patchId} patch:`));
      console.log(JSON.stringify(patch, null, 2));
    }
  });
}

Receber informações de estado de um dispositivo

O aplicativo de back-end recebe informações de estado de um dispositivo como propriedades relatadas. Um dispositivo define as propriedades relatadas e as envia para o hub. Um aplicativo de back-end pode ler os valores atuais das propriedades relatadas do dispositivo gêmeo armazenado em seu hub.

Enviar propriedades relatadas de um dispositivo

É possível enviar atualizações para valores de propriedade relatados como um patch. O snippet a seguir mostra um modelo para o patch que o dispositivo simulado envia. O dispositivo simulado atualiza os campos no patch antes de enviá-lo para o hub:

// Create a patch to send to the hub
var reportedPropertiesPatch = {
  firmwareVersion:'1.2.1',
  lastPatchReceivedId: '',
  fanOn:'',
  minTemperature:'',
  maxTemperature:''
};

O dispositivo simulado usa a seguinte função para enviar o patch que contém as propriedades relatadas para o hub:

// Send the reported properties patch to the hub
function sendReportedProperties() {
  twin.properties.reported.update(reportedPropertiesPatch, function(err) {
    if (err) throw err;
    console.log(chalk.blue('\nTwin state reported'));
    console.log(JSON.stringify(reportedPropertiesPatch, null, 2));
  });
}

Processar propriedades relatadas

Um aplicativo de back-end acessa os valores de propriedade relatados atuais para um dispositivo por meio do dispositivo gêmeo. O snippet de código a seguir mostra como o aplicativo de back-end lê os valores da propriedade relatada do dispositivo simulado:

// Display the reported properties from the device
function printReportedProperties(twin) {
  console.log("Last received patch: " + twin.properties.reported.lastPatchReceivedId);
  console.log("Firmware version: " + twin.properties.reported.firmwareVersion);
  console.log("Fan status: " + twin.properties.reported.fanOn);
  console.log("Min temperature set: " + twin.properties.reported.minTemperature);
  console.log("Max temperature set: " + twin.properties.reported.maxTemperature);
}

Executar os aplicativos

Nesta seção, você executará os dois aplicativos de exemplo para observar como um aplicativo de back-end envia atualizações de propriedades desejadas para um aplicativo de dispositivo simulado.

Para executar o dispositivo simulado e os aplicativos de back-end, você precisa das cadeias de conexão de dispositivo e serviço. Você anotou as cadeias de conexão quando criou os recursos no início deste tutorial.

Para executar o aplicativo de dispositivo simulado, abra uma janela de prompt de comando ou shell e navegue até a pasta iot-hub/Tutorials/DeviceTwins no projeto Node.js baixado. Em seguida, execute os seguintes comandos:

npm install
node SimulatedDevice.js "{your device connection string}"

Para executar o aplicativo de back-end, abra outra janela do prompt de comando ou shell. Em seguida, navegue até a pasta iot-hub/Tutorials/DeviceTwins no projeto de Node.js baixado. Em seguida, execute os seguintes comandos:

npm install
node ServiceClient.js "{your service connection string}"

Observar as atualizações de propriedade desejadas

A captura de tela a seguir mostra a saída do aplicativo de dispositivo simulado e destaca como ele lida com uma atualização para a propriedade maxTemperature desejada. Você pode ver como o manipulador de nível superior e os manipuladores de componentes climáticos são executados:

Captura de tela que mostra como o manipulador de nível superior e os manipuladores de componentes climáticos são executados.

A captura de tela a seguir mostra a saída do aplicativo de back-end e destaca como ele envia uma atualização para a propriedade maxTemperature desejada:

Captura de tela que mostra a saída do aplicativo de back-end e destaca como ele envia uma atualização.

Observar as atualizações de propriedade relatada

A captura de tela a seguir mostra a saída do aplicativo de dispositivo simulado e destaca como ele envia uma atualização de propriedade relatada ao hub:

Captura de tela que mostra o dispositivo simulado atualizando seu estado gêmeo.

A captura de tela a seguir mostra a saída do aplicativo back-end e destaca como ela recebe e processa uma atualização de propriedade relatada de um dispositivo:

Captura de tela que mostra o aplicativo de back-end recebendo as propriedades relatadas pelo dispositivo.

Limpar os recursos

Se você planeja concluir o próximo tutorial, deixe o grupo de recursos e o hub IoT para reutilizá-los mais tarde.

Se você não precisar mais do hub IoT, exclua-o e o grupo de recursos no portal. Para fazer isso, selecione o grupo de recursos tutorial-iot-hub-rg que contém o hub IoT e selecione Excluir.

Como alternativa, use a CLI:

# Delete your resource group and its contents
az group delete --name tutorial-iot-hub-rg

Próximas etapas

Neste tutorial, você aprendeu a sincronizar informações de estado entre seus dispositivos e o hub IoT. Avance para o próximo tutorial para saber como usar dispositivos gêmeos para implementar o processo de atualização do dispositivo.