# Pending Features & Issues Priority: `P1` quick win · `P2` moderate · `P3` large effort ## Processing Pipeline - [ ] `P3` **Transition effects** — Crossfade, wipe, or dissolve between sources/profiles instead of instant cut - Complexity: large — requires a new transition layer concept in ProcessorManager; must blend two live streams simultaneously during switch, coordinating start/stop timing - Impact: medium — polishes profile switching UX but ambient lighting rarely switches sources frequently ## Output Targets - [ ] `P2` **Art-Net / sACN (E1.31)** — Stage/theatrical lighting protocols, DMX controllers - Complexity: medium — UDP-based protocols with well-documented specs; similar architecture to DDP client; needs DMX universe/channel mapping UI - Impact: medium — opens stage/theatrical use case, niche but differentiating ## Capture Engines - [ ] `P3` **SCRCPY capture engine** — Implement SCRCPY-based screen capture for Android devices - Complexity: large — external dependency on scrcpy binary; need to manage subprocess lifecycle, parse video stream (ffmpeg/AV pipe), handle device connect/disconnect - Impact: medium — enables phone screen mirroring to ambient lighting; appeals to mobile gaming use case ## Code Health - [ ] `P1` **"Start All" targets button** — "Stop All" exists but "Start All" is missing - [x] `P2` **Manual backup trigger endpoint** — `POST /system/auto-backup/trigger` (~5 lines) - [ ] `P2` **Scene snapshot should capture device brightness** — `software_brightness` not saved/restored - [ ] `P2` **Distinguish "crashed" vs "stopped" in dashboard** — `metrics.last_error` is already populated - [ ] `P3` **CSS source import/export** — share individual sources without full config backup ## Backend Review Fixes (2026-03-14) ### Performance - [x] **P1** PIL blocking in async handlers → `asyncio.to_thread` - [x] **P2** `subprocess.run` blocking event loop → `asyncio.create_subprocess_exec` - [x] **P3** Audio enum blocking async → `asyncio.to_thread` - [x] **P4** Display enum blocking async → `asyncio.to_thread` - [x] **P5** `colorsys` scalar loop in hot path → vectorize numpy - [x] **P6** `MappedStream` per-frame allocation → double-buffer - [x] **P7** Audio/effect per-frame temp allocs → pre-allocate - [x] **P8** Blocking `httpx.get` in stream init → documented (callers use to_thread) - [x] **P9** No-cache middleware runs on all requests → scope to static - [x] **P10** Sync file I/O in async handlers (stores) → documented as accepted risk (< 5ms) - [x] **P11** `frame_time` float division every loop iter → cache field - [x] **P12** `_check_name_unique` O(N) + no lock → add threading.Lock - [x] **P13** Imports inside 1-Hz metrics loop → move to module level ### Code Quality - [x] **Q1** `DeviceStore` not using `BaseJsonStore` - [x] **Q2** `ColorStripStore` 275-line god methods → factory dispatch - [x] **Q3** Layer violation: core imports from routes → extract to utility - [x] **Q4** 20+ field-by-field update in Device/routes → dataclass + generic update - [x] **Q5** WebSocket auth copy-pasted 9x → extract helper - [x] **Q6** `set_device_brightness` bypasses store → use update_device - [x] **Q7** DI via 16+ module globals → registry pattern - [x] **Q8** `_css_to_response` 30+ getattr → polymorphic to_response - [x] **Q9** Private attribute access across modules → expose as properties - [x] **Q10** `ColorStripSource.to_dict()` emits ~25 nulls → per-subclass override - [x] **Q11** `DeviceStore.get_device` returns None vs raises → raise ValueError - [x] **Q12** `list_all_tags` fragile method-name probing → use get_all() - [x] **Q13** Route create/update pass 30 individual fields → **kwargs ## UX - [ ] `P1` **Collapse dashboard running target stats** — Show only FPS chart by default; uptime, errors, and pipeline timings in an expandable section collapsed by default - [x] `P1` **Daylight brightness value source** — New value source type that reports a 0–255 brightness level based on daylight cycle time (real-time or simulated), reusing the daylight LUT logic - [x] `P1` **Tags input: move under name, remove hint/title** — Move the tags chip input directly below the name field in all entity editor modals; remove the hint toggle and section title for a cleaner layout