404 Commits

Author SHA1 Message Date
701eac19e5 Add "Always" condition type to profiles
- 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>
2026-02-25 14:38:25 +03:00
466527bd4a Add clone buttons, fix card navigation highlight, UI polish
- Add clone buttons to Audio Source and Value Source cards
- Fix command palette navigation destroying card highlight by skipping
  redundant data reload (skipLoad option on switchTab)
- Convert value source modal sliders to value-in-label pattern
- Change audio/value source modal footers to icon-only buttons
- Remove separator lines between card sections
- Add UI conventions to CLAUDE.md (card appearance, modal footer, sliders)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 03:10:36 +03:00
2b6bc22fc8 Sticky header, dim overlay on card navigation, fix sticky stacking
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>
2026-02-25 02:55:23 +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
7b07f38ce5 Fix command palette selection mismatch and card highlight z-index
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>
2026-02-25 02:45:41 +03:00
8bf40573f1 Add search button in header for touchscreen command palette access
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 02:42:14 +03:00
f67936c977 Add WebUI navigation improvements: keyboard shortcuts, hash routing, command palette, cross-entity links
- 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>
2026-02-25 02:40:24 +03:00
a82eec7a06 Enhance card section filter: multi-term OR/AND, filtered count badge
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>
2026-02-25 02:06:21 +03:00
d4a7c81296 Search all card text content in section filter, not just title
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 01:46:13 +03:00
e0e744095e Unify value source icons across dropdowns and card badges
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>
2026-02-25 01:41:13 +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
68ce394ccc Move overlay toggle into calibration visual editor, add tutorial step
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>
2026-02-25 00:50:39 +03:00
f2f67493b1 Fix LED overlay tick positions and reverse handling
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>
2026-02-25 00:50:33 +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
468cfa2022 Add brightness source badge to target cards, clean up FPS badge
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>
2026-02-24 20:42:23 +03:00
d45e59b0e6 Add min/max value range to audio value sources
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>
2026-02-24 20:41:49 +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
a5d855f469 Fix provider kwargs leak for mock device fields
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>
2026-02-24 20:41:36 +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
dc12452bcd Fix section toggle firing on filter input drag
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>
2026-02-24 19:22:45 +03:00
0b89731d0c Add palette type badge to audio color strip source cards
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>
2026-02-24 19:22:40 +03:00
858a8e3ac2 Rework root README to reflect current project state
Rewritten from scratch as "LED Grab" with organized feature sections,
full architecture tree, actual config examples, and comprehensive API listing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 19:22:34 +03:00
e4c4301a7b Add dirty check to all remaining editor modals
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>
2026-02-24 18:12:30 +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
48651f0a4e Show uptime in target cards, fix dashboard uptime stale after tab switch
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>
2026-02-24 14:36:14 +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
27720e51aa Add incremental card reconciliation to prevent full DOM rebuild on auto-refresh
CardSection now diffs cards by key attributes instead of rebuilding innerHTML,
preserving DOM elements, filter input focus, scroll position, and Chart.js
instances across the 2s targets tab auto-refresh cycle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 00:58:38 +03:00
166ec351b1 Add collapsible card sections with name filtering
Introduces CardSection class that wraps each card grid with a collapsible
header and inline filter input. Collapse state persists in localStorage,
filter value survives auto-refresh re-renders. When filter is active the
add-card button is hidden. Applied to all 13 sections across Targets,
Sources, and Profiles tabs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 00:46:14 +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
199039326b Add ADB-based Android screen capture engine with display picker integration
New scrcpy/ADB capture engine that captures Android device screens over
ADB using screencap polling. Supports USB and WiFi ADB connections with
device auto-discovery. Engine-aware display picker shows Android devices
when scrcpy engine is selected, with inline ADB connect form for WiFi
devices.

Key changes:
- New scrcpy_engine.py using adb screencap polling (~1-2 FPS over WiFi)
- Engine-aware GET /config/displays?engine_type= API
- ADB connect/disconnect API endpoints (POST /adb/connect, /adb/disconnect)
- Display picker supports engine-specific device lists
- Stream/test modals pass engine type to display picker
- Test template handler changed to sync def to prevent event loop blocking
- Restart script merges registry PATH for newly-installed tools
- All engines (including unavailable) shown in engine list with status flag

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 18:06:15 +03:00
cc08bb1c19 Add clone support for all entity types
Clone button on every card opens the editor in create mode pre-filled
with copied data and a "(Copy)" name suffix. Cancelling discards the
clone — entity is only persisted on Save.

Supported: LED targets, color strip sources, KC targets, pattern
templates, picture sources, capture templates, PP templates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 15:38:40 +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
f9a5fb68ed Add effect palette preview bar in CSS editor
Show a gradient color bar below the effect type description, giving
users a visual preview of palette colors before applying. Updates
live when switching effect type, palette, or meteor head color.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 01:59:25 +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
a4083764fb Add 5 procedural LED effects, gradient presets, auto-crop min aspect ratio, static source polling optimization
New features:
- Procedural effect source type with fire, meteor, plasma, noise, and aurora algorithms
  using palette LUT system and 1D value noise generator
- 12 predefined gradient presets (rainbow, sunset, ocean, forest, fire, lava, aurora,
  ice, warm, cool, neon, pastel) selectable from a dropdown in the gradient editor
- Auto-crop filter: min aspect ratio parameter to prevent false-positive cropping
  in dark scenes on ultrawide displays

Optimization:
- Static/gradient sources without animation: stream thread sleeps 0.25s instead of
  frame_time; processor repolls at frame_time instead of 5ms (~40x fewer iterations)
- Inverted isinstance checks in routes to test for PictureColorStripSource only

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