Соглашения IoT Plug and Play

Устройства IoT Plug and Play должны следовать набору соглашений, когда обмениваются сообщениями с IoT-хабом. Устройства IoT Plug and Play используют протокол MQTT для обмена данными с Центром Интернета вещей. Центр Интернета вещей также поддерживает протокол AMQP, доступный в некоторых пакетах SDK для устройств Интернета вещей.

Устройство может включать модули или реализовываться в модуле IoT Edge, размещенном в среде выполнения IoT Edge.

Вы описываете телеметрию, свойства и команды, которые реализует устройство IoT Plug and Play с помощью модели на языке определения цифровых двойников (DTDL). В этой статье рассматриваются два типа моделей:

  • Нет компонентов — модель без компонентов. Модель объявляет данные телеметрии, свойства и команды в качестве элементов верхнего уровня в разделе содержимого основного интерфейса. В Обозревателе Интернета вещей Azure эта модель отображается как отдельный компонент по умолчанию.
  • Несколько компонентов — модель, состоящая из двух или более интерфейсов. Основной интерфейс, который отображается как компонент по умолчанию с данными телеметрии, свойствами и командами. Один или несколько интерфейсов, объявленных как компоненты с дополнительными данными телеметрии, свойствами и командами.

Дополнительные сведения см. в статье Руководство по созданию моделей IoT Plug and Play.

Определение модели

Чтобы объявить реализуемую модель, устройство или модуль IoT Plug and Play вносит идентификатор модели в пакет подключения MQTT, добавляя model-id в поле USERNAME.

Для идентификации модели, реализуемой устройством или модулем, служба может получить идентификатор модели из:

  • Поле двойника устройства modelId.
  • Поле цифрового двойника $metadata.$model.
  • Уведомление об изменении цифрового двойника.

Телеметрия

  • Данные телеметрии, отправляемые с устройства без компонента, не нуждаются в дополнительных метаданных. Система добавляет свойство dt-dataschema.
  • Данные телеметрии, отправленные с устройства с помощью компонентов, должны добавить имя компонента в сообщение телеметрии.
  • При использовании MQTT добавьте $.sub свойство с именем компонента в тему телеметрии, система добавляет dt-subject свойство.
  • При использовании AMQP добавьте свойство dt-subject с именем компонента в аннотации сообщения.

Замечание

Для телеметрии из компонентов требуется одно сообщение для каждого компонента.

Дополнительные примеры телеметрии см. в разделе "Пейлоады > телеметрии"

Свойства только для чтения

Устройство задает свойство только для чтения, которое затем сообщает внутреннему приложению.

Образец свойства без компонента, доступного только для чтения

Устройство или модуль может отправлять любой допустимый json, который соответствует правилам DTDL.

DTDL, определяющий свойство в интерфейсе:

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

Пример полезных данных передаваемого свойства:

"reported" :
{
  "temperature" : 21.3
}

Пример свойства нескольких компонентов только для чтения

Устройство или модуль должны добавить маркер {"__t": "c"}, чтобы указать, что элемент ссылается на компонент.

DTDL, ссылающийся на компонент:

{
  "@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, определяющий компонент:

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

Пример полезных данных передаваемого свойства:

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

Для дополнительных примеров свойств только для чтения см. Свойства загрузки >.

Свойства, доступные для записи

Серверное приложение устанавливает параметр записи, который IoT Hub затем отправляет на устройство.

Устройство или модуль должны подтвердить, что они получили свойство, отправив сообщаемое свойство. Передаваемое свойство должно включать в себя:

  • value — фактическое значение свойства (обычно полученное значение, однако устройство может передать другое значение).
  • ac — код подтверждения, использующий код состояния HTTP.
  • av — версия подтверждения, относящаяся к $version требуемого свойства. Это значение можно найти в JSON-структуре заданного свойства.
  • ad — необязательное описание подтверждения.

Ответы на подтверждение

При составлении отчетов о свойствах, доступных для записи, устройство должно создать сообщение подтверждения с помощью четырех полей в предыдущем списке, чтобы указать фактическое состояние устройства, как описано в следующей таблице:

Status(ac) Версия(av) Значение(value) Описание (av)
200 Требуемая версия Требуемое значение Принятое значение требуемого свойства
202 Требуемая версия Значение, принятое устройством Принятое значение требуемого свойства, обновление выполняется (должно завершиться с 200)
203 0 Значение, заданное устройством Набор параметров с устройства, не соответствующий требуемым значениям.
400 Требуемая версия Фактическое значение, используемое устройством Значение требуемого свойства не принято
500 Требуемая версия Фактическое значение, используемое устройством Исключение при применении свойства

Когда устройство запускается, оно должно запросить двойника этого устройства и проверить наличие обновлений свойств, доступных для записи. Если версия свойства, доступного для записи, увеличилась, когда устройство находилось в автономном режиме, устройство должно отправить ответ о передаваемом свойстве, чтобы подтвердить, что обновление получено.

При первом запуске устройства он может отправить начальное значение для сообщаемого свойства, если оно не получает исходное требуемое свойство из Центра Интернета вещей. В этом случае устройство может отправлять значение по умолчанию из av в 0 и из ac в 203. Рассмотрим пример.

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

Устройство может использовать сообщаемое свойство для предоставления других сведений концентратору. Например, устройство может отвечать серией сообщений о ходе выполнения, таких как:

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

Когда устройство достигает целевой температуры, оно отправляет следующее сообщение:

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

Устройство может сообщить об ошибке, например:

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

Тип объекта

Если записываемое свойство определяется как объект, служба должна отправить полный объект на устройство. Устройство должно подтвердить обновление, отправив в службу достаточную информацию, чтобы понять, как устройство действовало в обновлении. Этот ответ может включать:

  • Весь объект.
  • Только поля, обновленные устройством.
  • Подмножество полей.

Для больших объектов рекомендуется свести к минимуму размер объекта, который вы включаете в подтверждение.

В следующем примере показано свойство, доступное для записи, определенное как Object с четырьмя полями.

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
}

Чтобы обновить это записываемое свойство, отправьте полный объект из службы, который выглядит следующим образом:

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

Устройство отвечает с подтверждением, которое выглядит следующим образом:

{
  "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
    }
  }
}

Пример отсутствия записываемого свойства компонента

Когда устройство получает сразу несколько необходимых свойств в одной полезной нагрузке, оно может отправлять ответы о свойствах по нескольким полезным нагрузкам или объединять их в одну полезную нагрузку.

Устройство или модуль может отправлять любой допустимый json, который соответствует правилам 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
    }
  ]
}

Пример содержимого желаемого свойства:

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

Пример первой полезной нагрузки свойства:

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

Пример второй полезной нагрузки сообщенного свойства:

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

Замечание

Вы можете объединить эти два набора данных свойств в один набор данных.

Пример многокомпонентного записываемого свойства

Устройство или модуль должны добавить маркер {"__t": "c"}, чтобы указать, что элемент ссылается на компонент.

Маркер отправляется только для обновлений свойств, определенных в компоненте. Обновления свойств, определенных в компоненте по умолчанию, не включают маркер, см. пример компонента без свойства только для записи.

Когда устройство получает несколько сообщаемых свойств в одной полезной нагрузке, оно может отправлять ответы на сообщаемые свойства в нескольких полезных нагрузках или объединять ответы в одну полезную нагрузку.

Устройство или модуль должны подтвердить, что они получили свойства, отправив передаваемые свойства:

DTDL, ссылающийся на компонент:

{
  "@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, определяющий компонент:

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

Пример содержимого желаемого свойства:

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

Пример первой полезной нагрузки свойства:

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

Пример второй полезной нагрузки сообщенного свойства:

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

Замечание

Вы можете объединить эти два набора данных свойств в один набор данных.

Для дополнительных примеров свойств, доступных для записи, см. раздел Свойства нагрузки.

Команды

Ни один из интерфейсов компонентов не использует имя команды без префикса.

На устройстве или модуле в интерфейсах с несколькими компонентами имена команд используются в следующем формате: componentName*commandName.

Дополнительные примеры команд см. в разделе Команды полезной нагрузки .

Подсказка

IoT Central имеет собственные соглашения для реализации команд длительного выполнения и оффлайн-команд.

Дальнейшие действия

Теперь, когда вы узнали о соглашениях Plug and Play для Интернета вещей, вот некоторые другие ресурсы: