Newer
Older
smart-home-server / docs / server-api.md

REST API сервера — справочник

Веб-клиент общается с сервером по HTTP+JSON. Все API-запросы идут через proxy.php (CORS).

Политика управления устройствами

Клиент не управляет устройствами напрямую. Вся логика — только через скрипты (ControlScripts):

  • управление устройствами — через action-скрипты (POST /api/v1/scripts/actions/run)
  • реакция на физические события — через event-хендлеры в скриптах
  • периодические задачи — через regular-скрипты (cron)

Прямые вызовы устройств (/api/v1/devices/action и т.п.) — служебные endpoint'ы сервера для внутреннего использования, не предназначены для вызова из клиентского кода.


Формат ответов

Все endpoint'ы используют единый формат из Utils::response_success / Utils::response_error.

Успех:

{
  "status": true,
  "data": { ... }
}

Ошибка:

{
  "status": false,
  "error_alias": "device_not_found",
  "failed_fields": ["device_id"],
  "msg": "Устройство не найдено"
}

Примечание. Авторизация (Authorization: Bearer <token>) пока не реализована на уровне middleware — все endpoint'ы в данный момент открыты. Заголовок описан в спецификации, но проверка не подключена.


Устройства /api/v1/devices

GET /api/v1/devices/list

Список всех активных устройств.

Ответ:

{
  "status": true,
  "data": {
    "devices": [
      {
        "id": 12,
        "alias": "kitchen_relay",
        "device_type": "relay",
        "device_hard_id": "ecf0a1b5c9d7...",
        "device_mac": "A4:CF:12:9B:3F:D2",
        "device_ip": "192.168.2.42",
        "firmware_version": "1.22 dev",
        "name": "Реле кухни",
        "status": "active",
        "connection_status": "active",
        "last_contact": "2026-04-22 18:35",
        "create_at": "2025-12-01 10:00"
      }
    ],
    "total": 1
  }
}

GET /api/v1/devices/id/{id}

Данные одного устройства из БД (без запроса к самому устройству).

Ответ: data.device — поля устройства (те же что в списке выше).


GET /api/v1/devices/id/{id}/info

Данные устройства + живой ответ /about с самого устройства.

Ответ:

{
  "status": true,
  "data": {
    "device": {
      "id": 12,
      "alias": "...",
      "name": "...",
      "description": "...",
      "status": "active",
      "connection_status": "active",
      "last_contact": "...",
      "create_at": "...",
      "device": { /* ответ GET /about с устройства */ }
    }
  }
}

GET /api/v1/devices/id/{id}/status

Живое состояние устройства — проксирует GET /status на само устройство.

Ответ:

{
  "status": true,
  "data": {
    "device": {
      "id": 12,
      "alias": "...",
      "device_response": { /* ответ GET /status с устройства */ }
    }
  }
}

GET /api/v1/devices/scanning/setup

Сканировать сеть и вернуть только устройства в режиме setup (ещё не добавленные).
Параллельный curl_multi по диапазону IP из конфига (192.168.2.2–192.168.2.254).

Ответ: data.devices — массив ответов /about найденных устройств.


GET /api/v1/devices/scanning/all

Сканировать сеть и вернуть все найденные устройства (любой статус).


POST /api/v1/devices/setup/new-device

Добавить устройство. Сервер запрашивает /about, сохраняет в БД, генерирует токен, отправляет его устройству через /set_token, задаёт имя через /set_device_name.

Тело:

{
  "device_ip": "192.168.2.42",
  "alias": "kitchen_relay",
  "name": "Реле кухни",
  "description": "..."
}

Ответ (успех): data.device — объект нового устройства.

Ответ (ошибка): error_aliasinvalid_ip | empty_field | alias_already_exists | device_not_found | device_mode_error | db_error


POST /api/v1/devices/action

Выполнить действие на устройстве — проксирует POST /action на само устройство.

Тело:

{
  "device_id": 12,
  "action": "toggle_channel",
  "params": { "channel": 0 }
}

Ответ (успех):

{
  "status": true,
  "data": {
    "device": {
      "id": 12,
      "alias": "...",
      "device_response": { /* ответ устройства */ }
    }
  }
}

POST /api/v1/devices/update-name

Обновить имя устройства (в БД + на самом устройстве через /set_device_name).

Тело: { "device_id": 12, "name": "Новое имя" }


POST /api/v1/devices/update-description

Обновить описание устройства (только в БД).

Тело: { "device_id": 12, "description": "..." }


POST /api/v1/devices/update-alias

Обновить alias устройства (только в БД). Осторожно: сломает скрипты, использующие старый alias.

Тело: { "device_id": 12, "new_alias": "new_alias_name" }


POST /api/v1/devices/place-in-area

Поместить устройство в область.

Тело: { "target_id": 12, "place_in_area_id": 3 }


GET /api/v1/devices/id/{id}/unassign-from-area

Отвязать устройство от области (сделать «без области»).


POST /api/v1/devices/resetup

Переустановить токен устройства (перепривязка).

Тело: { "device_id": 12 }


POST /api/v1/devices/reset

Сбросить устройство к заводским настройкам (вызывает POST /reset на устройстве).

Тело: { "device_id": 12 }


GET /api/v1/devices/id/{id}/reboot

Перезагрузить устройство.


GET /api/v1/devices/id/{id}/remove

Удалить устройство: сбрасывает устройство (POST /reset), деактивирует токен, помечает запись как removed в БД.


Области /api/v1/areas

Области — иерархическая структура физических пространств (комнаты, этажи, здания). Устройства и скрипты можно размещать в областях.

GET /api/v1/areas/list

Список всех областей.

Ответ: data.areas — массив объектов AREA, data.total.

{
  "id": 2,
  "type": "room",
  "alias": "kitchen",
  "display_name": "Кухня",
  "parent_area_id": 0
}

GET /api/v1/areas/id/{area_id}/list

Список дочерних областей указанной области.


POST /api/v1/areas/new-area

Создать новую область.

Тело: { "type": "room", "alias": "kitchen", "display_name": "Кухня" }

Ответ: data.alias, data.area.

Ошибки: alias_already_exists | empty_field (поля type, display_name)


GET /api/v1/areas/id/{area_id}/remove

Удалить область. Все устройства и дочерние области внутри — отвязываются (но не удаляются). Нельзя удалить area_id ≤ 1.


POST /api/v1/areas/place-in-area

Вложить одну область в другую.

Тело: { "target_id": 5, "place_in_area_id": 2 }


GET /api/v1/areas/id/{area_id}/unassign-from-area

Отвязать область от родительской (поднять на верхний уровень).


POST /api/v1/areas/update-display-name

Переименовать область.

Тело: { "area_id": 2, "display_name": "Кухня (1 этаж)" }


POST /api/v1/areas/update-alias

Изменить alias области. Осторожно: сломает скрипты, использующие старый alias.

Тело: { "area_id": 2, "new_alias": "kitchen_floor_1" }


GET /api/v1/areas/id/{area_id}/devices

Список устройств в области (включая вложенные области).

Ответ: data.devices — массив устройств, data.total.


GET /api/v1/areas/id/{area_id}/scripts

Список скриптов, размещённых в области (action + regular).

Ответ: data.scripts, data.total.


GET /api/v1/areas/id/{area_id}/reboot_devices

GET /api/v1/areas/reboot_devices

Перезагрузить все устройства в области (или все устройства системы).

Ответ:

{
  "status": true,
  "data": {
    "results": {
      "kitchen:relay_1": { /* ответ от устройства */ }
    },
    "total": 1
  }
}

GET /api/v1/areas/types/list

Список всех существующих типов областей в БД (для подсказок при создании новой).

Ответ: data.types — массив строк, например ["room", "floor", "building"].


Скрипты /api/v1/scripts

Управление тремя типами скриптов: action (ручной запуск), regular (cron), scope (PHP-класс, контейнер для action + regular).

GET /api/v1/scripts/actions/list

Список всех зарегистрированных action-скриптов с их состоянием (enabled/disabled).

Ответ:

{
  "status": true,
  "data": {
    "scripts": [
      {
        "alias": "kitchen_light_toggle",
        "name": "Свет на кухне",
        "icon": "<i class=\"ph ph-lightbulb\"></i>",
        "description": "...",
        "author": "Eugene Sukhodolskiy",
        "state": "enabled",
        "filename": "LightHubScope.php",
        "path": "/srv/http/smart-home-serv.local/server/ControlScripts"
      }
    ],
    "total": 3
  }
}

GET /api/v1/scripts/regular/list

Список всех зарегистрированных regular-скриптов.


GET /api/v1/scripts/scopes/list

Список всех Scope-классов с их состоянием.

Ответ: data.scopes — массив { name, filename, state, path }, data.total.


GET /api/v1/scripts/scopes/name/{name}

Получить исходный код PHP-файла Scope. Возвращает raw PHP-код (не JSON).


POST /api/v1/scripts/actions/run

Запустить action-скрипт вручную.

Тело:

{
  "alias": "kitchen_light_toggle",
  "params": {}
}

Ответ:

{
  "status": true,
  "data": {
    "return": {
      "result": { /* возвращаемое скриптом */ },
      "exec_time": "0.042 seconds"
    }
  }
}

Ошибка: action_script_not_found (если alias не существует или скрипт disabled)


GET /api/v1/scripts/actions/alias/{alias}/enable

GET /api/v1/scripts/actions/alias/{alias}/disable

Включить / выключить action-скрипт (записывает состояние в БД).


GET /api/v1/scripts/regular/alias/{alias}/enable

GET /api/v1/scripts/regular/alias/{alias}/disable

Включить / выключить regular-скрипт.


GET /api/v1/scripts/actions/scope/{name}/enable

GET /api/v1/scripts/actions/scope/{name}/disable

Включить / выключить весь Scope (все его скрипты перестают регистрироваться при следующем старте сервера).


POST /api/v1/scripts/scopes/update

Перезаписать содержимое PHP-файла Scope.

Тело: { "name": "LightHubScope", "path": "/srv/.../ControlScripts", "file": "<?php ..." }


POST /api/v1/scripts/place-in-area

Поместить скрипт в область.

Тело: { "target_id": 5, "place_in_area_id": 2 }


GET /api/v1/scripts/id/{id}/unassign-from-area

Отвязать скрипт от области.


Общее

GET /api/v1/status

Статус сервера.

{
  "status": "active",
  "docs": "https://git.gnexus.space/root/smart-home-server/tree/master/docs"
}

События от устройств

POST /events/new

Endpoint для устройств (не для клиента). Принимает событие, немедленно отвечает 200 OK, затем асинхронно запускает обработчики из Control Scripts.

Тело (от устройства):

{
  "device_id": "ecf0a1b5c9d74f9a8e294c1f67b0a8b9",
  "event_name": "press",
  "data": { "channel": 0 }
}

Требует Authorization: Bearer <device_token>.


Cron-маршруты

Не для клиента — вызываются планировщиком на сервере.

Endpoint Действие
GET /cron/regular-scripts Запустить все enabled regular-скрипты
GET /cron/status-update-scanning Сканировать сеть, обновить connection_status и device_ip в БД

Запланировано, не реализовано

Следующие разделы описаны в спецификациях (docs/server-api-v1/), но ещё не реализованы:

Раздел Файл спеки
Авторизация auth.md
Пользователи users.md
Группы пользователей и права groups.md
Логи logs.md
Уведомления notifications.md