Convenções do IoT Plug and Play

Os dispositivos IoT Plug and Play devem seguir um conjunto de convenções quando trocam mensagens com um hub IoT. Os dispositivos IoT Plug and Play usam o protocolo MQTT para se comunicar com o Hub IoT. O Hub IoT também suporta o protocolo AMQP, que está disponível em alguns SDKs de dispositivos IoT.

Um dispositivo pode incluir módulos ou ser implementado em um módulo do IoT Edge hospedado pelo tempo de execução do IoT Edge.

Você descreve a telemetria, as propriedades e os comandos que um dispositivo IoT Plug and Play implementa com um modelo DTDL (Digital Twins Definition Language). Existem dois tipos de modelos referidos neste artigo:

  • Sem componente - Um modelo sem componentes. O modelo declara telemetria, propriedades e comandos como elementos de nível superior na seção de conteúdo da interface principal. Na ferramenta Azure IoT explorer, esse modelo aparece como um único componente padrão.
  • Vários componentes - Um modelo composto por duas ou mais interfaces. Uma interface principal, que aparece como o componente padrão, com telemetria, propriedades e comandos. Uma ou mais interfaces declaradas como componentes com mais telemetria, propriedades e comandos.

Para obter mais informações, consulte Guia de modelagem IoT Plug and Play.

Identificar o modelo

Para anunciar o modelo que implementa, um dispositivo ou módulo IoT Plug and Play inclui o ID do modelo no pacote de conexão MQTT adicionando model-id ao USERNAME campo.

Para identificar o modelo que um dispositivo ou módulo implementa, um serviço pode obter a ID do modelo de:

  • O campo gêmeo modelId do dispositivo.
  • O campo de gêmeos $metadata.$model digitais.
  • Uma notificação de alteração de gêmeo digital.

Telemetria

  • A telemetria enviada de um dispositivo sem componente não requer metadados extras. O sistema adiciona a dt-dataschema propriedade.
  • A telemetria enviada de um dispositivo usando componentes deve adicionar o nome do componente à mensagem de telemetria.
  • Ao usar MQTT, adicione a $.sub propriedade com o nome do componente ao tópico de telemetria, o sistema adiciona a dt-subject propriedade.
  • Ao usar AMQP, adicione a dt-subject propriedade com o nome do componente como uma anotação de mensagem.

Nota

A telemetria dos componentes requer uma mensagem por componente.

Para obter mais exemplos de telemetria, consulte Telemetria de > cargas úteis

Propriedades só de leitura

Um dispositivo define uma propriedade somente leitura que, em seguida, relata para o aplicativo back-end.

Exemplo de propriedade somente leitura sem componente

Um dispositivo ou módulo pode enviar qualquer JSON válido que siga as regras DTDL.

DTDL que define uma propriedade em uma interface:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:example: Thermostat;1",
  "@type": "Interface",
  "contents": [
    {
      "@type": "Property",
      "name": "temperature",
      "schema": "double"
    }
  ]
}

Amostra de carga útil da propriedade relatada:

"reported" :
{
  "temperature" : 21.3
}

Exemplo de propriedade somente leitura de vários componentes

O dispositivo ou módulo deve adicionar o marcador para indicar que o {"__t": "c"} elemento se refere a um componente.

DTDL que faz referência a um componente:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:com:example:TemperatureController;1",
  "@type": "Interface",
  "displayName": "Temperature Controller",
  "contents": [
    {
      "@type" : "Component",
      "schema": "dtmi:com:example:Thermostat;1",
      "name": "thermostat1"
    }
  ]
}

DTDL que define o componente:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:com:example:Thermostat;1",
  "@type": "Interface",
  "contents": [
    {
      "@type": "Property",
      "name": "temperature",
      "schema": "double"
    }
  ]
}

Amostra de carga útil da propriedade relatada:

"reported": {
  "thermostat1": {
    "__t": "c",
    "temperature": 21.3
  }
}

Para obter mais exemplos de propriedades somente leitura, consulte Propriedades de > cargas úteis.

Writable properties

Um aplicativo back-end define uma propriedade gravável que o Hub IoT envia para o dispositivo.

O dispositivo ou módulo deve confirmar que recebeu a propriedade enviando uma propriedade relatada. A propriedade relatada deve incluir:

  • value - o valor real da propriedade (normalmente o valor recebido, mas o dispositivo pode decidir relatar um valor diferente).
  • ac - um código de reconhecimento que usa um código de status HTTP.
  • av - uma versão de reconhecimento que se refere ao $version do imóvel desejado. Você pode encontrar esse valor na propriedade desejada JSON payload.
  • ad - uma descrição opcional do agradecimento.

Respostas de agradecimento

Ao relatar propriedades graváveis, o dispositivo deve compor a mensagem de confirmação, usando os quatro campos na lista anterior, para indicar o estado real do dispositivo, conforme descrito na tabela a seguir:

Estado(ac) Versão(av) Valor (valor) Descrição(av)
200 Versão desejada Valor desejado Valor desejado da propriedade aceito
202 Versão desejada Valor aceite pelo dispositivo Valor desejado do imóvel aceito, atualização em andamento (deve terminar com 200)
203 0 Valor definido pelo dispositivo Propriedade definida a partir do dispositivo, não refletindo qualquer desejado
400 Versão desejada Valor real utilizado pelo dispositivo Valor desejado da propriedade não aceito
500 Versão desejada Valor real utilizado pelo dispositivo Exceção ao aplicar a propriedade

Quando um dispositivo é iniciado, ele deve solicitar o dispositivo gêmeo e verificar se há atualizações de propriedade graváveis. Se a versão de uma propriedade gravável aumentou enquanto o dispositivo estava offline, o dispositivo deve enviar uma resposta de propriedade relatada para confirmar que recebeu a atualização.

Quando um dispositivo é iniciado pela primeira vez, ele pode enviar um valor inicial para uma propriedade relatada se não receber uma propriedade desejada inicial do hub IoT. Nesse caso, o dispositivo pode enviar o valor padrão com av para e ac para 0203. Por exemplo:

"reported": {
  "targetTemperature": {
    "value": 20.0,
    "ac": 203,
    "av": 0,
    "ad": "initialize"
  }
}

Um dispositivo pode usar a propriedade relatada para fornecer outras informações ao hub. Por exemplo, o dispositivo pode responder com uma série de mensagens em andamento, como:

"reported": {
  "targetTemperature": {
    "value": 35.0,
    "ac": 202,
    "av": 3,
    "ad": "In-progress - reporting current temperature"
  }
}

Quando o dispositivo atinge a temperatura alvo, ele envia a seguinte mensagem:

"reported": {
  "targetTemperature": {
    "value": 20.0,
    "ac": 200,
    "av": 4,
    "ad": "Reached target temperature"
  }
}

Um dispositivo pode comunicar um erro como:

"reported": {
  "targetTemperature": {
    "value": 120.0,
    "ac": 500,
    "av": 3,
    "ad": "Target temperature out of range. Valid range is 10 to 99."
  }
}

Object type

Se uma propriedade gravável for definida como um objeto, o serviço deverá enviar um objeto completo para o dispositivo. O dispositivo deve confirmar a atualização enviando informações suficientes de volta ao serviço para que o serviço entenda como o dispositivo agiu na atualização. Esta resposta poderá incluir:

  • O objeto inteiro.
  • Apenas os campos que o dispositivo atualizou.
  • Um subconjunto dos campos.

Para objetos grandes, considere minimizar o tamanho do objeto incluído na confirmação.

O exemplo a seguir mostra uma propriedade gravável definida como uma Object com quatro campos:

DTDL:

{
  "@type": "Property",
  "name": "samplingRange",
  "schema": {
    "@type": "Object",
    "fields": [
      {
        "name": "startTime",
        "schema": "dateTime"
      },
      {
        "name": "lastTime",
        "schema": "dateTime"
      },
      {
        "name": "count",
        "schema": "integer"
      },
      {
        "name": "errorCount",
        "schema": "integer"
      }
    ]
  },
  "displayName": "Sampling range"
  "writable": true
}

Para atualizar essa propriedade gravável, envie um objeto completo do serviço semelhante ao exemplo a seguir:

{
  "samplingRange": {
    "startTime": "2021-08-17T12:53:00.000Z",
    "lastTime": "2021-08-17T14:54:00.000Z",
    "count": 100,
    "errorCount": 5
  }
}

O dispositivo responde com uma confirmação semelhante ao exemplo a seguir:

{
  "samplingRange": {
    "ac": 200,
    "av": 5,
    "ad": "Weighing status updated",
    "value": {
      "startTime": "2021-08-17T12:53:00.000Z",
      "lastTime": "2021-08-17T14:54:00.000Z",
      "count": 100,
      "errorCount": 5
    }
  }
}

Amostra de nenhuma propriedade gravável de componente

Quando um dispositivo recebe várias propriedades desejadas em uma única carga útil, ele pode enviar as respostas de propriedade relatadas em várias cargas úteis ou combinar as respostas em uma única carga útil.

Um dispositivo ou módulo pode enviar qualquer JSON válido que siga as regras DTDL.

DTDL:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:example: Thermostat;1",
  "@type": "Interface",
  "contents": [
    {
      "@type": "Property",
      "name": "targetTemperature",
      "schema": "double",
      "writable": true
    },
    {
      "@type": "Property",
      "name": "targetHumidity",
      "schema": "double",
      "writable": true
    }
  ]
}

Amostra de carga útil da propriedade desejada:

"desired" :
{
  "targetTemperature" : 21.3,
  "targetHumidity" : 80,
  "$version" : 3
}

Amostra de primeira carga útil da propriedade relatada:

"reported": {
  "targetTemperature": {
    "value": 21.3,
    "ac": 200,
    "av": 3,
    "ad": "complete"
  }
}

Exemplo de segunda carga útil da propriedade relatada:

"reported": {
  "targetHumidity": {
    "value": 80,
    "ac": 200,
    "av": 3,
    "ad": "complete"
  }
}

Nota

Você pode optar por combinar essas duas cargas úteis de propriedade relatadas em uma única carga útil.

Exemplo de propriedade gravável de vários componentes

O dispositivo ou módulo deve adicionar o marcador para indicar que o {"__t": "c"} elemento se refere a um componente.

O marcador é enviado apenas para atualizações de propriedades definidas em um componente. As atualizações das propriedades definidas no componente padrão não incluem o marcador, consulte Amostra de nenhuma propriedade gravável do componente.

Quando um dispositivo recebe várias propriedades relatadas em uma única carga útil, ele pode enviar as respostas de propriedade relatadas em várias cargas úteis ou combinar as respostas em uma única carga útil.

O dispositivo ou módulo deve confirmar que recebeu as propriedades enviando propriedades relatadas:

DTDL que faz referência a um componente:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:com:example:TemperatureController;1",
  "@type": "Interface",
  "displayName": "Temperature Controller",
  "contents": [
    {
      "@type" : "Component",
      "schema": "dtmi:com:example:Thermostat;1",
      "name": "thermostat1"
    }
  ]
}

DTDL que define o componente:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:com:example:Thermostat;1",
  "@type": "Interface",
  "contents": [
    {
      "@type": "Property",
      "name": "targetTemperature",
      "schema": "double",
      "writable": true
    }
  ]
}

Amostra de carga útil da propriedade desejada:

"desired": {
  "thermostat1": {
    "__t": "c",
    "targetTemperature": 21.3,
    "targetHumidity": 80,
    "$version" : 3
  }
}

Amostra de primeira carga útil da propriedade relatada:

"reported": {
  "thermostat1": {
    "__t": "c",
    "targetTemperature": {
      "value": 23,
      "ac": 200,
      "av": 3,
      "ad": "complete"
    }
  }
}

Exemplo de segunda carga útil da propriedade relatada:

"reported": {
  "thermostat1": {
    "__t": "c",
    "targetHumidity": {
      "value": 80,
      "ac": 200,
      "av": 3,
      "ad": "complete"
    }
  }
}

Nota

Você pode optar por combinar essas duas cargas úteis de propriedade relatadas em uma única carga útil.

Para obter mais exemplos de propriedades graváveis, consulte Propriedades de > cargas úteis.

Comandos

Nenhuma interface de componente usa o nome do comando sem um prefixo.

Em um dispositivo ou módulo, várias interfaces de componentes usam nomes de comando com o seguinte formato: componentName*commandName.

Para obter mais exemplos de comandos, consulte Comandos de > cargas úteis.

Gorjeta

O IoT Central tem suas próprias convenções para implementar comandos de longa execução e comandos offline.

Próximos passos

Agora que você aprendeu sobre as convenções IoT Plug and Play, aqui estão alguns outros recursos: