Система управления устройствами DuoTec с REST API, таблицей, статистикой, картой и сервисными эндпоинтами для регистрации и передачи телеметрии.
db_bxs.db), таблица BxS. Дополнительно создаётся таблица geocode_cache для кэширования адресов.
Основная таблица BxS содержит 37 колонок в базовой схеме:
| Колонка | Тип | Описание | Пример |
|---|---|---|---|
DTM | TEXT | Дата изменения записи (YYMMDD) | 250731 |
MAC | TEXT NOT NULL | MAC-адрес датчика (12 HEX) | 50547B85F73C |
DTC | TEXT | Дата создания записи (YYMMDD) | 240617 |
TOS | TEXT | Тип датчика (Type Of System) | BMS |
STS | TEXT | Подтип датчика | V6 |
NOP | INTEGER | Номер партии (Number Of Production) | 2421 |
KEY | TEXT | Ключ устройства | c46c24ab |
POS | TEXT | Пароль пользователя датчика | — |
FWS | TEXT | Версия прошивки датчика | 35 |
BAT | TEXT | Заряд / напряжение батареи датчика | 3.6 |
TOW | TEXT | Время работы датчика | 39 d 23:32:33 |
MAV | TEXT | Версия мобильного приложения | 20230123 |
MOS | TEXT | Версия операционной системы телефона | Android 10.5 |
MPV | TEXT | Модель телефона | Samsung Note20 |
LAL | TEXT | GPS-координаты (lat,lon) | 59.9448669,30.335429 |
COR | TEXT | Количество перезапусков датчика | 5 |
COC | TEXT | Количество подключений | 3 |
COA | TEXT | Количество авторизаций | 2 |
CNT | TEXT | Счётчик датчика | 1234 |
ERR | TEXT | Номер ошибки; 0 означает, что ошибок нет | 0 |
CDT | TEXT | Канал передачи данных | 1 |
VO1 | TEXT | Параметр 1: BLS/HLS — уровень, BTS — температура | 4000 |
VO2 | TEXT | Параметр 2: BLS/HLS — температура, BTS — контакт | 28 |
VO3 | TEXT | Параметр 3 (значение зависит от типа датчика) | — |
COF | TEXT | Для BLS/HLS — счётчик пустого | 54332 |
COE | TEXT | Для BLS/HLS — счётчик полного | 12433 |
VOF | TEXT | Степень фильтрации | 5 |
COP | TEXT | Период измерения | 80 |
LOV | TEXT | Таблица калибровки: уровни | — |
LOL | TEXT | Таблица калибровки: литры | — |
COM | TEXT | Для BLS/HLS — комментарий; для остальных типов — серийный номер | 304858 |
TSC | INTEGER | Дата создания записи (Unix timestamp) | 1718582400 |
TSM | INTEGER | Дата изменения записи (Unix timestamp) | 1753973159 |
VER | TEXT | Версия протокола | 1 |
REQ | TEXT | Тело исходного запроса | ver=1&mac=... |
DOP | TEXT | Дата производства/создания; API v1 назначает Unix-время регистрации. В карточке показываются DTC и TSC | 1674056224 |
OTK | TEXT | ФИО сотрудника ОТК | Иванов И. И. |
При установке поля DOP и OTK добавляются и в существующие базы без изменения сохранённых записей.
geocode_cacheСоздаётся автоматически при работе панели и API v1:
| Колонка | Тип | Описание |
|---|---|---|
lat | TEXT | Широта (6 знаков) |
lon | TEXT | Долгота (6 знаков) |
address | TEXT | Адрес из Nominatim |
cached_at | INTEGER | Unix-метка кэширования |
Ключ: (lat, lon) — координаты с округлением до 6 знаков. Адрес запрашивается один раз и сохраняется в БД. При повторном запросе тех же координат адрес берётся из кэша без обращения к внешнему API.
map_cache хранит готовый JSON карты; изменения координат, MAC или типа датчика автоматически обновляют версию кэша.api_keys хранит метку сервиса, хеш и маскированный фрагмент ключа, состояние и время последнего использования. Секрет целиком в базе не хранится.registration_rules содержит разрешённые комбинации TOS/STS/NOP. Пока правил нет, сохраняется прежняя свободная регистрация.sensor_types содержит дополнительные типы датчиков и подписи для интерфейса.Журнал bxs_logs.db → request_log хранит запросы к сервисам устройств; в response_body записывается ответ, чувствительные поля маскируются.
Используйте этот интерфейс для новых интеграций. Он разделён на три направления: регистрация устройств, передача мобильной телеметрии и чтение ключевых параметров по MAC. Старые адреса factory_bxs.php, ble.php и blex.php продолжают работать.
Создайте ключ в Администрирование → API → Ключи. Войдите в раздел администрирования по паролю сотрудника. Этот пароль не используется как ключ интеграции. Секрет API показывается один раз при выпуске; в базе хранится его хеш. Перевыпуск немедленно отключает старый ключ. При необходимости для совместимости можно задать серверный общий ключ BXS_API_KEY. Используйте HTTPS.
Передавайте ключ заголовком Authorization: Bearer <ключ> (или X-API-Key). Ответы содержат X-API-Version: 1 и JSON с полями api_version, ok, data или error. Имена входных полей не зависят от регистра, в ответе они в нижнем регистре.
POST /api/v1/devices. Обязательны mac, tos, sts и nop. Дополнительные поля регистрации: fws (можно передать как fw), bat, otk, pos, key; для типа 304 можно передать vo3 как серийный номер. Сервер устанавливает dtm/dtc в формате YYMMDD, tsm/tsc и dop как Unix-время. Для BMS и 303 серийный номер назначается по логике factory_bxs.php; для 304 используется VO3. Ответ включает весь объект устройства, SN (если применимо), ANS и количество устройств с теми же TOS/NOP. Повторная регистрация MAC вернёт 409.
curl -X POST https://example.com/api/v1/devices \
-H 'Authorization: Bearer <API-ключ>' \
-H 'Content-Type: application/json' \
-d '{"device":{"mac":"50547B85F73C","tos":"BLS","sts":"V6","nop":"2605","fw":"35","bat":"3.6","key":"0604485b","pos":"1234"}}'
{"api_version":"1","ok":true,"data":{"ans":"INSERTED","mac":"50547B85F73C","quantity":1,"sn":null,"device":{"mac":"50547B85F73C","tos":"BLS","sts":"V6","nop":"2605","key":"0604485b","pos":"1234","fws":"35","dtm":"261006","dtc":"261006","tsm":1791244800,"tsc":1791244800,"dop":"1791244800","com":null,"bat":"3.6"}}}
Пример ответа показывает основные заполненные поля; объект device содержит остальные столбцы базы также (их значения будут null, если они ещё не передавались). После регистрации идентификаторы mac, tos, sts, nop и key неизменяемы через API и заводской/legacy обработчики. Если key нужно исправить, устройство следует зарегистрировать с правильным ключом до начала эксплуатации.
POST /api/v1/telemetry. MAC уже должен быть зарегистрирован. Переданные поля обновляются, пропущенные сохраняются, а явное null очищает значение. dtm и tsm обновляются сервером. Запрос принимает поля мобильной телеметрии из таблицы ниже; значения MAC/TOS/STS/NOP/KEY, отправленные внутри data, отклоняются как неподдерживаемые и не меняют запись.
curl -X POST https://example.com/api/v1/telemetry \
-H 'Authorization: Bearer <API-ключ>' \
-H 'Content-Type: application/json' \
-d '{"mac":"50547B85F73C","data":{"bat":"3.6","fws":"35","mav":"2.4.1","mos":"Android 15","mpv":"Pixel 8","lal":"59.944867,30.335429","cdt":"BLE","vo1":"4000","vo2":"28","vo3":"0","cof":"54332","coe":"12433","vof":"2","cop":"60","tow":"2 d 12:00:16","cor":"4","coc":"19","coa":"18","cnt":"902","err":"0","lov":"...","lol":"...","com":"Склад A-12","pos":"1234"}}'
{"api_version":"1","ok":true,"data":{"mac":"50547B85F73C","updated":true,"fields":["bat","fws","mav","mos","mpv","lal","cdt","vo1","vo2","vo3","cof","coe","vof","cop","tow","cor","coc","coa","cnt","err","lov","lol","com","pos"]}}
GET /api/v1/devices/{mac} возвращает ключевые параметры: MAC, тип, подтип, партию, индивидуальный ключ, серийный номер/комментарий, прошивку, батарею и даты. Чтобы выбрать дополнительные столбцы, передайте список в fields. Ключ передаётся тем же заголовком.
curl https://example.com/api/v1/devices/50547B85F73C \
-H 'Authorization: Bearer <API-ключ>'
{"api_version":"1","ok":true,"data":{"device":{"mac":"50547B85F73C","tos":"BLS","sts":"V6","nop":2605,"key":"0604485b","com":"Склад A-12","fws":"35","bat":"3.6","dtm":"261006","dtc":"261006","dop":"1791244800","tsm":1791244800,"tsc":1791244800}}}
Запрос произвольных полей: GET /api/v1/devices/50547B85F73C?fields=mac,tos,sts,nop,vo1,vo2,err. Разрешены имена столбцов из описания структуры базы ниже.
Если сервер не настроен на rewrite, используйте прямой адрес файла: api_v1.php?action=register, api_v1.php?action=telemetry или api_v1.php?action=device&mac=50547B85F73C.
Ниже приведены эквивалентные прямые URL для обычной установки без настройки rewrite. Все POST-запросы должны содержать заголовок Content-Type: application/json и JSON-объект в теле. В примерах замените домен и секрет на адрес вашей системы и ключ, созданный в панели.
# Linux / macOS: регистрация нового датчика
curl -i -X POST 'https://example.com/api_v1.php?action=register' \
-H 'Authorization: Bearer <API-ключ>' \
-H 'Content-Type: application/json' \
-d '{"mac":"50547B85F73C","tos":"BLS","sts":"V6","nop":"2605","fws":"35","bat":"3.6"}'
# Linux / macOS: обновить только заряд и координаты, прочие поля останутся прежними
curl -i -X POST 'https://example.com/api_v1.php?action=telemetry' \
-H 'Authorization: Bearer <API-ключ>' \
-H 'Content-Type: application/json' \
-d '{"mac":"50547B85F73C","data":{"bat":"3.5","lal":"59.944867,30.335429"}}'
# Получить только перечисленные поля устройства
curl -i 'https://example.com/api_v1.php?action=device&mac=50547B85F73C&fields=mac,tos,sts,nop,key,vo1,vo2,err' \
-H 'Authorization: Bearer <API-ключ>'
Тот же запрос регистрации из Windows PowerShell:
$base = 'https://example.com/api_v1.php'
$headers = @{ Authorization = 'Bearer <API-ключ>' }
$payload = @{ device = @{
mac = '50547B85F73C'; tos = 'BLS'; sts = 'V6'; nop = '2605'
fw = '35'; bat = '3.6'; key = '0604485b'; pos = '1234'
} } | ConvertTo-Json -Depth 5
Invoke-RestMethod -Method Post -Uri "$base?action=register" -Headers $headers `
-ContentType 'application/json' -Body $payload
Поле device при регистрации можно опустить и передать поля прямо в корне JSON, как в cURL-примере. Для телеметрии MAC всегда находится в корне, а измерения — внутри объекта data. При чтении MAC указывается в пути ресурса или параметром mac.
Успешная регистрация возвращает HTTP 201. В data.device сервер отдаёт запись после сохранения, включая установленные им даты. Для BMS и 303 номер SN записывается в com; для 304 серийный номер берётся из vo3. quantity — количество зарегистрированных устройств с теми же TOS и NOP.
{"api_version":"1","ok":true,"data":{"ans":"INSERTED","mac":"50547B85F73C","quantity":1,"sn":null,"device":{"mac":"50547B85F73C","tos":"BLS","sts":"V6","nop":"2605","fws":"35","bat":"3.6","dtm":"261006","dtc":"261006","tsm":"1791244800","tsc":"1791244800","dop":"1791244800"}}}
Примеры ошибок возвращаются в одном формате JSON; проверяйте и HTTP-статус, и поле ok:
// Такой MAC уже зарегистрирован: HTTP 409
{"api_version":"1","ok":false,"error":"Device is already registered","mac":"50547B85F73C"}
// Комбинация TOS/STS/NOP выключена правилами: HTTP 403
{"api_version":"1","ok":false,"error":"Device registration is not allowed for this type, subtype and party","tos":"BLS","sts":"V6","nop":"2605"}
// MAC ещё не зарегистрирован при передаче телеметрии: HTTP 404
{"api_version":"1","ok":false,"error":"Device is not registered","mac":"50547B85F73C"}
// Неверный или выключенный ключ: HTTP 401
{"api_version":"1","ok":false,"error":"Valid Bearer token required"}
При частичном обновлении телеметрии сервер меняет только переданные поля. Пропущенное поле остаётся без изменений; чтобы очистить поле, передайте для него JSON null, например {"mac":"50547B85F73C","data":{"lal":null}}. Не отправляйте в data регистрационные идентификаторы mac, tos, sts, nop или key: API отклонит такой запрос с 422.
Если ответ не JSON, проверьте URL и конфигурацию веб-сервера. Если приходит 503, выпустите и включите хотя бы один ключ в панели или задайте серверный BXS_API_KEY. Если приходит 401, проверьте Bearer-заголовок и статус ключа. Поля ответа fields или field в ошибке 422 подскажут, какое имя не поддерживается.
| Поля | Назначение |
|---|---|
ver, mac, bat, fws | Версия протокола, MAC, напряжение батареи, прошивка |
mav, mos, mpv, lal, cdt | Версия мобильного приложения, ОС и модель телефона, координаты, канал передачи |
vo1, vo2, vo3 | BLS/HLS: уровень и температура; BTS: температура и контакт; VO3 — третье значение датчика |
cof, coe, vof, cop | BLS/HLS: счётчики пустого и полного, фильтр и период измерения |
tow, cor, coc, coa, cnt, err | Время работы, перезапуски, подключения, авторизации, счётчик, код ошибки (0 — ошибок нет) |
lov, lol, com | Таблицы уровня и литров; комментарий BLS/HLS, серийный номер других типов |
pos, tos, sts, key, nop | Пароль датчика, тип, подтип, индивидуальный ключ, номер партии |
Регистрацию можно ограничивать в административном разделе комбинацией TOS + STS + NOP. Пока правил нет, действует прежний режим без ограничений. После добавления первого правила пропускаются только совпавшие активные комбинации; * заменяет любое значение отдельно в каждом поле. Правило можно включать и отключать. Оно применяется к API v1 и legacy-регистрации новых устройств. Старые правила TOS/NOP автоматически переносятся с подтипом *.
В разделе Администрирование → Типы датчиков показаны системные типы, типы из базы устройств и добавленные вручную. Название каждого типа можно менять — оно отображается в карточке устройства, а в основной таблице остаётся короткий код TOS. В блоке управления устройством администратор может отредактировать поля записи (включая регистрационные идентификаторы) или физически удалить её из BxS. Это административное исправление; ограничения неизменяемости в API остаются в силе. Журналы запросов при удалении сохраняются, а при смене MAC остаются привязаны к прежнему MAC.
200 — чтение или обновление; 201 — создано; 401 — неверный ключ; 403 — регистрация не разрешена правилом; 404 — ресурс или MAC не найдены; 405 — неверный HTTP-метод; 409 — MAC уже зарегистрирован; 415 — нужен JSON; 422 — неверное поле или формат; 503 — не создан ни один API-ключ.
Журнал интеграции содержит время, endpoint, MAC, причину, набор полей, сырой запрос и тело ответа. Значения ключей и паролей в журнале маскируются.
POST Регистрирует новое устройство при производстве. Данные шифруются AES-256-CBC с ключом BxS.
| Параметр | Обязательный | Описание |
|---|---|---|
| mac | ✓ | MAC-адрес (12 HEX) |
| dop | ✓ | Дата производства (Unix) |
| tos | ✓ | Тип устройства: BMS, BLS, BAS, BTS, HLS... |
| sts | — | Подтип: V6, V8... |
| nop | — | Номер партии |
| key | — | Ключ устройства |
POST factory_bxs.php
Body: ver=1&mac=50547B85F73C&dop=1718582400&tos=BMS&sts=V6&nop=2421&key=c46c24ab
{"ok":true,"mac":"50547B85F73C","sn":"304858"}
BxS, метод — AES-256-CBC. Расшифровка происходит на сервере.POST Принимает телеметрию от мобильного приложения по Bluetooth. Версия протокола ver=1.
| Параметр | Обязательный | Описание |
|---|---|---|
| ver | ✓ | Версия протокола (1) |
| mac | ✓ | MAC-адрес датчика |
| bat | — | Батарея датчика |
| fws | — | Версия прошивки датчика |
| mav | — | Версия мобильного приложения |
| mos | — | Версия операционной системы телефона |
| mpv | — | Модель телефона |
| lal | — | Широта и долгота |
| cdt | — | Канал передачи данных |
| vo1 | — | BLS/HLS — уровень; BTS — температура |
| vo2 | — | BLS/HLS — температура; BTS — контакт |
| vo3 | — | Параметр 3, значение зависит от типа датчика |
| cof | — | Для BLS/HLS — счётчик пустого |
| coe | — | Для BLS/HLS — счётчик полного |
| vof | — | Степень фильтрации |
| cop | — | Период измерения |
| tow | — | Время работы датчика |
| cor | — | Количество перезапусков |
| coc | — | Количество подключений |
| coa | — | Количество авторизаций |
| cnt | — | Счётчик |
| err | — | Номер ошибки; 0 — ошибок нет |
| lov, lol | — | Таблицы калибровки уровня и литров |
| com | — | Для BLS/HLS — комментарий; у остальных типов — серийный номер |
| pos | — | Пароль пользователя датчика |
| tos, sts | — | Тип и подтип датчика |
| key | — | Индивидуальный ключ |
| nop | — | Номер партии |
| otk | — | ФИО ОТК |
| req | — | Тело запроса |
| dtm, dtc | — | Дата изменения и дата создания записи |
| tsm, tsc | — | Unix-время изменения и создания записи |
| dop | — | Дата производства (Unix timestamp) |
POST ble.php
Body: ver=1&mac=50547B85CDE1&bat=3.6&fws=19&mav=20230123&mos=Android+10.5&mpv=Samsung+Note20&lal=59.9448669,30.335429&cor=5&coc=3&cnt=1234&err=0&vo1=4000&vo2=28&cof=54332&coe=12433&vof=5&cop=80
{"ok":true,"mac":"50547B85CDE1","updated":true}
GET/POST Возвращает данные конкретного устройства в формате JSON. Используется для запроса информации по MAC.
| Параметр | Тип | Описание |
|---|---|---|
| mac | string | MAC-адрес устройства |
GET blex.php?mac=50547B85CDE1
{
"ok": true,
"device": {
"MAC": "50547B85CDE1",
"TOS": "BMS",
"STS": "V6",
"BAT": "3.6",
"FWS": "19",
"LAL": "59.9448669,30.335429",
"TOW": "39 d 23:32:33"
}
}
GET/POST Возвращает серийный номер (COM) для устройства BMS по его MAC-адресу.
GET bms_get_id.php?mac=50547B85F73C
{"ok":true,"mac":"50547B85F73C","sn":"304858"}
GET/POST Обратный поиск: возвращает MAC-адрес по серийному номеру (COM).
GET bms_get_mac.php?sn=304858
{"ok":true,"mac":"50547B85F73C","sn":"304858"}
POST Регистрирует RFID-метку. Данные шифруются AES с ключом DTARFID.
| Параметр | Обязательный | Описание |
|---|---|---|
| mac | ✓ | MAC-адрес устройства |
| rfid | ✓ | RFID-метка |
| key | — | Ключ подтверждения |
POST rfid_get_id.php
Content-Type: application/octet-stream
Body: [AES-256-CBC encrypted payload]
{"ok":true,"mac":"50547B85F73C","rfid":"A1B2C3D4"}
Некоторые сервисы используют симметричное шифрование для защиты данных при передаче:
| Сервис | Метод | Ключ | Что шифруется |
|---|---|---|---|
factory_bxs.php | AES-256-CBC | BxS | Тело запроса (параметры устройства) |
rfid_get_id.php | AES-256-CBC | DTARFID | Тело запроса (RFID-данные) |
ble.php | — | — | Открытый текст (ver=1) |
// Шифрование запроса для factory_bxs.php
$key = 'BxS';
$method = 'AES-256-CBC';
$iv = openssl_random_pseudo_bytes(16);
$data = 'ver=1&mac=50547B85F73C&dop=1718582400&tos=BMS&sts=V6&nop=2421&key=c46c24ab';
$encrypted = openssl_encrypt($data, $method, $key, OPENSSL_RAW_DATA, $iv);
// Отправка: base64($iv) + base64($encrypted)
$payload = base64_encode($iv) . '.' . base64_encode($encrypted);
// POST factory_bxs.php с телом $payload
$key = 'BxS';
$method = 'AES-256-CBC';
$parts = explode('.', $payload);
$iv = base64_decode($parts[0]);
$encrypted = base64_decode($parts[1]);
$decrypted = openssl_decrypt($encrypted, $method, $key, OPENSSL_RAW_DATA, $iv);
// $decrypted содержит исходные параметры
Поле COM зависит от типа датчика: у BLS/HLS в нём хранится комментарий, у остальных типов — серийный номер. Для устройств, где формируется S/N, он генерируется при заводской регистрации:
factory_bxs.php с новым MAC — создаётся запись в БДCOMble.php — S/N не меняется, обновляются только телеметрические данныеbms_get_id.php — возвращает S/N по MAC (только для типа BMS)bms_get_mac.php — обратный поиск MAC по S/N (только для типа BMS)COM используется как S/N, номер уникален. Для BLS/HLS в этом поле хранится комментарий. При повторной регистрации того же MAC возвращается существующий S/N./var/www/bxs-panel, данные — в /var/lib/bxs. Задайте абсолютный путь BXS_DATA_DIR.BXS_DATA_DIR=/var/lib/bxs php install.php. Через веб установщик недоступен.cd /path/to/dta-panel
php install.php
php -S 127.0.0.1:8080
Затем откройте http://localhost:8080/index.php
| Файл | Назначение |
|---|---|
index.php | Веб-интерфейс: таблица, статистика, карта, карточки |
api_v1.php | Единый API v1 для интеграций регистрации, телеметрии и чтения устройств |
docs.php | Документация API (эта страница) |
factory_bxs.php | Заводская регистрация устройств (AES) |
ble.php | Приём телеметрии от мобильного приложения |
blex.php | Совместимый HTML-просмотр данных устройства |
bms_get_id.php | Получение S/N по MAC (BMS) |
bms_get_mac.php | Получение MAC по S/N (BMS) |
rfid_get_id.php | Регистрация RFID-меток (AES) |
db_bxs.db | База данных SQLite (не входит в поставку) |