Commit Graph

180 Commits

Author SHA1 Message Date
c5ced0d904 Dashboard: show color strip source type in target subtitle
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 19:43:26 +03:00
7479b1fb8d CSS: add GradientColorStripSource with visual editor
- Backend: GradientColorStripSource storage model, GradientColorStripStream
  with numpy interpolation (bidirectional stops, auto-size from device LED count),
  ColorStop Pydantic schema, API create/update/guard routes
- Frontend: gradient editor modal (canvas preview, draggable markers, stop rows),
  CSS hard-edge card swatch, locale keys (en + ru)
- Fixes: stop row mousedown no longer rebuilds DOM (buttons now clickable),
  position input max-width, bidir/remove button static width

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 19:35:41 +03:00
2a8e2daefc CSS: add StaticColorStripSource type with auto-sized LED count
Introduces a new 'static' source type that fills all device LEDs with a
single constant RGB color — no screen capture or processing required.

- StaticColorStripSource storage model (color + led_count=0 auto-size)
- StaticColorStripStream: no background thread, configure() sizes to device
  LED count at processor start; hot-updates preserve runtime size
- ColorStripStreamManager dispatches static sources (no LiveStream needed)
- WledTargetProcessor calls stream.configure(device_led_count) on start
- API schemas/routes: source_type Literal["picture","static"]; color field;
  overlay/calibration-test endpoints return 400 for static
- Frontend: type selector modal, color picker, type-aware card rendering
  (🎨 icon + color swatch), LED count field hidden for static type
- Locale keys: color_strip.type, color_strip.static_color (en + ru)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 17:49:48 +03:00
0a23cb7043 Overlay: show CW/CCW instead of full direction word
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 17:26:36 +03:00
018bedf9f6 Overlay: fix 404, crash on repeat, missing edge test colors, device reset on stop
- Target overlay works without active processing: route pre-loads calibration
  and display info from the CSS store, passes to processor as fallback
- Fix server crash on repeated overlay: replace per-window tk.Tk() with single
  persistent hidden root; each overlay is a Toplevel child dispatched via
  root.after() — eliminates Tcl interpreter crashes on Windows
- Fix edge test colors not lighting up: always call set_test_mode regardless
  of processing state (was guarded by 'not proc.is_running'); pass calibration
  so _send_test_pixels knows which LEDs map to which edges
- Fix device reset on overlay stop: keep idle serial client cached after
  clearing test mode; start_processing() already closes it before connecting

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 17:16:10 +03:00
a3aeafef13 CSS: add led_count field; calibration dialog improvements; color corrections collapsible section
- Add explicit led_count to PictureColorStripSource (0 = auto from calibration)
- Stream pads with black or truncates to match led_count exactly
- Calibration dialog: show led_count input above visual editor in CSS mode
- Calibration dialog: pre-populate led_count with effective count (cal sum) when stored value is 0
- Calibration dialog: sync preview label live as led_count input changes
- CSS editor: group brightness/saturation/gamma into collapsible "Color Corrections" section

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 16:42:32 +03:00
7de3546b14 Introduce ColorStripSource as first-class entity
Extracts color processing and calibration out of WledPictureTarget into a
new PictureColorStripSource entity, enabling multiple LED targets to share
one capture/processing pipeline.

New entities & processing:
- storage/color_strip_source.py: ColorStripSource + PictureColorStripSource models
- storage/color_strip_store.py: JSON-backed CRUD store (prefix css_)
- core/processing/color_strip_stream.py: ColorStripStream ABC + PictureColorStripStream (runs border-extract → map → smooth → brightness/sat/gamma in background thread)
- core/processing/color_strip_stream_manager.py: ref-counted shared stream manager

Modified storage/processing:
- WledPictureTarget simplified to device_id + color_strip_source_id + standby_interval + state_check_interval
- Device model: calibration field removed
- WledTargetProcessor: acquires ColorStripStream from manager instead of running its own pipeline
- ProcessorManager: wires ColorStripStreamManager into TargetContext

API layer:
- New routes: GET/POST/PUT/DELETE /api/v1/color-strip-sources, PUT calibration/test
- Removed calibration endpoints from /devices
- Updated /picture-targets CRUD for new target structure

Frontend:
- New color-strips.js module with CSS editor modal and card rendering
- Calibration modal extended with CSS mode (css-id hidden field + device picker)
- targets.js: Color Strip Sources section added to LED tab; target editor/card updated
- app.js: imports and window globals for CSS + showCSSCalibration
- en.json / ru.json: color_strip.* and targets.section.color_strips keys added

Data migration runs at startup: existing WledPictureTargets are converted to
reference a new PictureColorStripSource created from their old settings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 15:49:47 +03:00
c4e0257389 Polymorphism Phase 2 + remove unused gamma/saturation fields
ProcessorManager: replace all isinstance checks with property-based
dispatch via base TargetProcessor (device_id, led_client,
get_display_index, update_device, update_calibration).

