АПК Синапс v1.0. ПО. Спецификации на разработку
Последнее изменение: 13.12.2025, 19:20 МСК
1. Назначение документа
Описать структуру базы данных (USM, Unit System Model) прошивки контроллера.
2. Термины и определения
1.1. Рабочие данные — необходимые для организации работы освещения и в прошивке, и в приложении. В приложении находятся в таблицах SQLite, в прошивке в виде массивов структур C.
1.2. Интерфейсные данные — используемые только приложением для организации пользовательского интерфейса. Примеры: названия светильников, номера их иконок. В приложении находятся в таблицах SQLite, в прошивке в виде единого блока где-то в постоянной памяти. Для понятности в описании БД прошивки и логики работы прошивки считаем, что блок интерфейсных данных лежит в BLOB-поле единственной записи в таблице CONTROLLERS.
3. Основные положения
2.1. «Таблицы» БД в прошивке разложены в массивы структур C. Тем не менее ниже для простоты они представляются именно как таблицы.
2.2. Индексация записей в таблицах ниже осуществляется по индексам соответствующих структур в массивах. Поэтому отдельных полей ID, как в аналогичных таблицах приложения, здесь нет, но поля с FK на эти индексы (типа LOCATION_ID) есть. LUMINAIRES.LOCATION_ID = 5 означает, что светильник приписан к локации, которая в массиве локаций лежит в 6-м элементе массива с локациями (нумерация индексов массивов начинается с 0).
4. Таблицы
4.1. CONTROLLERS
Таблица с информацией о контроллере. Имеет одну запись. Представлена здесь таблицей для общности с DB приложения. В реальности является просто набором переменных, хранящихся в прошивке.
- NAME (char[20] / "") — название контроллера, показываемое в приложении и списке устройств Bluetooth;
- PASSWORD (char[4] / "") — пароль заводской или изменённый пользователем; 4 цифры; заводской на коробке (или наклейке на корпусе);
- IS_SCHEDULE (uint8_t / 0) — включена ли в контроллере работа по расписанию (1/0);
- IS_AUTO (uint8_t / 0) — главный выключатель автоматического режима для всего контроллера (1/0);
- ICO_NUM (uint8_t / 100) — номер иконки, которую будет иметь контроллер в приложении; 100 — дефолтная.
- STATUS (char[1] / 'A') — текущее состояние контроллера: A (ACTIVE) — штатная работа, I (INIT) — инициализация линии DALI, F (FAILURE) — неполадка.
- SCENE_NUM (uint8_t / 255) — световая сцена, включённая для всего объекта (0,1,2,3,4); 255 = нет активной сцены
- TIMESTAMP (uint32_t / 0) — текущие дата и время в формате Unix timestamp (количество секунд с 01.01.1970 00:00:00 UTC); обновляется при каждом подключении телефона.
- IDATA (BLOB(50000)) — интерфейсные данные; просто обозначим это здесь, чтобы где-то было; понятно, что это некая отдельная область памяти в контроллере. В версии USM приложения этого поля нет, оно там разложено по дополнительным полям в этих же таблицах. Всё по честному: тут нет этих доп. полей, там нет этого BLOB поля. Конвертация происходит в JSON/USML-конверторе приложения.
4.2. LOCATIONS
Локации.
- EXIST (uint8_t / 0) — задействована ли запись в работе или это пустое место, где может храниться запись (1/0).
- IS_AUTO (uint8_t / 0) — работает ли локация в автоматическом режиме по датчикам (1/0).
- SCENE_NUM (uint8_t / 255) - световая сцена, включенная в этой локации (0,1,2,3,4); 255 = нет активной сцены
4.3. GROUPS
Группы светильников. Номер группы в DALI совпадает с ID (индексу в массиве) записи.
- EXIST (uint8_t / 0) — задействована ли запись в работе или это пустое место, где может храниться запись (1/0).
- LOCATION_ID (short / -1) — локация, к которой привязана группа; -1 — группа без локации (в корне);
- SCENE_NUM (uint8_t / 255) - световая сцена, включенная в этой группе (0,1,2,3,4); 255 = нет активной сцены
4.4. LUMINAIRES
Светильники.
- EXIST (uint8_t / 0) — задействована ли запись в работе или это пустое место, где может храниться запись (1/0).
- DALI_ADDR (uint8_t / 255) — короткий адрес DALI; 255 = адрес не назначен
- LOCATION_ID (short / -1) — локация, к которой привязан светильник; -1 — светильник без локации (в корне);
- GROUP_ID (short / -1) — группа, к которой привязан светильник; если светильник не в группе: -1;
- VAL_BRIGHT (uint8_t / 0) — значение яркости;
- VAL_TW (uint8_t / 127) — значение температуры белого света;
- VAL_R (uint8_t / 255) — значение красного канала (для RGB);
- VAL_G (uint8_t / 0) — значение зелёного канала (для RGB);
- VAL_B (uint8_t / 0) — значение синего канала (для RGB);
- VAL_W (uint8_t / 0) — значение белого канала (для RGBW).
- SCENE_NUM (uint8_t / 255) - световая сцена, включенная у этого светильника (0,1,2,3,4); 255 = нет активной сцены
- MIN_LEVEL (uint8_t / 0) — минимальный уровень яркости светильника;
- MAX_LEVEL (uint8_t / 254) — максимальный уровень яркости светильника;
- FADE_TIME (uint8_t / 0) — время плавного перехода между уровнями яркости.
- STATUS (char[1] / 'A') — текущее состояние устройства: A (ACTIVE) — штатная работа, C (CHANGE) — замена устройства, F (FAILURE) — неполадка.
4.5. SCENE_LUMINAIRES
Параметры светильников в сценах.
- SCENE_NUM (uint8_t / 0) - световая сцена (0,1,2,3,4)
- LUMINAIRE_ID (uint8_t / 0) — светильник;
- VAL_BRIGHT (uint8_t / 0) — значение яркости;
- VAL_TW (uint8_t / 127) — значение температуры белого света;
- VAL_R (uint8_t / 255) — значение красного канала (для RGB);
- VAL_G (uint8_t / 0) — значение зелёного канала (для RGB);
- VAL_B (uint8_t / 0) — значение синего канала (для RGB);
- VAL_W (uint8_t / 0) — значение белого канала (для RGBW).
4.6. PRES_SENSORS
Датчики присутствия.
- EXIST (uint8_t / 0) — задействована ли запись в работе или это пустое место, где может храниться запись (1/0).
- DALI_ADDR (uint8_t / 255) — короткий адрес DALI датчика; 255 = адрес не назначен
- DALI_INST (uint8_t / 0) — номер инстанса датчика движения в DALI;
- LOCATION_ID (short / -1) — локация, к которой привязан датчик; -1 — датчик без локации (в корне);
- ACTION_OCCUPANCY_ID (short / -1) — действие, повешенное на присутствие; -1 — не повешено действие;
- ACTION_VACANCY_ID (short / -1) — действие, повешенное на отсутствие; -1 — не повешено действие;
- HOLD_TIME (uint8_t / 0) — задержка перед срабатыванием действия на отсутствие.
- STATUS (char[1] / 'A') — текущее состояние устройства: A (ACTIVE) — штатная работа, C (CHANGE) — замена устройства, F (FAILURE) — неполадка.
4.7. BRIGHT_SENSORS
Датчики освещённости.
- EXIST (uint8_t / 0) — задействована ли запись в работе или это пустое место, где может храниться запись (1/0).
- DALI_ADDR (uint8_t / 255) — короткий адрес DALI датчика; 255 = адрес не назначен
- DALI_INST (uint8_t / 0) — номер инстанса датчика движения в DALI;
- LOCATION_ID (short / -1) — локация, к которой привязан датчик; -1 — датчик без локации (в корне);
- GROUP_ID (short / -1) — группа, к которой привязан датчик; -1 — группа не назначена.
- SCENE_BRIGHTNESS_0 (uint8_t / 0) — целевая освещённость для сцены 0;
- SCENE_BRIGHTNESS_1 (uint8_t / 0) — целевая освещённость для сцены 1;
- SCENE_BRIGHTNESS_2 (uint8_t / 0) — целевая освещённость для сцены 2;
- SCENE_BRIGHTNESS_3 (uint8_t / 0) — целевая освещённость для сцены 3;
- SCENE_BRIGHTNESS_4 (uint8_t / 0) — целевая освещённость для сцены 4;
- STATUS (char[1] / 'A') — текущее состояние устройства: A (ACTIVE) — штатная работа, C (CHANGE) — замена устройства, F (FAILURE) — неполадка.
4.8. BUTTON_PANELS
Кнопочные панели.
- EXIST (uint8_t / 0) — задействована ли запись в работе или это пустое место, где может храниться запись (1/0).
- DALI_ADDR (uint8_t / 255) — короткий адрес панели в DALI; 255 = адрес не назначен
- LOCATION_ID (short / -1) — локация, к которой привязана панель; -1 — панель без локации (в корне);
- STATUS (char[1] / 'A') — текущее состройние устройства: A (ACTIVE) — штатная работа, C (CHANGE) — замена устройства, F (FAILURE) — неполадка.
4.9. BUTTONS
Кнопки.
- BUTTON_PANEL_ID (short / -1) — кнопочная панель, в которой кнопка расположена;
- DALI_INST (uint8_t / 0) — номер инстанса кнопки в DALI.
4.10. ACTIONS
Действия с устройствами.
- BUTTON_SHORT_ID (short / -1) — кнопка, на короткое нажатие которой навешено действие; -1 — действие не привязано к короткому нажатию кнопки (может быть привязано к датчику или событию расписания);
- BUTTON_LONG_ID (short / -1) — кнопка, на долгое нажатие которой навешено действие; -1 — действие не привязано к долгому нажатию кнопки (может быть привязано к датчику или событию расписания);
- POS (uint8_t / 0) — позиция действия в наборе (начиная с 1); для перебора нескольких действий одной кнопкой.
4.11. SUBACTIONS
Поддействия действий.
- ACTION_ID (short / -1) — действие;
- OBJECT_TYPE (uint8_t / 0) — тип объекта изменений:
- 1 — весь объект;
- 2 — локация;
- 3 — группа;
- 4 — светильник;
- OBJECT_NUM (uint8_t / 0) — номер объекта изменений:
- 1 — сцена;
- 2 — температура TW;
- 3 — флаг АВТО.
- VALUE (uint8_t / 0) — значение в зависимости от объекта:
- сцена - 0..4;
- температура TW - 0..254;
- флаг АВТО - 0 / 1.
4.12. EVENTS
События расписания.
- EXIST (uint8_t / 0) — задействована ли запись в работе или это пустое место, где может храниться запись (1/0).
- DAYS (char[7] / "TTTTTTT") — 'FFTFFFF' — событие по дням недели; если все T — ежедневное;
- TIME (char[4] / "0000") — время события с точностью до минуты в формате HHMM 24H;
- SMOOTH (uint8_t / 0) — плавное изменение параметров от предыдущих значений (яркость, температура света) (1/0);
- ACTION_ID (short / -1) — действие.
5. Структура БД прошивки (USM прошивки)
CONTROLLERS (1)
- NAME (20)
- PASSWORD (4)
- IS_SCHEDULE (1)
- IS_AUTO (1)
- ICO_NUM (1)
- STATUS (1)
- SCENE_NUM (1)
- TIMESTAMP (4)
- IDATA (50000)
LOCATIONS (16)
- EXIST (1)
- IS_AUTO (1)
- SCENE_NUM (1)
GROUPS (16)
- EXIST (1)
- LOCATION_ID (2)
- SCENE_NUM (1)
LUMINAIRES (64)
- EXIST (1)
- DALI_ADDR (1)
- LOCATION_ID (2)
- GROUP_ID (2)
- VAL_BRIGHT (1)
- VAL_TW (1)
- VAL_R (1)
- VAL_G (1)
- VAL_B (1)
- VAL_W (1)
- SCENE_NUM (1)
- STATUS (1)
SCENE_LUMINAIRES (320)
- SCENE_NUM (1)
- LUMINAIRE_ID (1)
- VAL_BRIGHT (1)
- VAL_TW (1)
- VAL_R (1)
- VAL_G (1)
- VAL_B (1)
- VAL_W (1)
PRES_SENSORS (64)
- EXIST (1)
- DALI_ADDR (1)
- DALI_INST (1)
- LOCATION_ID (2)
- ACTION_OCCUPANCY_ID (2)
- ACTION_VACANCY_ID (2)
- HOLD_TIME (1)
- STATUS (1)
BRIGHT_SENSORS (64)
- EXIST (1)
- DALI_ADDR (1)
- DALI_INST (1)
- LOCATION_ID (2)
- GROUP_ID (2)
- SCENE_BRIGHTNESS_0 (1)
- SCENE_BRIGHTNESS_1 (1)
- SCENE_BRIGHTNESS_2 (1)
- SCENE_BRIGHTNESS_3 (1)
- SCENE_BRIGHTNESS_4 (1)
- STATUS (1)
BUTTON_PANELS (64)
- EXIST (1)
- DALI_ADDR (1)
- LOCATION_ID (2)
- STATUS (1)
BUTTONS (512)
- BUTTON_PANEL_ID (2)
- DALI_INST (1)
- ACTION_LONG_ID (2)
ACTIONS (512)
- BUTTON_SHORT_ID (2)
- POS (1)
SUBACTIONS (512)
- ACTION_ID (2)
- OBJECT_TYPE (1)
- OBJECT_NUM (1)
- VALUE (1)
EVENTS (256)
- EXIST (1)
- DAYS (7)
- TIME (4)
- SMOOTH (1)
- ACTION_ID (2)
6. Структура БД прошивки в виде JSON (USM прошивки)
ВАЖНО: При любом изменении структуры БД (добавление/удаление полей, изменение размеров, изменение количества записей, изменение порядка таблиц или полей) ОБЯЗАТЕЛЬНО увеличивать VERSION.
{
"VERSION": 13,
"CONTROLLERS": {
"RECORDS": 1,
"FIELDS": {
"NAME": 20,
"PASSWORD": 4,
"IS_SCHEDULE": 1,
"IS_AUTO": 1,
"ICO_NUM": 1,
"STATUS": 1,
"SCENE_NUM": 1,
"TIMESTAMP": 4,
"IDATA": 50000
}
},
"LOCATIONS": {
"RECORDS": 16,
"FIELDS": {
"EXIST": 1,
"IS_AUTO": 1,
"SCENE_NUM": 1
}
},
"GROUPS": {
"RECORDS": 16,
"FIELDS": {
"EXIST": 1,
"LOCATION_ID": 2,
"SCENE_NUM": 1
}
},
"LUMINAIRES": {
"RECORDS": 64,
"FIELDS": {
"EXIST": 1,
"DALI_ADDR": 1,
"LOCATION_ID": 2,
"GROUP_ID": 2,
"VAL_BRIGHT": 1,
"VAL_TW": 1,
"VAL_R": 1,
"VAL_G": 1,
"VAL_B": 1,
"VAL_W": 1,
"SCENE_NUM": 1,
"MIN_LEVEL": 1,
"MAX_LEVEL": 1,
"FADE_TIME": 1,
"STATUS": 1
}
},
"SCENE_LUMINAIRES": {
"RECORDS": 320,
"FIELDS": {
"SCENE_NUM": 1,
"LUMINAIRE_ID": 1,
"VAL_BRIGHT": 1,
"VAL_TW": 1,
"VAL_R": 1,
"VAL_G": 1,
"VAL_B": 1,
"VAL_W": 1
}
},
"PRES_SENSORS": {
"RECORDS": 64,
"FIELDS": {
"EXIST": 1,
"DALI_ADDR": 1,
"DALI_INST": 1,
"LOCATION_ID": 2,
"ACTION_OCCUPANCY_ID": 2,
"ACTION_VACANCY_ID": 2,
"HOLD_TIME": 1,
"STATUS": 1
}
},
"BRIGHT_SENSORS": {
"RECORDS": 64,
"FIELDS": {
"EXIST": 1,
"DALI_ADDR": 1,
"DALI_INST": 1,
"LOCATION_ID": 2,
"GROUP_ID": 2,
"SCENE_BRIGHTNESS_0": 1,
"SCENE_BRIGHTNESS_1": 1,
"SCENE_BRIGHTNESS_2": 1,
"SCENE_BRIGHTNESS_3": 1,
"SCENE_BRIGHTNESS_4": 1,
"STATUS": 1
}
},
"BUTTON_PANELS": {
"RECORDS": 64,
"FIELDS": {
"EXIST": 1,
"DALI_ADDR": 1,
"LOCATION_ID": 2,
"STATUS": 1
}
},
"BUTTONS": {
"RECORDS": 512,
"FIELDS": {
"BUTTON_PANEL_ID": 2,
"DALI_INST": 1
}
},
"ACTIONS": {
"RECORDS": 512,
"FIELDS": {
"BUTTON_SHORT_ID": 2,
"BUTTON_LONG_ID": 2,
"POS": 1
}
},
"SUBACTIONS": {
"RECORDS": 512,
"FIELDS": {
"ACTION_ID": 2,
"OBJECT_TYPE": 1,
"OBJECT_NUM": 1,
"VALUE": 1
}
},
"EVENTS": {
"RECORDS": 256,
"FIELDS": {
"EXIST": 1,
"DAYS": 7,
"TIME": 4,
"SMOOTH": 1,
"ACTION_ID": 2
}
}
}
7. Структура блока интерфейсных данных (IDATA)
Интерфейсные данные находятся в:
- Приложении: в виде отдельных полей БД (APP-USM); никакого поля IDATA в таблице CONTROLLERS в APP-USM не существует.
- Прошивке: в виде блока 50000 байт где-то в памяти; отдельных полей для этих данных, как в приложении, нет; для простоты считаем во всех документах, что этот блок лежит в поле IDATA единственной записи таблицы CONTROLLERS прошивки.
Блок IDATA представляет собой последовательность байтов интерфейсных данных (это поля, которые есть в БД приложения APP-USM, но отсутствуют в БД прошивки FW-USM как отдельные поля). Данные идут строго в следующем порядке:
{
"VERSION": 1,
"CONTROLLERS": {
"RECORDS": 1,
"FIELDS": {
"SCALE": 2
}
},
"LOCATIONS": {
"RECORDS": 16,
"FIELDS": {
"NAME": 30,
"ICO_NUM": 1,
"SCALE": 2,
"POS_X": 2,
"POS_Y": 2
}
},
"GROUPS": {
"RECORDS": 16,
"FIELDS": {
"NAME": 30
}
},
"LUMINAIRES": {
"RECORDS": 64,
"FIELDS": {
"NAME": 30,
"ICO_NUM": 1,
"POS_X": 2,
"POS_Y": 2
}
},
"PRES_SENSORS": {
"RECORDS": 64,
"FIELDS": {
"NAME": 30
}
},
"BRIGHT_SENSORS": {
"RECORDS": 64,
"FIELDS": {
"NAME": 30
}
},
"BUTTON_PANELS": {
"RECORDS": 64,
"FIELDS": {
"NAME": 30
}
},
"BUTTONS": {
"RECORDS": 512,
"FIELDS": {
"NAME": 30
}
}
}
Примечания:
7.1. Все текстовые поля (NAME) имеют фиксированную длину с завершающим нулём \0. Если название короче, оставшиеся байты заполняются нулями.
7.2. Порядок данных в блоке IDATA строго соответствует порядку таблиц и записей в структуре БД прошивки (раздел 5).
7.3. При конвертации телег JSON↔USML конвертер приложения распаковывает/упаковывает IDATA в соответствующие поля таблиц APP-USM.