Convenções do IoT Plug and Play

Os dispositivos de 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 comunicarem com o Hub IoT. O Hub IoT também oferece suporte ao protocolo AMQP, disponível em alguns SDKs de dispositivos IoT.

Um dispositivo pode incluir os módulosou ser implementado em um módulo IoT Edge hospedado pelo runtime 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). Há dois Microsoft SQL Server System CLR Types de modelo mencionados neste artigo:

  • Nenhum componente-Um modelo sem componentes. O modelo declara um evento de telemetria, propriedades e comandos como elementos de nível superior na seção de conteúdos da interface principal. Na ferramenta de Internet das Coisas do Azure, esse modelo aparece como um únicocomponente padrão.
  • Vários componentes–Um modelo composto por duas ou mais interfaces. Uma interface principal, aparece como ocomponente padrão, com telemetria, propriedades e comandos. Uma ou mais interfaces fornecidas assim como os componentes com mais telemetria, propriedades e comandos.

Para obter mais informações, confira oGuia de modelagem do IoT Plug and Play.

Identificar o modelo

Para divulgar o modelo que ele implementa, um dispositivo ou módulo do IoT Plug and Play inclui a ID do modelo no pacote de conexão MQTT adicionandomodel-id aoUSERNAME campo.

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

  • Obter o campo do dispositivomodelIdgêmeo.
  • O campo gêmeo$metadata.$model digital.
  • Notificações de alteração do gêmeo digital.

Telemetria

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

Observação

A telemetria dos componentes requer uma mensagem por componente.

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

Propriedades somente leitura

Um dispositivo define uma propriedade somente leitura que ele relata ao aplicativo back-end.

O exemplo de somente leitura da propriedade do 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"
    }
  ]
}

Exemplo do payload da propriedade relatada:

"reported" :
{
  "temperature" : 21.3
}

Exemplo da propriedade de diversos componentes somente leitura

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

DTDL que referencia 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 fixa o componente:

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

Exemplo do payload da propriedade relatada:

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

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

As propriedades graváveis

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

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

  • value-o valor efetivo da propriedade (normalmente o valor recebido, mas o dispositivo pode decidir o relatório de um valor diferente).
  • ac-um código de confirmação que usa um código de estado HTTP.
  • av-uma versão da confirmação que se refere à$versionpropriedade desejada. Você pode encontrar este valor no payload JSON da propriedade desejada.
  • ad-uma descrição de confirmação opcional.

Respostas de confirmação

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:

Status(ac) Version(av) Value(value) Description(av)
200 Versão desejada Valor desejado Valor desejado da propriedade aceito
202 Versão desejada Valor aceito pelo dispositivo Valor desejado da propriedade aceito, atualização em andamento (deve terminar com 200)
203 0 Valor definido pelo dispositivo Conjunto de propriedades do dispositivo, sem refletir nenhuma propriedade desejada
400 Versão desejada Valor real usado pelo dispositivo Valor desejado da propriedade não aceito
500 Versão desejada Valor real usado pelo dispositivo Exceção ao aplicar a propriedade

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

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

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

Um dispositivo pode usar a propriedade reportada para fornecer outras informações ao Hub. Por exemplo, o dispositivo pode responder com uma série de mensagens em andamento,tal 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 reportar um erro como:

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

Tipo de objeto

Se uma propriedade gravável é definida como um objeto, o serviço deve enviar um objeto completo para o dispositivo. O dispositivo deve reconhecer a atualização enviando informações suficientes de volta ao serviço para que o serviço entenda como o dispositivo foi acionado na atualização. Essa resposta pode incluir:

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

Se os objetos forem grandes, considere diminuir o tamanho do objeto incluído na confirmação.

O exemplo a seguir mostra uma propriedade gravável definida como um 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 da propriedade do componente não gravável

Quando um dispositivo recebe várias propriedades desejadas em apenas um payload, ele pode enviar as respostas de propriedade relatada a várias cargas ou combinar as respostas em apenas uma carga.

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 do payload da propriedade desejada:

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

Exemplo do payload da propriedade relatada:

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

Exemplo do segundo payload da propriedade relatada:

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

Observação

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

Exemplo da propriedade gravável de vários componentes

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

O marcador é enviado somente para atualizações das propriedades definidas em um componente. As atualizações das propriedades definidas no componente padrão não incluem o marcador, confira aAmostra da propriedade do componente sem gravação.

Quando um dispositivo recebe diversas propriedades relatadas em um único payload, ele pode enviar as respostas de propriedade relatadas entre vários payloads ou combinar as respostas em um único payload.

O dispositivo ou módulo deve confirmar que recebeu a propriedade enviada pela propriedade relatada:

DTDL que referencia 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 fixa 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 do payload da propriedade desejada:

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

Exemplo do payload da propriedade relatada:

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

Exemplo do segundo payload da propriedade relatada:

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

Observação

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

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

Comandos

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

Em um dispositivo ou módulo,com diversas interfaces do componente usam nomes de comando com o seguinte formato:componentName*commandName.

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

Dica

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

Próximas etapas

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