Skip to main content

ThingsBoard

Интеграция ThingsBoard пересылает данные устройств приложения ONS в ThingsBoard по HTTP. На каждый uplink сервер отправляет два POST-запроса в HTTP API устройства ThingsBoard: атрибуты и телеметрию. Устройство ONS связывается со своим устройством ThingsBoard через токен доступа, который хранится в переменной устройства. Данные идут только в одну сторону: команды из ThingsBoard на устройства через эту интеграцию не попадают. Интеграцию настраивают на странице приложения в веб-интерфейсе; у приложения может быть одна интеграция ThingsBoard.

Как подключить​

  1. В ThingsBoard создайте устройство и скопируйте его токен доступа (Access Token) со страницы устройства.
  2. В ONS откройте карточку этого устройства в разделе «Узлы», на вкладке «Настройки узла» включите режим «Расширенный» и в блоке «Переменные» добавьте переменную ThingsBoardAccessToken со значением токена, см. Токен устройства.
  3. Повторите шаги 1 и 2 для каждого устройства, данные которого нужны в ThingsBoard.
  4. Откройте приложение в разделе «Приложения» и в блоке «Интеграции» на карточке ThingsBoard.io нажмите «Add».
  5. В поле «Server» укажите адрес ThingsBoard, например https://thingsboard.example.com, см. Поля интеграции.
  6. Включите переключатель «Active». У новой интеграции он выключен, а выключенную интеграцию сервер не запускает.
  7. Нажмите «Сохранить».

Блок «Интеграции» есть только на странице существующего приложения: на странице добавления его нет. Подпись карточки — «Интеграция ThingsBoard.io пересылает данные на ThingsBoard.io через HTTP.».

Блок «Интеграции» на странице приложения, интеграции ThingsBoard ещё нет
  1. Заголовок страницы приложения — App ID, App EUI и имя приложения: блок «Интеграции» есть только на странице существующего приложения.
  2. Интеграции — блок с карточками интеграций приложения.
  3. Подпись карточки ThingsBoard.io — «Интеграция ThingsBoard.io пересылает данные на ThingsBoard.io через HTTP.».
  4. Add — открывает форму новой интеграции ThingsBoard. Кнопка видна, пока у приложения нет интеграции ThingsBoard.

Сохранённые настройки сервер применяет сразу, без перезапуска: активную интеграцию он перезапускает с новой конфигурацией, выключенную или удалённую — останавливает. Изменить настройки можно кнопкой «Edit» на карточке, удалить интеграцию — кнопкой «Удалить».

Поля интеграции​

ПолеЧто задаёт
«Server»Обязательно. Базовый адрес ThingsBoard: http:// или https://, хост, при необходимости порт и префикс пути — без /api/v1 и без / в конце. Например, https://thingsboard.example.com
«Active»Включает интеграцию. У новой интеграции выключено
Форма интеграции ThingsBoard.io
  1. ThingsBoard.io — пока открыта форма, в заголовке блока «Интеграции» стоит название интеграции.
  2. Server — базовый адрес ThingsBoard, без /api/v1 и без / в конце.
  3. Active — включает интеграцию; у новой интеграции выключен.
  4. Сохранить — сохраняет настройки, сервер применяет их сразу.
  5. Отмена — закрывает форму без сохранения.

Адреса запросов сервер собирает подстановкой строк: <Server>/api/v1/<токен>/attributes и <Server>/api/v1/<токен>/telemetry. С «Server» https://thingsboard.example.com и токеном my_device_token атрибуты уйдут на https://thingsboard.example.com/api/v1/my_device_token/attributes.

Форма проверяет поле «Server»: адрес должен начинаться с http:// или https:// и не заканчиваться на /. Пустое поле — ошибка «URL сервера обязателен», неверный адрес, в том числе с / в конце, — «URL сервера должен начинаться с http:// или https://. Например, http://example.com или https://example.com». Сервер при сохранении проверяет только, что поле задано и значение — строка: пустую строку он примет. Лишний /api/v1 в адресе форма не заметит, и запросы уйдут на …/api/v1/api/v1/….

Токен устройства​

ThingsBoard определяет устройство по токену в адресе запроса. Сервер берёт токен из переменной устройства ThingsBoardAccessToken.

  • Имя переменной — ровно ThingsBoardAccessToken, с учётом регистра. Значение сервер подставляет в адрес как есть: не обрезает пробелы и не кодирует символы.
  • Где задать. В карточке существующего устройства, в режиме «Расширенный», блок «Переменные» — таблица с колонками «Ключ», «Значение», «Действие» и кнопками «Добавить» и «Удалить». Изменить переменную нельзя: удалите её и добавьте заново. Добавить ключ, который у устройства уже есть, сервер не даст: «Variable already exists.». В окне массового изменения узлов переменных нет — задать токен многим устройствам можно через REST API.
  • Когда начинает действовать. Новый или изменённый токен действует для uplink, принятых после изменения, перезапуск не нужен. Uplink, которые уже стоят в очереди интеграции, уйдут со старым токеном.
  • Устройство без токена. Если у устройства нет переменной ThingsBoardAccessToken, сервер отбрасывает его uplink: в ThingsBoard ничего не уходит. Запись «ThingsBoardAccessToken not found in variables. Skipping data send.» появляется только в журнале сервиса, в веб-интерфейсе её не видно. Отправку данных остальных устройств приложения это не задерживает.
  • Кто видит токен. Значения переменных карточка показывает открытым текстом: токен видит каждый, кто может открыть устройство. Токен входит в адрес запроса. В журнал настроек попадает только факт изменения переменных, без значений.
  • Соседство с настройками кодека. Те же переменные получает JS-кодек приложения как input.variables; кодек Protocol 78 читает из них deviceType и language. Токен и настройки кодека лежат в одном списке переменных устройства.
Карточка устройства, вкладка «Настройки узла», режим «Расширенный»: блок «Переменные»
  1. Заголовок карточки — DevEUI, DevAddr и описание устройства.
  2. Простой / Расширенный — переключатель режима на вкладке «Настройки узла»; блок «Переменные» есть только в режиме «Расширенный».
  3. Переменные — блок переменных устройства внизу вкладки, под блоком «Теги».
  4. Ключ, Значение, Действие — колонки таблицы; значения видны открытым текстом.
  5. Строка добавления — в поле «Ключ» введите ThingsBoardAccessToken, в поле «Значение» — токен устройства ThingsBoard.
  6. Добавить — добавляет переменную сразу, кнопка «Сохранить» карточки для этого не нужна.
  7. Удалить — удаляет переменную после подтверждения. Изменить переменную нельзя: удалите её и добавьте заново.

Токен через REST API​

Переменными устройства управляет REST API сервера, которым пользуется веб-интерфейс. Адрес — <база API>/node/{DevEUI}/variables/, только для активных устройств. База API зависит от развёртывания: /api/v1/ или /ons/api/v1/, если веб-интерфейс открыт по префиксу /ons/.

МетодТелоЧто делаетНужное право
GET—Возвращает переменные устройства словарёмПросмотр узла
POST{"ThingsBoardAccessToken": "<токен>"}Добавляет переменные; за один запрос можно передать несколькоИзменение узла
DELETE{"variable": "ThingsBoardAccessToken"}Удаляет переменнуюИзменение узла

Что отправляет сервер​

На каждый uplink сервер одновременно отправляет два POST-запроса:

ЗапросАдресТело
Атрибуты<Server>/api/v1/<токен>/attributesСм. Атрибуты
Телеметрия<Server>/api/v1/<токен>/telemetryСм. Телеметрия
  • Заголовки: Content-Type: application/json и User-Agent: OnsHTTPClient. Тело — JSON.
  • Тайм-аут каждого запроса — 5 секунд.
  • Ошибкой сервер считает ответ с кодом 400 и выше, тайм-аут и ошибку соединения. Что происходит при ошибках — в разделе Доставка и повторы.
  • Сертификат TLS сервер проверяет всегда, см. «Что важно знать».

В интеграцию приходят только uplink с данными — подтверждаемые и неподтверждаемые (Confirmed и Unconfirmed Data Up). Join и статусы кадров downlink в неё не попадают.

Атрибуты​

КлючЗначение
dev_euiDevEUI устройства
dev_addrDevAddr устройства
app_idApp ID приложения, которому принадлежит устройство
ТегиТеги приложения и устройства: каждый тег — отдельный ключ
{
"dev_eui": "6F1E570FFE14DBFC",
"dev_addr": "78130AE1",
"app_id": "77179F01",
"building": "A"
}
  • Теги добавляются после трёх полей: сначала теги приложения, затем теги устройства. Тег устройства перекрывает одноимённый тег приложения, а тег с именем dev_eui, dev_addr или app_id перекрывает одноимённое поле.
  • Атрибуты сервер отправляет заново с каждым uplink.
  • По документации ThingsBoard запрос на /attributes записывает клиентские (client-side) атрибуты устройства.

Телеметрия​

КлючЗначение
battery_levelЗаряд батареи из последнего ответа устройства на запрос статуса (DevStatusAns): 0 — внешнее питание, 255 — устройство не может измерить заряд, иначе — проценты. null, пока сервер не получил такой ответ
marginЗапас по SNR из того же ответа, дБ, от −32 до 31. null, пока сервер не получил ответ
join_request_timeВремя последнего Join Request устройства по часам шлюза. null, если сервер не видел активации устройства
data_…Данные JS-кодека, см. ниже

Поля battery_level, margin и join_request_time есть в каждом запросе. Их смысл тот же, что у одноимённых полей сообщения realtime_data WebSocket API.

Данные кодека​

Данные кодека попадают в телеметрию, только если у приложения задан JS-кодек и decodeUplink вернул поле data. Сервер берёт только data: errors и warnings кодека в ThingsBoard не уходят. Без JS-кодека в телеметрии остаются три поля статуса.

Объект data сервер раскладывает в плоский набор ключей:

  • ключ — путь от корня с префиксом data и разделителем _; элемент массива получает в пути свой индекс;
  • передаются только конечные значения, в полном пути которых есть подстрока value — строчными буквами: rawValue не подходит;
  • если value есть в имени родительского поля, например values, передаются все значения под ним.
data из decodeUplinkЧто уйдёт в ThingsBoard
{"temperature": {"value": 25.5, "unit": "C"}}data_temperature_value: 25.5; unit отбрасывается
{"sensors": {"temp": {"value": 22.0}}}data_sensors_temp_value: 22.0
{"readings": [{"value": 1.0}, {"value": 2.0}]}data_readings_0_value: 1.0, data_readings_1_value: 2.0
{"temperature": 21.5}Ничего: в пути нет value

Если кодек отдаёт плоский объект без value в именах, в ThingsBoard из его данных ничего не попадёт.

У приложения настроен JS-кодек Protocol 78, у устройства заданы переменные deviceType = TWM, language = ru и ThingsBoardAccessToken. Устройство прислало полезную нагрузку 782520125EC3732F04A8CD002D8101. Кодек вернул:

{
"data": {
"id": 120,
"seq": 37,
"language": "ru",
"device_type": "TWM",
"flags": {
"current_limited": { "value": false, "description": "current_limited" },
"temperature_low": { "value": false, "description": "Низкая температура" },
"temperature_high": { "value": false, "description": "Высокая температура" },
"tamper_magnet": { "value": false, "description": "Датчик магнитного поля (TAMPER)" },
"tamper_open": { "value": false, "description": "Обнаружен тампер" },
"time_need_update": { "value": true, "description": "Время устройства требует обновления" },
"tamper_overlight": { "value": false, "description": "tamper_overlight" },
"tamper_backflow": { "value": false, "description": "Обнаружен обратный поток" }
},
"payloads": [
{
"shift": 15,
"len": 12,
"pid": "0x12",
"sid": "Sensors",
"direct": {
"initialization": false,
"ts": 1742800606000,
"timestamp": 1742800606,
"utctimestamp": "2025-03-24T07:16:46.000Z",
"alarms": [],
"temperature": { "rawValue": 205, "value": 20.5, "coefficient": 0.1, "unit": "°C" },
"humidity": { "rawValue": 385, "value": 38.5, "coefficient": 0.1, "unit": "%" }
}
}
]
},
"errors": [],
"warnings": []
}

Тело запроса телеметрии:

{
"data_flags_current_limited_value": false,
"data_flags_temperature_low_value": false,
"data_flags_temperature_high_value": false,
"data_flags_tamper_magnet_value": false,
"data_flags_tamper_open_value": false,
"data_flags_time_need_update_value": true,
"data_flags_tamper_overlight_value": false,
"data_flags_tamper_backflow_value": false,
"data_payloads_0_direct_temperature_value": 20.5,
"data_payloads_0_direct_humidity_value": 38.5,
"battery_level": 100.0,
"join_request_time": "2026-10-01T06:12:40.114233Z",
"margin": 9
}
  • Флаги кодек отдаёт как {value, description}, поэтому в ThingsBoard уходят восемь ключей data_flags_<флаг>_value.
  • Измерения лежат в payloads[].direct: температура и влажность приходят как data_payloads_0_direct_temperature_value и data_payloads_0_direct_humidity_value. Индекс нагрузки зависит от её места в кадре: в кадре с несколькими нагрузками то же измерение получит другой ключ.
  • Не уходят id, seq, language, device_type, description, shift, len, pid, sid, initialization, alarms, rawValue, coefficient, unit и метки времени ts, timestamp, utctimestamp.

Разобрать свой пакет кодеком и посмотреть его JSON можно в Playground Protocol 78.

Доставка и повторы​

  • Хватает одного успешного запроса. Если удался хотя бы один из двух запросов, сервер считает uplink доставленным. Если атрибуты ушли, а телеметрия нет, телеметрия этого uplink теряется.
  • Оба запроса не удались — пауза. Сервер возвращает uplink в очередь и приостанавливает интеграцию: перестаёт читать очередь, значок на карточке — Disconnected. Первая пауза — около 20 секунд, следующие — 40, 80, 160 и 300 секунд, дальше по 300 секунд; к каждой добавляется до 10 %. После паузы интеграция снова читает очередь, и первая удачная отправка сбрасывает отсчёт пауз.
  • Uplink уходят по одному. Uplink приложения сервер отправляет строго по одному и в порядке очереди: следующий — только после того, как закончил с предыдущим. Пока ThingsBoard отклоняет оба запроса по одному uplink — отвечает кодом 400 и выше или не отвечает за 5 секунд, — отправка в ThingsBoard по всему приложению стоит и возобновляется после пауз до 5 минут. Ждут и uplink остальных устройств.
  • Неверный токен останавливает отправку. На неверный токен ThingsBoard, по его документации, отвечает кодом 401 на оба запроса. Сервер возвращает uplink в очередь, и отправка по всему приложению стоит. Исправление переменной не поможет uplink, которые уже в очереди: токен записан в них в момент приёма. Проверьте токены до включения интеграции.
  • Пока ThingsBoard недоступен, uplink копятся. У каждой интеграции своя очередь на сервере; по умолчанию число сообщений в ней и срок их жизни не ограничены. После восстановления ThingsBoard сервер отправляет накопленное. По умолчанию очередь удаляется вместе с данными, если её не читают 14 дней.
  • Повторы возможны. Доставка — «как минимум один раз»: например, если ThingsBoard принял оба запроса, но не ответил за 5 секунд, сервер отправит uplink ещё раз.

Состояние на карточке​

ЗначокЧто значит
Нет значкаИнтеграция ещё не запускалась
Connected, зелёныйИнтеграция запущена и готова отправлять. Это не значит, что ThingsBoard доступен
Disconnected, жёлтыйИнтеграция не читает очередь. У активной интеграции — пауза после ошибки отправки, см. Доставка и повторы
Карточка ThingsBoard.io: интеграция включена и запущена
  1. Значок переключателя — зелёный: интеграция включена («Active»), серый — выключена.
  2. Значок состояния — здесь Connected, зелёный. Disconnected — жёлтый; у интеграции, которая ещё не запускалась, значка нет.
  3. Edit — открывает форму с текущими настройками.
  4. Удалить — удаляет интеграцию после подтверждения.

Состояния Error у интеграции ThingsBoard не бывает. Счётчиков успешных и неудачных отправок и истории запросов у неё нет: дошли ли данные, видно только в ThingsBoard.

Что важно знать​

  • Обратного канала нет. Команды и RPC из ThingsBoard через эту интеграцию на устройство не попадут. Отправить устройству downlink можно через интеграцию MQTT или WebSocket API.
  • Время в ThingsBoard — время доставки. Телеметрия уходит без поля ts, и по документации ThingsBoard в этом случае ставит время своего сервера. Показания, накопленные за время недоступности ThingsBoard, придут с временем доставки. Метки времени из кодека (ts, timestamp, utctimestamp у Protocol 78) не передаются: в их пути нет value.
  • Параметры приёма не передаются. В ThingsBoard не уходят rssi, lsnr, datr, freq, fcnt, fport, шлюз приёма, packet_loss_rate и сырые байты полезной нагрузки. Они есть в сообщениях интеграции MQTT и в realtime_data WebSocket API.
  • Самоподписанный сертификат не подойдёт. Сертификат TLS сервер проверяет всегда, настройки, отключающей проверку, у интеграции нет. ThingsBoard с самоподписанным сертификатом по https:// подключить не получится.
  • «Доступные приложения» добавляют чужие uplink. Интеграция получает и uplink приложений, выбранных в поле «Доступные приложения» её приложения. У таких uplink app_id в атрибутах — App ID исходного приложения, а токен берётся из переменных устройства исходного приложения.
  • После выключения или удаления накопленное уйдёт при включении. Выключение («Active») и удаление останавливают чтение очереди, но очередь интеграции ThingsBoard сервер не удаляет. Uplink, накопленные за время выключения, уйдут в ThingsBoard при повторном включении, если интеграция была выключена меньше 14 дней. Если интеграцию удалили и создали заново в течение 14 дней, в ThingsBoard уйдут uplink, накопленные с момента удаления.
  • Строки из цифр ThingsBoard может сохранить числами. По документации ThingsBoard параметр transport.json.type_cast_enabled, по умолчанию включённый, превращает строковые значения телеметрии и атрибутов, похожие на число, в числа. Тогда DevAddr или DevEUI из одних цифр, например 26011234, может сохраниться числом, а ведущие нули — пропасть.

См. также​