АПК Синапс v1.0. ПО. Спецификации на разработку
Последнее изменение: 22.12.2025, 12:24 МСК
1. Назначение документа
Описать протокол передачи команд и данных между программными модулями АПК Синапс.
2. Термины и определения
2.1. USM (Unit System Model) — виртуальная модель системы освещения, включающая как данные устройств DALI-линии, так и метаданные (названия локаций, светильников и т.п.), так и данные для автоматизации (расписание и т.п.), так и много ещё чего.
2.2. FW-USM — USM в прошивке. В виде массивов структур языка С. Описано в SynapsePDS_FW_DB.
2.3. APP-USM — USM в приложении. В виде реляционной базы в SQLite. Описано в SynapsePDS_APP_DB.
2.4. USML (Unit System Model Language) — система команд (телеграмм) для обмена данными между приложением и USM в прошивке.
2.5. JSON/USML-конвертер — конвертилка телеграмм из формата JSON в USML и обратно.
2.6. Телеграмма, она же телега — название команды в USML, названная так, дабы отличать их от других команд, содержащая часть или все данные USM.
2.7. АПК — аппаратно-программный комплекс Синапс.
3. Общие моменты
3.1. Передача данных в АПК:
3.2. Экземпляр USM в приложении (APP-USM) — своего рода кэш USM контроллера (FW-USM). Так же как USM контроллера хранит состояние устройств DALI, чтобы за ним каждый раз не лазать в линию, так и USM в приложении нужен для оперативного получения состояния системы LLM'кой и UI.
3.3. Команды на изменение своего состояния FW-USM получает от LLM и UI (после их конвертации в JSON/USML-конвертер из JSON в USML).
3.4. Изменив своё состояние, FW-USM отправляет телеги об этом в APP-USM всех телефонов, которые в данный момент подключены к контроллеру.
3.5. В телегах, дабы не забивать узкие каналы передачи данных (UART например), надо по возможности передавать только изменяющиеся данные, а не всю USM целиком. Внутри приложения на это понятно пофиг. В LLM при каждом запросе надо слать всю USM, чтобы нейросеть понимала всю картину.
4. Формат телеграмм
Телеги в АПК имеют хождение в двух форматах:
- JSON — где в виде текстового JSON передаются данные из таблиц APP-USM, в том виде, в каком они в этих таблицах лежат и в каком во всём цивилизованном мире их передавать принято. В этом JSON в виде нормальных значений находятся в том числе ID и интерфейсные данные из таблиц. В отличие от их вида в телегах USML, где они подаются одним бинарным блоком, обозванным IDATA.
- USML — бинарный формат с хитрым форматом, но зато размером в разы меньшим, чем JSON-вид.
Телеги формата JSON могут взаимно однозначно конвертироваться в формат USML.
4.1. JSON
Здесь всё тривиально. Представить кусок реляционной базы данных (USM в SQLite приложения) в виде JSON не составляет труда.
Например, информация о включении в трех локациях световой сцены 3:
ID=0, SCENE_NUM=3
ID=1, SCENE_NUM=3
ID=2, SCENE_NUM=3
в JSON будет иметь вид:
{
"LOCATIONS": [
{
"ID":"0",
"SCENE_NUM":"3"
},
{
"ID":"1",
"SCENE_NUM":"3"
},
{
"ID":"2",
"SCENE_NUM":"3"
},
]
}
4.2. USML
Вот тут начинается жуткий треш 🤦♂️
USML-телега состоит из двух частей:
- Реестр — битовая последовательность, определяющая, какие данные находятся в части данные.
- Данные — собственно данные в виде последовательностей байтов, идущих одна за другой без разделителей в том виде, в каком они хранятся в переменных языка Си.
4.2.1. Реестр
4.2.1.1. В реестре битами кодируется наличие объектов БД в данных.
4.2.1.2. Под объектами понимаются:
- таблицы;
- записи в таблицах;
- поля записей.
4.2.1.3. Формирование идёт строго в порядке, определённом в SynapsePDS_FW_DB — раздел 5 «Структура БД прошивки».
4.2.1.4. Первый шаг: идём по таблицам; ставим 1 — если таблица нужна, 0 — если не нужна.
4.2.1.5. Второй шаг: идём по записям тех таблиц, которые нужны (см. Первый шаг); ставим 1 — если запись нужна, 0 — если не нужна; порядок записей — согласно их расположению в соответствующих массивах прошивки.
4.2.1.6. Третий шаг: идём по полям записей, которые нужны (см. Второй шаг); ставим 1 — если поле нужно, 0 — если не нужно.
4.2.2. Данные
Имея согласно реестру набор полей, которые нас интересуют, собираем из их значений блок с данными в понятном порядке.
4.2.3. Пример
Телега про три локации из раздела о JSON-формате в реалиях USML:
Исходные данные (изменение сцены в 3 локациях):
- Локация 0: SCENE_NUM=3
- Локация 1: SCENE_NUM=3
- Локация 2: SCENE_NUM=3
Реестр (битовая последовательность):
-
Таблицы (12 таблиц):
- Биты:
0 1 0 0 0 0 0 0 0 0 0 0(только LOCATIONS=1, остальные=0)
- Биты:
-
Записи LOCATIONS (16 записей):
- Биты:
1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0(записи 0,1,2 нужны)
- Биты:
-
Поля для записей 0,1,2 (порядок: EXIST, IS_AUTO, SCENE_NUM):
- Запись 0:
0 0 1(только SCENE_NUM) - Запись 1:
0 0 1(только SCENE_NUM) - Запись 2:
0 0 1(только SCENE_NUM) - Итого:
001 001 001
- Запись 0:
Итоговая битовая последовательность реестра (37 бит):
010000000000 1110000000000000 001001001
В байтах (дополняем до кратности 8, добавляя 3 нуля):
01000000 00001110 00000000 00000010 01001000
В HEX:
40 0E 00 02 48
Данные (последовательность байтов):
Для записи 0: SCENE_NUM = 3 = 0x03
Для записи 1: SCENE_NUM = 3 = 0x03
Для записи 2: SCENE_NUM = 3 = 0x03
Итоговая USML-телеграмма (в HEX):
40 0E 00 02 48 | 03 03 03
[ Реестр ] [Данные: 3 байта]
Важно: Передаём только изменившееся поле SCENE_NUM (п.3.5), а не все поля записей LOCATIONS