diff --git a/docs/device-spec.md b/docs/device-spec.md new file mode 100644 index 0000000..738fe19 --- /dev/null +++ b/docs/device-spec.md @@ -0,0 +1,259 @@ +# Спецификация REST API для устройств умного дома на ESP + +## Общие положения + +- **Транспорт:** HTTP, формат данных — JSON. +- **Архитектура:** Каждый тип устройства реализует базовые эндпоинты `/about`, `/status`, `/action`. +- **Режимы работы устройства:** + - `setup` — устройство ожидает настройки (доступны `/setup`, `/about`, `/set_token` без авторизации). + - `normal` — устройство работает в штатном режиме (требуется токен). + - `error`, `updating` — для расширения. +- **Безопасность:** Все запросы (кроме `/about`, `/setup` в режиме `setup`, `/set_token` в режиме `setup`) требуют передачи токена авторизации. + +--- + +## Авторизация + +- Для всех эндпоинтов, кроме `GET /about`, `GET/POST /setup` (в режиме `setup`) и `POST /set_token` (в режиме `setup`), в запросах должен присутствовать заголовок: + ``` + Authorization: Bearer + ``` +- Без валидного токена устройство должно возвращать ошибку 401 Unauthorized. + +#### Пример ответа при отсутствии или неверном токене + +```json +{ + "status": "error", + "error": "Unauthorized", + "message": "Missing or invalid token" +} +``` + +--- + +## Эндпоинты + +### 1. `GET /about` + +Отдаёт базовую информацию об устройстве. + +- **Доступно всегда. Токен не требуется.** + +#### Пример ответа + +```json +{ + "device_name": "Relay 1", + "device_type": "relay", + "firmware_version": "1.0.3", + "device_id": "ecf0a1b5c9d74f9a8e294c1f67b0a8b9", + "server": "http://192.168.1.10", + "status": "normal", // normal | setup | error | updating + "ip_address": "192.168.1.42", + "mac_address": "A4:CF:12:9B:3F:D2", + "uptime": 123456 // в секундах +} +``` + +--- + +### 2. `GET /status` + +Отдаёт текущее состояние устройства. +**В режиме `normal` требует заголовок Authorization с валидным токеном!** +**В режиме `setup` может быть недоступен или возвращать ограниченную информацию.** + +#### Пример для реле + +```json +{ + "state": "on" +} +``` + +#### Пример для температурного датчика + +```json +{ + "temperature_c": 21.8, + "humidity_percent": 45.3, + "battery_level": 93 +} +``` + +--- + +### 3. `POST /action` + +Позволяет управлять устройством. +**В режиме `normal` требует заголовок Authorization с валидным токеном!** +**В режиме `setup` эндпоинт недоступен.** + +#### Пример запроса для реле + +```json +{ + "action": "set_state", + "params": { + "state": "off" + } +} +``` + +#### Пример ответа + +```json +{ + "status": "ok", + "message": "State changed" +} +``` + +--- + +### 4. `POST /set_token` + +Используется для первичной инициализации устройства (в режиме `setup`) и для смены токена по инициативе сервера (в режиме `normal`). + +- **В режиме `setup`**: доступен **без токена** — сервер устанавливает токен впервые, переводит устройство в режим `normal`. +- **В режиме `normal`**: требует заголовок Authorization с валидным токеном! — смена токена доступна только авторизованному серверу. + +#### Пример запроса + +```json +{ + "token": "QmFzZVRva2VuU2FtcGxlMTIz" +} +``` + +#### Пример ответа (при успешной установке токена) + +```json +{ + "status": "ok", + "message": "Token set. Device mode: normal" +} +``` + +#### Пример ошибки, если устройство уже в normal-режиме и попытка установки без токена + +```json +{ + "status": "error", + "error": "Unauthorized", + "message": "Missing or invalid token" +} +``` + +#### Пример ошибки, если устройство уже provisioned (уже переведено в normal и повторно в setup режим попасть нельзя) + +```json +{ + "status": "error", + "error": "AlreadyProvisioned", + "message": "Device already provisioned" +} +``` + +--- + +### 5. `GET /setup` и `POST /setup` + +**Доступно только в режиме `setup`.** +Позволяет настроить подключение к Wi-Fi через веб-интерфейс. + +#### Описание: + +- Эндпоинт `/setup` доступен только, пока устройство находится в статусе `setup` (до получения токена). +- При обращении через браузер на `/setup` открывается веб-панель для ввода параметров Wi-Fi (SSID, пароль) и, при необходимости, адреса сервера. +- После успешной настройки и подключения к сети устройство переходит к процедуре ожидания установки токена (`/set_token`). +- После перехода в статус `normal` эндпоинт `/setup` становится недоступен (возвращает ошибку или заглушку). + +#### Пример запроса (POST /setup): + +```json +{ + "ssid": "Home_WiFi", + "password": "MySecretPass", + "server": "http://192.168.1.10" +} +``` + +#### Пример ответа: + +```json +{ + "status": "ok", + "message": "Wi-Fi configured. Connecting..." +} +``` + +#### Пример ошибки при попытке доступа к `/setup` вне режима `setup`: + +```json +{ + "status": "error", + "error": "NotAvailable", + "message": "Setup mode is not active" +} +``` + +--- + +### 6. `POST /reboot` + +Физическая перезагрузка устройства. +**Доступно только в режиме `normal`. Требует заголовок Authorization с валидным токеном!** + +#### Пример запроса + +```json +{} +``` + +#### Пример ответа + +```json +{ + "status": "ok", + "message": "Device will reboot now" +} +``` + +--- + +### 7. `POST /reset` + +Сброс всех настроек к заводским, переход в режим `setup`. +**Доступно только в режиме `normal`. Требует заголовок Authorization с валидным токеном!** + +#### Пример запроса + +```json +{} +``` + +#### Пример ответа + +```json +{ + "status": "ok", + "message": "Device reset to factory settings. Entering setup mode." +} +``` + +--- + +## Рекомендации + +- Все устройства реализуют эндпоинты `/about`, `/status`, `/action`. +- Для специфических функций устройства могут реализовать дополнительные эндпоинты по своему усмотрению. +- Поле `device_type` помогает серверу различать логику работы с устройством. +- Для расширения можно ввести версионирование схемы ответа (например, `status_schema_version`). + +--- + +## На будущее + +- Добавить процедуру получения токена на сервере (админка). diff --git a/docs/devices/relay.md b/docs/devices/relay.md new file mode 100644 index 0000000..18d6507 --- /dev/null +++ b/docs/devices/relay.md @@ -0,0 +1,54 @@ +### `GET /status` + +#### Пример запроса состояния реле + +```json +{ + "state": "on" +} +``` + +--- + +### `POST /action` + +#### Пример запроса на смену состояния реле в разомкнутый + +```json +{ + "action": "set_state", + "params": { + "state": "off" + } +} +``` + +--- + +### `POST /action` + +#### Пример запроса для смены состояния реле на противоположный + +```json +{ + "action": "set_state_reverse", + "params": {} +} +``` + +--- + +### Опционально + +Реле может генерировать ивент от концевика, или даже концевиков, в зависимости от реализации конкретного реле. +В целом - это может быть полезно, а потому ожидаемо сервером. + +#### Пример запроса от смарт реле к серверу + +```json +{ + "device_type": "relay", // Тип устройства (relay, sensor, button и т.п.) + "device_id": "ecf0a1b5c9d74f9a8e294c1f67b0a8b9", // Уникальный идентификатор устройства + "event_name": "limit_switch_activated", // Название события (button_press, state_change, sensor_data и т.д.) + "data": {} +} \ No newline at end of file diff --git a/docs/server-api.md b/docs/server-api.md new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/docs/server-api.md diff --git a/docs/server-spec.md b/docs/server-spec.md new file mode 100644 index 0000000..36c2703 --- /dev/null +++ b/docs/server-spec.md @@ -0,0 +1,25 @@ +# REST API для умного дома +## Приём событий от устройств + +### POST `/events/new` + +**Описание:** +Принимает событие (ивент) от устройства умного дома. Предназначен для отправки любых событий: нажатий кнопок, изменения состояний, передачи измерений и других сигналов. + +**Доступ:** +Только для авторизованных устройств. +Требует заголовок `Authorization: Bearer ` + +--- + +### Формат запроса + +```json +{ + "device_type": "relay", // Тип устройства (relay, sensor, button и т.п.) + "device_id": "ecf0a1b5c9d74f9a8e294c1f67b0a8b9", // Уникальный идентификатор устройства + "event_name": "button_press", // Название события (button_press, state_change, sensor_data и т.д.) + "data": { // Объект с данными события, структура зависит от event_name и device_type + // специфичные для события поля + } +}