- Refactor process-picker.ts into generic NamePalette with two concrete
instances: ProcessPalette (running processes) and NotificationAppPalette
(OS notification history apps)
- Notification color strip app colors and filter list now use
NotificationAppPalette (shows display names like "Telegram" instead of
process names like "telegram.exe")
- Fix case-insensitive matching for app_colors and app_filter_list in
notification_stream.py
- Compact browse/remove buttons in notification app color rows with
proper search icon
- Remove old inline process-picker HTML/CSS (replaced by palette overlay)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Settings modal split into 3 tabs: General, Backup, MQTT
- Log viewer moved to full-screen overlay with compact toolbar
- External URL setting: API endpoints + UI for configuring server domain
used in webhook/WS URLs instead of auto-detected local IP
- Sources tab tree restructured: Picture Source (Screen Capture/Static/
Processed sub-groups), Color Strip, Audio, Utility
- TreeNav extended to support nested groups (3-level tree)
- Audio tab split into Sources and Templates sub-tabs
- Fix audio template test: device picker now filters by engine type
(was showing WASAPI indices for sounddevice templates)
- Audio template test device picker disabled during active test
- Rename "Input Source" to "Source" in CSS test preview (en/ru/zh)
- Fix i18n: log filter/level items deferred to avoid stale t() calls
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
API Input CSS rework:
- Remove led_count field from ApiInputColorStripSource (always auto-sizes)
- Add segment-based payload: solid, per_pixel, gradient modes
- Segments applied in order (last wins on overlap), auto-grow buffer
- Backward compatible: legacy {"colors": [...]} still works
- Pydantic validation: mode-specific field requirements
Test preview:
- Enable test preview button on api_input cards
- Hide LED/FPS controls for api_input (sender controls those)
- Show input source selector for all CSS tests (preselected)
- FPS sparkline chart using shared createFpsSparkline (same as target cards)
- Server only sends frames when push_generation changes (no idle frames)
HAOS integration:
- New light.py: ApiInputLight entity per api_input source (RGB + brightness)
- turn_on pushes solid segment, turn_off pushes fallback color
- Register wled_screen_controller.set_leds service for arbitrary segments
- New services.yaml with field definitions
- Coordinator: push_colors() and push_segments() methods
- Platform.LIGHT added to platforms list
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
UI fixes:
- Automation card badge moved to flex layout — title truncates, badge stays visible
- Automation condition pills max-width increased to 280px
- Dashboard crosslinks fixed: pass correct sub-tab key (led-targets not led)
- navigateToCard only skips data load when tab already has cards in DOM
- Badge gets white-space:nowrap + flex-shrink:0 to prevent wrapping
New features:
- formatCompact() for large frame/error counters (1.2M, 45.2K) with hover title
- Log filter and log level selects replaced with IconSelect grids
- OpenRGB devices now support software brightness control
OpenRGB improvements:
- Added brightness_control capability (uses software brightness fallback)
- Change-threshold dedup compares raw pixels before brightness scaling
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend:
- VideoCaptureSource dataclass with url, loop, playback_speed, start/end_time,
resolution_limit, clock_id, target_fps fields
- VideoCaptureStream: OpenCV decode thread with frame-accurate sync clock seeking,
loop, trim range, resolution downscale at decode time
- YouTube URL resolution via yt-dlp (auto-detects youtube.com, youtu.be, shorts)
- Thumbnail extraction from first frame (GET /picture-sources/{id}/thumbnail)
- Video test WS preview: streams JPEG frames with elapsed/frame_count metadata
- Run video_stream.start() in executor to avoid blocking event loop during
yt-dlp resolution
- Full CRUD via existing picture source API (stream_type: "video")
- Wired into LiveStreamManager for target streaming
Frontend:
- Video icon (film) in picture source type map and graph node subtypes
- Video tree nav node in Sources tab with CardSection
- Video fields in stream add/edit modal: URL, loop toggle, playback speed slider,
target FPS, start/end trim times, resolution limit
- Video card rendering with URL, FPS, loop, speed badges
- Clone data support for video sources
- i18n keys for video source in en/ru/zh
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add Color Strip Processing Template (CSPT) entity: reusable filter chains
for 1D LED strip postprocessing (backend, storage, API, frontend CRUD)
- Add "processed" color strip source type that wraps another CSS source and
applies a CSPT filter chain (dataclass, stream, schema, modal, cards)
- Add Reverse filter for strip LED order reversal
- Add CSPT and processed CSS nodes/edges to visual graph editor
- Add CSPT test preview WS endpoint with input source selection
- Add device settings CSPT template selector (add + edit modals with hints)
- Use icon grids for palette quantization preset selector in filter lists
- Use EntitySelect for template references and test modal source selectors
- Fix filters.css_filter_template.desc missing localization
- Fix icon grid cell height inequality (grid-auto-rows: 1fr)
- Rename "Processed" subtab to "Processing Templates"
- Localize all new strings (en/ru/zh)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add horizontal axis with tick marks and LED index labels below strip
and composite preview canvases (first/last labels edge-aligned)
- Show actual/calibration LED count label on picture-based composite
layers (e.g. "25/934")
- Display warning icon in orange when LED counts don't match
- Send is_picture and calibration_led_count in composite layer_infos
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace inline type selectors with pre-modal type picker grid for devices,
color strip sources, and value sources
- Add filterable search to icon grid when items > 9 (no auto-focus on touch)
- Show disabled (grayed-out) filtered items instead of hiding them
- Responsive grid columns (2-5 cols based on viewport width)
- Add "Select a port..." placeholder to serial port dropdown
- Update en/ru/zh locales with new keys
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New device providers: ESP-NOW, Philips Hue, USB HID, SPI Direct,
Razer Chroma SDK, and SteelSeries GameSense — each with client,
provider, full backend registration, schemas, routes, and frontend
support including discovery, form fields, and i18n.
Add IconSelect grids for SPI LED chipset selector and GameSense
peripheral type selector with new Lucide icons (cpu, keyboard,
mouse, headphones).
Replace emoji graph overlay buttons (eye, bell) with proper SVG
path icons for consistent cross-platform rendering.
Fix connection overlay causing horizontal scroll by adding
overflow: hidden.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Full-stack implementation of DMX output for stage lighting and LED controllers:
- DMXClient with Art-Net and sACN packet builders, multi-universe splitting
- DMXDeviceProvider with manual_led_count capability and URL parsing
- Device store, API schemas, routes wired with dmx_protocol/start_universe/start_channel
- Frontend: add/settings modals with DMX fields, IconSelect protocol picker
- Fix add device modal dirty check on type change (re-snapshot after switch)
- i18n keys for DMX in en/ru/zh locales
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add FPS control (1-60, default 20) to test preview modal next to LED count
- Server accepts fps query param, controls frame send interval
- Single Apply icon button (✓) applies both LED count and FPS
- FPS control stays visible for picture sources (LED count hidden)
- Fix composite sub-stream consumer ID collision: use unique instance ID
to prevent old WebSocket release from killing new connection's streams
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Stream live JPEG frames from picture sources into the test preview rectangle
- Add composite layer brightness display via value source streaming
- Fix missing id on css-test-rect-screen element that prevented frame display
- Preload images before swapping to eliminate flicker on frame updates
- Increase preview resolution to 480x360 and add subtle outline
- Prevent auto-focus on name field in modals on touch devices (desktopFocus)
- Fix performance chart padding, color picker clipping, and subtitle offset
- Add calibration-style ticks and source name/LED count to rectangle preview
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Composite sources show per-layer strip canvases with composite result on top
- Server sends composite wire format with per-layer RGB data
- LED count is configurable via input field, persisted in localStorage
- Notification sources show a bell fire button on the strip preview
- Composite with notification layers shows per-layer fire buttons
- Fixed stale WS frame bug with generation counter and unique consumer IDs
- Modal width is now fixed at 700px to prevent layout jumps
- Target card composite layers now use same-height canvases
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wrap edge canvases in container divs with position:relative + overflow:hidden,
and absolutely-position the canvases inside. This prevents canvas intrinsic
pixel dimensions from overriding CSS grid cell sizing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New WebSocket endpoint streams real-time RGB frames from any CSS source.
Generic sources show a horizontal LED strip canvas. Picture sources show
a rectangle with per-edge canvases matching the calibration layout.
Server computes exact output indices per edge (offset + reverse + CW/CCW)
so the frontend renders edges in correct visual orientation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Animation section only has one field, so flatten it to a simple
form group with label instead of a details/summary wrapper.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove the separate tags form-group (label, hint toggle, hint text)
from all 14 editor modals and place the tags container directly
below the name input for a cleaner, more compact layout.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New value source that outputs brightness (0-1) based on the daylight
color LUT, computing BT.601 luminance from the simulated sky color.
Supports real-time wall-clock mode or configurable simulation speed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Full-stack implementation of two new color strip source types:
- Daylight: simulates day/night color cycle with real-time or speed-based mode, latitude support
- Candlelight: multi-candle fire simulation with Gaussian falloff, layered-sine flicker, warm color shift
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add `tags: List[str]` field to all 13 entity types (devices, output targets,
CSS sources, picture sources, audio sources, value sources, sync clocks,
automations, scene presets, capture/audio/PP/pattern templates)
- Update all stores, schemas, and route handlers for tag CRUD
- Add GET /api/v1/tags endpoint aggregating unique tags across all stores
- Create TagInput component with chip display, autocomplete dropdown,
keyboard navigation, and API-backed suggestions
- Display tag chips on all entity cards (searchable via existing text filter)
- Add tag input to all 14 editor modals with dirty check support
- Add CSS styles and i18n keys (en/ru/zh) for tag UI
- Also includes code review fixes: thread safety, perf, store dedup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Portal IconSelect popups to document.body with position:fixed to prevent
clipping by modal overflow-y:auto
- Replace custom scene selectors in automation editor with EntitySelect
command-palette pickers (main scene + fallback scene)
- Add IconSelect grid for automation deactivation mode (none/revert/fallback)
- Add IconSelect grid for automation condition type and match type
- Replace mapped zone source dropdowns with EntitySelect pickers
- Replace scene target selector with EntityPalette.pick() pattern
- Remove effect palette preview bar from CSS editor
- Remove sensitivity badge from audio color strip source cards
- Clean up unused scene-selector CSS and scene-target-add-row CSS
- Add locale keys for all new UI elements across en/ru/zh
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Filter type picker: IconSelect with 3-column grid, auto-add on select, removed redundant + button
- Audio mode picker: IconSelect with SVG visualizations for RMS/Peak/Beat
- Capture engine grid: added per-engine icons and localized descriptions
- Fixed scroll flash during icon grid open animation (settled class after transitionend)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract shared process picker module (core/process-picker.js) used by
both automation conditions and notification CSS app filter
- Remove led_count property from notification CSS source (backend + frontend)
- Replace comma-separated app filter with newline-separated textarea + browse
- Inline color cycle add button (+) into the color row
- Fix notification app color layout to horizontal rows
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New source_type "notification" fires one-shot visual effects (flash, pulse, sweep)
triggered via POST webhook. Designed as a composite layer for overlay on persistent
sources. Includes app color mapping, whitelist/blacklist filtering, and auto-sizing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add `startup` automation condition type that activates on server boot,
replacing the per-target `auto_start` flag
- Remove `auto_start` field from targets, scene snapshots, and all API layers
- Remove auto-start UI section and star buttons from dashboard and target cards
- Remove `color` field from scene presets (backend, API, modal, frontend)
- Add card color support to scene preset cards (color picker + border style)
- Show localStorage-backed card colors on all dashboard cards (targets,
automations, sync clocks, scene presets)
- Fix card color picker updating wrong card when duplicate data attributes
exist by using closest() from picker wrapper instead of global querySelector
- Add sync clocks step to Sources tab tutorial
- Bump SW cache v9 → v10
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Speed is now exclusively controlled via sync clocks — CSS sources no longer
carry their own speed/cycle_speed fields. Streams default to 1.0× when no
clock is assigned. Also fixes false-positive dirty check on the device
settings modal (array reference comparison) and converts several frontend
modules to use DataCache for consistent API response caching.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduces Synchronization Clocks — shared, controllable time bases
that CSS sources can optionally reference for synchronized animation.
Backend:
- New SyncClock dataclass, JSON store, Pydantic schemas, REST API
- Runtime clock with thread-safe pause/resume/reset and speed control
- Ref-counted runtime pool with eager creation for API control
- clock_id field on all ColorStripSource types
- Stream integration: clock time/speed replaces source-local values
- Paused clock skips rendering (saves CPU + stops frame pushes)
- Included in backup/restore via STORE_MAP
Frontend:
- Sync Clocks tab in Streams section with cards and controls
- Clock dropdown in CSS editor (hidden speed slider when clock set)
- Clock crosslink badge on CSS source cards (replaces speed badge)
- Targets tab uses DataCache for picture/audio sources and sync clocks
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Zone picker UI in device add/settings modals with per-zone checkbox selection
- Combined mode: pixels distributed sequentially across zones
- Separate mode: full effect resampled independently to each zone via linear interpolation
- Per-zone LED preview in target cards: one canvas strip per zone with hover overlay labels
- Zone badges on device cards enriched with actual LED counts from OpenRGB API
- Fix stale led_count by using device_led_count discovered at connect time
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cache camera enumeration results for 30s and limit probe range using
WMI camera count on Windows. Open source modal instantly with a loading
spinner while dropdowns are populated asynchronously.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New CameraEngine using OpenCV VideoCapture for webcam capture
- HAS_OWN_DISPLAYS class attribute on CaptureEngine base to distinguish
engines with their own device lists from desktop monitor engines
- Display picker renders device list for cameras/scrcpy, spatial layout
for desktop monitors
- Engine-aware display label formatting (camera name vs monitor index)
- Stream modal properly loads engine-specific displays on template change,
edit, and clone
- Camera backend config rendered as dropdown (auto/dshow/msmf/v4l2)
- Remove offline label from device cards (healthcheck indicator suffices)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New device type enabling control of keyboards, mice, RAM, GPU, and fans
via the OpenRGB SDK server (TCP port 6742). Includes auto-discovery,
health monitoring, state snapshot/restore, and fast synchronous pixel
send with brightness scaling. Also updates TODO.md with complexity notes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New WS device type: broadcaster singleton + LEDClient that sends binary
frames to connected WebSocket clients during processing
- FastAPI WS endpoint at /api/v1/devices/{device_id}/ws with token auth
- Frontend: add/edit WS devices, connection URL with copy button in settings
- Add health_check and auto_restore capabilities to WLED and Serial providers;
hide health interval and auto-restore toggle for devices without them
- Skip health check loop for virtual devices (Mock, MQTT, WS) — set always-online
- Copy buttons and labels for API CSS push endpoints (REST POST / WebSocket)
- Hide mock:// and ws:// URLs in target device dropdown
- Hide filter textbox when card section is collapsed (cs-collapsed CSS class)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove SVG icon function calls from <option> textContent — native
select elements render markup as literal text. Capture template options
now show "name (engine_type)", source options show just the name.
Add i18n placeholders to automation and scene editor name inputs.
Rename HAOS Scenes device from "{server_name} Scenes" to "Scenes".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove DeviceBrightnessSnapshot and AutomationSnapshot from scene data model
- Simplify capture_current_snapshot and apply_scene_state to targets only
- Remove device/automation dependencies from scene preset API routes
- Add target selector (combobox + add/remove) to scene capture modal
- Fix stale profiles reference bug in scene_preset_store recapture
- Update automation engine call sites for simplified scene functions
- Sync scene presets cache between automations and scene-presets modules
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rename the "profiles" entity to "automations" throughout the entire
codebase for clarity. Updates Python models, storage, API routes/schemas,
engine, frontend JS modules, HTML templates, CSS classes, i18n keys
(en/ru/zh), dashboard, tutorials, and command palette.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Profiles now activate scene presets instead of individual targets, with
configurable deactivation behavior (none/revert/fallback scene). The
target checklist UI is replaced by a searchable combobox for scene
selection that scales well with many scenes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Feature 1 — Profile Conditions: time-of-day, system idle (Win32
GetLastInputInfo), and display state (GUID_CONSOLE_DISPLAY_STATE)
condition types for automatic profile activation.
Feature 2 — Scene Presets: snapshot/restore system that captures target
running states, device brightness, and profile enables. Server-side
capture with 5-step activation order. Dedicated Scenes tab with
CardSection-based card grid, command palette integration, and dashboard
quick-activate section.
Feature 3 — MQTT Integration: MQTTService singleton with aiomqtt,
MQTTLEDClient device provider for pixel output, MQTT profile condition
type with topic/payload matching, and frontend support for MQTT device
type and condition editor.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Stability:
- Fix race condition: set _is_running before create_task in target processors
- Await probe task after cancel in wled_target_processor
- Replace raw fetch() with fetchWithAuth() across devices, kc-targets, pattern-templates
- Add try/catch to showTestTemplateModal in streams.js
- Wrap blocking I/O in asyncio.to_thread (picture_targets, system restore)
- Fix dashboardStopAll to filter only running targets with ok guard
Performance:
- Vectorize fire effect spark loop with numpy in effect_stream
- Vectorize FFT band binning with cumulative sum in analysis.py
- Rewrite pixel_processor with vectorized numpy (accept ndarray or list)
- Add httpx.AsyncClient connection pooling with lock in wled_provider
- Optimize _send_pixels_http to avoid np.hstack allocation in wled_client
- Mutate chart arrays in-place in dashboard, perf-charts, targets
- Merge dashboard 2-batch fetch into single Promise.all
- Hoist frame_time outside loop in mapped_stream
Usability:
- Fix health check interval load/save in device settings
- Swap confirm modal button classes (No=secondary, Yes=danger)
- Add aria-modal to audio/value source editors, fix close button aria-labels
- Add modal footer close button to settings modal
- Add dedicated calibration LED count validation error keys
i18n:
- Replace ~50 hardcoded English strings with t() calls across 12 JS files
- Add 50 new keys to en.json, ru.json, zh.json
- Localize inline toasts in index.html with window.t fallback
- Add data-i18n to command palette footer
- Add localization policy to CLAUDE.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace all emoji characters across WebUI with inline Lucide SVG icons
for cross-platform consistency (icon paths in icon-paths.js)
- Add accent color picker popover with 9 preset colors + custom picker,
persisted to localStorage, updates all CSS custom properties
- Remove subtab separator line for cleaner look
- Color badge icons with accent color for visual pop
- Remove processing badge from target cards
- Fix hardcoded #4CAF50 in FPS labels and active badges to use CSS vars
- Replace CSS content emoji (▶) with pure CSS triangle
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add protocol field (ddp/http) to storage, API schemas, routes, processor
- WledTargetProcessor passes protocol to create_led_client(use_ddp=...)
- Target editor: protocol dropdown + keepalive in collapsible Specific Settings
- FPS, brightness threshold, adaptive FPS moved to main form area
- Hide Specific Settings section for serial devices (protocol is WLED-only)
- Card badge: show DDP/HTTP for WLED devices, Serial for serial devices
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DDP uses fire-and-forget UDP, so when a WiFi device becomes overwhelmed
by sustained traffic, sends appear successful while the device is
actually unreachable. This adds:
- HTTP liveness probe (GET /json/info, 2s timeout) every 10s during
streaming, exposed as device_streaming_reachable in target state
- Adaptive FPS (opt-in): exponential backoff when device is unreachable,
gradual recovery when it stabilizes — finds sustainable send rate
- Honest health checks: removed the lie that forced device_online=true
during streaming; now runs actual health checks regardless
- Target editor toggle, FPS display shows effective rate when throttled,
health dot reflects streaming reachability, red highlight when
unreachable
- Auto-backup scheduling support in settings modal
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backend: GET /api/v1/system/backup bundles all 11 store JSON files into a
single downloadable backup with metadata envelope. POST /api/v1/system/restore
validates and writes stores atomically, then schedules a delayed server restart
via detached restart.ps1 subprocess.
Frontend: Settings modal (gear button in header) with Download Backup and
Restore from Backup buttons. Restore shows confirm dialog, uploads via
multipart FormData, then displays fullscreen restart overlay that polls
/health until the server comes back and reloads the page.
Locales: en, ru, zh translations for all settings.* keys.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Type is set at creation and cannot be changed, so hide the selector
when editing (same pattern already used in value source editor).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add real-time value source test: WebSocket endpoint streams get_value() at
~20Hz, frontend renders scrolling time-series chart with min/max/current stats
- Add auto-gain for audio value sources: rolling peak normalization with slow
decay, sensitivity range increased to 0.1-20.0
- Always show brightness overlay on LED preview when brightness source is set
- Refactor ValueStreamManager to shared ref-counted streams (value streams
produce scalars, not LED-count-dependent, so sharing is correct)
- Simplify acquire/release API: remove consumer_id parameter since streams
are no longer consumer-dependent
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New per-target property: when effective output brightness
(max pixel value × device/source brightness) falls below
the threshold, LEDs turn off completely. Useful for cutting
dim flicker in audio-reactive and ambient setups.
Threshold slider (0–254) in target editor, badge on card,
hot-swap to running processors, persisted in storage.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>