-
-
Notifications
You must be signed in to change notification settings - Fork 2
uk Api Reference
Базова URL-адреса: http://localhost/api/v1
Більшість точок доступу вимагають Bearer-токен у заголовку Authorization:
Authorization: Bearer <module_token>
Токени зберігаються на диску в /secure/module_tokens/. Для розробки встановіть змінну середовища DEV_MODULE_TOKEN.
Усі автентифіковані точки доступу обмежені до 120 запитів за 60 секунд на клієнта. Це налаштовується через RateLimitMiddleware. Перевищення ліміту повертає 429 Too Many Requests.
| Заголовок | Опис |
|---|---|
Authorization |
Bearer <token> (обов'язковий для більшості точок доступу) |
X-Request-Id |
Автоматично згенерований UUID для кожного запиту (додається RequestIdMiddleware) |
Інтерактивна документація API доступна за адресою /docs, коли встановлено змінну середовища DEBUG=true. Вимкнено у продакшені.
Повертає поточний стан працездатності екземпляра SelenaCore. Автентифікація не потрібна.
Відповідь 200:
{
"status": "ok",
"version": "0.3.142-beta+0644435",
"mode": "normal",
"uptime": 3600,
"integrity": "ok"
}| Поле | Тип | Значення |
|---|---|---|
status |
string | "ok" |
mode |
string |
"normal" або "safe_mode"
|
uptime |
int | Секунди з моменту запуску |
integrity |
string |
"ok" або "violation"
|
Повертає детальну інформацію про систему та апаратне забезпечення. Потребує автентифікації.
Відповідь 200:
{
"initialized": true,
"wizard_completed": true,
"version": "0.3.142-beta+0644435",
"hardware": {
"model": "raspberrypi",
"ram_total_mb": 8192,
"has_hdmi": false,
"has_camera": false
},
"audio": {
"inputs": [],
"outputs": []
},
"display_mode": "headless"
}| Поле | Тип | Опис |
|---|---|---|
initialized |
bool | Чи завершено ядром першу ініціалізацію |
wizard_completed |
bool | Чи завершено майстер налаштування |
display_mode |
string |
"headless" або ідентифікатор дисплея |
Усі точки доступу пристроїв потребують автентифікації.
Отримати список усіх зареєстрованих пристроїв.
Відповідь 200:
{
"devices": [
{
"device_id": "uuid-string",
"name": "Kitchen Light",
"type": "actuator",
"protocol": "zigbee",
"state": {"power": true, "brightness": 80},
"capabilities": ["turn_on", "turn_off", "set_brightness"],
"last_seen": 1711900000.0,
"module_id": "protocol-bridge",
"meta": {"manufacturer": "IKEA"}
}
]
}Зареєструвати новий пристрій.
Запит:
{
"name": "Kitchen Light",
"type": "actuator",
"protocol": "zigbee",
"capabilities": ["turn_on", "turn_off"],
"meta": {}
}| Поле | Тип | Обов'язкове | Опис |
|---|---|---|---|
name |
string | так | Зрозуміла людині назва пристрою |
type |
string | так | Одне з: sensor, actuator, controller, virtual
|
protocol |
string | так | Протокол зв'язку (наприклад, zigbee, mqtt, http) |
capabilities |
list[string] | так | Підтримувані дії |
meta |
object | ні | Довільні метадані |
Відповідь 201: DeviceResponse (та сама схема, що й елементи у GET /devices).
Публікує подію device.registered на шині подій.
Отримати окремий пристрій за його UUID.
Відповідь 200: DeviceResponse
Відповідь 404:
{"detail": "Device not found"}Оновити стан пристрою.
Запит:
{
"state": {"power": true, "brightness": 80}
}Об'єкт state -- це словник довільної форми. Його ключі залежать від можливостей пристрою.
Відповідь 200: DeviceResponse (з оновленим станом)
Публікує подію device.state_changed, що містить old_state та new_state.
Видалити пристрій з реєстру.
Відповідь 204: Без тіла.
Публікує подію device.removed.
Пошук пристроїв за entity_type, location та/або keyword.
Параметри запиту:
| Параметр | Тип | Опис |
|---|---|---|
entity_type |
string |
Фільтр за типом сутності (напр. "light", "thermostat") |
location |
string |
Фільтр за розташуванням (напр. "kitchen", "bedroom") |
keyword |
string |
Пошук за клю��овим словом |
Відповідь 200: DeviceListResponse
Усі точки доступу радіо потребують автентифікації. Радіостанції використовуються модулем media-player та для побудови LLM промптів. Назви зберігаються у двомовному форматі: name_user (оригінал) та name_en (автоматично перекладено англійською).
Список усіх радіостанцій.
Параметри запиту:
| Параметр | Тип | Опис |
|---|---|---|
enabled_only |
bool |
Повертати тільки увімкнені станції (за замовчуванням: false) |
genre |
string |
Фільтр за жанром (час��кове співпадінн��) |
Відповідь 200: RadioStationListResponse
Створити нову радіостанцію. Назви автоматично перекладаються англійською через LLM.
Відповідь 201: RadioStationResponse
Оновити радіостанцію. Оновлюються тільки надані поля.
Відповідь 200: RadioStationResponse
Видалити радіостанцію.
Відповідь 204: Без тіла.
Усі точки доступу сцен потребують автентифікації. Сцени — це іменовані набори дій з прис��роями. Назви зберігаються у двомовному форматі.
Список усіх сцен.
Параметри запиту:
| Параметр | Тип | Опис |
|---|---|---|
enabled_only |
bool |
Повертати тільки увімкнені сцени (за замовчуванням: false) |
Відповідь 200: SceneListResponse
Створити нову сцену. Н��зва автоматично перекладається англійською через LLM.
Відповідь 201: SceneResponse
Оновити сцену. Оновлюються тільки надані поля.
Відповідь 200: SceneResponse
Видалити сцену.
Відповідь 204: Без тіла.
Усі точки доступу подій потребують автентифікації.
Опублікувати власну подію на шині подій.
Запит:
{
"type": "my.custom_event",
"source": "my-module",
"payload": {"key": "value"}
}| Поле | Тип | Обов'язкове | Опис |
|---|---|---|---|
type |
string | так | Ідентифікатор типу події (простір імен, розділений крапками) |
source |
string | так | Модуль або компонент, що згенерував подію |
payload |
object | ні | Довільні дані події |
Відповідь 201:
{
"event_id": "uuid",
"type": "my.custom_event",
"timestamp": 1711900000.0
}Відповідь 403: Повертається, коли модуль намагається опублікувати подію core.*. Лише ядро системи може генерувати події у просторі імен core.
Підписатися на події через webhook-зворотний виклик.
Застаріло. Використовуйте Module Bus WebSocket замість цього.
Запит:
{
"event_types": ["device.state_changed"],
"webhook_url": "http://localhost:8100/webhook"
}Відповідь 201:
{
"subscription_id": "uuid",
"event_types": ["device.state_changed"],
"webhook_url": "http://localhost:8100/webhook"
}Усі точки доступу модулів потребують автентифікації.
Отримати список усіх встановлених модулів.
Відповідь 200:
{
"modules": [
{
"name": "weather-module",
"version": "1.0.0",
"type": "UI",
"status": "RUNNING",
"runtime_mode": "always_on",
"port": 0,
"installed_at": 1711900000.0,
"ui": {
"icon": "icon.svg",
"widget": {"file": "widget.html", "size": "2x2"}
}
}
]
}| Поле | Тип | Опис |
|---|---|---|
type |
string | Тип модуля (наприклад, UI, SYSTEM, SERVICE) |
status |
string |
VALIDATING, READY, RUNNING, STOPPED, ERROR
|
runtime_mode |
string |
always_on або on_demand
|
port |
int | Призначений порт (0, якщо не застосовується) |
ui |
object або null | Конфігурація UI-віджета, якщо модуль його надає |
Встановити модуль із ZIP-архіву. Використовує завантаження multipart form.
Запит:
Content-Type: multipart/form-data
Field: module (file, .zip)
Відповідь 201:
{
"name": "my-module",
"status": "VALIDATING",
"message": "Module uploaded, validation in progress"
}Встановлення виконується асинхронно. Використовуйте SSE-потік для відстеження прогресу.
Потік Server-Sent Events для відстеження встановлення модуля та змін життєвого циклу.
Відповідь: text/event-stream
data: {"status": "VALIDATING", "message": "Manifest validated, installing..."}
data: {"status": "READY", "message": "Validation passed, starting..."}
data: {"status": "RUNNING", "message": "Module started"}
Повідомлення heartbeat надсилається кожні 30 секунд, якщо немає оновлень статусу.
Запустити зупинений модуль.
Відповідь 200:
{"name": "my-module", "status": "RUNNING"}Зупинити працюючий модуль.
Відповідь 200:
{"name": "my-module", "status": "STOPPED"}Відповідь 403: Повертається при спробі зупинити модуль типу SYSTEM. Системні модулі не можуть бути зупинені.
Видалити встановлений модуль та очистити його ресурси.
Відповідь 204: Без тіла.
Відповідь 403: Повертається при спробі видалити модуль типу SYSTEM. Системні модулі не можуть бути видалені.
Усі точки доступу секретів потребують автентифікації.
Отримати список ідентифікаторів збережених секретів. Значення ніколи не повертаються у відкритому вигляді.
Зберегти OAuth-токен або інший секрет. Секрети шифруються у стані спокою за допомогою AES-256-GCM.
Усі точки доступу цілісності потребують автентифікації.
Повертає поточний стан агента цілісності, який відстежує підробку файлів та конфігурації.
Застаріло. Інтенти тепер керуються через механізм
announceModule Bus. Ці REST-точки доступу залишаються для зворотної сумісності, але будуть видалені у майбутньому релізі.
Отримати список інтентів, оголошених через Module Bus.
Зареєструвати нові інтенти. Використовуйте announce Module Bus замість цього.
WebSocket-точка доступу для комунікації з Module Bus у реальному часі. Модулі підключаються сюди для оголошення можливостей, підписки на події та обміну повідомленнями з ядром.
Передайте токен модуля як параметр запиту token.
Див. Протокол Module Bus для повного довідника формату повідомлень та рукостискання.
Базова адреса: /api/ui
Ці маршрути призначені лише для локального веб-інтерфейсу. Вони захищені правилами iptables (доступ лише з localhost) та не потребують Bearer-токенів.
| Маршрут | Опис |
|---|---|
POST /api/ui/setup/* |
Кроки майстра налаштування |
GET /api/ui/setup/vosk/catalog |
Каталог моделей Vosk для розпізнавання мовлення |
| Точки доступу голосового рушія | Керування конфігурацією STT/TTS |
| Маршрутизація UI модулів | Обслуговування файлів віджетів та іконок модулів |
| Метод | Маршрут | Опис |
|---|---|---|
| GET | /api/ui/setup/audio/devices |
Список виявлених ALSA пристроїв |
| POST | /api/ui/setup/audio/select |
Зберегти вибір пристроїв {input, output}
|
| POST | /api/ui/setup/audio/test/output |
Тест динаміка (лівий/правий канал) |
| POST | /api/ui/setup/audio/test/input |
Запис 3с з мікрофона, вимірювання піку, відтворення |
| GET | /api/ui/setup/audio/mic-level |
Рівень мікрофона → {level: 0.0-1.0}
|
| GET | /api/ui/setup/audio/levels |
Поточні {output_volume, input_gain}
|
| POST | /api/ui/setup/audio/levels |
Встановити {output_volume?, input_gain?}
|
| GET | /api/ui/setup/audio/sources |
Список аудіо-джерел → {sources: [{module, name, volume}]}
|
| POST | /api/ui/setup/audio/sources/volume |
Гучність джерела {module, volume}
|
Обгортка над bluetoothctl (bluez) для адмін-інтерфейсу. bluetoothctl виконується всередині контейнера selena-core; DBus-сокет хоста та /var/lib/bluetooth прокинуті volume-ами, тож стан сполучень переживає перезапуски. Реалізація: core/bluetooth.py.
| Метод | Маршрут | Опис |
|---|---|---|
| GET | /api/ui/setup/bluetooth/status |
Стан адаптера → {available, powered, discovering, pairable, address, name, alias}. available=false коли немає контролера або бінарника bluetoothctl. |
| POST | /api/ui/setup/bluetooth/power |
Тіло {enable: bool} — bluetoothctl power on/off. 503 якщо адаптер відсутній. |
| GET | /api/ui/setup/bluetooth/devices |
Список сполучених пристроїв → {devices: [{mac, name, alias, icon, connected, trusted, paired}]}. |
| GET | /api/ui/setup/bluetooth/scan?timeout=N |
Пошук протягом N секунд (обмежено 3–30, типово 10). Повертає лише пристрої з розпізнаним ім'ям — анонсування лише MAC (iPhone з рандомізованим MAC) приховуються. |
| POST | /api/ui/setup/bluetooth/connect/{mac} |
Під'єднатися до вже сполученого пристрою. 400 connect_failed при відмові. |
| POST | /api/ui/setup/bluetooth/disconnect/{mac} |
Від'єднання без розривання сполучення. |
| POST | /api/ui/setup/bluetooth/unpair/{mac} |
bluetoothctl remove <mac> — прибирає сполучення. |
| POST | /api/ui/setup/bluetooth/rename |
Тіло {mac, alias} — встановлює постійний alias (Device1.Alias). Використовує bluetoothctl; fallback — busctl set-property для старих версій bluez. |
| GET | /api/ui/setup/bluetooth/pair?mac=… |
SSE-стрим подій сесії сполучення (див. нижче). |
| POST | /api/ui/setup/bluetooth/pair/respond |
Тіло {mac, pin?, confirm?} — подає PIN або yes/no в активну сесію. 404 no_active_session якщо для цього MAC немає активної сесії. |
| POST | /api/ui/setup/bluetooth/pair/cancel?mac=… |
Скасовує активну сесію (вбиває stdin-пайп bluetoothctl). |
SSE-події сполучення (один JSON-об'єкт на data: рядок):
data: {"type": "started"}
data: {"type": "pin_required", "prompt": "[agent] Enter PIN code:"}
data: {"type": "confirm_code", "code": "123456"}
data: {"type": "success"}
data: {"type": "failed", "reason": "authentication_failed"}
Максимальний час сесії — 90с; стрим закривається після success або failed. Пристрої "Just Works" (більшість BT-навушників/колонок) переходять зі started одразу в success — події pin_required / confirm_code з'являються лише для клавіатур, телефонів, автомобілів тощо.
Усі помилки повертають JSON-тіло з полем detail.
Стандартна помилка:
{
"detail": "Error message"
}Помилка валідації (422 Unprocessable Entity):
{
"detail": {"errors": ["error1", "error2"]}
}| Код | Значення |
|---|---|
| 200 | Успіх |
| 201 | Створено |
| 204 | Без вмісту (успішне видалення) |
| 400 | Некоректний запит |
| 401 | Не авторизовано (відсутній або недійсний токен) |
| 403 | Заборонено (недостатньо дозволів) |
| 404 | Не знайдено |
| 422 | Помилка валідації |
| 429 | Забагато запитів (перевищено ліміт частоти) |
| 500 | Внутрішня помилка сервера |
Події використовують простір імен, розділений крапками. Визначені наступні простори імен:
Зарезервовано для ядра системи. Модулі не можуть публікувати ці події.
| Подія | Опис |
|---|---|
core.startup |
Ядро запущено |
core.shutdown |
Ядро завершує роботу |
core.integrity_violation |
Виявлено підробку файлу або конфігурації |
core.integrity_restored |
Перевірка цілісності пройшла після попереднього порушення |
core.safe_mode_entered |
Система перейшла у безпечний режим |
core.safe_mode_exited |
Система вийшла з безпечного режиму |
| Подія | Опис |
|---|---|
device.state_changed |
Стан пристрою оновлено (містить old_state та new_state) |
device.registered |
Додано новий пристрій |
device.removed |
Пристрій видалено |
device.offline |
Пристрій перестав відповідати |
device.online |
Пристрій знову підключився |
device.discovered |
Новий пристрій виявлено в мережі |
| Подія | Опис |
|---|---|
module.installed |
Модуль встановлено |
module.started |
Модуль запущено |
module.stopped |
Модуль зупинено |
module.error |
Модуль зіткнувся з помилкою |
module.removed |
Модуль видалено |
| Подія | Опис |
|---|---|
sync.command_received |
Отримано віддалену команду з хмарної синхронізації |
sync.command_ack |
Надіслано підтвердження команди |
sync.connection_lost |
Втрачено з'єднання з хмарною синхронізацією |
sync.connection_restored |
Відновлено з'єднання з хмарною синхронізацією |
| Подія | Опис |
|---|---|
voice.wake_word |
Виявлено слово активації |
voice.recognized |
Мовлення розпізнано |
voice.intent |
Інтент витягнуто з мовлення |
voice.response |
Згенеровано голосову відповідь |
voice.privacy_on |
Мікрофон вимкнено / режим приватності увімкнено |
voice.privacy_off |
Мікрофон увімкнено / режим приватності вимкнено |
🤖 This wiki is auto-synced from docs/ in the main repo. Hand-edits on the wiki UI get overwritten on the next push. Open a PR against the main repo instead.
MIT License · Sponsor · Ko-fi
SelenaCore
🇬🇧 English
Getting started
Architecture
Voice & translation
Hardware integration
Development
- Modules overview
- Module development
- System module development
- Module API guide
- Module bus protocol
- Widget development
- User manager / auth
Reference
🇺🇦 Українська
Початок
Архітектура
Голос і переклад
Інтеграція заліза
Розробка
- Розробка модулів
- Розробка системних модулів
- Module API
- Module bus
- Widget development
- User manager / auth
Довідник