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>
- Keyboard shortcuts: Ctrl+1-4 for tab switching
- URL hash routing: #tab/subtab format with browser back/forward support
- Tab count badges: running targets and active profiles counts
- Cross-entity quick links: clickable references navigate to related cards
- Command palette (Ctrl+K): global search across all entities with keyboard navigation
- Expand/collapse all sections: buttons in sub-tab bars
- Sticky section headers: headers pin while scrolling long card grids
- Improved section filter: better styling with reset button
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Space-separated terms use OR logic, comma-separated use AND.
Count badge shows visible/total when filter is active.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract getValueSourceIcon() into value-sources.js and use it for
brightness source dropdowns and card badges in both LED and KC targets.
Icons now match value source cards: 📊 static, 🔄 animated, 🎵 audio,
🕐 adaptive_time, 🌤️ adaptive_scene.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add nonlocal declarations for _u16_a, _u16_b, _i32 in nested functions
_blend_u16 and _apply_corrections — Python treats augmented assignments
(*=, +=, >>=) as local variable bindings, causing UnboundLocalError
that prevented any frames from being sent to devices.
Move 🔢 emoji from brightness source label to dropdown option items.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
filter_template references were silently ignored in PP template test,
picture source test, and KC target test routes — they created a no-op
FilterTemplateFilter instead of expanding into the referenced template's
filters. Centralized expansion logic into PostprocessingTemplateStore.
resolve_filter_instances() and use it in all test routes + live stream
manager.
Also fixed empty template_id when adding filter_template filters: the
select dropdown showed the first template visually but onchange never
fired, saving "" instead. Now initializes with first choice's value and
auto-corrects stale/empty values at render time.
Other fixes: ScreenCapture dimensions now use actual image shape after
filter processing; brightness source label emoji updates.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Place the overlay button inside the preview screen as a pill toggle,
add it as a tutorial step that auto-skips in device calibration mode.
Tutorial engine now skips hidden/missing targets in both directions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use i/(count-1) fraction (matching calibration dialog) so LEDs span
the full edge, and apply seg.reverse flag for correct numbering.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
audio_capture.py:
- Move _fft_bands from inner function to method (avoid per-frame closure)
- Pre-allocate channel split buffers and RMS scratch arrays
- Use in-place numpy ops (np.copyto, np.multiply) instead of copies
- In-place FFT smoothing instead of temp array allocation
- Cache loop-invariant values as locals
- Fix energy index to wrap-around instead of unbounded increment
audio_stream.py:
- Pre-compute interpolation arrays (band_x, led_x, full_amp, indices_buf,
vu_gradient) once on LED count change instead of every frame
- Pre-compute VU meter base/peak float arrays in _update_from_source
- Reuse full_amp and indices_buf buffers across frames
- In-place spectrum smoothing to avoid temp allocations
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The processing loop skipped resending when the CSS frame was
unchanged (static source). With a dynamic brightness value source
(e.g. audio), brightness can change every frame while colors stay
the same. Now compare effective brightness against previous value
and resend when it differs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Show brightness value source name on LED and KC target cards when
configured. Remove redundant 'fps' text from FPS badges.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add min_value and max_value fields to AudioValueSource so audio
brightness can be mapped to a configurable range (e.g. silence =
30% brightness floor instead of fully black).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add resolve_audio_source() that accepts both MultichannelAudioSource
(defaults to mono mix) and MonoAudioSource. Update CSS and brightness
value source dropdowns to show all audio sources with type badges.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pop send_latency_ms and rgbw from kwargs in WLED, Adalight, and
AmbiLED providers so mock-only fields don't leak through to
non-mock client constructors.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instrument AudioCaptureStream with read/FFT timing and
AudioColorStripStream with render timing. Display audio-specific
timing segments (read/fft/render/send) in the target card
breakdown bar when an audio source is active.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Virtual device with configurable LED count, RGB/RGBW mode, and simulated
send latency. Includes full provider/client implementation, API schema
support, and frontend add/settings modal integration.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Changed header collapse from click to mousedown so dragging from the
filter input to outside no longer triggers a toggle.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shows palette name for spectrum and beat_pulse visualization modes,
matching the existing pattern on effect cards.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Subclass Modal with snapshotValues() for: value source editor, audio
source editor, add device, profile editor, capture template, stream
editor, and PP template modals. Close/cancel now triggers discard
confirmation when form has unsaved changes. Document the convention
in CLAUDE.md.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Stream real-time LED colors from running WLED targets to the browser via
binary WebSocket (RGB bytes, throttled to ~15 fps). Toggle button on
target card opens a compact canvas strip that renders each frame using
ImageData. Cached last frame is re-rendered after card reconciliation to
prevent flicker during auto-refresh.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a 💡 button in the calibration modal header (CSS mode only) that
toggles the LED overlay visualization. Auto-stops overlay on modal close
if started from the dialog. Checks and reflects current overlay status
on modal open.
Fix serial devices creating a new connection on every edge test toggle,
which triggered Arduino bootloader resets. Now reuses the cached idle
client for all device types.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New source_type "api_input" allows external clients to push raw LED
color arrays ([R,G,B] per LED) via REST POST or WebSocket. Includes
configurable fallback color and timeout for automatic revert when no
data is received. Stream auto-sizes LED count from the target device.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace single "adaptive" type with adaptive_mode sub-selector by two
distinct source types in the dropdown. Removes the adaptive_mode field
entirely — the source_type itself carries the mode. Clearer UX with
"Adaptive (Time of Day)" and "Adaptive (Scene)" as separate options.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New "adaptive" value source type that automatically adjusts brightness
based on external conditions. Two sub-modes: time-of-day (schedule-based
interpolation with midnight wrap) and scene brightness (frame luminance
analysis via numpy BT.601 subsampling with EMA smoothing).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add uptime metric to both LED and KC target cards in the targets tab.
Move formatUptime() to shared ui.js module. Fix dashboard uptime freezing
when switching tabs by re-caching DOM element refs on early return paths.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Background task samples system (CPU/RAM/GPU) and per-target (FPS/timing) metrics
every 1s into a 120-sample ring buffer (~2 min). New API endpoint
GET /system/metrics-history returns the buffer. Dashboard charts now seed from
server history on load instead of sessionStorage, surviving page refreshes.
Also removes emoji from brightness source labels.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extend value source brightness modulation to Key Colors targets (matching LED target support).
Also fix stream subtab CSS selector collision that broke target subtab selection, and use 🔢 emoji
for value source UI elements.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>