Remove gamma/saturation from ProcessingSettings, ColorCorrection
schema, serialization, and migration — these were never used in the
processing pipeline and are handled by postprocessing template filters.
Delete dead apply_color_correction() function.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 02:34:03 +03:00
99f47fdbf9 Encapsulate target-type dispatch via polymorphism (Phase 1)
Replace isinstance checks with polymorphic methods on PictureTarget
hierarchy: register_with_manager, sync_with_manager, update_fields,
and has_picture_source property.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 02:20:33 +03:00
c3b1d3edd9 Fix header z-index overlaying modal dialogs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 01:19:22 +03:00
3ae20761a1 Frontend: structured error handling, state fixes, accessibility, i18n
- Enhance fetchWithAuth with auto-401, retry w/ exponential backoff, timeout
- Remove ~40 manual 401 checks across 10 feature files
- Fix state: brightness cache setter, manual edit flag resets, static import
- Add ARIA: role=dialog/tablist, aria-modal, aria-labelledby, aria-selected
- Add focus trapping in Modal base class, aria-expanded on hint toggles
- Fix WCAG AA color contrast with --primary-text-color variable
- Add i18n pluralization (CLDR rules for en/ru), getCurrentLocale export
- Replace hardcoded strings in dashboard.js and profiles.js
- Add data-i18n-aria-label support, 20 new keys in en.json and ru.json

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 01:18:29 +03:00
2b90fafb9c Split monolithic index.html and style.css for maintainability
- Extract 15 modals and 3 partials from index.html into Jinja2 templates
  (templates/modals/*.html, templates/partials/*.html)
- Split style.css (3,712 lines) into 11 feature-scoped CSS files under
  static/css/ (base, layout, components, cards, modal, calibration,
  dashboard, streams, patterns, profiles, tutorials)
- Switch root route from FileResponse to Jinja2Templates
- Add jinja2 dependency
- Consolidate duplicate @keyframes spin definition
- Browser receives identical assembled HTML — zero JS changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 00:42:50 +03:00
755077607a Optimize frontend rendering: delta updates, rAF debouncing, cached DOM refs
- Disable Chart.js animations on real-time FPS and perf charts
- Dashboard: delta-update profile badges on state changes instead of full DOM rebuild
- Dashboard: cache querySelector results in Map for metrics update loop
- Dashboard: debounce poll interval slider restart (300ms)
- Calibration: debounce ResizeObserver and span drag via requestAnimationFrame
- Calibration: batch updateCalibrationPreview canvas render into rAF

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 23:06:39 +03:00
fbf597dc29 Optimize streaming pipeline and capture hot paths
- Replace asyncio.to_thread with dedicated ThreadPoolExecutor (skip
  per-frame context copy overhead)
- Move brightness scaling into _process_frame thread (avoid extra
  numpy array copies on event loop)
- Remove PIL intermediate in MSS capture (direct bytes→numpy)
- Unify median/dominant pixel mapping to numpy arrays (eliminate
  Python list-of-tuples path and duplicate Phase 2/3 code)
- Cache CalibrationConfig.segments property (avoid ~240 rebuilds/sec)
- Make KC WebSocket broadcasts concurrent via asyncio.gather
- Fix fps_samples list.pop(0) → deque(maxlen=10) in both processors
- Cache time.time() calls to reduce redundant syscalls per frame
- Log event queue drops instead of silently discarding

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 22:55:21 +03:00
bfe6a7a2ab Replace WMI process enumeration with Win32 EnumProcesses (350x faster)
Use PROCESS_QUERY_LIMITED_INFORMATION + QueryFullProcessImageNameW
instead of WMI Win32_Process. Reduces process enumeration from ~3s
to ~8ms. All user-facing applications are detected; only protected
system services are not visible (irrelevant for profile conditions).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 22:30:22 +03:00
ab8041269e Add fullscreen and topmost+fullscreen profile condition modes
New match types for application conditions:
- "fullscreen": app has a fullscreen window on any monitor (detected via
  EnumWindows, works even when another window is focused on a different
  display)
- "topmost_fullscreen": app is the focused foreground window AND fullscreen

Optimizes profile evaluation to only call expensive detection methods when
needed: WMI process enumeration (~3s) is skipped when no condition uses
"running" mode; foreground/fullscreen checks (<1ms each) are called
selectively based on active match types.

Filters false positives from fullscreen detection by excluding desktop/shell
process windows, tool windows, and non-activatable overlay windows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 22:26:50 +03:00
ff4e054ef8 Show edge test colors on LED device when overlay is active
Lights up device LEDs with calibration edge colors (top=red, right=green,
bottom=blue, left=yellow) when the overlay is started, and clears them when
the overlay is stopped. Skips if the target is currently processing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 14:39:37 +03:00
bef28ece5c Add static color support, HAOS light entity, and real-time profile updates
- Add static_color capability to WLED and serial providers with native
  set_color() dispatch (WLED uses JSON API, serial uses idle client)
- Encapsulate device-specific logic in providers instead of device_type
  checks in ProcessorManager and API routes
- Add HAOS light entity for devices with brightness_control + static_color
  (Adalight/AmbiLED get light entity, WLED keeps number entity)
- Fix serial device brightness and turn-off: pass software_brightness
  through provider chain, clear device on color=null, re-send static
  color after brightness change
- Add global events WebSocket (events-ws.js) replacing per-tab WS,
  enabling real-time profile state updates on both dashboard and profiles tabs
- Fix profile activation: mark active when all targets already running,
  add asyncio.Lock to prevent concurrent evaluation races, skip process
  enumeration when no profile has conditions, trigger immediate evaluation
  on enable/create/update for instant target startup
- Add reliable server restart script (restart.ps1)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 14:23:47 +03:00
6388e0defa Decouple i18n from feature modules and fix auth/login UX
Replace hardcoded updateAllText() calls with languageChanged event
pattern so feature modules subscribe independently. Guard all API
calls behind apiKey checks to prevent unauthorized requests when not
logged in. Fix login modal localization, hide tabs when logged out,
clear all panels on logout, and treat profiles with no conditions as
always-true.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 12:32:14 +03:00
747cdfabd6 Prioritize selected rectangle in pattern editor hit test
When multiple rectangles overlap, the currently selected one is now
tested first for both click and hover, keeping its edges and body
interactive even when another rectangle sits on top.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 11:42:08 +03:00
df52a197d9 Group dashboard targets into a collapsible Targets section with Running/Stopped subsections
Wrap running and stopped target lists under a parent Targets group.
Fix narrow-screen layout by keeping action buttons inline and hiding
metrics below 768px.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 03:08:00 +03:00
f83cd81937 Extract SerialDeviceProvider base class and power off serial devices on shutdown
Create SerialDeviceProvider as the common base for Adalight and AmbiLED
providers, replacing the misleading Adalight→AmbiLED inheritance chain.
Subclasses now only override device_type and create_client(). Also send
explicit black frames to all serial LED devices during server shutdown.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 03:04:27 +03:00
45634836b6 Add FPS sparkline charts, configurable poll interval, and uptime interpolation
Replace text FPS labels with Chart.js sparklines on running targets,
use emoji icons for metrics, add in-place DOM updates to preserve
chart animations, and add a 1-10s poll interval slider that controls
all dashboard timers. Uptime now ticks every second via client-side
interpolation regardless of poll interval.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 03:04:17 +03:00
ef925ad0a9 Fix Adalight power toggle using cached idle client and tracked state
Serial devices now route power on/off through the cached idle client
instead of opening a new serial connection (which caused PermissionError).
Adds tracked power_on state to DeviceState since Adalight has no
hardware power query.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 02:26:57 +03:00
46be9922bd Add brightness control to Key Colors targets with HAOS integration
Adds brightness (0.0-1.0) to KeyColorsSettings, applies scaling in the
KC processing pipeline after smoothing, exposes a slider on the WebUI
target card, and creates a HA number entity for KC target brightness.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 02:26:46 +03:00
10e426be13 Fix dashboard perf section not localizing on language change
The persistent perf section was created once and never rebuilt,
so switching language left stale text. Now updateAllText() removes
the persistent element and reloads the dashboard to recreate it
with the new locale.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 02:02:02 +03:00
81afa6cfaf Expose device brightness as HA number entity
Add a Number platform to the HAOS integration so each LED target
with a brightness-capable device gets a 0-255 slider in Home
Assistant. Coordinator now fetches device list and brightness on
each poll cycle. Also enable chart animation in perf-charts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 01:59:15 +03:00
aa57ce763a Skip targets tab auto-refresh while color picker is open
The 2-second auto-refresh was destroying the DOM and closing the
native color picker popup. Now checks if an input inside the targets
panel is focused before refreshing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 00:13:15 +03:00
390f71ebae Cache idle LED clients to avoid repeated Arduino resets
Adalight devices trigger a ~3s bootloader reset on every serial
connection open. Add a persistent idle client cache in ProcessorManager
so calibration test toggles, static color changes, and auto-restore
reuse an existing connection instead of creating a new one each time.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 00:09:55 +03:00
6e973965b1 Fix calibration side test not applying LED offset rotation
The test mode pixel array was built from segment positions but never
rotated by the configured offset, causing LEDs to light up on the
wrong side. Apply the same offset rotation used in the normal
rendering pipeline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 21:22:00 +03:00
4a1b4f7674 Add real-time system performance charts to dashboard
Backend: GET /api/v1/system/performance endpoint using psutil (CPU/RAM)
and nvidia-ml-py (GPU utilization, memory, temperature) with graceful
fallback. Frontend: Chart.js line charts with rolling 60-sample history
persisted to sessionStorage, flicker-free updates via persistent DOM
and diff-based dynamic section refresh.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 21:02:55 +03:00
66d1a77981 Add collapsible dashboard sections with localStorage persistence
Each dashboard section (Profiles, Running, Stopped) now has a chevron
toggle that collapses/expands the section content. Collapsed state is
persisted in localStorage so it survives page reloads and WebSocket
re-renders. Stop All button uses event.stopPropagation() to avoid
triggering the section toggle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 18:11:40 +03:00
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