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

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

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

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

  • Нет компонентов — модель без компонентов. Модель объявляет данные телеметрии, свойства и команды в качестве элементов верхнего уровня в разделе содержимого главного интерфейса. В Обозревателе Интернета вещей 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 V2.

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) Версия(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 V2.

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 Plug and Play, ознакомьтесь с другими ресурсами: