Entender os gêmeos digitais de IoT Plug and Play

Um dispositivo IoT Plug and Play implementa um modelo descrito pelo esquema DTDL (Linguagem de Definição de Gêmeos Digitais). Um modelo descreve o conjunto de componentes, propriedades, comandos e mensagens de telemetria que um dispositivo específico pode ter.

Observação

A DTDL não é exclusiva do IoT Plug and Play. Outros serviços IoT, como os Gêmeos Digitais do Azure, o usam para representar ambientes inteiros, como edifícios e redes de energia.

Os SDKs do serviço IoT do Azure incluem APIs que permitem que um serviço interaja com o gêmeo digital de um dispositivo. Por exemplo, um serviço pode ler as propriedades do dispositivo do gêmeo digital ou usar o gêmeo digital para chamar um comando em um dispositivo. Para saber mais, confira exemplos de gêmeo digital do Hub IoT.

O dispositivo IoT Plug and Play de exemplo neste artigo implementa um modelo de controlador de temperatura que tem componentes de termostato.

Dispositivos gêmeos e gêmeos digitais

Junto com um gêmeo digital, o Hub IoT do Azure também mantém um dispositivo gêmeo para cada dispositivo conectado. Um dispositivo gêmeo é semelhante a um gêmeo digital, pois é uma representação das propriedades de um dispositivo. Um Hub IoT inicializa um gêmeo digital e um dispositivo gêmeo na primeira vez em que um dispositivo IoT Plug and Play é provisionado. Os SDKs do serviço IoT do Azure incluem APIs para interagir com dispositivos gêmeos.

Dispositivos gêmeos são documentos JSON que armazenam informações do estado do dispositivo, incluindo metadados, configurações e condições. Para saber mais, confira exemplos de cliente do serviço do Hub IoT. Os criadores de dispositivo e de solução podem continuar usando o mesmo conjunto de APIs e SDKs de dispositivo gêmeo para implementar dispositivos e soluções usando as convenções do IoT Plug and Play. Em um dispositivo gêmeo, o estado de uma propriedade gravável é dividido nas seções propriedades desejadas e propriedades relatadas. Todas as propriedades somente leitura estão disponíveis na seção de propriedades relatadas.

As APIs de gêmeo digital operam em constructos DTDL de alto nível, como componentes, propriedades e comandos, além de facilitarem a criação de soluções IoT Plug and Play. Em um gêmeo digital, há uma exibição unificada do estado atual e desejado da propriedade. O estado de sincronização de uma determinada propriedade é armazenado na seção $metadata do componente padrão correspondente.

Exemplo de JSON do dispositivo gêmeo

O seguinte snippet de código mostra um dispositivo gêmeo IoT Plug and Play formatado como um objeto JSON:

{
  "deviceId": "sample-device",
  "modelId": "dtmi:com:example:TemperatureController;1",
  "version": 15,
  "properties": {
    "desired": {
      "thermostat1": {
        "__t": "c",
        "targetTemperature": 21.8
      },
      "$metadata": {...},
      "$version": 4
    },
    "reported": {
      "serialNumber": "alwinexlepaho8329",
      "thermostat1": {
        "maxTempSinceLastReboot": 25.3,
        "__t": "c",
        "targetTemperature": {
          "value": 21.8,
          "ac": 200,
          "ad": "Successfully executed patch",
        }
      },
      "$metadata": {...},
      "$version": 11
    }
  }
}

Exemplo de gêmeo digital

O seguinte snippet de código mostra um gêmeo digital formatado como um objeto JSON:

{
  "$dtId": "sample-device",
  "serialNumber": "alwinexlepaho8329",
  "thermostat1": {
    "maxTempSinceLastReboot": 25.3,
    "targetTemperature": 21.8,
    "$metadata": {
      "targetTemperature": {
        "desiredValue": 21.8,
        "desiredVersion": 4,
        "ackVersion": 4,
        "ackCode": 200,
        "ackDescription": "Successfully executed patch",
        "lastUpdateTime": "2020-07-17T06:11:04.9309159Z"
      },
      "maxTempSinceLastReboot": {
         "lastUpdateTime": "2020-07-17T06:10:31.9609233Z"
      }
    }
  },
  "$metadata": {
    "$model": "dtmi:com:example:TemperatureController;1",
    "serialNumber": {
      "lastUpdateTime": "2020-07-17T06:10:31.9609233Z"
    }
  }
}

A seguinte tabela descreve os campos no objeto JSON do gêmeo digital:

Nome do campo Descrição
$dtId Uma cadeia de caracteres fornecida pelo usuário que representa a ID do gêmeo digital do dispositivo.
{propertyName} O valor de uma propriedade em JSON.
$metadata.$model [Opcional] A ID da interface do modelo que caracteriza este gêmeo digital.
$metadata.{propertyName}.desiredValue [Somente para propriedades graváveis] O valor desejado da propriedade especificada.
$metadata.{propertyName}.desiredVersion [Somente para propriedades graváveis] A versão do valor desejado mantido pelo Hub IoT.
$metadata.{propertyName}.ackVersion [Obrigatório, somente para propriedades graváveis] A versão reconhecida pelo dispositivo que está implementando o gêmeo digital. Ela precisa ser maior ou igual à versão desejada.
$metadata.{propertyName}.ackCode [Obrigatório, somente para propriedades graváveis] O código ack retornado pelo aplicativo de dispositivo que implementa o gêmeo digital.
$metadata.{propertyName}.ackDescription [Opcional, somente para propriedades graváveis] A descrição ack retornada pelo aplicativo de dispositivo que implementa o gêmeo digital.
$metadata.{propertyName}.lastUpdateTime O Hub IoT mantém o carimbo de data/hora da última atualização da propriedade pelo dispositivo. Os carimbos de data e hora estão em UTC e são codificados no formato ISO8601 AAAA-MM-DDTHH:MM:SS.mmmZ.
{componentName} Um objeto JSON que contém os valores de propriedade e metadados do componente.
{componentName}.{propertyName} O valor da propriedade do componente em JSON.
{componentName}.$metadata As informações de metadados do componente.

Propriedades

As propriedades são campos de dados que representam o estado de uma entidade, como as propriedades de várias linguagens de programação orientadas a objeto.

Propriedade somente leitura

Esquema DTDL:

{
    "@type": "Property",
    "name": "serialNumber",
    "displayName": "Serial Number",
    "description": "Serial number of the device.",
    "schema": "string"
}

Neste exemplo, alwinexlepaho8329 é o valor atual da propriedade serialNumber somente leitura relatada pelo dispositivo.

Os seguintes snippets de código mostram a representação JSON lado a lado da propriedade serialNumber:

Dispositivo gêmeo

"properties": {
"reported": {
"serialNumber": "alwinexlepaho8329"
}
}

Gêmeo digital

"serialNumber": "alwinexlepaho8329"

Propriedade gravável

Os exemplos a seguir mostram uma propriedade gravável no componente padrão.

DTDL:

{
  "@type": "Property",
  "name": "fanSpeed",
  "displayName": "Fan Speed",
  "writable": true,
  "schema": "double"
}

Dispositivo gêmeo

{
"properties": {
"desired": {
"fanSpeed": 2.0,
},
"reported": {
"fanSpeed": {
"value": 3.0,
"ac": 200,
"av": 1,
"ad": "Successfully executed patch version 1"
}
}
},
}

Gêmeo digital

{
"fanSpeed": 3.0,
"$metadata": {
"fanSpeed": {
"desiredValue": 2.0,
"desiredVersion": 2,
"ackVersion": 1,
"ackCode": 200,
"ackDescription": "Successfully executed patch version 1",
"lastUpdateTime": "2020-07-17T06:10:31.9609233Z"
}
}
}

Neste exemplo, 3.0 é o valor atual da propriedade fanSpeed relatada pelo dispositivo. 2.0 é o valor desejado definido pela solução. O valor desejado e o estado de sincronização de uma propriedade no nível da raiz são definidos no nível da raiz $metadata para um gêmeo digital. Quando o dispositivo ficar online, ele poderá aplicar essa atualização e reportar o valor atualizado.

Componentes

Os componentes permitem criar uma interface de modelo como uma montagem de outras interfaces. Por exemplo, a interface Termostato pode ser incorporada como componentes thermostat1 e thermostat2 no modelo de Controlador de Temperatura.

Em um dispositivo gêmeo, um componente é identificado pelo marcador { "__t": "c"}. Em um gêmeo digital, a presença de $metadata marca um componente.

Neste exemplo, thermostat1 é um componente com duas propriedades:

  • maxTempSinceLastReboot é uma propriedade somente leitura.
  • targetTemperature é uma propriedade gravável que foi sincronizada com êxito pelo dispositivo. O valor desejado e o estado de sincronização dessas propriedades estão no $metadata do componente.

Os seguintes snippets de código mostram a representação JSON lado a lado do componente thermostat1:

Dispositivo gêmeo

"properties": {
"desired": {
"thermostat1": {
"__t": "c",
"targetTemperature": 21.8
},
"$metadata": {
},
"$version": 4
},
"reported": {
"thermostat1": {
"maxTempSinceLastReboot": 25.3,
"__t": "c",
"targetTemperature": {
"value": 21.8,
"ac": 200,
"ad": "Successfully executed patch",
"av": 4
}
},
"$metadata": {
},
"$version": 11
}
}

Gêmeo digital

"thermostat1": {
"maxTempSinceLastReboot": 25.3,
"targetTemperature": 21.8,
"$metadata": {
"targetTemperature": {
"desiredValue": 21.8,
"desiredVersion": 4,
"ackVersion": 4,
"ackCode": 200,
"ackDescription": "Successfully executed patch",
"lastUpdateTime": "2020-07-17T06:11:04.9309159Z"
},
"maxTempSinceLastReboot": {
"lastUpdateTime": "2020-07-17T06:10:31.9609233Z"
}
}
}

APIs de gêmeo digital

As APIs de gêmeo digital incluem as operações Obter Gêmeo Digital, Atualizar Gêmeo Digital, Invocar Comando do Componente e Invocar Comando, gerenciando mais um gêmeo digital. Você pode usar as APIs REST diretamente ou por meio de um dos SDKs de serviço.

Eventos de alteração de gêmeo digital

Quando os eventos de alteração do gêmeo digital são habilitados, um evento é disparado sempre que o valor atual ou o desejado do componente ou da propriedade é alterado. Os eventos de alteração do gêmeo digital são gerados no formato Patch JSON. Os eventos correspondentes serão gerados no formato de dispositivo gêmeo se os eventos de alteração do gêmeo estiverem habilitados.

Para saber como habilitar o roteamento para eventos de dispositivo gêmeo e de gêmeo digital, confira Usar o roteamento de mensagem do Hub IoT para enviar mensagens do dispositivo para nuvem a diferentes pontos de extremidade. Para entender o formato da mensagem, confira Criar e ler mensagens do Hub IoT.

Por exemplo, o seguinte evento de alteração de gêmeo digital é acionado quando targetTemperature é definido pela solução:

iothub-connection-device-id:sample-device
iothub-enqueuedtime:7/17/2020 6:11:04 AM
iothub-message-source:digitalTwinChangeEvents
correlation-id:275d463fa034
content-type:application/json-patch+json
content-encoding:utf-8
[
  {
    "op": "add",
    "path": "/thermostat1/$metadata/targetTemperature",
    "value": {
      "desiredValue": 21.8,
      "desiredVersion": 4
    }
  }
]

O seguinte evento de alteração do gêmeo digital é disparado quando o dispositivo relata que a alteração acima foi aplicada:

iothub-connection-device-id:sample-device
iothub-enqueuedtime:7/17/2020 6:11:05 AM
iothub-message-source:digitalTwinChangeEvents
correlation-id:275d464a2c80
content-type:application/json-patch+json
content-encoding:utf-8
[
  {
    "op": "add",
    "path": "/thermostat1/$metadata/targetTemperature/ackCode",
    "value": 200
  },
  {
    "op": "add",
    "path": "/thermostat1/$metadata/targetTemperature/ackDescription",
    "value": "Successfully executed patch"
  },
  {
    "op": "add",
    "path": "/thermostat1/$metadata/targetTemperature/ackVersion",
    "value": 4
  },
  {
    "op": "add",
    "path": "/thermostat1/$metadata/targetTemperature/lastUpdateTime",
    "value": "2020-07-17T06:11:04.9309159Z"
  },
  {
    "op": "add",
    "path": "/thermostat1/targetTemperature",
    "value": 21.8
  }
]

Observação

As mensagens de notificação de alteração de gêmeo são duplicadas quando ativadas na notificação de alteração tanto do dispositivo gêmeo quanto do gêmeo digital.

Próximas etapas

Agora que você sabe mais sobre os gêmeos digitais, confira mais alguns recursos: