SelenaCore Architecture
SelenaCore Architecture
Overview
SelenaCore consists of two independent processes running in Docker (core) and systemd (agent).
Module Execution Model
SelenaCore uses a two-tier module execution model to conserve RAM (~580 MB saved on Raspberry Pi):
| Type | Execution | Port | Communication | Container |
|---|---|---|---|---|
| SYSTEM | In-process via importlib | None | Direct Python calls + SystemModule ABC | smarthome-core (shared) |
| User (UI/INTEGRATION/DRIVER/AUTOMATION) | Docker sandbox | 8100–8200 | HTTP API + webhook events | smarthome-modules |
1. Core API
FastAPI REST server, port 7070. Entry point for all modules.
X-Request-Idgenerated for each request, propagated viacontextvars- CORS — only
localhostallowed - Rate limiting — 100 req/sec per token
Authorization: Bearer <module_token>required for all endpoints except/health
2. Device Registry
SQLite device storage via SQLAlchemy 2.0 async.
Tables:
devices— id, name, type, protocol, state JSON, capabilities, last_seen, module_id, metastate_history— last 1000 states per device (archive)audit_log— all user actions (10,000 records, rotation)
On PATCH /devices/{id}/state, a device.state_changed event is automatically published to Event Bus.
3. Event Bus
# Publishing
await bus.publish(event) # asyncio.Queue
# Subscribing (user modules — webhook)
await bus.subscribe("device.*", webhook_url) # wildcard
# Subscribing (system modules — in-process)
bus.subscribe_direct(sub_id, module_id, ["device.*"], callback)
# Delivery
# Webhooks: POST http://module:810X/webhook/events
# Direct: asyncio.create_task(callback(event))
# X-Selena-Signature: sha256=<hmac>
Protection: core.* events cannot be published from a module → 403 Forbidden. HMAC-SHA256 signature on every webhook delivery.
4. Module Loader
Module lifecycle:
UPLOADED → VALIDATING → READY → RUNNING → STOPPED → REMOVED
↓
ERROR
Installation step: Upload ZIP → Validator checks manifest.json → Sandbox test → DockerSandbox launch.
Modules with type: SYSTEM cannot be stopped via API → 403 Forbidden.
5. Integrity Agent
Independent process (systemd), does not import the core.
Every 30 sec:
1. Read /secure/master.hash
2. Compute SHA256 of /secure/core.manifest
3. Compare → if mismatch: MANIFEST TAMPERED
4. For each core file: SHA256 from manifest vs SHA256 on disk
5. If changes found:
a) Log to /var/log/selena/integrity.log
b) Stop all modules (Docker stop)
c) Notify platform
d) Rollback from /secure/core_backup/ (3 attempts, 5 sec pause)
e) If rollback failed → SAFE MODE
SAFE MODE: Core API read-only (GET only), module installation prohibited, GET /health returns "mode": "safe_mode".
6. Cloud Sync
Background task: heartbeat every 60 sec + long-poll commands. HMAC-SHA256 signed. Retry: exponential backoff 2^n sec, max 300 sec.
7. Voice Core
| Component | Technology |
|---|---|
| Wake-word | openWakeWord |
| STT | Whisper.cpp (pywhispercpp) |
| TTS | Piper TTS |
| Speaker ID | resemblyzer |
| Audio I/O | ALSA + PipeWire |
Audio input priorities: usb > i2s_gpio > bluetooth > hdmi > builtin
8. LLM Engine
Two-level router:
- Level 1: Fast Matcher — YAML keyword/regex rules, ~50 ms, no GPU
- Level 2: Ollama (fallback) — phi-3-mini (2.3 GB) or gemma:2b (1.5 GB). Auto-disable when RAM < 5 GB.
9. Secrets Vault
Each secret stored as nonce(12 bytes) + ciphertext (AES-256-GCM). Encryption key: PBKDF2(HMAC-SHA256, passphrase, salt=module_name, iterations=480000).
OAuth Device Flow (RFC 8628): module never receives the token directly — only via API proxy. SSRF protection: only https://, private IP blocking.
Network Isolation
localhost
:7070 Core API (modules + UI only)
:80 UI Core (user browser)
:8100 User Module 1 (Docker sandbox only)
...
:8200 User Module 100
Docker network: selena-net (bridge, internal). User modules CANNOT communicate with each other directly. System modules have NO network ports.