Commit Graph

84 Commits

Author SHA1 Message Date
2712c6682e Add EntitySelect/IconSelect UI improvements across modals
- 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>
2026-03-09 16:00:30 +03:00
353a1c2d85 Rename picture-targets to output-targets across entire codebase
Rename all Python modules, classes, API endpoints, config keys, frontend
fetch URLs, and Home Assistant integration URLs from picture-targets to
output-targets. Store loads both new and legacy JSON keys for backward
compatibility with existing data files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 10:55:36 +03:00
8061c26bef Fix autorestore logic and protocol badge per device type
Autorestore fixes:
- Snapshot WLED state before connect() mutates it (lor, AudioReactive)
- Gate restore on auto_shutdown setting (was unconditional)
- Remove misleading auto_restore capability from serial provider
- Default auto_shutdown to false for all new devices

Protocol badge fixes:
- Show correct protocol per device type (OpenRGB SDK, MQTT, WebSocket)
- Was showing "Serial" for all non-WLED devices

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 10:04:40 +03:00
d6bda9afed Unify process picker, improve notification CSS editor, remove notification led_count
- 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>
2026-03-08 22:58:36 +03:00
bc5d8fdc9b Remove led_count from static, gradient, color_cycle, and effect CSS sources
These types always auto-size from the connected device — the explicit
led_count override was unused clutter. Streams now use getattr fallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 21:21:00 +03:00
de04872fdc Add notification reactive color strip source with webhook trigger
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>
2026-03-08 21:10:32 +03:00
39e41dfce7 Remove per-source speed, fix device dirty check, and add frontend caching
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>
2026-03-01 22:07:54 +03:00
aa1e4a6afc Add sync clock entity for synchronized animation timing
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>
2026-03-01 21:46:55 +03:00
52ee4bdeb6 Add OpenRGB per-zone LED control with separate/combined modes and zone preview
- 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>
2026-03-01 20:35:51 +03:00
fa81d6a608 Add WebSocket device type, capability-driven settings, hide filter on collapse
- 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>
2026-02-28 20:55:09 +03:00
bd8d7a019f Codebase review: stability, performance, usability, and i18n fixes
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>
2026-02-28 12:12:37 +03:00
d33d70cfe8 Fix keepalive not sent during zero-brightness suppression
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>
2026-02-26 21:45:26 +03:00
6f5bda6d8f Optimize processing pipeline and fix multi-target crash
Performance optimizations across 5 phases:
- Saturation filter: float32 → int32 integer math (~2-3x faster)
- Frame interpolation: pre-allocated uint16 scratch buffers
- Color correction: single-pass cv2.LUT instead of 3 channel lookups
- DDP: numpy vectorized color reorder + pre-allocated RGBW buffer
- Calibration boundaries: vectorized with np.arange + np.maximum
- wled_client: vectorized pixel validation and HTTP pixel list
- _fit_to_device: cached linspace arrays (now per-instance)
- Diagnostic lists: bounded deque(maxlen=...) instead of unbounded list
- Health checks: adaptive intervals (10s streaming, 60s idle)
- Profile engine: poll interval 3s → 1s

Bug fixes:
- Fix deque slicing crash killing targets when multiple run in parallel
  (deque doesn't support [-1:] or [:5] slice syntax unlike list)
- Fix numpy array boolean ambiguity in send_pixels() validation
- Persist fatal processing loop errors to metrics for API visibility
- Move _fit_to_device cache from class-level to instance-level to
  prevent cross-target cache thrashing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 21:28:17 +03:00
fda040ae18 Add per-target protocol selection (DDP/HTTP) and reorganize target editor
- 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>
2026-02-26 20:52:03 +03:00
cadef971e7 Add adaptive FPS and honest device reachability during streaming
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>
2026-02-26 20:22:58 +03:00
9cfe628cc5 Codebase review fixes: stability, performance, quality improvements
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>
2026-02-26 18:23:04 +03:00
bafd8b4130 Add value source card crosslinks and fix scene initial value bias
- 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>
2026-02-26 16:56:26 +03:00
88b3ecd5e1 Add value source test modal, auto-gain, brightness always-show, shared value streams
- 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>
2026-02-26 15:48:45 +03:00
a164abe774 Add min brightness threshold to LED targets
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>
2026-02-26 15:03:53 +03:00
c2deef214e Add brightness overlay and enlarge LED preview on target cards
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>
2026-02-26 14:44:03 +03:00
147ef3b4eb Add real-time audio spectrum test for audio sources and templates
- 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>
2026-02-26 14:19:41 +03:00
bae2166bc2 Add audio capture engine template system with multi-backend support
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>
2026-02-26 13:55:46 +03:00
1dc43f1259 Show both fps_current and fps_actual in WebUI charts and labels
- 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>
2026-02-26 00:08:32 +03:00
847ac38d8a Replace HAOS light entity with select entities, add zero-brightness optimization
- 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>
2026-02-25 23:33:25 +03:00
f507a6cf11 Fix gamma correction, frame interpolation flicker, and target card redraws
- 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>
2026-02-25 21:35:05 +03:00
83800e71fa Fix mock device RGBW badge, add icons to audio/value source card badges
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>
2026-02-25 02:49:47 +03:00
16f29bee30 Fix nonlocal scoping in CSS processing, move brightness source emoji to dropdown items
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>
2026-02-25 01:34:35 +03:00
359f33fdbb Fix filter_template expansion in test routes and select defaults
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>
2026-02-25 01:27:46 +03:00
04ee2e5830 Optimize audio capture and render loop performance
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>
2026-02-25 00:36:51 +03:00
0cd8304004 Resend frames when dynamic brightness changes on static CSS
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>
2026-02-24 20:45:44 +03:00
f96cd5f367 Allow multichannel audio sources as direct CSS and value source input
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>
2026-02-24 20:41:42 +03:00
34d9495eb3 Add audio capture timing metrics to target pipeline
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>
2026-02-24 20:41:29 +03:00
a39dc1b06a Add mock LED device type for testing without hardware
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>
2026-02-24 19:22:53 +03:00
053a56eed3 Add live LED strip preview via WebSocket on target cards
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>
2026-02-24 17:47:40 +03:00
a6253e8d96 Add overlay toggle to calibration dialog, fix serial reconnect on edge test
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>
2026-02-24 17:22:15 +03:00
67a15776b2 Add API Input color strip source type with REST and WebSocket push
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>
2026-02-24 17:07:47 +03:00
1e4a7a067f Split adaptive value source into explicit adaptive_time and adaptive_scene types
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>
2026-02-24 15:23:50 +03:00
d339dd3f90 Add adaptive brightness value source with time-of-day and scene modes
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>
2026-02-24 15:14:30 +03:00
425deb9570 Add server-side metrics ring buffer, seed dashboard charts from server history
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>
2026-02-24 13:21:37 +03:00
8f79b77fe4 Add dynamic brightness value source support for KC targets, fix subtab selector collision
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>
2026-02-24 12:42:00 +03:00
ef474fe275 Add value sources for dynamic brightness control on LED targets
Introduces a new Value Source entity that produces a scalar float (0.0-1.0)
for dynamic brightness modulation. Three subtypes: Static (constant),
Animated (sine/triangle/square/sawtooth waveform), and Audio-reactive
(RMS/peak/beat from mono audio source). Value sources can be optionally
attached to LED targets to control brightness each frame.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 12:19:40 +03:00
808037775f Remove target segments, use single color strip source per target
Segments are redundant now that the "mapped" CSS type handles spatial
multiplexing internally. Each target now references one color_strip_source_id
instead of an array of segments with start/end/reverse ranges.

Backward compat: existing targets with old segments format are migrated
on load by extracting the first segment's CSS source ID.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 00:00:26 +03:00
9efb08acb6 Add audio sources as first-class entities, add mapped CSS type, simplify target editor for mapped sources
- Audio sources moved to separate tab with dedicated CRUD API, store, and editor modal
- New "mapped" color strip source type: assigns different CSS sources to distinct LED sub-ranges (zones)
- Mapped stream runtime with per-zone sub-streams, auto-sizing, hot-update support
- Target editor auto-collapses segments UI when mapped CSS is selected
- Delete protection for CSS sources referenced by mapped zones
- Compact header/footer layout

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 23:35:58 +03:00
f15ff8fea0 Add audio channel selection (mono/left/right), show device LED count in target editor
Audio capture now produces per-channel FFT spectrum and RMS alongside
the existing mono mix. Each audio color strip source can select which
channel to visualize via a new "Channel" dropdown. This enables stereo
setups with separate left/right segments on the same LED strip.

Also shows the device LED count under the device selector in the target
editor for quick reference.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 15:05:15 +03:00
9d593379b8 Add multi-segment LED targets, replace single color strip source + skip fields
Each target now has a segments list where each segment maps a color strip
source to a pixel range (start/end) on the device with optional reverse.
This enables composing multiple visualizations on a single LED strip.
Old targets auto-migrate from the single source format on load.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 12:49:26 +03:00
bbd2ac9910 Add audio-reactive color strip sources, improve delete error messages
Add new "audio" color strip source type with three visualization modes
(spectrum analyzer, beat pulse, VU meter) supporting WASAPI loopback and
microphone input via PyAudioWPatch. Includes shared audio capture with
ref counting, real-time FFT spectrum analysis, and beat detection.

Improve all referential integrity 409 error messages across delete
endpoints to include specific names of referencing entities instead of
generic "one or more" messages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 11:56:54 +03:00
2657f46e5d Add composite color strip source type with layer blending
Composite sources stack multiple existing color strip sources as layers
with configurable blend modes (Normal, Add, Multiply, Screen) and per-layer
opacity. Includes full CRUD, hot-reload, delete protection for referenced
layers, and pre-allocated integer blend math at 30 FPS.

Also eliminates per-frame numpy allocations in color_strip_stream,
effect_stream, and wled_target_processor (buffer pre-allocation).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 11:01:44 +03:00
e5a6eafd09 Make count-dependent streams non-sharable, each target gets own instance
Static, gradient, color cycle, and effect streams depend on LED count
and were being reconfigured per-consumer when shared. Now only picture
streams (expensive capture) are shared; count-dependent sources get
per-consumer instances keyed by css_id:target_id.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 02:31:08 +03:00
e32bfab888 Add LED skip start/end, rename standby_interval to keepalive_interval, remove migrations
LED skip: set first N and last M LEDs to black on a target. Color sources
(static, gradient, effect, color cycle) render across only the active
(non-skipped) LEDs. Processor pads with blacks before sending to device.

Rename standby_interval → keepalive_interval across all Python, API
schemas, and JS. from_dict falls back to old key for existing configs.

Remove legacy migration functions (_migrate_devices_to_targets,
_migrate_targets_to_color_strips) and legacy fields from target model.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 02:15:29 +03:00
9e555cef2e Add composable filter templates, skip keepalive for serial devices
Filter Template meta-filter: reference existing PP templates inside others
for composable, DRY filter chains. Filters are recursively expanded at
pipeline build time with cycle detection. New `select` option type with
dynamic choices populated by the API.

Keepalive optimization: serial devices (Adalight, AmbiLED) don't need
keepalive — they hold last frame indefinitely. Check `standby_required`
capability at processor start, skip keepalive sends for serial targets,
and hide keepalive metrics in the UI. Rename "Standby Interval" to
"Keep Alive Interval" throughout the frontend.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 01:48:23 +03:00