Протокол
Протокол общения агента с платформой состоит из следующего набора действий:
- получение конфигурации агентом из платформы;
- отправка агентом данных от устройств на платформу;
- выполнение полученных агентом команд из платформы;
- отправка агентом логов в платформу.
Конфигурация агента имеет уникальную версию, которая монотонно возрастает при изменении метаинформации агента, либо одного из подключенных к нему устройств.
При первом запуске агент автоматически получает последнюю версию конфигурации из шлюза платформы. В дальнейшем обновление конфигурации агента активируется с помощью команды.
Пример команды:
agent_tag/$state/$config/$version = new_version
После получения и применения конфигурации, агент рапортует в платформу текущую версию конфигурации и время обновления в специальные системные подтэги типа state $state/$config/$version $state/$config/$updated_at
.
На основе разницы между версией конфигурации агента в метаинформации и версией, которую рапортует агент, платформа и пользователь могут понять, находится ли на агенте последняя конфигурация или требуется отправка команды на обновление.
Агент отправляет данные на платформу:
- Маппинг показаний устройств на соответствующие тэги типа
event
иstate
. - Свой статус, а также о статусе всех подключенных устройств в тэги
$state/$status
.
Если связь с платформой оборвалась, агент буферизирует получаемые данные для отправки на платформу после восстановления связи.
Агент должен поддерживать получение команд из платформы.
Команда может быть адресована:
- агенту;
- устройству подключенному к агенту.
Адресат команды вычисляется по переданным в команде тэгам, в чьем поддереве тэгов находятся переданные тэги. Одна команда может быть адресована только одному агенту или устройству.
Команда может содержать произвольный набор новых значений для любых тэгов типа state
с полем
properties.readonly = false
из поддерева тэгов целевого агента/устройства.
Есть два вида статусов команды:
- Платформенные:
new
— команда была только что создана в Digital Twins.sending
— команда была взята в работу в Peons.sent
— команда была отправлена на передачу агенту в HTTP Gateway или MQTT Gateway.failed
— отправка команды по каким-то причинам не удалась. Подробности в полеreason
.
- Статусы, которые обязан рапортовать агент:
received
— команда была получена агентом.done
— команда успешно завершена.skipped
— команда была по каким то причинам пропущена агентом. Например, при получении сразу нескольких команд на обновление конфигурации агент может выполнить только последнюю команду, а остальные перевести вskipped
, заполнив полеreason
).failed
— агенту не удалось выполнить команду, подробные причины должны быть указаны в поле reason.
По результатам выполнения команды агент должен отчитаться о статусе команды в платформу через специальное API, послав статус команды done
или failed
с описанием возникшей ошибки в поле reason
.
Этот протокол описывает лишь транспорт для передачи команд от платформы к агенту, реализация выполнения этих команд остается на усмотрение агента.
Протокол поддерживает отправку агентом произвольных логов в виде произвольной строки. При этом платформа может ограничивать количество принимаемых логов с агента в единицу времени.
Логи могут содержать информацию о функционировании:
- агента;
- подключенных устройств.
Полученные логи доступны для просмотра на странице «Логирование» в административной консоли платформы.
Протокол агента может работать как только поверх HTTP(S), так и поверх связки HTTP(S) + MQTT.
Логин агента формируется по шаблону { client_id }_{ agent_id }
.
Пароль берется из поля token агента.
HTTP API расположено здесь.
Для авторизации агента в HTTP API используется Basic authentication. При подключении к платформе только по протоколу HTTP(S) платформа не может напрямую пересылать команды агенту, поэтому агент обязан периодически опрашивать апи платформы для получения команд на выполнение.
Данное описание может быть неполным/неточным, для просмотра актуальной спецификации API перейдите по ссылке.
GET /v1/agents/config
— эндпоинт для получения конфигурации, вызывается с параметром version=latest при бутстрапе агента для получения начальной конфигурации, а также с указанной в команде версией для обновления конфигурации по пришедшей команде.POST /v1/events
— эндопоинт для отправки данных в платформу, принимает массив значений видаtag_id=value
.POST /v1/logs
— эндпоинт для отправки логов в платформу, принимает массив значений видаtimestamp=timestam_with_microsends
,msg=string
.GET /v1/commands
— эндпоинт для получения команд на выполнение. Данный эндпоинт необходимо периодически вызывать для получения новых команд на выполнение. Данный эндопоинт будет всегда возвращать список всех активных команд.PATCH /v1/agents/{ agent_id }/commands/{command_id}/status
— эндпоинт для перевода взятой команды агента в конечный статус, принимает объект видаstatus=received/done/failed/skipped, reason=optional_string_mesage_for_failed_or_skipped_status
.PATCH /v1/devices/{ device_id }/commands/{command_id}/status
- эндпоинт для перевода взятой команды устройства в конечный статус, принимает объект видаstatus=received/done/failed/skipped, reason=optional_string_mesage_for_failed_or_skipped_status
.GET /v1/devices/{device_id}/config/{version}
— эндпоинт для получения конфигурации, которую необходимо физически применить на подключенное устройство в рамках выполнения команды.
При подключении агента к платформе через связку протоколов HTTP(S) + MQTT платформа может напрямую коммуницировать с агентом и отправлять ему команды без необходимости постоянного опроса http api.
В протоколе на базе MQTT отсутствует поддержка следующих операций:
GET /v1/agents/config
GET /v1/devices/{device_id}/config/{version}
Агент должен отправлять данные в топик iot/event/fmt/json
с QOS=1 в следующем формате:
1{ 2 "tags": [ 3 { 4 "id": ..., // id конечного тэга, который представляет собой датчик 5 "value": ..., // значение 6 "timestamp": ... // timestamp in microseconds 7 }, 8 ... 9 ] 10}
Например, чтобы послать сообщение для тэга с id=10 со значением '100', необходимо опубликовать сообщение:
1{ 2 "tags": [ 3 { 4 "id": 10, 5 "value": 100, 6 "timestamp": 1 7 } 8 ] 9 }
Для получения команд от платформы агент должен быть подписан на топик вида iot/cmd/agent/+/fmt/json
, вместо одноуровневого wildcard
. А еще должен стоять уникальный id клиента. Сообщение с командами публикуется с флагом retain=1
, что позволяет клиенту гарантированно получить последнее сообщение с командами. Например, чтобы подписаться на команды для агента с id=1, необходимо подписаться на топик iot/cmd/agent/1/fmt/json
.
В сообщении всегда собраны все активные команды для агента.
Команды имеют следующий формат:
1{ 2 "command": { 3 "id": "...", // command id 4 "tags": [ 5 { 6 "id": ..., // tag to change 7 "value": ... // new tag value 8 }, 9 ... 10 ], 11 "timestamp": ... // timestamp in microseconds 12 }, // active command for agent if any 13 "devices": [ 14 { 15 "device_id": 1, 16 "command": { 17 "id": "...", // command id 18 "tags": [ 19 { 20 "id": ..., // tag to change 21 "value": ... // new tag value 22 }, 23 ... 24 ], 25 "timestamp": ... // timestamp in microseconds 26 } 27 } 28 ] // active commands for devices if any 29 }
Агент должен сообщать статус своей команды в отдельный топик вида iot/cmd/agent/+/status/fmt/json
с QOS=1 сообщениями вида:
1{ 2 "id": "...", // command id 3 "status": "...", // skipped | received | failed | done 4 "reason": "...", // optional field for failed status 5 "timestamp": ... // timestamp in microseconds 6 } 7 8 9Агент должен сообщать статусы команд для устройств в отдельные топики вида `iot/cmd/device/+/status/fmt/json` с QOS=1 сообщениями вида: 10``` json 11 { 12 "id": "...", // command id 13 "status": "...", // skipped | received | failed | done 14 "reason": "...", // optional field for failed status 15 "timestamp": ... // timestamp in microseconds 16 }
Поддерживаемые статусы команд:
- received — команда получена агентом/устройством.
- failed — агент/устройство не смогли применить команду, дополнительно в поле
reason
должна быть указан причина. - done — агент/устройство успешно применили команду.
Для отправки произвольных логов в платформу агент должен использовать топик iot/log/fmt/json
с QOS=1 в формате:
1[ 2 { 3 "msg": "...", 4 "timestamp": ... // timestamp in microseconds 5 } 6]
Данная команда обязательна к реализации всеми агентами. Она всегда содержит набор значений для следующих тэгов агента:
$state/$config/$version
По получении этой команды агент обязан получить конфигурацию указанной в команде версии из соответствующего эндпоинта HTTP API.
По успешному выполнению команды агент обязан отправить в платформу новые значения для следующих тэгов агента:
$state/$config/$version
$state/$config/$updated_at
Эта команда необязательна к реализации агентом и может быть применена только к устройству, которое поддерживает конфигурирование агентом.
Признаком того, что устройство может быть сконфигурировано агентом, является флаг properties.readonly
выставленный в false
у тэга устройства $state/$config/$version
.
Команда всегда содержит набор значений для следующих тэгов устройства:
$state/$config/$version
По получении данной команды агент обязан получить конфигурацию для устройства указанной в команде версии из соответствующего эндпоинта HTTP API.
Реализация обновления конфигурации устройства полностью отдается на откуп агенту.
По успешному выполнению команды агент обязан отправить в платформу новые значения для следующих тэгов устройства:
$state/$config/$version
$state/$config/$updated_at
Данная команда необязательна к реализации агентом и может быть применена только к агенту, который поддерживает автоматическое обновление прошивки.
Признаком того, что агент может обновлять свою прошивку является флаг properties.readonly выставленный в false
у тэга агента $state/$firmware/$source
.
Данная команда всегда содержит набор значений для следующих тэгов агента:
$state/$firmware/$source
— источник, например, http url для скачивания новой прошивки.
Также команда может содержать следующие необязательные тэги:
$state/$firmware/$vendor
$state/$firmware/$version
Реализация обновления прошивки полностью отдается на откуп агенту.
По успешному выполнению команды агент обязан отправить в платформу новые значения для следующих тэгов агента:
$state/$firmware/$source
$state/$firmware/$updated_at
Еще агент может заполнить следующие тэги в зависимости от содержания команды/особенностей реализации:
$state/$firmware/$vendor
$state/$firmware/$version
Данная команда необязательна к реализации агентом и может быть применена только к устройству, которое поддерживает автоматическое обновление прошивки.
Признаком того, что агент может обновлять прошивку у устройства является флаг properties.readonly
, выставленный в false
у тэга устройства $state/$firmware/$source
.
Эта команда всегда содержит набор значений для следующих тэгов устройства:
$state/$firmware/$source
— источник, например, http url для загрузки новой прошивки.
Также команда может содержать следующие необязательные тэги:
$state/$firmware/$vendor
$state/$firmware/$version
Реализация обновления прошивки на устройстве полностью отдается на откуп агенту. По успешному выполнению команды агент обязан отправить в платформу новые значения для следующих тэгов устройства:
$state/$firmware/$source
$state/$firmware/$updated_at
Еще агент может заполнить следующие тэги устройства в зависимости от содержания команды/особенностей реализации:
$state/$firmware/$vendor
,$state/$firmware/$version
.