Соглашения IoT Plug and Play
Когда устройства IoT Plug and Play обмениваются сообщениями с центром Интернета вещей, к ним применимы требования набора соглашений. Устройства IoT Plug and Play используют протокол MQTT для обмена данными с Центром Интернета вещей. Центр Интернета вещей также поддерживает протокол AMQP, доступный в некоторых пакетах SDK для устройств Интернета вещей.
Устройство может включать модули или реализовываться в модуле IoT Edge, размещенном в среде выполнения IoT Edge.
Вы описываете данные телеметрии, свойства и команды, которые устройство IoT самонастраивающийся реализует с помощью модели языка определения цифровых двойников (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
}
}
Дополнительные примеры свойств только для чтения см. в разделе "Свойства полезных > данных".
Свойства, доступные для записи
Серверное приложение задает записываемое свойство, которое Центр Интернета вещей затем отправляется на устройство.
Устройство или модуль должны подтвердить, что они получили свойство, отправив передаваемое свойство. Передаваемое свойство должно включать в себя:
value
— фактическое значение свойства (обычно полученное значение, однако устройство может передать другое значение).ac
— код подтверждения, использующий код состояния HTTP.av
— версия подтверждения, относящаяся к$version
требуемого свойства. Это значение можно найти в полезных данных JSON требуемого свойства.ad
— необязательное описание подтверждения.
Ответы на подтверждение
При составлении отчетов о свойствах, доступных для записи, устройство должно создать сообщение подтверждения с помощью четырех полей в предыдущем списке, чтобы указать фактическое состояние устройства, как описано в следующей таблице:
Status(ac) | Version(av) | Value(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 имеет собственные соглашения для реализации длительных команд и автономных команд.
Следующие шаги
Теперь, когда вы узнали о соглашениях самонастраивающийся Интернета вещей, вот некоторые другие ресурсы: