- Add enumerate_devices_by_engine() returning per-engine device lists
without cross-engine dedup so frontend can filter correctly
- API /audio-devices now includes by_engine dict alongside flat list
- Frontend caches per-engine data, filters device dropdown by selected
template's engine_type, refreshes on template change
- Reorder getting-started tutorial: add API docs and accent color steps
- Fix tutorial trigger button focus outline persisting on step 2
- Use accent color variable for tutorial pulse ring animation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace btn-icon with transparent flat dashboard-action-btn style
- Use Lucide power icon instead of square for stop/turn-off buttons
- Add accent-tinted hover backgrounds for start (green) and stop (amber)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Show CPU and GPU model names as overlays on performance chart cards
- Add cpu_name field to performance API with cross-platform detection
- Extract reusable color-picker popover module (9 presets + custom picker)
- Per-chart color customization for CPU/RAM/GPU performance charts
- Redesign header: compact toolbar container with icon-only buttons
- Compact language dropdown (EN/RU/ZH), icon-only login/logout
- Use accent color for FPS charts, range slider accent, dashboard icons
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add --primary-contrast CSS variable that auto-switches between white and
dark text based on accent color luminance (WCAG relative luminance).
Replace all hardcoded #fff/white on primary-color backgrounds with
var(--primary-contrast) so light accent colors like yellow remain readable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Color SVG icons in card titles (.card-title, .template-name) with accent
- Color SVG icons in property badges (.stream-card-prop, .card-meta) with accent
- Revert badge icon to white on crosslink hover
- Remove border-bottom separator from subtab bar
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 sub-tutorials for Dashboard, Targets, Sources, and Profiles tabs
with ? trigger buttons, en/ru/zh translations, and hidden-ancestor
skip via offsetParent check
- Add expand/collapse all buttons to Profiles tab toolbar
- Move dashboard poll slider from section header to toolbar
- Fix cardEnter animation forcing opacity:1 on disabled profile cards
- Use data-card-section selectors instead of data-cs-toggle to avoid
z-index misalignment during tutorial spotlight
- Add tutorial sync convention to CLAUDE.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Auto-starts on first visit with a 9-step walkthrough covering header,
tabs, settings, search, theme, and language controls. Stores completion
in localStorage; restart via ? button in the header. Includes en/ru/zh
translations for all tour steps.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove card-enter class after entrance animation completes to prevent
re-triggering when card-highlight is removed. Change fill-mode from
both to backwards so stale transforms don't block hover effects.
Suppress hover globally during drag via body.cs-drag-active class.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dashboard cards (targets, auto-start, profiles) are now clickable,
navigating to the full entity card on the appropriate tab. Card
sections support drag-and-drop reordering via grip handles with
localStorage persistence. Fix crosslink navigation scoping to avoid
matching dashboard cards, and fix highlight race on rapid clicks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When brightness source (e.g. Audio Volume) returned 0 during silence,
the zero-brightness suppression path skipped all frames without sending
DDP keepalive packets, causing WLED to exit live mode after ~2.5s.
Now sends periodic keepalive even when suppressing zero-brightness frames.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reduces map_leds_ms timing spikes from 4ms to ~1.5ms by eliminating
~540KB/frame of numpy temporary allocations:
- Pre-allocate _led_buf (reused instead of np.zeros per call)
- Pre-compute offset-adjusted segment indices (eliminates np.roll copy)
- Lazy-cache per-edge cumsum and mean buffers with np.mean/cumsum out=
- Pre-compute Phase 3 skip resampling arrays in __init__
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>
Stability: Add outer try/except/finally with _running=False cleanup to all 6
processing loop methods (live, color_strip, effect, audio, composite, mapped).
Add exponential backoff on consecutive capture errors in live_stream. Move
audio stream.stop() outside lock scope.
Performance: Replace per-pixel Python loop with np.array().tobytes() in
ddp_client. Vectorize pixelate filter with cv2.resize down+up. Vectorize
gradient rendering with np.searchsorted.
Frontend: Add lockBody/unlockBody re-entrancy counter. Add {once:true} to
fetchWithAuth abort listener. Null ws.onclose before ws.close() in LED preview.
Backend: Remove auth token prefix from log messages. Add atomic_write_json
helper (tempfile + os.replace) and update all 10 stores. Add name uniqueness
checks to all update methods. Fix DELETE status codes to 204 in audio_sources
and value_sources. Fix get_source() silent bug in color_strip_sources.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Audio value source cards link to the referenced audio source
- Adaptive scene cards link to the referenced picture source
- Fix SceneValueStream starting at 0.5 regardless of actual scene;
first frame now skips smoothing to avoid artificial bias
- Add crosslinks guidance to CLAUDE.md card appearance section
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>
- Make parent audio source badge on mono cards a clickable crosslink
that navigates to the multichannel source card
- Add missing color_strip.animation.type.none.desc locale key in
en/ru/zh
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace blocking REST-based capture tests with WebSocket endpoints that
stream intermediate frame thumbnails at ~100ms intervals, giving real-time
visual feedback during capture. Preview resolution adapts dynamically to
the client viewport size and device pixel ratio.
- New shared helper (_test_helpers.py) with engine_factory pattern to
avoid MSS thread-affinity issues
- WS endpoints for stream, capture template, and PP template tests
- Enhanced overlay spinner with live preview image and stats
- Frontend _runTestViaWS shared helper replaces three REST test runners
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>
Show effective brightness percentage on the LED preview when a
value source dims below 100%. Prepend a brightness byte to the
preview WebSocket wire format. Increase preview height to 32px.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add WebSocket endpoints for live audio spectrum streaming at ~20Hz
- Audio source test: resolves device/channel, shares stream via ref-counting
- Audio template test: includes device picker dropdown for selecting input
- Canvas-based 64-band spectrum visualizer with falling peaks and beat flash
- Channel-aware: mono sources show left/right/mixed spectrum correctly
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduces an engine+template abstraction for audio capture, mirroring the
existing screen capture engine pattern. This enables multiple audio backends
(WASAPI for Windows, sounddevice for cross-platform) with per-source
engine configuration via reusable templates.
Backend:
- AudioCaptureEngine ABC with WasapiEngine and SounddeviceEngine implementations
- AudioEngineRegistry for engine discovery and factory creation
- AudioAnalyzer class decouples FFT/RMS/beat analysis from engine-specific capture
- ManagedAudioStream wraps engine stream + analyzer in background thread
- AudioCaptureTemplate model and AudioTemplateStore with JSON CRUD
- AudioCaptureManager keyed by (engine_type, device_index, is_loopback)
- Auto-migration: default template created on startup, assigned to existing sources
- Full REST API: CRUD for audio templates + engine listing with availability flags
- audio_template_id added to MultichannelAudioSource model and API schemas
Frontend:
- Audio template cards in Streams > Audio tab with engine badge and config details
- Audio template editor modal with engine selector and dynamic config fields
- Audio template dropdown in multichannel audio source editor
- Template name crosslink badge on multichannel audio source cards
- Confirm modal z-index fix (always stacks above editor modals)
- i18n keys for EN and RU
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The dashboard panel appears before the targets panel in the DOM and both
use data-target-id. document.querySelector was finding the dashboard
element (which has no data-tm children) instead of the target card.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Charts: blue filled area for fps_actual (rolling avg), green line for
fps_current (real-time sends/sec)
- Labels: fps_current/fps_target as primary, avg fps_actual as secondary
- Track fps_current in metrics history for dashboard chart preload
- Applied to both LED targets page and dashboard
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove light.py platform (static color control via HA light entity)
- Add select.py with CSS Source and Brightness Source dropdowns for LED targets
- Coordinator now fetches color-strip-sources and value-sources lists
- Add generic update_target() method for partial target updates
- Clean up stale device registry entries on integration reload
- Skip frame sends when effective brightness is ~0 (suppresses unnecessary
UDP/HTTP traffic while LEDs are dark)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The refreshing bar was briefly visible during quick tab switches and
auto-refreshes. Delay adding the .refreshing class by 400ms so loads
that complete quickly never show the bar at all.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix inverted gamma formula: use (i/255)^gamma instead of (i/255)^(1/gamma)
so gamma>1 correctly darkens midtones (standard LED gamma correction)
- Fix frame interpolation flicker: move interp buffer update after temporal
smoothing so idle-tick output is consistent with new-frame output
- Fix target card hover/animation reset: use stable placeholder values in
card HTML for volatile metrics (data-tm attributes), patch real values
in-place after reconcile instead of replacing entire card DOM element
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add tab refresh loading bar animation for all 4 tab loaders
- Add profiles loading guard to prevent concurrent fetches
- Centralize theme colors into CSS variables (--text-secondary, --text-muted,
--bg-secondary, --success-color, --shadow-color) for both dark/light themes
- Replace hardcoded gray values across 10 CSS files with variables
- Fix duplicate .btn-sm definition in modal.css
- Fix z-index: toast 2001→2500 to safely clear modals at 2000
- Add :focus-visible keyboard navigation indicators for all interactive elements
- Add responsive breakpoints for tab bar and header on narrow screens
- Prevent background page scroll when command palette is open
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add loading guard to loadPictureSources to prevent concurrent fetches
- Pause perf chart polling and uptime timer when browser tab is hidden
- Disconnect KC and LED preview WebSockets when leaving targets tab
- Add error toasts to loadCaptureTemplates and saveKCBrightness
- Skip auto-refresh polling when document is hidden
- Widen auto-start dashboard cards for better text display
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add auto_start boolean field to PictureTarget model (persisted per-target)
- Wire auto_start through API schemas, routes, and store
- Auto-start targets on server boot in main.py lifespan
- Add star toggle button on target cards (next to delete button)
- Add auto-start section on dashboard between performance and profiles
- Remove auto-start section from profiles tab
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add AlwaysCondition model and evaluation (always returns true)
- Add condition type selector (Always/Application) in profile editor
- Show condition type pill on profile cards
- Fix misleading empty-conditions text (was "never activate", actually always active)
- Add i18n keys for Always condition (en + ru)
- Add CSS for condition type selector and description
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Make header sticky so search button stays visible on scroll. Section
headers stick below it using a JS-measured --header-height variable.
Add dim overlay behind highlighted cards for better focus effect.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fall back to stored device rgbw field when health check doesn't report
it (mock devices have no hardware to query). Add emoji icons to all
property badges on audio source and value source cards.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sort filtered items by group order so display indices match the array,
preventing wrong entity selection. Raise card-highlight z-index above
sticky section headers so the outline isn't clipped.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>