Поделиться через


Регистрация компонентов помощью Обновления устройств

В этой статье показан пример реализации перечислителя компонентов к Обновлению устройств для Центра Интернета вещей. Вы можете использовать этот пример, чтобы реализовать пользовательский перечислитель компонентов для своих устройств Интернета вещей. Компонент — это удостоверение под уровнем устройства, которое имеет отношение композиции с устройством узла.

В этой статье демонстрируется перечислитель компонентов с помощью виртуального устройства Интернета вещей под названием Contoso Virtual Vacuum. Перечислители компонентов используются для реализации возможности обновления прокси-сервера.

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

Ниже перечислены некоторые варианты использования, в которых применимы обновления прокси-сервера:

  • Нацеливание конкретных файлов обновлений на разделы на устройстве.
  • Нацеливание конкретных файлов обновлений на приложения или компоненты на устройстве.
  • Нацеливание конкретных файлов обновлений на датчики, подключенные к устройствам IoT через сетевой протокол (например, USB или шина CAN).

Дополнительные сведения см. в статье Обновления прокси-сервера и многокомпонентное обновление.

Агент Обновления устройств запускается на устройстве узла. Он может отправить каждое обновление конкретному компоненту или группе компонентов одного класса оборудования (т. е. тех, которым требуется одинаковое обновление программного обеспечения или встроенного ПО).

Что такое перечислитель компонентов?

Перечислитель компонентов — это расширение агента Обновления устройств, которое предоставляет сведения обо всех компонентах, необходимых для обновления по беспроводной связи через подключение Центра Интернета вещей Azure устройства.

Агент Обновления устройств не зависит от устройств и компонентов. Сам агент на момент обновления ничего не знает о компонентах, находящихся на устройстве узла (или подключенных к нему).

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

Схема: поток обновления прокси-сервера.

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

  • Построитель устройств

    • Проектирование и создание устройства.

    • Интеграция агента Обновления устройств и его зависимостей.

    • Реализация расширения перечислителя компонентов для конкретного устройства и регистрация в агенте Обновления устройств.

      Перечислитель компонентов использует сведения из инвентаризации компонентов или файла конфигурации для дополнения статических данных о компонентах (требуется Обновление устройств) динамическими (такими как версия встроенного ПО, состояние подключения и удостоверение оборудования).

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

    • Отправка обновления оператору решений.

  • Оператор решений

    • Импорт обновления и манифеста в службу Обновления устройств.

    • Развертывание обновления для группы устройств.

  • Агент Обновления устройств

    • Получение сведений об обновлении из Центра Интернета вещей Azure через двойник устройства или модуля.

    • Вызов обработчика шагов для обработки обновления прокси-сервера, предназначенного для одного или нескольких компонентов на устройстве.

      Пример в этой статье содержит два обновления: host-fw-1.1 и motors-fw-1.1. Для каждого дочернего обновления родительский обработчик шагов вызывает дочерний обработчик шагов, чтобы перечислить все компоненты, которые соответствуют свойствам Compatibilities, указанным в файле манифеста дочернего обновления. Затем обработчик скачивает, устанавливает и применяет дочернее обновление для всех целевых компонентов.

      Чтобы получить соответствующие компоненты, дочернее обновление вызывает API SelectComponents, предоставляемый перечислителем компонентов. Если соответствующие компоненты отсутствуют, дочернее обновление пропускается.

    • Сбор всех результатов обновления из родительского и дочернего обновлений и их передача в Центр Интернета вещей.

  • Дочерний обработчик шагов

    • Выполнение итерации по списку экземпляров компонента, совместимых с содержимым дочернего обновления. Дополнительные сведения см. в разделе Обработчик шагов.

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

Компоненты Virtual Vacuum

В этой статье мы используем виртуальное устройство Интернета вещей для демонстрации основных понятий и возможностей. Устройство Virtual Vacuum состоит из пяти логических компонентов:

  • Встроенное ПО узла
  • Файловая система загрузки узла
  • Корневая файловая система узла
  • Три двигателя (левое колесо, правое колесо и создание вакуума)
  • Две камеры (передняя и задняя)

Схема: компоненты Contoso Virtual Vacuum.

Следующая структура каталогов имитирует компоненты:

/usr/local/contoso-devices/vacuum-1/hostfw
/usr/local/contoso-devices/vacuum-1/bootfs
/usr/local/contoso-devices/vacuum-1/rootfs
/usr/local/contoso-devices/vacuum-1/motors/0   /* left motor */
/usr/local/contoso-devices/vacuum-1/motors/1   /* right motor */
/usr/local/contoso-devices/vacuum-1/motors/2   /* vacuum motor */
/usr/local/contoso-devices/vacuum-1/cameras/0  /* front camera */
/usr/local/contoso-devices/vacuum-1/cameras/1  /* rear camera */

