API¶
REST API на плате и в облаке. Канонический справочник эндпоинтов с body-схемами лежит в коде:
- Плата:
ctrl-board/docs/API.md - Облако: OpenAPI на запущенном сервисе — https://cloud.kavlev.ru/docs (Swagger) или https://cloud.kavlev.ru/redoc
Здесь — обзор групп эндпоинтов и принципы. За точными схемами тел запросов идите по ссылкам выше.
Авторизация¶
Плата¶
- Bearer-токен в заголовке
Authorization: Bearer <token>. Получается черезPOST /api/v1/auth/login. - Формат:
<userId>:<expiresEpoch>:<sha256(payload + token_secret)>. Stateless, без серверных сессий. - TTL: 1 час (по умолчанию) или 30 дней (с
remember=true). - Если
auth_settings.require_auth = false— авторизация не проверяется, все запросы считаются отdefault_user_id(admin). Это режим домашней LAN.
Облако¶
- JWT (HS256) для пользователей.
POST /api/v1/auth/loginшлёт код на email;POST /api/v1/auth/verifyобменивает код на JWT + refresh-token. - HMAC-SHA256 для плат. Каждый heartbeat подписан
project_api_key. Заголовки:X-Device-Uuid,X-Device-Ts,X-Device-Sig.
Группы эндпоинтов: плата¶
| Группа | Префикс | Описание |
|---|---|---|
| Auth | /api/v1/auth/... |
login, me, config |
| Users | /api/v1/users/... |
CRUD пользователей (admin) |
| Devices | /api/v1/devices/... |
CRUD реле/датчиков, scan OneWire, state |
| Tasks | /api/v1/tasks/... |
CRUD задач, run |
| Settings | /api/v1/settings/... |
Wi-Fi, device, auth, network, time, sleep |
| Logs | /api/v1/logs |
RAM-лог |
| OTA | /api/v1/ota |
Заливка прошивки |
| Sensors / Triggers / Conditions / Actions | /api/v1/{category} |
Список compiled-in плагинов с UI manifest |
| Plugins | /api/v1/{category} |
Список плагинов с UI manifest |
| Pins | /api/v1/pins |
GPIO справочник платы |
| Mesh | /api/v1/settings/network_secret, /api/v1/peers |
Параметры UDP + соседи |
| Cloud | /api/v1/cloud |
URL + API-key облака |
| Factory reset / reboot | /api/v1/factory-reset, /api/v1/system/reboot |
Полный справочник с body-схемами — docs/API.md.
Группы эндпоинтов: облако¶
| Группа | Префикс | Описание |
|---|---|---|
| Auth | /api/v1/auth/... |
login (email-code), refresh, change-password, /me |
| Projects | /api/v1/projects/... |
CRUD проектов, rotate api_key, members |
| Groups | /api/v1/projects/{pid}/groups/... |
CRUD групп устройств |
| Members | /api/v1/projects/{pid}/members/... |
роли, удалить, инвайты |
| Devices | /api/v1/devices/... |
CRUD платы в проекте, last_state |
| Heartbeat | /api/v1/devices/{uuid}/heartbeat |
приём от платы (HMAC) |
| Commands | /api/v1/commands/... |
очередь команд, revoke |
| Firmwares | /api/v1/firmwares/... |
список, download |
| Notes | /api/v1/notes/... |
заметки с email-уведомлениями |
| Notifications | /api/v1/users/me/notifications |
per-user inbox |
| Yandex Smart Home | /v1.0/user/... |
discovery, query, action, callback |
| Marusya Smart Home | /marusya/user/... |
то же для Маруси |
| Sber Smart Home | /sber/user/... |
то же для Салюта |
| OAuth | /oauth/... |
OAuth2 endpoints для голосовых ассистентов |
Полный справочник — https://cloud.kavlev.ru/docs (Swagger UI с возможностью «попробовать»).
Heartbeat-протокол¶
Pull-модель: плата каждые interval_sec (по умолчанию 15) шлёт POST /api/v1/devices/{uuid}/heartbeat на облако.
Заголовки¶
| Header | Что |
|---|---|
X-Device-Uuid |
UUID платы |
X-Device-Ts |
Unix-секунды на момент отправки |
X-Device-Sig |
HMAC-SHA256(body + ts, project_api_key) |
Тело¶
{
"fw_version": "0.4.7-esp8266",
"ip": "192.168.1.50",
"uptime_sec": 3600,
"interval_sec": 15,
"state": {
"devices": [
{"id": 1, "name": "Свет улица", "type": "relay", "state": false},
{"id": 2, "name": "Температура", "type": "ds18b20", "value": 21.4}
]
},
"tasks": [
{"id": 1, "name": "Свет по закату", "last_fire_ms": 1234, "enabled": true}
],
"applied_command_ids": [42, 43]
}
Ответ¶
{
"server_ts": 1778080000,
"pending_commands": [
{ "id": 44, "type": "set_relay", "payload": {"device_id": 1, "state": true}, "cmd_id": "abc-123" }
]
}
Плата выполняет команды последовательно, складывает ID в applied_command_ids, на следующем heartbeat'е возвращает облаку.
Команды¶
| Тип | Payload | Что делает |
|---|---|---|
set_relay |
{device_id, state} |
переключить реле |
reboot |
{} |
перезагрузить плату |
ota_update |
{firmware_id} |
скачать и применить новую прошивку |
ota_fs_update |
{firmware_id} |
скачать и применить новый FS-image |
factory_reset |
{} |
стереть /config/* (с двойным подтверждением UI) |
Plugins endpoint shape¶
Одинаковая schema для всех 4 категорий (/api/v1/sensors, /api/v1/triggers, /api/v1/conditions, /api/v1/actions):
{
"plugins": [
{
"name": "interval",
"data_size": 4,
"types_provided": ["interval"],
"ui_raw": "{\"label_key\":\"trg.type.interval\",\"fields\":[...]}"
}
],
"total": 6
}
ui_raw — JSON-строка с UI manifest'ом плагина. Формат manifest'а — в Архитектуре плагинов → UI manifest.
Идемпотентность и атомарность¶
- Все мутации на плате пишут в
/config/*.jsonчерез atomic rename:.tmp + remove + rename. Если плата ребутнётся в момент записи — старая версия файла останется неповреждённой. - Cloud-команды дедуплицируются по
cmd_idна стороне платы. Повторная доставка одной и той же команды (например, после reconnect'а MQTT) не повторит действие. - Heartbeat'ы независимы: пропуск одного не ломает state (
applied_command_idsприходят на следующем).
Где смотреть Swagger / OpenAPI¶
- Облако (production): https://cloud.kavlev.ru/docs (Swagger UI), https://cloud.kavlev.ru/redoc (ReDoc).
- Облако (локально): запустить cloud-service из репы, открыть
http://localhost:8000/docs. - Плата: Swagger нет (нет места на ESP). Канонический справочник — API.md в репе.
Дальше¶
- Полный справочник эндпоинтов платы:
ctrl-board/docs/API.md - Swagger облака: https://cloud.kavlev.ru/docs
- Архитектура плагинов — как plugin'ы попадают в
/api/v1/{category}ответ.