VEGA μclient
Параметры подключения по-умолчанию
MQTT клиент подключается с следующими параметрами:
- Сервер: vegaiot.com либо указанный сервер через http запрос
- Порт сервера: 1883
- MQTT Client-ID: Мак адрес без делителя ':' в маленьком регистре, пример: 50aa11bb22cc
Топики MQTT
У всех топиков есть префикс из установленного токена: Устройство будет общатся только через свой токен:
/{token}/{cmd}
Чтение запись указывается со стороны устройства:
- R - Устройство будет публиковать данные в данный топик, но не будет подписано на него
- W - Устройство подпишется на данный топик, но не публикует в него
- RW - Устройство подписывается и публикует в данный топик
- E - Устройство подписывается и публикует в данный топик, выполняем топик, указанное действие выполняется только если в данный топик публикуется название топика.
| Название | R/W/RW/E | Тип данных | описание |
|---|---|---|---|
| /reg | W | uint32_t | Регистрация устройства на сервере |
| /hub | RW | uint32_t | Поиск хаба по ID устройства |
| /user/devs | RW | base64 | Поиск устройств пользователя (читай авторизация) |
| /{token}/time | W | uint32_t | Сервер обновляет время на хабе и всех подключенных устройствах . Завершает регистрацию устройства |
| /{token}/lifetime | W | uint32_t | Максимальное время между отправкой статуса устройством. Указано в секундах |
| /{token}/info | R | uint32_t | Данные о подключенном хабе, отправляются после регистрации, отдает список подключенных устройств |
| /{token}/status | R | uint32_t | Текущее состояние устройства. Хранит число событий с момента регистрации |
| /{token}/ping | E | Простой запрос, что бы убедится, что девайс еще с нами,девайсы всегда возвращает "OK" | |
| /{token}/error | W | uint32_t | Номер ошибки сервера |
| /{token}/add | RW | uint32_t / base64 | Используется для сигнализации того, что данного терморегулятора нет в базе данных (нету сопоставленного пользователя) |
| см. <Описание топика ADD в хабе> | |||
| /{token}/server | W | char[128] | Меняет сервер, должно происходит во время после отправки сообщения /reg (SRV_DEREG состояние) |
| /{token}/fw/pkg | W | {uint16_t; base64} | Содержимое прошивки устройства (не моста) |
| /{token}/fw/udp | RW | base64 | Запускает обновление устройства, в ответ отдает текущее состояние (# отправляемого chunk-а) |
| /{token}/{instance-id}/{reg} | RW | uint32_t | Доступ к регистрам SPI. По умолчанию данное устройство имеет instance-id = reg[0] |
| /{token}/{instance-id}/serial | RE | uint32_t | Серийный номер устройства (фактически instance-id), копирует 0-ой регистр |
| /{token}/{instance-id}/type | RE | uint32_t | Тип устройства (фактически instance-id), копирует 15-ой регистр |
| /{token}/{instance-id}/version | E | char[128] | Версия устройства, максимальный размер строки: 128 байт |
| /{token}/{instance-id}/status | R | uint32_t | Статус устройтсва (какое количество событий произошло с момента регистрации) |
| /{token}/{instance-id}/read | RW | {uint32_t; uint8_t} | Чтение памяти устройства (расписание, итд), По умолчанию данное устройство имеет instance-id = reg[0] |
| /{token}/{instance-id}/write | RW | {uint32_t; base64} | Запись памяти устройства По умолчанию данное устройство имеет instance-id = reg[0] |
| /{token}/{instance-id}/reset | RW | uint32_t | Сброс устройства в состояние по-умолчанию (то же 31 бит, 8-го регистра) (0/1). |
| Для сброса необходимо опубликовать значение серийного номера | |||
| /{token}/{instance-id}/user/add | W | base64 | Топик устройства для добавления пользователей |
| /{token}/{instance-id}/user/remove | W | user-id | Топие для удаление пользователей. См. <Топики пользователей> |
| /{token}/{instance-id}/user/list | E | Получает список пользователй | |
| /{token}/{instance-id}/events/{reg} | RW | {uint32_t; uin32_t} | Используется для получения списка сохраненных событий с сервера / хаба. см. <Описание топика> |
Исключения из правила составляет топик ‘/hub’ и '/devs'.
Топик hub используется для поиска устройства без знания токена хаба, пример:
111222345 => /hub # Клиент отправляет серийный номер устройства на броке
/hub => aa:bb:cc:dd:ee:ff # Хаб который содержит данное устройство отвечает со своим токеном
Топик devs для получения всех устройств пользователя. Пример:
полный хеш user-id => /devs # Запрос на поиск
/devs => '/{token}/{instance-id}' # Каждое устройство отдает свой базовый топик
Регистрация на сервере
Регистрация на сервере выполняется в два шага.
- Устройство отправляет свой token (указаный при вызове ctrl) в топик /reg. По-умолчанию это MAC адрес устройства.
- Сервер должен отдать время epoch unixtime в милисекундах в топик /{token}/time (где {token} - токен указаный при вызове /ctrl)
- Хаб должен отдать info топик, с списком всех доступных устройств подключенных к хабу
- Каждое из устройств подключенное к хабу должно отдать свой тип (type), (раньше был 15-ый регистр)
- Каждое устройство должно отдать последние значения своих регистров
Все запросы к серверу выполняются с QOS=1 После регистрации клиент для синхронзизации с сервером отправляет данные в топики с нумерацие регистров, тем самым указывая какие регистры есть на устройстве
Пример регистрации:
| Устройство | Направление | Сервер | Описание |
|---|---|---|---|
| /reg (token) | -> | Регистрация на сервере, устройство отправляет свой токен в /reg топик | |
| <- | /{token}/time (unixtime in ms) | Сервер отдает unixtime в милисекундах | |
| /{token}/info | -> | Устройство отправляет данные о себе | |
| /{token}/{instance-id}/type | -> | Каждое устройство отдает свой тип | |
| /{token}/{instance-id}/{regs} | -> | Каждое устройство должно отдать последние значения своих регистров, которые не равны 0 |
Обновление регистрации
Если в подключенном хабе статус оказывается больше чем на сервере, это может указывать на пропущенные события со стороны сервера. И для поддержания всегда актуальных данных на сервере - серверу следует отправить error=3, для обновления значений регистров, и уравнение значений статуса. Если статус оказывается больше на сервере чем на устройстве - это может указывать на управление устройством сторонними средствами - и должно быть игнорировано.
Пример данных в топике info
{"mac":"aa:bb:cc:dd:ee:ff","version":"1", "type":"LTC..", "devices":[ 87455673 ]}"
Где:
- mac - MAC адрес хаба
- version - Версия прошивки хаба
- type - Тип хаба
devices - Список подключенных устройств к хабу
Смена брокера
Смена брокера должна происходить через топик /{token}/server только в самом начале регистрации. Если при нормальной регистрации, для завершения регистрации будет отправлено время на устройство, то в случае смены брокера - устройство должно получть в топик /{token}/server хост нового брокера. Пример:
| Топик | Значение | Описание |
|---|---|---|
| /reg | 12:34:56:aa:bb:cc | Устройство отправляет серверу свой токен |
| /12:34:56:aa:bb:cc/server | x.ks.ua | Сервер отдает устройству хост другого брокера |
Идентификатор пользователя (USER_ID)
ID пользователя вычисляется через sha256 хеш взятый от имени пользователя и пароля с разделителем '\0'. Далее в документе используется приведенный ID пользователя из примера
Пример:
- Пользователь: admin@admin.com
- Пароль: 11223344
- Итоговое слово для хеширования: admin@admin.com\011223344
- Итоговое слово в bin виде: 61646d696e4061646d696e2e636f6d003131323233333434
- ID пользователя, хеш: fb81c4cc20a3d5d1c700b89c4ebaecf786ea76c0518c7592119b6949f912d44e
- ID пользователя в base64: +4HEzCCj1dHHALicTrrs94bqdsBRjHWSEZtpSfkS1E4=
Подпись сообщения
Каждое передаваемое сообщение к устройству должно быть подписано хешом пользователя. Устройство будет обрабатывать сообщения без подписи только в случае отсутствия пользователей в памяти.
Подпись представляет из себя base64(hmac-sha256(msg, user-id)) отправляемых данных с используемым ключем - USER_ID При принятии сообщения - устройство восстанавливает USER_ID и выполняет команду согласно битам доступа пользователя
Формат сообщения с подписью:
| Данные | Разделитель | Подпись |
|---|---|---|
| 1103560704 | '.' | /xQfpY7TUQo+1QcNaJopuaXytCClf7HTKcDta9lKDNc= |
Пример использования:
| Действие | Топик | Данные |
|---|---|---|
| Запись 3-го регистра | /aa:bb:cc:dd:ee:ff/11223344/3 | 1103560704./xQfpY7TUQo+1QcNaJopuaXytCClf7HTKcDta9lKDNc= |
| Запись памяти | /aa:bb:cc:dd:ee:ff/11223344/write | 512;ggXLmX3EMFCVa5NTud4AL4L0R+ts3vC0JypOAhbOTYw=.NbTV9IEf1YQNebx7lrteRs8fr23NRsve/QcUVTo446g= |
Если в устройстве были добавлены пользователи, устройство будет подписывать свои сообщения подобным образом. Ключем подписи в таком случае станет add_hash (см. <Описание топика ADD в хабе>)
В дальнейшем по документу в примерах подписывание не используется
Топики пользователей. Добавление пользователя
Добавление пользователя возможно только с пользователя имеющим соответствующий доступ, либо с устройства в котором нет добавленных пользователей.
Сервер должен добавить пользователей при первом подключении устройства (если они есть).
Для добавления устройства используется топик /user/add. Данные передаваемые имеют биинарный формат и передаются в виде base64
| Смещение | Размер (байт) | Описание |
|---|---|---|
| 0 | 32 | Полный хеш USER-ID |
| 32 | 1 | Флаги пользователя (Биты доступа) |
| 33 | 1 | Размер текста с именем пользователя (e-mail) |
| 34 | * | Строка имени пользователя |
Максимальное количество пользователей: 32
По выполнению добавления будет возвращено текущее количество пользователей, если пользователь не добавлен будет возвращено значение 32.
Биты доступа:
| Бит | Название | Описание |
|---|---|---|
| 0 | rfu | - |
| 1 | write | Разрешает подписку устройством на топики пользователя (Пользователь может изменять значения устройства) |
| 2 | mem_read | Разрешает чтение памяти |
| 3 | mem_write | Разрешает запись памяти |
| 4 | fw | Разрешает топики обновления устройства |
| 5 | events | Пользователь может считывать список событий |
| 6 | users | Управление пользователями |
| 7 | root | Разрешает сброс устройства |
- После сброса устройства, список пользователь удаляется *
Пример:
Кодируемые данные:
- user-id: fb81c4cc20a3d5d1c700b89c4ebaecf786ea76c0518c7592119b6949f912d44e
- Биты доступа: ff
- Размер имени пользователя: 0f
- Имя пользователя: admin@admin.com => 61646d696e4061646d696e2e636f6d
Итоговые данные до конвертации в base64: fb81c4cc20a3d5d1c700b89c4ebaecf786ea76c0518c7592119b6949f912d44eff0f61646d696e4061646d696e2e636f6d
/aa:bb:cc:dd:ee:ff/11223344/user/add => +4HEzCCj1dHHALicTrrs94bqdsBRjHWSEZtpSfkS1E7/D2FkbWluQGFkbWluLmNvbQ== # Добавляет пользователя с admin@admin.com c доступом 0xff - Полный админский доступ
/aa:bb:cc:dd:ee:ff/11223344/user/add <= 1 # Устройство отвечает, что был добавлен первый пользователь
7369646966613832383640616c696364682e636f6d00646f76656d656e2b63617265 => sidifa8286@alicdh.com\dovemen+care
4f4037698637e72bef8c274e63c199861c76835f0c208f2d8bff573bf2f1bd1eff157369646966613832383640616c696364682e636f6d => hash(mail+pwd) + 0xff + 0x15 + sidifa8286@alicdh.com
T0A3aYY35yvvjCdOY8GZhhx2g18MII8ti/9XO/LxvR7/FXNpZGlmYTgyODZAYWxpY2RoLmNvbQ== => b64 of text above
[1615929511] /94:b8:6d:84:54:e9/2763606/user/add T0A3aYY35yvvjCdOY8GZhhx2g18MII8ti/9XO/LxvR7/FXNpZGlmYTgyODZAYWxpY2RoLmNvbQ==.zYHofxeY/YWMdwTOgqCcFD7HWD+o0RybHsuwhx4CnfM=
[1615929560] /94:b8:6d:84:54:e9/2763606/user/add 2
Топики пользователя. Удаление пользователя
Для удаления пользователя необходимо отправить полный хеш пользователя (user-id) в топик /user/remove
В случае ошибки удаления будет возвращенно "-1" Сам себя пользователь удалить не может. Удалить всех пользователей можно только через сброс к заводским настройкам
Пример:
/aa:bb:cc:dd:ee:ff/11223344/user/remove => +4HEzCCj1dHHALicTrrs94bqdsBRjHWSEZtpSfkS1E4= # Удаляет пользователя с admin@admin.com c доступом 0xfb
/aa:bb:cc:dd:ee:ff/11223344/user/remove <= 1 # Устройство отвечает, что был удален первый пользователь
[1615922047] /94:b8:6d:84:54:e9/2763606/user/remove FnpzN4lau3TrSnuWbm1YIMLTqqC43qwwgtOZjeFWx/0=./+ynIGJy8TtB5V6JqYwdIxHbC/MjKq0OG7tgUzZcLmM=
[1615922090] /94:b8:6d:84:54:e9/2763606/user/remove 1
Топики пользователя. Список пользователей
Список пользователей отдается в JSON формате. Для получения необходимо выполнить топик /user/list
Формат отдаваемых данных:
| Ключ | Тип данных | Описание |
|---|---|---|
| u | user-id | USERID пользователя (user) |
| p | uint8_t | Биты доступа (1 байтовый int) (permission) |
| n | string | Читаемое имя пользователя (name) |
Последний элемент обозначается пустым обьектом {}
Пример:
/aa:bb:cc:dd:ee:ff/11223344/user/list => list
/aa:bb:cc:dd:ee:ff/11223344/user/list <= {"u":"fb81c4cc20a3d5d1c700b89c4ebaecf786ea76c0518c7592119b6949f912d44e", "s":255, "n": "admin@admin.com"},
/aa:bb:cc:dd:ee:ff/11223344/user/list <= {"u":"0cad6119aa11e62c6a8eb1f0d9771a49e8968e769e09b80c4a04ac8a3cb6ceb5", "s": 42, "n": "intx82@gmail.com"}
/aa:bb:cc:dd:ee:ff/11223344/user/list <= {}
[1615908169] /94:b8:6d:84:54:e9/2763606/user/list list.l2zLP3vs8TRqSZZtLxgLvFcQU9FJYOKHlWaPy5IG868=
[1615908169] /94:b8:6d:84:54:e9/2763606/user/list {"u": "fb81c4cc20a3d5d1c700b89c4ebaecf786ea76c0518c7592119b6949f912d44e", "s": 255, "n": "admin@admin.com"}
[1615908169] /94:b8:6d:84:54:e9/2763606/user/list {"u": "167a7337895abb74eb4a7b966e6d5820c2d3aaa0b8deac3082d3998de156c7fd", "s": 15, "n": "intx82@gmail.com"}
[1615908169] /94:b8:6d:84:54:e9/2763606/user/list {}
Топики пользователя. Поиск устройств пользователя
Для поиска устройств пользователя необходимо опубликовать user-id в топик /user/dev
Пример:
/user/dev => yt2q8P3UwdnRsQHRD9VS9TKrGx0aaSfbDOXC7m1xjHY
/user/dev <= /aa:bb:cc:dd:ee:ff/11223344
/user/dev <= /00:11:22:33:44:55/11234567
[1628846604] /user/dev yt2q8P3UwdnRsQHRD9VS9TKrGx0aaSfbDOXC7m1xjHY=
[1628846604] /user/dev /10:52:1c:df:13:cb/1114059810
Описание топика ADD в хабе
Устройства имеют дополнительный режим добавления в базу данных через SHA256 хеш настроек устройства.
При регистрации (/reg) устройства которое не принадлежит не одному из пользователей, сервер должен отправить в топик /add количество секунд данное на обнаружение устройства по хешу настроек.
В ответ устройство отдаст хеш настроек.
Далее при добавлении устройства у пользователя, также спрашиваются данные настройки, после из них генерируется SHA256 хеш и сранивнивается с хешами всех доступных в текущий момент устройств.
Если в данном временном списке хешей настроек устройств находится хеш введенных параметров пользователем - то данное устройство связывается с данными пользователем (добавляется данному пользователю).
Если хеш не находится за указанное время, то хеш удаляется из временного хранилища.
Пример по шагам
- Пользователь настроил WIFI подключение терморегулятора
- Устройство подключилось к WIFI и провело регистрацию на сервере
- Сервер не нашел связку устройство-пользователь, отправляет в топик /add количество секунд за которое устройство будет доступно для добавления в базу
- Устройство выводит дополнительное сообщение / мигает светодиодом, указывая пользователю, что необходимо добавить его в базу
- Устройство отправляет серверу SHA256 хеш настроек, сервер сохраняет его как временное значение принадлежащее устройству.
- Пользователь выбирает добавление по хешу, и вводит необходимые настройки
- Сервер считает хеш из введенных настроек и сравнивает его с хешами которые есть во временном хранилище.
- Если такой хеш был найден - то создается связь устройство-пользователь
- Если такой хеш не был найден - то выводится ошибка.
- Если за указанное время в топике /add устройство не было добавлено. Пользователь не сможет его добавить до следующей регистрации устройства на сервере. (т.е включение/выключения устройства)
Пример:
Формат настроек от которых считается хеш
| Название точки доступа | \0 | Пароль Wifi | \0 |
|---|---|---|---|
| ap0 | 0 | y78bug57 | 0 |
- Точка доступа: ap0
- Пароль: y78bug57
- Строка с которой будет считатся хеш: "ap0\0y78bug57\0"
- Hex значение строки: "61703000793738627567353700"
-
Посчитанный SHA256 хеш: "986b2683c88ece86efdfd3ac1f6f6ff97048d2ba6ef508622bf29a787cf2b56b"
-
Что будет отправленно устройству => /48:3f:da:7d:fa:95/add 60
- Что должно быть принято от устройства <= /48:3f:da:7d:fa:95/add 986b2683c88ece86efdfd3ac1f6f6ff97048d2ba6ef508622bf29a787cf2b56b
Описание топика events
Топик events используется для получения истории событий со стороны устройства либо сервера. Выбор кто будет публиковать данные основывается на публикации сервером error 4. Если сервер опубликует error 4, то устройство не будет отдавать статистику. Это должен будет делать сервер. Данная настройка будет сброшена при следующей полной регистрации. (error 1)
Аргументы: [ Unixtime начала ; Unixtime конца ]
Формат ответа:
[ { "ts": 1607178057, "r": 13, "v": 1103560704 }, ... ]
Где:
- ts - Timestamp, Unixtime события
- r - Register, Номер регистра
- v - Value, Значение регистра
Максимальное количество событий в запросе: 64
Пример работы events
Пример работы топика events
| Канал связи | Описание |
|---|---|
| /b8:27:eb:f2:97:2c/894064187/events/9 -> 1607126400;1607212799 | Запрос на историю 9-го регистра с 1607126400 по 1607212799 |
| /b8:27:eb:f2:97:2c/894064187/events/9 -> | Ответ с историей регистров |
| [ { "ts": 1607178057, "r": 9, "v": 1103560704 }, { "ts": 1607140124, "r": 9, "v": 1103560704 } ] | Всего 2 записи |
Обработка событий
Событие - это изменение одного из регистров устройство. Когда происходит событие устройство отправляет новые данные регистра в соответствующий топик. Пример: При переключении реле, будет отправлено состояние в соответсвующий топик
{dev} => {val} - публикация устройство {val} => {dev} - публикация сервером
/{token}/0/8 => 0 // Событие: Реле выключилось (для arduino) 1 => /{token}/0/8 // Команда: Включить реле (для arduino)
Всего в устройстве есть 17 регистров, не все из них используются. Все регистры имеют размер в 4 байта (uint32) Тип преобразовывается на сервере. В mqtt сессии все передается в виде uint32_t числа.
Список регистров для каждого устройство свой, но он должен наследоватся с данного списка.
| № регистра | Название | Тип данных | Описание |
|---|---|---|---|
| 0 | SERIAL | uint32 | Серийный номер (он же номер instance) |
| 1 | TIME | uint32 | Время в Unixtime |
| 2 | NU | * | Не используется мостом, детальное описание регистра зависит от устройства |
| 3 | NU | * | Не используется мостом, детальное описание регистра зависит от устройства |
| 4 | NU | * | Не используется мостом, детальное описание регистра зависит от устройства |
| 5 | NU | * | Не используется мостом, детальное описание регистра зависит от устройства |
| 6 | NU | * | Не используется мостом, детальное описание регистра зависит от устройства |
| 7 | MODE | uint32 | Используется только 31 бит |
| 8 | NU | * | Не используется мостом, детальное описание регистра зависит от устройства |
| 9 | NU | * | Не используется мостом, детальное описание регистра зависит от устройства |
| 10 | NU | * | Не используется мостом, детальное описание регистра зависит от устройства |
| 11 | NU | * | Не используется мостом, детальное описание регистра зависит от устройства |
| 12 | NU | * | Не используется мостом, детальное описание регистра зависит от устройства |
| 13 | NU | * | Не используется мостом, детальное описание регистра зависит от устройства |
| 14 | NU | * | Не используется мостом, детальное описание регистра зависит от устройства |
| 15 | DEVICE_TYPE | enum | Тип устройства |
| 16 | OBSERVE | uint32 | Биты наблюдения |
| 17 | NU | * | Не используется мостом, детальное описание регистра зависит от устройства |
| 18 | NU | * | Не используется мостом, детальное описание регистра зависит от устройства |
Значения регистра DEVICE_TYPE
В данный момент есть:
| Номер устройства | Название |
|---|---|
| 1 | Тестовый терморегулятор на arduino |
| 48 | LTC-030 |
| 112 | LTC-070 |
| 144 | LTC-090 |
| 1024 | Python эмулятор хаба |
Ошибки сервера
Сервер может принудительно установить клиенту код ошибки, тем самым вызвав определенную реакцию.
| № | Название | Описание |
|---|---|---|
| 0 | NU | Не используется (нет ошибки) |
| 1 | REG_NEEDED | Сервер использует для полной перерегистрации. |
| 2 | AUTH_DENIED | Публикации этого устройства будут игнорированы, доступ к серверу запрещен, устройство заблокировано. Устройство отключится от брокера до переподключения wifi/перезагрузки |
| 3 | REG_UPDATE | Запрашивает значения регистров с хаба (для всех устройств хаба). Используется если status на сервере меньше чем на устройстве |
| 4 | BLOCK_EVENTS | Запрещает отправлять устройству список событий по запросу, флаг сбрасывается после error = 1 |
Наблюдения за изменениями регистров
Для выбора наблюдаемых регистров используется регистр №16 (OBSERVE). Если в соответсвующий бит номеру регистра будет установленно значение 1, при изменении выбранного регистра будет выполнена публикация с новым значением регистра
Пример:
| Значение | Значение HEX | Описание |
|---|---|---|
| 0b.0000.0000.0000.0000.0000.0000.0000.0000 | 0x00000000 | Нет наблюдаемых регистров, при изменнии значения любого регистра публикация значения выполнятся не будет |
| 0b.0000.0000.0000.0000.0001.0001.0010.1000 | 0x00001128 | Значение по-умолчанию для arduino, отслеживания изменений для 3,5,8, и 12го регистров. (TARGET_TEMP, HYSTERESIS, RELAY, FLOOR_TEMP) |
| 0b.0000.0000.0000.0001.1111.1111.1111.1111 | 0x0001ffff | Отслеживание всех возможных регистров |
Запись/чтение памяти терморегулятора
Доступ к внутреней памяти терморегулятора используется для управления расписаниями, получением данных из кольцевого буфера событий, итд. В каждом типе устройства могут быть совершенно разное предназначение и разные адресса памяти.
Доступ к памяти выполняется через два топика находящиеся в устройстве. Максимальный размер передаваемых данных 52 байта
Топик /{mac}/{instance-id}/read для чтения содержимого памяти Топик /{mac}/{instance-id}/write для чтения содержимого памяти
Пример чтения памяти
Формат запроса сообщения:
| Адрес | Разделитель | Размер | |
|---|---|---|---|
| Тип данных | uint32 | ';' | uint8 |
Пример: для чтения 32 байт с 87644422 терморегулятора по адресу 0x200 необходимо отправить /{mac}/87644422/read => 512;32
Формат ответа:
| Адрес | Разделитель | Данные | |
|---|---|---|---|
| тип данных | uint32 | ';' | base64 |
Пример: ответа который будет отправлен в read топик 512;ggXLmX3EMFCVa5NTud4AL4L0R+ts3vC0JypOAhbOTYw=
Где: 512 - начальный адрес {base64} - Закодированное значение 32 байт: 8205cb997dc43050956b9353b9de002f82f447eb6cdef0b4272a4e0216ce4d8c (hex)
Главная отличие base64 в суффиксе '='
Пример записи памяти
Запись памяти происходит ровно наоборот и с записью в топик write
Формат запроса:
| Адрес | Разделитель | Данные | |
|---|---|---|---|
| тип данных | uint32 | ';' | base64 |
Пример: запроса который должен быть отправлен в write топик 512;ggXLmX3EMFCVa5NTud4AL4L0R+ts3vC0JypOAhbOTYw=
Где: 512 - начальный адрес {base64} - Закодированное значение 32 байт: 8205cb997dc43050956b9353b9de002f82f447eb6cdef0b4272a4e0216ce4d8c (hex)
Формат ответа:
| Адрес | Разделитель | Размер записаных данных | |
|---|---|---|---|
| Тип данных | uint32 | ';' | uint8 |
Пример: для ответа записи 32 байт в 87644422 терморегулятор по адресу 0x200 : /{mac}/87644422/write => 512;32
Обновление прошивки устройства
Для обновления прошивки устройства используется два топика устройства /{instance-id}/fw/pkg и /{instance-id}/fw/upd
- /{instance-id}/fw/pkg - для записи файла прошивки устройства в память хаба
- /{instance-id}/fw/upd - Для старта обвновления устройства
Обновление происходит в два этапа:
- Запись прошивки в файловую систему хаба
- Запуск обновления устройства прошиивкой находящейся в файловой системе хаба
При старте записи прошивки будет удалена история событий устройств.
Формат прошивки записываемой через pkg - chunk размером 148 байт, кодированных через base64, в ответ на запись в pkg - хаб будет публиковать текущий размер файла прошивки В случае ошибки записи файла - будет опубликован 0. Такое может происходить, в момент записи данных на флеш, рекомендуемое действие - подождать 10 сек, если ошибка повторяется - то это ошибка файловой системы хаба.
После окончания записи файла прошивки в память хаба - необходимо выполнить публикацию команды upd 2, которая запустит механизм обновления. Если из-за ошибок передачи данных произошла лишняя запись в память, необходимо сбросить передачу и начать сначала, делается это через upd команду 1
| Команды upd | Описание |
|---|---|
| 0 | По завершению передачи прошивки в устройство - хаб опубликует в данный топик 0 |
| 1 | Удаление файла прошивки из хаба (к примеру, в случае неправильной записи) |
| 2 | Перевод устройства в режим перепрограмирования и запись прошивки в устройство |
После старта прошивки устройства, устройство не будет отвечать не на какие измение регистров, впредь до загрузки новой прошивки.
Пример загрузки прошивки
| Описание | Топик | Направление | значение |
|---|---|---|---|
| Удаление старого файла прошивки | /{token}/{instance-id}/fw/upd | => | 2 |
| Отправка chunk-а прошивки для записи их в файл | /{token}/{instance-id}/fw/pkg | => | ur8s...wuCEHqw== |
| Ответ о размере файла прошивки | /{token}/{instance-id}/fw/pkg | <= | 148 |
| Отправка chunk-а прошивки для записи их в файл | /{token}/{instance-id}/fw/pkg | => | ur/WH...Cb/sz2A= |
| Ответ о размере файла прошивки | /{token}/{instance-id}/fw/pkg | <= | 296 |
| ...запись всех chunk-ов из файла прошивки | - | - | * |
| Публикация команды старта обновления | /{token}/{instance-id}/fw/upd | => | 1 |
| Ожидание завершение обновления устройства | - | - | * |
| Обновление завершено | /{token}/{instance-id}/fw/upd | <= | 0 |
Формат файла прошивки
Прошивка представляет из себя xml файл. Файл должен иметь вид [DEV].R[DATE].uebf Формат:
<root>
<chunks>
<chunk>[BASE64 данные прошивки]</chunk>
...
<chunk>[BASE64 данные прошивки]</chunk>
</chunks>
</root>
Где chunk – зашифрованные куски прошивки по 148 байт. Т.е все данные которые будут отправлены на устройство.
Обновление прошивки HUB
Обновление прошивки хаба происходит точно таким же образом как и обновление прошивки устройства, с единой разницой размер блока равен 1024 байтам
Используемые топики:
- Для записи файла прошивки -/fw/pkg
- Для управлению перепрошивкой - /fw/upd
Формат и номера команд такие же как и для устройства. После публикации сообщения - 1, начнется прошивка хаба, хаб при этом не будет доступен по сети.
Пример загрузки прошивки хаба
| Описание | Топик | Направление | значение |
|---|---|---|---|
| Удаление старого файла прошивки | /{token}/fw/upd | => | 2 |
| Отправка chunk-а прошивки для записи их в файл | /{token}/fw/pkg | => | ur8s...wuCEHqw== |
| Ответ о размере файла прошивки | /{token}/fw/pkg | <= | 1028 |
| Отправка chunk-а прошивки для записи их в файл | /{token}/fw/pkg | => | ur/WH...Cb/sz2A= |
| Ответ о размере файла прошивки | /{token}/fw/pkg | <= | 2052 |
| ...запись всех chunk-ов из файла прошивки | - | - | * |
| Публикация команды старта обновления | /{token}/fw/upd | => | 1 |
| Ожидание завершение обновления устройства | - | - | * |
| Обновление завершено | /{token}/fw/upd | <= | 0 |