Посібник розробника
Розробка модулів для SelenaCore
Розробка модулів для SelenaCore
Що таке модуль
Користувацький модуль — ізольований мікросервіс у Docker-контейнері, який спілкується з ядром лише через Core API (http://localhost:7070/api/v1).
Модуль може: реєструвати пристрої, підписуватися на події, публікувати події (крім core.*), зберігати OAuth-токени.
Модуль не може: читати /secure/, звертатися до SQLite, публікувати core.* події, отримувати OAuth-токен напряму.
Структура модуля
my-module.zip
manifest.json ← обов'язково
main.py ← точка входу
requirements.txt ← залежності Python
Dockerfile ← як запускати
icon.svg ← іконка в UI
manifest.json
{
"name": "my-module",
"version": "1.0.0",
"type": "UI",
"ui_profile": "FULL",
"api_version": "1.0",
"runtime_mode": "always_on",
"port": 8100,
"permissions": ["device.read", "device.write", "events.subscribe", "events.publish"]
}
Дозволи (permissions)
| Дозвіл | Доступно для | Опис |
|---|---|---|
| device.read | всі | GET /devices |
| device.write | всі | POST/PATCH/DELETE /devices |
| events.subscribe | всі | Підписка на події |
| events.publish | всі | Публікація подій |
| secrets.oauth | лише INTEGRATION | Запуск OAuth flow |
| secrets.proxy | лише INTEGRATION | API proxy через vault |
SDK — base_module.py
from sdk.base_module import SmartHomeModule, on_event, scheduled
class MyModule(SmartHomeModule):
name = "my-module"
version = "1.0.0"
async def on_start(self):
self.logger.info("Module started")
@on_event("device.state_changed")
async def handle_state(self, payload: dict):
device = await self.get_device(payload["device_id"])
@scheduled("every:5m")
async def periodic_sync(self):
devices = await self.list_devices()
Локальна розробка
smarthome new-module my-module— створити структуруsmarthome dev— запустити mock Core API- Розробити модуль на FastAPI
smarthome test— запустити тестиsmarthome publish --core http://localhost:7070— деплой
Webhook від Event Bus
Ядро відправляє POST з X-Selena-Signature: sha256=<hmac>. SDK верифікує HMAC автоматично.
OAuth інтеграція
Токен НІКОЛИ не покидає ядро — лише через API proxy (POST /api/v1/secrets/proxy).