Подключение устройств по протоколу MQTT

Обзор страницы
Точка входа и минимальный процесс подключения
- Создайте и опубликуйте MQTT-продукт в управлении продуктами, уточните ID продукта, номер устройства, MQTT-аккаунт, пароль и код авторизации устройства.
- Устройство или MQTTX подключается к MQTT-сервису с согласованными
clientId,userName,password. - После успешного подключения сначала опубликуйте
/info/post, затем/property/postили/event/post. - На стороне платформы подтвердите замкнутость канала через состояние работы, журнал событий, журнал команд и сценарии правил в деталях устройства.
1. Шаги подключения
提示
- Исходный код аппаратного SDK для ESP8266: FastBee Arduino SDK
- Если формат MQTT-сообщений устройства фиксирован, пересылку можно адаптировать к платформе через механизм правил
- Встроенный netty-mqtt: поддерживает пересылку топиков и содержимого
- Промежуточное ПО EMQX: поддерживает пересылку содержимого; топики можно пересылать через встроенный механизм правил EMQX
1. Аутентификация устройства
- Шифрованная аутентификация (рекомендуется)
- Простая аутентификация
2. Взаимодействие устройства
- Публикация MQTT-топиков, связанных с моделью вещи, информацией об устройстве и синхронизацией времени
- Подписка на MQTT-топики, связанные с моделью вещи, обновлением устройства и синхронизацией времени
3. AP-настройка сети устройства (опционально, только для WiFi-устройств)
- Интерфейс обнаружения устройства
- Интерфейс конфигурации устройства
2. Аутентификация устройства
提示
- Типы аутентификации: S = простая, E = шифрованная
- Если для продукта включён код авторизации устройства, код авторизации не может быть пустым
- ID пользователя — это ID вошедшего пользователя; при разных ID пользователя устройства принадлежат разным пользователям. Можно единообразно использовать аккаунт admin с ID 1, а затем распределять устройства по пользователям через настройку сети или сканирование кода
- Номер устройства можно получить двумя способами: 1. использовать номер устройства, сгенерированный при создании устройства в системе; 2. не создавая устройство в системе, сгенерировать уникальный номер на стороне оборудования — после аутентификации система автоматически зарегистрирует сущность устройства (при большом количестве устройств рекомендуется этот способ)
1. Шифрованная аутентификация
В деталях продукта получите номер продукта, MQTT-аккаунт, MQTT-пароль и секретный ключ продукта; пароль шифруется AES с использованием секретного ключа продукта и передаётся в backend; backend расшифровывает его секретным ключом продукта для аутентификации. Для подключения к MQTT-серверу сообщений требуется уникальный ID клиента, имя пользователя и пароль в следующем формате:
# ID клиента = тип аутентификации + номер устройства + номер продукта + ID пользователя
clientId = E & deviceNumber & productId & userId
# имя пользователя
userName = fastbee
# пароль
password = MQTT-пароль & время истечения
password = MQTT-пароль & время истечения & код авторизации устройства (формат при включённой авторизации устройств для продукта)- ID клиента = тип аутентификации + номер устройства + номер продукта + ID пользователя, соединённые символом
&без пробелов; - В поле имени пользователя напрямую введите MQTT-аккаунт
- Пароль = MQTT-пароль + время истечения пароля + код авторизации устройства (опционально), после чего выполняется AES-шифрование. В целях безопасности время истечения пароля должно быть в пределах 24 часов, в формате метки времени с точностью до миллисекунд.
Пример конфигурации учётных данных:
clientId = "E&D68329VL588&2&1"
userName = "fastbee"
password = "/W2A/4MK+9cEGBhyBDgr2K5c62DAjAK4m0b5pvwxX6FFMzI3h1pUmaDY3BH1P2mI"2. Простая аутентификация
В деталях продукта получите MQTT-аккаунт и MQTT-пароль; рекомендуется для тестовой среды. Формат ID клиента MQTT аналогичен шифрованной аутентификации, но E заменяется на S.
# ID клиента = тип аутентификации + номер устройства + номер продукта + ID пользователя
clientId = S & deviceNumber & productId & userId
# имя пользователя
userName = fastbee
# пароль
password = MQTT-пароль
password = MQTT-пароль & код авторизации устройства (формат при включённой авторизации устройств для продукта)Пример конфигурации учётных данных:
# ID клиента = тип аутентификации + номер устройства + номер продукта + ID пользователя
clientId = "S&D68329VL588&2&1"
userName = "fastbee"
password = "PHYFED93WSFF1DAS"
password = "PHYFED93WSFF1DAS&ADBFCC8934864B26B55658C66F562AC5" (формат при включённой авторизации устройств для продукта)3. Получение устройством текущего времени
Для получения текущего времени можно вызвать NTP-интерфейс системы: в запросе передаётся текущее число миллисекунд работы устройства, в ответе возвращаются время отправки устройства, время приёма сервера и время отправки сервера. Затем получите текущее число миллисекунд работы устройства как время приёма устройства. Наконец, вычислите текущее время устройства по формуле; время должно быть в миллисекундах. Онлайн-инструмент меток времени
# deviceSendTime — текущее число миллисекунд работы устройства
http://localhost:8080/iot/tool/ntp?deviceSendTime=35768
# вычисление времени
текущее время устройства = (время приёма сервера + время отправки сервера + время приёма устройства - время отправки устройства) / 24. Описание AES-шифрования
Используется режим AES CBC, вектор инициализации фиксирован — wumei-smart-open, 16 символов, вывод Base64; пароль шифрования — секретный ключ продукта. Для тестирования можно использовать: онлайн-инструмент шифрования
режим шифрования: CBC
заполнение: pkcs5padding
блок данных: 128 бит
вектор инициализации: wumei-smart-open
вывод: base64
пароль: секретный ключ продукта в соответствующей системе
шифруемое содержимое: MQTT-пароль & expireTime & код авторизации (опционально)3. Взаимодействие устройства
{productId} обозначает ID продукта, {deviceNum} — номер устройства. Получите ID продукта и номер устройства в Web-интерфейсе; при автоматическом добавлении устройств в качестве номера устройства можно использовать уникальный код или MAC-адрес устройства — после успешной аутентификации в backend автоматически добавится соответствующая сущность устройства.
1. Топики подписки
| Топик | Описание |
|---|---|
| /{productId}/{deviceNum}/function/get | Подписка на команды платформы |
| /{productId}/{deviceNum}/info/get | Подписка на информацию об устройстве (при получении сообщения в этот топик публикуется информация об устройстве) |
| /{productId}/{deviceNum}/monitor/get | Подписка на сигнал мониторинга в реальном времени (публикация данных мониторинга по заданным количеству и интервалу) |
| /{productId}/{deviceNum}/ntp/get | Подписка на синхронизацию времени (опционально, для синхронизации текущего времени устройства) |
| /{deviceNum}/http/upgrade/set | Подписка на OTA-обновление по HTTPS (новый) |
| /{deviceNum}/fetch/upgrade/set | Подписка на OTA-обновление бинарным пакетом (новый) |
| /{productId}/{deviceNum}/ota/get | Подписка на обновление устройства (старый) |
| /{productId}/{deviceNum}/property/get | устарело в 2.x Подписка на свойства (публикует сервер, подписывается устройство) |
| /{productId}/{deviceNum}/property-online/get | устарело в 2.x Подписка на свойства (онлайн-режим, публикует клиент пользователя, подписывается устройство) |
| /{productId}/{deviceNum}/function-online/get | устарело в 2.x Подписка на функции (онлайн-режим, публикует клиент пользователя, подписывается устройство) |
2. Топики публикации
| Топик | Описание |
|---|---|
| /{productId}/{deviceNum}/property/post | Публикация данных (отображение в реальном времени; данные свойств/функций и мониторинга; возможна периодическая отправка данных мониторинга) |
| /{productId}/{deviceNum}/info/post | Публикация информации об устройстве |
| /{productId}/{deviceNum}/event/post | Публикация событий |
| /{productId}/{deviceNum}/monitor/post | Публикация данных мониторинга в реальном времени (только для графиков реального времени, без сохранения) |
| /{productId}/{deviceNum}/ntp/post | Публикация синхронизации времени (опционально) |
| /{deviceNum}/http/upgrade/reply | Ответ на OTA-обновление по HTTPS (новый) |
| /{deviceNum}/fetch/upgrade/reply | Ответ на OTA-обновление бинарным пакетом (новый) |
| /{productId}/{deviceNum}/upgrade/reply | Ответ на OTA-обновление (старый) |
| /{productId}/{deviceNum}/function/post | устарело в 2.x Публикация функций (отображение в реальном времени) |
3. Формат данных
Взаимодействие устройства и системы использует формат JSON
- Подписка на информацию об устройстве, топик:
/info/get
# Описание: при получении сообщения с информацией об устройстве публикуется информация об устройстве — решает проблему синхронизации состояния устройства
# содержимое сообщения устройства пустое- Публикация информации об устройстве, топик:
/info/post
# Описание: 1. устройство публикует информацию о себе после включения; 2. устройство публикует информацию о себе после получения команды запроса информации
# rssi сигнал устройства (отличный [-55— 0], хороший [-70— -55], средний [-85— -70], плохой [-100— -85])
# status состояние устройства, фиксировано 3 — в сети
# firmwareVersion версия прошивки
# userId ID пользователя; можно установить ID пользователя 1 (администратор) — при настройке сети устройство будет назначено конкретному пользователю
# longitude опционально, долгота; передаётся при использовании позиционирования устройства
# latitude опционально, широта; передаётся при использовании позиционирования устройства
# iccid опционально, ICCID IoT-карты; передаётся, когда устройство использует IoT-карту
# cardPlatformId опционально, соответствует номеру карточной платформы в управлении IoT-картами; передаётся вместе с ICCID, если не передан — по умолчанию опрашиваются все карточные платформы
# summary опционально, сводка — конфигурация устройства и т. п., формат JSON, объект произвольный
{
"rssi": -43,
"firmwareVersion": 1.2,
"status": 3,
"userId": 2,
"longitude": 0,
"latitude": 0,
"iccid": 898604293620C0000970,
"cardPlatformId": 0,
"summary": {
"name": "FastBee",
"chip": "ESP8266",
"author": "fastbee",
"deliveryTime": "2023-06-06",
"activeTime": "2022-10-01"
}
}- Подписка на мониторинг в реальном времени, топик:
/monitor/get
# Описание: при получении сообщения мониторинга публикуются данные мониторинга по заданным количеству и интервалу
# count количество
# interval интервал, в миллисекундах
{
"count": 60,
"interval": 1000
}- Публикация мониторинга в реальном времени, топик:
/monitor/post
# Описание: публикация данных мониторинга с заданными количеством и интервалом по полученному сообщению мониторинга
# id идентификатор; мониторинг в реальном времени — это свойство в модели вещи, идентификатор смотрите в деталях продукта, соответствует значению id
# value значение, собранное устройством; только целое или дробное число, передаётся строкой
# remark может быть пустым или содержать текущее время устройства
[{
"id": "temperature",
"value": "27.43",
"remark": ""
}, {
"id": "humidity",
"value": "32.18",
"remark": ""
}]- Подписка на команды платформы, топик:
/function/get
# Описание: свойства, функции и события относятся к модели вещи, JSON-определение одинаковое. Например, при получении сообщения «открыть переключатель» обработка на устройстве — открыть переключатель.
# id идентификатор; смотрите модель вещи в деталях продукта, соответствует идентификатору модели вещи
# value значение, соответствует определению в модели вещи, передаётся строкой
# remark команды, отправленные платформой из оповещений, сценарной автоматизации и таймеров, содержат примечание
[{
"id": "gear",
"value": "1",
"remark": "таймер устройства"
},{
"id": "switch",
"value": "0",
"remark": "сработала сценарная автоматизация"
}]- Публикация данных и событий, топики:
/property/post,/event/post
# Описание: свойства, функции и события относятся к модели вещи, JSON-определение одинаковое. Если `value` булева типа, значение "0" или "1" означает вкл/выкл; для перечисления — ключ элемента перечисления (например "1" — средняя скорость); массив передаётся строкой через запятую.
# id идентификатор; смотрите модель вещи в деталях продукта, соответствует идентификатору модели вещи
# value значение, соответствует определению в модели вещи, передаётся строкой
# remark можно напрямую использовать примечание из полученной подписки; примечание видно в журнале устройства
[{
"id": "gear",
"value": "1",
"remark": "передача успешно установлена"
}, {
"id": "switch",
"value": "0",
"remark": "переключатель выключен"
}]Описание модели вещи
- Все ID (идентификаторы) моделей вещей уникальны; старайтесь не использовать специальные символы, преимущественно буквы и цифры.
- Формат ID (идентификатора) подмодели объектного типа модели вещи: parentId_childId; для объектного массива аналогично — к ID подмодели добавляется ID родителя через подчёркивание, например:
# ID родительской модели вещи: power
# ID дочерней модели вещи: power_light- Модель вещи типа массив (включая массив объектов) имеет только один ID (идентификатор), а значение модели — массив (хранится строкой через запятую), например строка
98,100,50. Поэтому отправка свойств/функций/событий типа массив имеет особенность: ID (идентификатор) должен начинаться сarray_индекс, индекс — две цифры, например:shell# обычный формат массива `array_00_RGB` # формат массива объектов `array_00_power_switch` # индекс 00 — первый элемент массива, 02 / 03 ... 98 / 99 и т. д., длина массива не более 100 [{ "id": "array_01_power_switch", // array_01 как префикс означает второй элемент массива "value": "1", "remark": "" }]
- Публикация синхронизации времени, топик:
/ntp/post
# Описание: опционально; публикация сообщения синхронизации времени — после получения подписки сервер отправляет сообщение синхронизации времени
# deviceSendTime время отправки устройства
{
"deviceSendTime": "1592361428000"
}- Подписка на синхронизацию времени, топик:
/ntp/get
# Описание: опционально; при получении сообщения синхронизации времени текущее время вычисляется как = (время приёма сервера + время отправки сервера + время приёма устройства - время отправки устройства) / 2
# deviceSendTime время отправки устройства
# serverRecvTime время приёма сервера
# serverSendTime время отправки сервера
{
"deviceSendTime": "1592361428000",
"serverSendTime": "1592366463548",
"serverRecvTime": "1592366463548"
}- Подписка на OTA-обновление, топики:
/http/upgrade/setили/fetch/upgrade/set
# Описание: после получения сообщения об обновлении устройства скачайте прошивку по адресу загрузки через HTTP-запрос и выполните обновление
# version номер версии, можно использовать для сопоставления версии прошивки
# downloadUrl адрес скачивания прошивки
{
"taskId": 26,
"url": "/profile/iot/1/2024-0824-001954.bin",
"version": 1.2,
"status": 1
}4. Настройка сети устройства (опционально, только для WiFi-устройств)
提示
- Устройство использует AP-настройку сети: во время настройки устройство поднимает точку доступа и предоставляет web-сервис. Мобильное приложение передаёт конфигурационную информацию через web-сервис устройства.
- Адрес точки доступа устройства: 192.168.4.1
- Можно ориентироваться на SDK проекта
1. Интерфейс обнаружения устройства
Устройство предоставляет интерфейс обнаружения; мобильное приложение реализует через него функцию обнаружения устройств — подходит для настройки сети одного устройства.
# Метод запроса: Get
# Адрес интерфейса: http://192.168.4.1/status
# Параметры: нет
# Ответ: код состояния HTTP 200 означает, что устройство обнаружено2. Интерфейс конфигурации
Устройство предоставляет интерфейс конфигурации для получения информации; мобильное приложение отправляет конфигурационную информацию, параметры передаются через URL, где SSID, password и userId — обязательные параметры.
# Метод запроса: Post
# Адрес интерфейса: http://192.168.4.1/config
# Параметры:
SSID # имя WiFi
password # пароль WiFi
userId # номер/ID пользователя
deviceNum # опционально, номер устройства
authCode # опционально, код авторизации
extra # опционально, дополнительная информация
# Ответ: код состояния HTTP 200 — настройка сети успешна; код состояния HTTP 500 — ошибка настройки сети;
# Примеры URL запроса: устройство получает параметры через URL и сохраняет их
http://192.168.4.1/config?SSID=mywifi&password=mywifipassword&userId=1
http://192.168.4.1/config?SSID=mywifi&password=mywifipassword&userId=1&deviceNum=D68329VL588&authCode=6688&extra=open5. Контрольный список приёмки интеграции
Подключение устройств по MQTT рекомендуется принимать в следующем порядке, чтобы избежать ситуации, когда подключение успешно, но бизнес-данные не попадают в платформу.
| Шаг | Проверяемое содержимое | Признак успеха |
|---|---|---|
| 1 | Продукт опубликован | Статус продукта — «Опубликован» |
| 2 | Подключение MQTTX или устройства | В консоли EMQX появляется подключение клиента |
| 3 | Состояние устройства | В деталях устройства отображается «в сети» или обновляется время последнего выхода в сеть |
| 4 | /info/post | Обновились поля информации об устройстве, сигнала, версии |
| 5 | /property/post | В состоянии работы отображаются значения свойств модели вещи |
| 6 | /event/post | В журнале событий появляются отправленные события |
| 7 | /function/get | Устройство получает команду после отправки платформой |
| 8 | Возврат результата | Устройство возвращает результат выполнения, состояние на платформе обновляется |
| 9 | Правила/сценарии | Связанные правила, сценарии и оповещения срабатывают |
6. Типичные ошибки
Соединение отклонено
Проверьте в первую очередь:
- Открыт ли порт
1883на сервере. - Запущен ли EMQX или встроенный MQTT-сервис.
- Соответствует ли
clientIdформатуS&deviceNumber&productId&userIdили формату шифрованной аутентификации. - Включена ли для продукта авторизация устройств; если включена — содержит ли пароль код авторизации.
- Не заблокировано ли устройство.
Устройство в сети, но свойства не обновляются
Проверьте в первую очередь:
- Является ли топик публикации
/{productId}/{deviceNum}/property/post. - Используется ли в
productIdID продукта, а не номер продукта. - Совпадает ли
deviceNumточно с номером устройства. - Является ли тело сообщения массивом.
- Совпадает ли
idточно с идентификатором модели вещи. - Соответствует ли
valueтипу данных.
Платформа отправляет команду, но устройство её не получает
Проверьте в первую очередь:
- Подписано ли устройство на
/{productId}/{deviceNum}/function/get. - Остаётся ли подключение MQTTX или устройства в сети.
- Является ли элемент модели вещи записываемой функцией или свойством, допускающим отправку.
- Есть ли у пользователя права на просмотр деталей устройства и отправку команд.
- Не влияет ли тень устройства на текущую оценку.
Правило или оповещение не срабатывает
Проверьте в первую очередь:
- Попадают ли данные устройства в состояние работы платформы.
- Верны ли продукт, устройство и переменные, привязанные к сценарию или правилу.
- Совпадает ли выражение условия по типу с отправляемым значением.
- Включена ли конфигурация оповещений.
7. Точки входа для вторичной разработки
| Тип | Путь или интерфейс | Описание |
|---|---|---|
| Аутентификация MQTT | /iot/tool/mqtt/auth, /iot/tool/mqtt/webhook | Точки входа аутентификации EMQX и Webhook |
| Интерфейс устройств | /iot/device | Онлайн-статус, состояние и детали устройств |
| Интерфейс модели вещи | /iot/model | Определение и сопоставление моделей |
| Модуль протоколов | springboot/fastbee-protocol | Разбор и преобразование MQTT-сообщений |
| Модуль данных | springboot/fastbee-iot-data | Обработка данных свойств, событий и мониторинга |
| Страница frontend | vue3/src/views/iot/device | Детали устройства, состояние работы, отладка данных |
| API frontend | vue3/src/api/iot | Обёртки запросов устройств и моделей вещей |
8. Связанные документы
- Полный цикл «от продукта к устройству» (на кит.)
- Управление продуктами
- Управление устройствами (на кит.)
- Общая модель вещи (на кит.)
- Контрольный список диагностики подключения устройств (на кит.)


