Commit Graph

59 Commits

Author SHA1 Message Date
6fc0e20e1d Add command palette entity selector for all editor dropdowns
Replace plain <select> dropdowns with a searchable command palette modal
for 16 entity selectors across 6 editors (targets, streams, CSS sources,
value sources, audio sources, pattern templates). Unified EntityPalette
singleton + EntitySelect wrapper in core/entity-palette.js.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 00:17:44 +03:00
fddbd771f2 Replace auto-start with startup automation, add card colors to dashboard
- 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>
2026-03-02 01:09:27 +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
6366b0b317 Fix mobile color picker popup clipping and locale update for tabs/sections
Color picker popover now uses fixed positioning on small screens to
escape the header toolbar overflow container. Section titles, sub-tab
labels, and filter placeholders use data-i18n attributes so they update
automatically on language change. Display picker title switches to
"Select a Device" for engine-owned display lists.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 14:26:15 +03:00
62b3d44e63 Add stop-all buttons to target sections, perf chart color reset, and TODO
- Add stop-all buttons to LED targets and KC targets section headers
  (visible only when targets are running, uses headerExtra on CardSection)
- Add reset ability to performance chart color pickers (removes custom
  color from localStorage and reverts to default)
- Remove CODEBASE_REVIEW.md
- Add prioritized TODO.md with P1/P2/P3 feature roadmap

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 01:46:58 +03:00
ec58282c19 Eliminate tab reload animation after saving card properties
- CardSection._animateEntrance: skip after first render to prevent
  card fade-in replaying on every data refresh
- automations: use reconcile() on subsequent renders instead of full
  innerHTML replacement that destroyed and recreated all cards
- streams: same reconcile() approach for all 9 CardSections
- targets/dashboard/streams: only show setTabRefreshing loading bar
  on first render when the tab is empty

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 00:07:18 +03:00
493d96d604 Show backend error details in toast notifications
Use error.detail from API responses instead of generic i18n messages
so users see specific reasons for failures (e.g. "Device is referenced
by target(s): ...").

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 22:11:24 +03:00
9b2ccde8a7 Add card color system with wrapCard helper and reset support
Introduce localStorage-backed card color assignment for all card types
with a reusable wrapCard() helper that provides consistent card shell
structure (top actions, bottom actions with color picker). Move color
picker from top-right to bottom-right action bar. Add color reset
button to clear card color back to default.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 21:55:29 +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
a34edf9650 Add reusable DataCache class, unify frontend cache patterns
- Create DataCache class with fetch deduplication, invalidation, subscribers
- Instantiate 10 cache instances in state.js (streams, templates, sources, etc.)
- Replace inline fetch+parse+set patterns with cache.fetch() calls across modules
- Eliminate dual _scenesCache/_presetsCache sync via shared scenePresetsCache
- Remove 9 now-unused setter functions from state.js
- Clean up unused setter imports from audio-sources, value-sources, displays

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 19:35:20 +03:00
0eb0f44ddb Remove all migration logic, scroll tutorial targets into view, mock URL uses device ID
- Remove legacy migration code: profiles→automations key fallbacks, segments array
  fallback, standby_interval compat, profile_id compat, wled→led type mapping,
  legacy calibration field, audio CSS migration, default template migration,
  loadTargets alias, wled sub-tab mapping
- Scroll tutorial step targets into view when off-screen
- Mock device URL changed from mock://{led_count} to mock://{device_id},
  hide mock URL badge on device cards

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 18:31:41 +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
c262ec0775 Replace all emoji icons with Lucide SVGs, add accent color picker
- 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>
2026-02-27 16:14:18 +03:00
efb6cf7ce6 Add per-tab tutorials, profile expand/collapse, and fix card animation
- 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>
2026-02-27 14:15:41 +03:00
9194b978e0 Add dashboard crosslinks and card drag-and-drop reordering
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>
2026-02-27 00:40:37 +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
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
cbbaa852ed Fix target metrics showing --- by scoping querySelector to targets panel
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>
2026-02-26 00:49:44 +03:00
f0e8f0ef33 Add crosslink navigation for picture source and audio source on CSS cards
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 00:21:32 +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
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
7f80faf8be Frontend polish: loading states, CSS variables, focus indicators, scroll lock
- 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>
2026-02-25 21:09:42 +03:00
82e12ffaac Fix critical frontend issues: race conditions, memory leaks, silent failures
- 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>
2026-02-25 17:29:47 +03:00
b51839ef3c Centralize icon resolution into core/icons.js, fix auto-start row alignment
- Create core/icons.js with type-resolution getters and icon constants
- Replace inline emoji literals across 11 feature files with imports
- Remove duplicate icon maps (getEngineIcon, _vsTypeIcons, typeIcons, etc.)
- Fix dashboard auto-start row missing metrics placeholder div

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 15:28:01 +03:00
d05b4b78f4 Add auto-start targets feature with dashboard section
- 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>
2026-02-25 15:08:01 +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
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
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
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
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
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
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
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
9392741f08 Batch API endpoints, reduce frontend polling by ~75%, fix resource leaks
Backend: add batch endpoints for target states, metrics, and device
health to replace O(N) individual API calls per poll cycle.
Frontend: use batch endpoints in dashboard/targets/profiles tabs,
fix Chart.js instance leaks, debounce server event reloads, add
i18n active-tab guards, clean up ResizeObserver on pattern editor
close, cache uptime timer DOM refs, increase KC auto-refresh to 2s.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 18:55:09 +03:00
d4a0f3a7f5 Add max HW FPS line on sparkline chart, fix button click race with polling
- Draw dashed orange line on target FPS sparkline showing hardware max FPS
- Prevent loadTargetsTab polling from rebuilding DOM while a button action
  (start/stop/overlay/delete) is in flight; add reentry guard on the
  refresh function itself

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 01:35:31 +03:00
1d5f542603 Show max FPS hint in target editor, fix gradient sharing for multi-target
- Add dynamic "Hardware max ≈ N fps" recommendation below FPS slider,
  computed from LED count (WLED: protocol timing) or baud rate (serial).
  Reuses shared _computeMaxFps from devices.js with named constants.
- Fix gradient looking different across targets sharing the same stream:
  configure() now uses max LED count across all consumers; _fit_to_device
  uses np.interp linear interpolation instead of truncate/tile.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 01:27:57 +03:00
1f6c913343 Move FPS from color strip source to target; dynamic capture rate
FPS is a consumption property (how fast to send to a device), not a
production property. Two targets sharing the same source may need
different FPS. This moves the fps field from PictureColorStripSource
to WledPictureTarget across the full stack.

The capture stream now auto-adjusts its rate to max(all connected
target FPS values) via ColorStripStreamManager tracking per-consumer
FPS. UI updates: FPS slider in target editor, FPS badge on target
cards, LED count repositioned in CSS editor, consistent speed icons.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 03:46:08 +03:00