Концепции¶
Общая картина платформы. Из чего она состоит, как куски разговаривают, где хранится состояние.
Архитектура целиком¶
┌──────────────┐
│ голосовой │
│ ассистент │
└──────┬───────┘
│ OAuth2 + Smart Home API
▼
┌────────────────────────────────────┐
│ cloud-service (cloud.kavlev.ru) │
│ FastAPI + Postgres + MQTT-брокер │
└─────────────┬────────────┬─────────┘
│ HTTPS │ MQTT (Phase Broker)
│ heartbeat │ commands
▼ ▼
┌─────────────────────────────────┐
│ ctrl-board (ESP8266/ESP32) │
│ web-UI + REST API + LittleFS │
└───┬─────────────────────┬───────┘
│ UDP multicast │ GPIO
│ (HMAC-SHA256) │
▼ ▼
соседние платы реле и датчики
Главный принцип: каждая плата — отдельная, самодостаточная единица. Облако сверху — слой обмена и удобства, а не зависимость.
Главные понятия платы¶
Устройство (Device)¶
«Физическая штука, привязанная к пину». Бывает двух больших классов:
- Actuator — то, чем плата управляет: реле, MOSFET, симистор. Контролируется командами
on/off/toggle. - Sensor — то, что плата читает: датчики температуры, влажности, расстояния, аналоговые/цифровые входы, кнопки.
Все устройства живут в /config/devices.json на самой плате. У каждого устройства минимум: id, name, type (плагин), pin (или pin1+pin2 для многоконтактных), плюс плагин-специфичные поля (i2c_address, onewire_address, inverted и т.д.).
Подробнее — Устройства.
Задача (Task)¶
«Если триггер сработал и условия выполнены — выполнить действия».
Структура задачи:
| Часть | Сколько | Что это |
|---|---|---|
| Триггеры | до 3, объединены ИЛИ | Когда задача может сработать |
| Условия | до 4, all/any | Дополнительный фильтр перед действиями |
| Окно валидности | 1 | По времени суток (start_min..end_min) и дням недели (days_mask) |
| Действия | до 4, последовательно | Что выполнить при срабатывании |
Подробнее — Задачи и сценарии.
Плагины¶
Всё расширяется через плагины. 4 категории:
- Sensors — поддержка железа (DHT22, BME280, HC-SR04, ваш собственный датчик).
- Triggers — типы триггеров (interval, cron, sunrise/sunset, device_state, udp_event, ping).
- Conditions — типы условий (time-window, wifi-rssi, peer-online, task-state, uptime).
- Actions — типы действий (relay, udp_send, reboot, wait).
Плагин — это одна папка с .cpp и .json. Он включается строчкой в *.enabled.json. Prebuild-скрипт сам пропишет PlatformIO build_src_filter, linker DCE выбросит лишнее из бинарника.
Подробнее — Архитектура плагинов.
Mesh¶
Платы общаются между собой по UDP multicast (224.0.13.31:13031 по умолчанию). Каждый пакет подписан HMAC-SHA256(payload, network_secret). Все платы с одним и тем же network_secret образуют одну mesh-группу.
Что даёт mesh:
- Триггер
udp_event— реакция одной платы на событие другой («движение на улице → свет в коридоре»). - Действие
udp_send— отправка события другим платам. - Условие
peer_online— проверка что сосед в эфире.
Облако в этом не участвует. Mesh работает на тех же платах в одной локальной сети.
Подробнее — Сеть и mesh.
Главные понятия облака¶
Проект (Project)¶
Единица расшаривания. Один человек создаёт проект, добавляет в него платы (по project_api_key), приглашает других людей по email или invite-токену с ролями:
- owner — всё. Удалить проект тоже может только owner.
- admin — управление платами, командами, OTA. Не может удалить проект и менять owner'а.
- viewer — только просмотр состояния плат, без управления.
Группа устройств (Group)¶
Логическая группировка плат внутри проекта для удобства фильтра на дашборде (например, «улица», «гараж», «дом»). Не влияет на ACL — это чисто UI-фишка.
Heartbeat и Command queue¶
Каждые ~15 секунд плата шлёт heartbeat на облако: POST /api/v1/devices/{uuid}/heartbeat с подписью HMAC-SHA256. В ответ облако возвращает pending_commands — список команд, которые накопились пока плата отсутствовала. Плата выполняет их, на следующем heartbeat'е возвращает applied_command_ids. У каждой команды есть TTL (1 час) и возможность revoke до доставки.
Это pull-модель: облако не пушит, плата сама ходит — поэтому никакого port-forwarding'а и VPN не надо. Минус — задержка управления равна heartbeat-интервалу.
Подробнее — Облако.
Где хранится состояние¶
| Где | Что |
|---|---|
Плата → LittleFS /config/*.json |
Wi-Fi, устройства, задачи, пользователи, секреты, UUID, настройки сети, deep-sleep |
| Плата → RAM | runtime task state, лог-кольцо для UI |
| Облако → Postgres | проекты, участники, плата↔проект, команды, прошивки, heartbeat-метаданные, заметки |
Облако → volume firmware_data |
бинарники прошивок (.bin + .littlefs.bin) |
Важно: плата не зависит от облака. Если облако упало — плата продолжает работать, выполнять задачи, отдавать локальный web-UI. Просто временно нельзя дистанционно ей управлять.
Безопасность в двух словах¶
- Пользователи на плате — bearer-токен из
sha256(payload + token_secret),token_secretгенерится на первом запуске. - Пароли на плате —
sha256(password + password_salt),password_saltтоже generated-on-first-boot. - Mesh —
HMAC-SHA256(packet, network_secret), общий для всех плат в одной группе. - Облако ↔ плата —
HMAC-SHA256(request, project_api_key)на каждом heartbeat'е. - Пользователи в облаке — JWT (HS256), email + одноразовый код для логина.
Нет ни одного зашитого секрета в коде, всё генерируется на старте либо вводится в UI.
Дальше¶
- Поддерживаемые платы — что поддержано из железа, как выбирать пины.
- Интерфейс платы — экраны UI с расшифровкой каждого поля.
- Облако — проекты, OTA, голосовые ассистенты.