# Спецификация 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 <token>
  ```
- Без валидного токена устройство должно возвращать ошибку 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"
}
```

#### Пример ошибки

```json
{
  "status": "error",
  "error": "IllegalActionOrParams",
  "message": "Device does not support this action or params"
}
```

---

### 4. `POST /set_token`

Используется для первичной инициализации устройства (в режиме `setup`) и для смены токена по инициативе сервера (в режиме `normal`).

- **В режиме `setup`**: доступен **без токена** — сервер устанавливает токен впервые, переводит устройство в режим `normal`.
- **В режиме `normal`**: требует заголовок Authorization с валидным токеном! — смена токена доступна только авторизованному серверу.

Важно! При установке токена устройство запоминает ip сервера и в дальнейшем может принимать авторизованные действия лишь с этого адреса.

#### Пример запроса

```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"
}
```

#### Пример ответа:

```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
{
  "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."
}
```

---

### 8. `POST /set_device_name`

Установка нового имени девайса. Максимум 32 байта.
**Доступно только в режиме `normal`. Требует заголовок Authorization с валидным токеном!**

#### Пример запроса

```json
{"device_name": "Relay Name"}
```

#### Пример ответа

```json
{
  "status": "ok",
  "message": "Device name updated"
}
```

---

### `GET /channels_schema`

Возвращает текущую конфигурацию каналов.
Это содержимое из памяти устройства, оно делиться по 4 байта на канал. Байты отвечают за:
 - 1. GPIO пин канала
 - 2. GPIO пин индикатора (LED), или номер светодиода, если используется адресная LED лента
 - 3. GPIO пин обратной связи
 - 4. Резервный байт общего назначения, например для реле это флаг инвертирования канала. А для кнопок этот байт не используйется.

Доступ:
 - В режиме normal требует Authorization.
 - В режиме setup доступен без токена.
 - В режимах error и updating может быть недоступен.

#### Пример ответа
```json
  {
    "status": "ok",
    "schema": [
      4,255,255,1,
      5,255,255,0,
      255,255,255,0,
      255,255,255,0,
      255,255,255,0,
      255,255,255,0,
      255,255,255,0,
      255,255,255,0
    ]
  }
```

##### Пояснение примера:
Канал 0:
 - pin = 4
 - indicator = 255 (не используется)
 - feedback = 255 (не используется)
 - flags = 1 (инвертирован)
Канал 1:
 - pin = 5
 - flags = 0 (обычный)
Остальные каналы не задействованы (255 = SH_PIN_UNUSED)

---

## 9. `POST /set_channels_schema`
Позволяет задать конфигурацию всех каналов целиком.
**При удачном обновлении будет совершена перезагрузка устройства.**

Доступ:
 - В режиме setup — без токена.
 - В режиме normal — с Authorization.
 - В режимах error, updating — недоступен.

#### Пример запроса

```json
  {
    "schema": [
      4,255,255,1,
      5,255,255,0,
      6,255,255,0,
      7,255,255,0,
      255,255,255,0,
      255,255,255,0,
      255,255,255,0,
      255,255,255,0
    ]
  }
```

#### Пример ответа

```json
  {
    "status": "ok",
    "message": "Channels schema updated"
  }
```

---

## Рекомендации

- Все устройства реализуют эндпоинты `/about`, `/status`, `/action`.
- Для специфических функций устройства могут реализовать дополнительные эндпоинты по своему усмотрению.
- Поле `device_type` помогает серверу различать логику работы с устройством.

---