Каталог каждого компонента содержит JSON-файл, в котором хранится номер версии программного обеспечения макета для каждого компонента. Примерами файлов JSON являются firmware.json и diskimage.json.

В этой демонстрации для обновления встроенного ПО компонентов мы скопируем firmware.json или diskimage.json (полезные данные обновления) в каталог целевых компонентов.

Ниже приведен пример файла firmware.json:

{
    "version": "0.5",
    "description": "This component is generated for testing purposes."
}

Примечание

Устройство Contoso Virtual Vacuum содержит версии программного обеспечения или встроенного ПО для демонстрации обновления прокси-сервера. Никаких других функциональных возможностей оно не предоставляет.

Реализация перечислителя компонентов (язык С)

Требования

Реализуйте все API, объявленные в component_enumerator_extension.hpp:

Функция Аргументы Возвращает
char* GetAllComponents() Нет Строка JSON, содержащая массив всех значений ComponentInfo. Дополнительные сведения см. в разделе Примеры возвращаемых значений.
char* SelectComponents(char* selector) Строка JSON, которая содержит одну или несколько пар "имя-значение", используемых для выбора целевых компонентов обновления. Строка JSON, содержащая массив значений ComponentInfo. Дополнительные сведения см. в разделе Примеры возвращаемых значений.
void FreeComponentsDataString(char* string) Указатель на буфер строки, ранее возвращенный функциями GetAllComponents или SelectComponents. Нет

ComponentInfo

Строка JSON ComponentInfo должна включать следующие свойства:

Имя Тип Описание
id строка Уникальное удостоверение компонента (область действия устройства). К примерам относятся серийный номер оборудования, идентификатор раздела диска и уникальный путь к файлу компонента.
name строка Логическое имя компонента. Это свойство является именем, которое построитель устройств назначает компоненту, доступному на каждом устройстве одного класса device.

Например, каждое устройство Contoso Virtual Vacuum содержит двигатель, управляющий левым колесом. Компания Contoso назначила значение left motor (левый двигатель) в качестве обычного (логического) имени для этого двигателя, чтобы упростить ссылку на данный компонент, вместо идентификатора оборудования, который может быть глобально уникальным.
group строка Группа, к которой принадлежит этот компонент.

Например, все двигатели могут относиться к группе motors (двигатели).
manufacturer строка Для физического аппаратного компонента это свойство является именем производителя или поставщика.

Для логического компонента, такого как раздел диска или каталог, может быть задано любое значение, определенное в построителе устройств.
model строка Для физического аппаратного компонента это свойство является именем модели.

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

Ниже приведен пример кода ComponentInfo на основе компонентов Contoso Virtual Vacuum:

{
    "id": "contoso-motor-serial-00000",
    "name": "left-motor",
    "group": "motors",
    "manufacturer": "contoso",
    "model": "virtual-motor",
    "properties": {
        "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/0",
        "firmwareDataFile": "firmware.json",
        "status": "connected",
        "version" : "motor-fw-1.0"
    }
}

Примеры возвращаемых значений

Ниже приведен документ JSON, возвращенный функцией GetAllComponents. Он основан на примере реализации перечислителя компонентов Contoso Virtual Vacuum.

{
    "components": [
        {
            "id": "hostfw",
            "name": "hostfw",
            "group": "firmware",
            "manufacturer": "contoso",
            "model": "virtual-firmware",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/hostfw",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "host-fw-1.0"
            }
        },
        {
            "id": "bootfs",
            "name": "bootfs",
            "group": "boot-image",
            "manufacturer": "contoso",
            "model": "virtual-disk",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/bootfs",
                "firmwareDataFile": "diskimage.json",
                "status": "ok",
                "version" : "boot-fs-1.0"
            }
        },
        {
            "id": "rootfs",
            "name": "rootfs",
            "group": "os-image",
            "manufacturer": "contoso",
            "model": "virtual-os",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/rootfs",
                "firmwareDataFile": "diskimage.json",
                "status": "ok",
                "version" : "root-fs-1.0"
            }
        },
        {
            "id": "contoso-motor-serial-00000",
            "name": "left-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/0",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "motor-fw-1.0"
            }
        },
        {
            "id": "contoso-motor-serial-00001",
            "name": "right-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/1",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "motor-fw-1.0"
            }
        },
        {
            "id": "contoso-motor-serial-00002",
            "name": "vacuum-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/2",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "motor-fw-1.0"
            }
        },
        {
            "id": "contoso-camera-serial-00000",
            "name": "front-camera",
            "group": "cameras",
            "manufacturer": "contoso",
            "model": "virtual-camera",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/camera\/0",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "camera-fw-1.0"
            }
        },
        {
            "id": "contoso-camera-serial-00001",
            "name": "rear-camera",
            "group": "cameras",
            "manufacturer": "contoso",
            "model": "virtual-camera",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/camera\/1",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "camera-fw-1.0"
            }
        }
    ]
}

Функция SelectComponents возвратила следующий документ JSON. Он основан на примере реализации перечислителя компонентов Contoso.

Ниже приведен входной параметр для выбора группы компонентов motors:

{
    "group" : "motors"
}

Ниже приведены выходные данные параметра. Все компоненты относятся к группе motors.

{
    "components": [
        {
            "id": "contoso-motor-serial-00000",
            "name": "left-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/0",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "motor-fw-1.0"
            }
        },
        {
            "id": "contoso-motor-serial-00001",
            "name": "right-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/1",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "motor-fw-1.0"
            }
        },
        {
            "id": "contoso-motor-serial-00002",
            "name": "vacuum-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/2",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "motor-fw-1.0"
            }
        }
    ]
}

Ниже приведен входной параметр для выбора одного компонента с именем hostfw:

{
    "name" : "hostfw"
}

Ниже приведены выходные данные параметра для компонента hostfw:

{
    "components": [
        {
            "id": "hostfw",
            "name": "hostfw",
            "group": "firmware",
            "manufacturer": "contoso",
            "model": "virtual-firmware",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/hostfw",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "host-fw-1.0"
            }
        }
    ]
}

Примечание

В предыдущем примере было продемонстрировано, что при необходимости можно отправить более новое обновление в любой экземпляр компонента, который выбран свойством name. Например, можно развернуть обновление motor-fw-2.0 в vacuum-motor, продолжая использовать motor-fw-1.0 в left-motor и right-motor.

Файл инвентаризации

Приведенный ранее пример реализации для перечислителя компонентов Contoso Virtual Vacuum считает сведения о компонентах, относящихся к конкретному устройству, из файла component-inventory.json. Этот пример реализации предназначен только для демонстрации.

В рабочем сценарии некоторые свойства следует получить непосредственно из фактических компонентов. Эти свойства включают в себя id, manufacturer и model.

Построитель устройств определяет свойства name и group. Эти значения не должны изменяться после их определения. Свойство name должно быть уникальным в пределах устройства.

Пример файла component-inventory.json

Примечание

Содержимое этого файла выглядит почти так же, как и возвращенное значение из функции GetAllComponents. Однако ComponentInfo в этом файле не содержит свойства version и status. Перечислитель компонентов заполнит эти свойства во время выполнения.

Например, для hostfw значение свойства properties.version будет заполнено из указанного (макетного) значения firmwareDataFile (/usr/local/contoso-devices/vacuum-1/hostfw/firmware.json).

{
    "components": [
        {
            "id": "hostfw",
            "name": "hostfw",
            "group": "firmware",
            "manufacturer": "contoso",
            "model": "virtual-firmware",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/hostfw",
                "firmwareDataFile": "firmware.json",
            }
        },
        {
            "id": "bootfs",
            "name": "bootfs",
            "group": "boot-image",
            "manufacturer": "contoso",
            "model": "virtual-disk",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/bootfs",
                "firmwareDataFile": "diskimage.json",
            }
        },
        {
            "id": "rootfs",
            "name": "rootfs",
            "group": "os-image",
            "manufacturer": "contoso",
            "model": "virtual-os",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/rootfs",
                "firmwareDataFile": "diskimage.json",
            }
        },
        {
            "id": "contoso-motor-serial-00000",
            "name": "left-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/0",
                "firmwareDataFile": "firmware.json",
            }
        },
        {
            "id": "contoso-motor-serial-00001",
            "name": "right-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/1",
                "firmwareDataFile": "firmware.json",
            }
        },
        {
            "id": "contoso-motor-serial-00002",
            "name": "vacuum-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/2",
                "firmwareDataFile": "firmware.json",
            }
        },
        {
            "id": "contoso-camera-serial-00000",
            "name": "front-camera",
            "group": "cameras",
            "manufacturer": "contoso",
            "model": "virtual-camera",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/camera\/0",
                "firmwareDataFile": "firmware.json",
            }
        },
        {
            "id": "contoso-camera-serial-00001",
            "name": "rear-camera",
            "group": "cameras",
            "manufacturer": "contoso",
            "model": "virtual-camera",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/camera\/1",
                "firmwareDataFile": "firmware.json",
            }
        }
    ]
}

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

В примере этой статьи используется язык C. Чтобы изучить примеры исходных кодов языка C++, ознакомьтесь со следующими статьями:

Различные примеры обновлений для компонентов, подключенных к устройству Contoso Virtual Vacuum, см. в разделе Демонстрация обновления прокси-сервера.