Commit Graph

348 Commits

Author SHA1 Message Date
ed220a97e7 Extract Modal base class and fix target editor defaults
Add core/modal.js with reusable Modal class that handles open/close,
body locking, backdrop close, dirty checking, error display, and a
static stack for ESC key management. Migrate all 13 modals across 8
feature files to use the base class, eliminating ~200 lines of
duplicated boilerplate. Replace manual ESC handler list in app.js
with Modal.closeTopmost(), fixing 3 modals that were previously
unreachable via ESC. Remove 5 unused initialValues variables from
state.js. Fix target editor to auto-select first device/source and
auto-generate name like the KC editor does.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 17:49:42 +03:00
20d5a42e47 Show device type in dashboard target subtitles for all targets
Fetch devices list alongside targets and profiles in loadDashboard,
then look up device_type from the devices map instead of relying on
state.device_name which is only available for running targets.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 17:22:51 +03:00
c79b7367da Add common.loading locale key and cancellable capture test overlay
Add missing common.loading i18n key to en/ru locales. Add close button
and ESC key support to the overlay spinner so users can cancel running
capture tests. Uses AbortController to abort the in-flight fetch request.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 17:20:09 +03:00
fb1086b309 Split monolithic app.js into native ES modules
Replace the single 7034-line app.js with 17 ES module files organized
into core/ (state, api, i18n, ui) and features/ (calibration, dashboard,
device-discovery, devices, displays, kc-targets, pattern-templates,
profiles, streams, tabs, targets, tutorials) with an app.js entry point
that registers ~90 onclick globals on window. No bundler needed — FastAPI
serves modules directly via <script type="module">.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 17:15:00 +03:00
3bac9c4ed9 Add AmbiLED device backend (client + provider)
AmbiLED protocol: raw RGB bytes (clamped 0-250) + 0xFF show command.
Subclasses Adalight infrastructure, shares serial transport and
discovery. Registered as built-in provider.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:12:55 +03:00
aa105f3958 Add profiles UI, dashboard improvements, and AmbiLED support
- Profile management tab with cards, condition editor, process browser
- Dashboard: add profiles section, compact layout, type subtitles
- AmbiLED serial device support (raw RGB + 0xFF show command)
- Unified serial device handling (isSerialDevice helper)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:12:45 +03:00
29d9b95885 Add profile system for automatic target activation
Profiles monitor running processes and foreground windows to
automatically start/stop targets when conditions are met.
Includes profile engine, platform detector (WMI), REST API,
process browser endpoint, and calibration persistence fix.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:12:34 +03:00
d6cf45c873 Add static color for simple devices, change auto-shutdown to auto-restore
- Add `static_color` capability to Adalight provider with `set_color()` method
- Add `static_color` field to Device model, DeviceState, and API schemas
- Add GET/PUT `/devices/{id}/color` API endpoints
- Change auto-shutdown behavior: restore device to idle state instead of
  powering off (WLED uses snapshot/restore, Adalight sends static color
  or black frame)
- Rename `_auto_shutdown_device_if_idle` to `_restore_device_idle_state`
- Add inline color picker on device cards for devices with static_color
- Add auto_shutdown toggle to device settings modal
- Update labels from "Auto Shutdown" to "Auto Restore" (en + ru)
- Remove backward-compat KC aliases from ProcessorManager
- Align card action buttons to bottom with flex column layout

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 13:42:05 +03:00
fc779eef39 Refactor core/ into logical sub-packages and split filter files
Reorganize the flat core/ directory (17 files) into three sub-packages:
- core/devices/ — LED device communication (led_client, wled/adalight clients, providers, DDP)
- core/processing/ — target processing pipeline (processor_manager, target processors, live streams, settings)
- core/capture/ — screen capture & calibration (screen_capture, calibration, pixel_processor, overlay)

Also split the monolithic filters/builtin.py (460 lines, 8 filters) into
individual files: brightness, saturation, gamma, downscaler, pixelate,
auto_crop, flip, color_correction.

Includes the ProcessorManager refactor from target-centric architecture:
ProcessorManager slimmed from ~1600 to ~490 lines with unified
_processors dict replacing duplicate _targets/_kc_targets dicts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 12:03:29 +03:00
77dd342c4c Add software brightness control for Adalight devices
Emulates hardware brightness by multiplying pixel values before serial
send. Stored per-device and persisted across restarts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 10:56:19 +03:00
27c97c3141 Add color correction postprocessing filter
New filter with color temperature (2000-10000K) and per-channel RGB
gain controls. Uses LUT-based processing for fast per-frame application.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 10:56:13 +03:00
c4955bcb34 Add FPS throttling to capture, processing, and send loops
All three frame pipeline loops were running unthrottled, consuming
excessive CPU. Now each sleeps for the remaining frame budget after
completing work.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 01:39:18 +03:00
cc91ccd75a Add power toggle button to LED device cards
WLED: native on/off via JSON API. Adalight: sends all-black frame
to blank LEDs (uses existing client if target is running, otherwise
opens temporary serial connection). Toggle button placed next to
delete button in card top-right corner.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 19:18:39 +03:00
f4503d36b4 Add dashboard tab with real-time target status overview
Dashboard is the new default tab showing running/stopped targets
with FPS, uptime, errors metrics. Updates live via events WebSocket.
Includes Stop All button and Start/Stop per target.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 14:54:11 +03:00
3ee17ed083 Optimize KC processing and add reactive HAOS state updates
- Optimize KC frame processing: downsample to 160x90 with cv2.resize
  before rectangle extraction, pre-compute pixel coords, vectorize
  smoothing with numpy arrays
- Add WebSocket event stream for server state changes: processor manager
  fires events on start/stop, new /api/v1/events/ws endpoint streams
  them to connected clients
- Add HAOS EventStreamListener that triggers coordinator refresh on
  state changes for near-instant switch updates
- Reduce HAOS polling interval from 10s to 3s for fresher FPS metrics
- Fix overlay button tooltips: flatten nested JSON keys in locale files
  to match flat dot-notation lookup used by t() function

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 14:21:47 +03:00
67da014684 Rewrite HAOS integration: target-centric architecture with KC color sensors
- Rewrite integration to target-centric model: each picture target becomes
  a HA device under a server hub with switch, FPS, and status sensors
- Replace KC light entities with color sensors (hex state + RGB attributes)
  for better automation support via WebSocket real-time updates
- Add WebSocket manager for Key Colors color streaming
- Add KC per-stage timing metrics (calc_colors, broadcast) with rolling avg
- Fix KC timing fields missing from API by adding them to Pydantic schema
- Make start/stop processing idempotent to prevent intermittent 404 errors
- Add HAOS localization support (en, ru) using translation_key system
- Rename integration from "WLED Screen Controller" to "LED Screen Controller"
- Remove obsolete select.py (display select) and README.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 13:01:40 +03:00
e92fe4eb0a Optimize frame processing pipeline for 55% FPS improvement
Replace slow PIL LANCZOS downscaler with OpenCV INTER_AREA (10-20x faster),
remove FPS throttling to maximize throughput, and add idle sleeps to prevent
CPU spinning. Also fix pixel mapping boundary clamping off-by-one error.

Changes:
- Downscaler filter: Use cv2.resize() with INTER_AREA instead of PIL LANCZOS
- Live streams: Remove FPS throttling, add 1ms sleep during idle/duplicate frames
- Processor manager: Remove FPS control sleep to process frames as fast as available
- Calibration: Fix boundary clamping to prevent index out of bounds crashes

Results: Processed stream FPS improved from 27 to ~42 FPS with lower CPU usage.
Parallel I2S network send verified at 0.1-0.2ms (can handle 200+ FPS).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-16 23:59:05 +03:00
4f4d17c44d Add screen overlay visualization for LED target testing
Implements transparent on-screen overlay that displays LED calibration data
directly on the target display for easier setup and debugging. Overlay shows
border zones, LED position axes with tick labels, and calibration details.

Features:
- Tkinter-based transparent overlay window with click-through support
- Border zones highlighting pixel sampling areas (colored rectangles)
- LED position axes with numbered tick marks at regular intervals
- Calibration info box showing target name, LED counts, and configuration
- Toggle button (eye icon) in target cards for show/hide
- Localized UI strings (English and Russian)

Implementation:
- New screen_overlay.py module with OverlayWindow and OverlayManager classes
- Overlay runs in background thread with proper asyncio integration
- API endpoints for start/stop/status overlay control
- overlay_active state tracking in processor manager

Known limitation: tkinter threading cleanup causes server restart when overlay
is closed, but functionality works correctly while overlay is active.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-16 22:33:16 +03:00
ac5c1d0c82 Optimize numpy pipeline, add per-stage timing, and auto-sync LED count
- Eliminate 5 numpy↔tuple conversions per frame in processing hot path:
  map_border_to_leds returns ndarray, inline numpy smoothing with integer
  math, send_pixels_fast accepts ndarray directly
- Fix numpy boolean bug in keepalive check (use `is not None`)
- Add per-stage pipeline timing (extract/map/smooth/send) to metrics API
  and UI with color-coded breakdown bar
- Expose device_fps from WLED health check in API schemas
- Auto-sync LED count from WLED device: health check detects changes and
  updates storage, calibration, and active targets automatically
- Use integer math for brightness scaling (uint16 * brightness >> 8)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:43:16 +03:00
350dafb1e8 Fix WLED LED stutters: restore DDP PUSH flag, skip HTTP during streaming
Three changes to eliminate periodic LED stutters on high-LED-count
WLED devices:

1. DDP PUSH flag: re-enable on the last packet of each frame so WLED
   waits for the complete frame before rendering (prevents tearing
   from partial multi-packet frames).

2. Health check: skip HTTP probe while a target is actively streaming
   to the device — the device is clearly online and the HTTP request
   to the ESP causes LED output to stutter.

3. Brightness polling: cache the value after first fetch and reuse it
   on subsequent 2-second UI refreshes instead of hitting the ESP
   every cycle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:48:08 +03:00
afb20f2dac Add configurable baud rate for Adalight with dynamic FPS hint
Baud rate is now a first-class device field, passed through the full
stack: Device model → API schemas → routes → ProcessorManager →
AdalightClient. The frontend shows a baud rate dropdown (115200–2M)
for Adalight devices in both Add Device and Settings modals, with a
live "Max FPS ≈ N" hint computed from LED count and baud rate.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:35:41 +03:00
1612c04c90 Add Adalight serial LED device support with per-type discovery and capability-based UI
Implements the second device provider (Adalight) for Arduino-based serial LED controllers,
validating the LEDDeviceProvider abstraction. Adds serial port auto-discovery, per-type
discovery caching with lazy-load, capability-driven UI (brightness control, manual LED count,
standby), and serial port combobox in both Add Device and General Settings modals.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 15:55:42 +03:00
242718a9a9 Add LEDDeviceProvider abstraction and standby capability flag
Consolidate all device-type-specific logic into LEDDeviceProvider ABC
with provider registry. WLEDDeviceProvider handles client creation,
health checks, validation, mDNS discovery, and brightness control.
Routes now delegate to providers instead of using if/else type checks.

Add standby_required capability and expose device capabilities in API.
Target editor conditionally shows standby interval based on selected
device's capabilities.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 13:39:27 +03:00
638dc526f9 Add WLED auto-discovery via mDNS with zeroconf
Scan the local network for WLED devices advertising _wled._tcp.local.
and present them in the Add Device modal for one-click selection.

- New discovery.py: async mDNS browse + parallel /json/info enrichment
- GET /api/v1/devices/discover endpoint with already_added dedup
- Header scan button (magnifying glass icon) in add-device modal
- Discovered devices show name, IP, LED count, version; click to fill form
- en/ru locale strings for discovery UI

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 13:06:29 +03:00
b5a6885126 Add LED device abstraction layer for multi-controller support
Introduce abstract LEDClient base class with factory pattern so new
LED controller types can plug in alongside WLED. ProcessorManager is
now fully type-agnostic — all device-specific logic (health checks,
state snapshot/restore, fast send) lives behind the LEDClient interface.

- New led_client.py: LEDClient ABC, DeviceHealth, factory functions
- WLEDClient inherits LEDClient, encapsulates WLED health checks and state management
- device_type field on Device storage model (defaults to "wled")
- Rename target_type "wled" → "led" with backward-compat migration
- Frontend: "WLED" tab → "LED", device type badge, type selector in
  add-device modal, device type shown in target device dropdown
- All wled_* API fields renamed to device_* for generic naming

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 12:41:02 +03:00
afce183f79 Add skip LEDs feature with physical resampling and per-edge tick labels
Skip LEDs at the start/end of the strip are blacked out while the full
screen perimeter is resampled onto the remaining active LEDs using linear
interpolation. Calibration canvas tick labels show per-edge display
ranges clipped to the active LED range. Moved LED offset control from
inline overlay to a dedicated form row alongside the new skip inputs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 10:55:21 +03:00
398f090eca Port WLED optimizations to KC loop: fix FPS metrics, add keepalive and auto-refresh test
- Fix KC fps_actual to use frame-to-frame timestamps (was inflated by measuring before sleep)
- Add fps_potential, fps_current, frames_skipped, frames_keepalive metrics to KC loop
- Add keepalive broadcast for static frames so WS clients stay in sync
- Expose all KC metrics in get_kc_target_state() and update UI card to show 7 metrics
- Add auto-refresh play/pause button to KC test lightbox (polls every ~1s)
- Fix WebSocket color swatches computing hex from r,g,b when hex field is absent
- Fix WebSocket auth crash by using get_config() instead of module-level config variable
- Fix lightbox closing when clicking auto-refresh button (event bubbling)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:57:07 +03:00
9383fb9a53 Apply postprocessing filters in KC test endpoint
The KC test was showing the raw captured image instead of the processed
one. Now resolves the filter chain from postprocessing templates and
applies them before color extraction, matching live KC processing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:38:32 +03:00
91e5384422 Reduce image memory allocation with ring buffer, LUTs, and pool reuse
Replace per-frame image.copy() in ProcessedLiveStream with a 3-slot
ring buffer that reuses pre-allocated arrays. Use 256-byte LUTs for
brightness and gamma filters instead of full float32 conversion. Add
reusable float32 buffer to saturation filter. Use pool scratch buffer
for flip filter. Remove redundant .copy() calls from WGC capture engine.
Release intermediate filter outputs back to ImagePool.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:33:46 +03:00
3100b0d979 Add frame-change detection, keepalive, current FPS, and compact metrics UI
Skip redundant processing/DDP sends when screen is static using object
identity comparison. Add configurable standby interval to periodically
resend last frame keeping WLED in live mode. Track frames skipped,
keepalive count, and current FPS (rolling 1-second send count). Always
use DDP regardless of LED count. Compact metrics grid with label-value
rows and remove Skipped from UI display.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:17:14 +03:00
8d5ebc92ee Optimize WLED processing pipeline and add FPS metrics
- Add numpy-based DDP pixel packing (send_pixels_numpy) and fast send
  path (send_pixels_fast) eliminating per-pixel Python loops
- Move ProcessedLiveStream filter processing to background thread so
  get_latest_frame() returns pre-computed cached result instantly
- Vectorize map_border_to_leds for average interpolation using cumulative
  sums instead of 934 individual np.mean calls (~16ms -> <1ms)
- Batch all CPU work into single asyncio.to_thread call per frame
- Fix FPS calculation to measure frame-to-frame interval (was measuring
  processing time only, reporting inflated values)
- Add Potential FPS metric showing theoretical max without throttling
- Add FPS label to WLED target card properties
- Add fps_potential field to TargetProcessingState API schema

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 14:43:19 +03:00
7e729c1e4b Add Target FPS slider to WLED target editor dialog
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 00:47:25 +03:00
0da1243fb0 Add KC target test button, API docs header link, and UI polish
- Add POST /api/v1/picture-targets/{target_id}/test endpoint for single-frame
  color extraction preview on Key Colors targets
- Add test button on KC target cards that opens lightbox with spinner,
  displays captured frame with rectangle overlays and color swatches
- Add API docs link in WebUI header
- Swap confirm dialog button colors (No=red, Yes=neutral)
- Remove type badges from WLED and KC target cards

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 22:10:01 +03:00
8d4dbbcc7f Polish Pattern Template UI: dialog sizing, KC editor layout, and conventions
- Fix dialog/canvas sizing: fit-content dialog follows canvas width, canvas
  max-width: 100% prevents overflow, horizontal resize supported
- Move pattern template dropdown above FPS/mode/smoothing in KC editor
- Remove emoji from pattern template dropdown options and auto-generated names
- Remove placeholder option from pattern template select, default to first
- Rename default pattern template from "Default" to "Full Screen"
- Add UI conventions to CLAUDE.md (hint pattern, select dropdown rules)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 18:46:08 +03:00
87e7eee743 Add Pattern Templates for Key Colors targets with visual canvas editor
Introduce Pattern Template entity as a reusable rectangle layout that
Key Colors targets reference via pattern_template_id. This replaces
inline rectangle storage with a shared template system.

Backend:
- New PatternTemplate data model, store (JSON persistence), CRUD API
- KC targets now reference pattern_template_id instead of inline rectangles
- ProcessorManager resolves pattern template at KC processing start
- Picture source test endpoint supports capture_duration=0 for single frame
- Delete protection: 409 when template is referenced by a KC target

Frontend:
- Pattern Templates section in Key Colors sub-tab with card UI
- Visual canvas editor with drag-to-move, 8-point resize handles
- Background capture from any picture source for visual alignment
- Precise coordinate list synced bidirectionally with canvas
- Resizable editor container, viewport-constrained modal
- KC target editor uses pattern template dropdown instead of inline rects
- Localization (en/ru) for all new UI elements

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 18:07:40 +03:00
5f9bc9a37e Add Key Colors target type for extracting colors from screen regions
Introduce a new "key_colors" target type alongside WLED targets, enabling
real-time color extraction from configurable screen rectangles with
average/median/dominant modes, temporal smoothing, and WebSocket streaming.

- Split WledPictureTarget into its own module, add KeyColorsPictureTarget
- Add KC target lifecycle to ProcessorManager (register, start/stop, processing loop)
- Extend API routes and schemas for KC targets (CRUD, settings, state, metrics, colors)
- Add WebSocket endpoint for real-time color updates with auth
- Add KC sub-tab in Targets UI with editor modal and live color swatches
- Add EN and RU translations for all key colors strings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 16:43:09 +03:00
3d2393e474 Fix tab jump on page reload and add config grid spacing
Apply saved active tab from localStorage via inline script during HTML
parse to prevent visible tab switch after page becomes visible.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 15:57:16 +03:00
58df163ded Rename WLED Grab to LED Grab, merge Devices into Targets tab with WLED sub-tab, and UI polish
- Rename "WLED Grab" to "LED Grab" across all files (title, logs, locales)
- Merge Devices and Targets into a single Targets tab with WLED sub-tab
  containing Devices and Targets sections (like Sources tab pattern)
- Make target card source name label full-width
- Render engine template config as two-column key-value grid
- Update CLAUDE.md: no server restart needed for frontend-only changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 15:44:11 +03:00
55814a3c30 Introduce Picture Targets to separate processing from devices
Add PictureTarget entity that bridges PictureSource to output device,
separating processing settings from device connection/calibration state.
This enables future target types (Art-Net, E1.31) and cleanly decouples
"what to stream" from "where to stream."

- Add PictureTarget/WledPictureTarget dataclasses and storage
- Split ProcessorManager into DeviceState (health) + TargetState (processing)
- Add /api/v1/picture-targets endpoints (CRUD, start/stop, settings, metrics)
- Simplify device API (remove processing/settings/metrics endpoints)
- Auto-migrate existing device settings to picture targets on first startup
- Add Targets tab to WebUI with target cards and editor modal
- Add en/ru locale keys for targets UI

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 15:27:41 +03:00
c3828e10fa Refactor capture engine architecture, rename PictureStream to PictureSource, and split API modules
- Separate CaptureEngine into stateless factory + stateful CaptureStream session
- Add LiveStream/LiveStreamManager for shared capture with reference counting
- Rename PictureStream to PictureSource across storage, API, and UI
- Remove legacy migration logic and unused compatibility code
- Split monolithic routes.py (1935 lines) into 5 focused route modules
- Split schemas.py (480 lines) into 7 schema modules with re-exports
- Extract dependency injection into dedicated dependencies.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:27:00 +03:00
b8389f080a Add color-scheme to dark/light themes for native control styling
Spin buttons, checkboxes, scrollbars, and other native form controls
now render in the correct theme instead of using default browser chrome.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 03:08:44 +03:00
472acd700a Add full-image lightbox and restore WLED state on stop
- Add GET /picture-streams/full-image endpoint to serve full-res images
- Click static image preview thumbnail to open full-res lightbox
- Snapshot WLED state (on/off, lor, AudioReactive) before streaming
- Restore saved WLED state when streaming stops

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 03:06:59 +03:00
66eecdb3c9 Fix settings persistence, streaming stability, and UI polish
- Fix device settings partial update using model_fields_set for true merge
- Add missing interpolation_mode and smoothing to all API responses
- Fix send_pixels race condition when wled_client is None during stop
- Allow LED segments to exceed edge pixel count (float stepping)
- Fix modal scroll lock using position:fixed to prevent layout shift
- Show loading state for brightness slider until real value is fetched
- Remove stream description from stream selector dialog

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 02:59:34 +03:00
aa02a5f372 Add WLED brightness control, auto-name dialogs, and UI fixes
- Brightness slider now reads/writes actual WLED device brightness via
  new GET/PUT /devices/{id}/brightness endpoints (0-255 range)
- Cache last-known brightness to prevent slider jumping on card refresh
- Auto-generate names for stream, engine template, and PP template dialogs
- Fix sub-tabs not re-rendering on language change
- Add capture template icon (camera) to stream card pills
- Fix last calibration tutorial popup position

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 02:20:35 +03:00
136f6fd120 Add Flip filter with bool option support and calibration UI polish
- New FlipFilter with horizontal/vertical bool options (np.fliplr/flipud)
- Add bool option type to filter system (base.py validate, app.js toggle UI)
- Rearrange calibration preview: direction toggle above LED count
- Normalize direction/offset control heights, brighten offset icon

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 01:55:00 +03:00
a4991c884a Fix DDP streaming and capture thread safety
- Fix WLED DDP config: use lor=0 (live overrides effects), remove
  live flag (read-only, causes issues on 0.15.x), disable PUSH flag
  which broke rendering on WLED 0.15.x
- Use dedicated single-thread executor for capture engine calls to
  fix thread-local state issues with BetterCam/MSS/DXcam
- Sync processor state on stream/template change even when stopped,
  preventing stale engine references on next start
- Add diagnostic logging for frame sends and DDP packets

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 01:27:01 +03:00
4c21ae5178 Fix DDP multi-bus color issues with PUSH flag and packet alignment
- Add PUSH flag (0x01) on last DDP packet to signal frame completion
- Align packet payload to multiples of 3 bytes to prevent splitting
  pixel RGB channels across packet boundaries
- Add per-bus WLED configuration logging (pin, color order, LED range)
- Add BusConfig dataclass and per-bus color reorder infrastructure
  for future use
- Remove old per-pixel color reordering (WLED handles internally)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 00:39:15 +03:00
d229c9a0d5 Improve property description hints for dialogs 2026-02-12 00:31:44 +03:00
ebec1bd16e Add BetterCam engine, UI polish, and bug fixes
- Add BetterCam capture engine (DXGI Desktop Duplication, priority 4)
- Fix missing picture_stream_id in get_device endpoint
- Fix template delete validation to check streams instead of devices
- Add description field to capture engine template UI
- Default template name changed to "Default" with descriptive text
- Display picker highlights selected display instead of primary
- Fix modals closing when dragging text selection outside dialog
- Rename "Engine Configuration" to "Configuration", hide when empty
- Rename "Run Test" to "Run" across all test buttons
- Always reserve space for vertical scrollbar
- Redesign Stream Settings info panel with pill-style props
- Fix processed stream showing internal ID instead of stream name
- Update en/ru locale files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 23:28:35 +03:00
9ae93497a6 Merge templates into Streams tab, rename app to WLED Grab
- Merge Capture Templates and Processing Templates main tabs into Picture
  Streams sub-tabs (Screen Capture shows streams + engine templates,
  Processed shows streams + filter templates)
- Rename "Capture Templates" to "Engine Templates" and "Processing
  Templates" to "Filter Templates" across all locale strings
- Rename "Picture Streams" tab to "Streams" throughout UI and locales
- Rename "WLED Screen Controller" to "WLED Grab" across all files
- Add subtab section headers and styling for merged template views
- Remove add card labels, keeping only plus icon for cleaner UI

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:53:03 +03:00