- Replace simple spinner with SVG circular progress ring
- Show progress percentage (0-100%) in center of ring
- Animate progress based on capture duration
- Update every 100ms for smooth animation
- Clean up timer on completion or cancellation
UI improvements:
- Full-page overlay with blur backdrop
- Large percentage display (28px)
- Progress ring uses primary color
- Clean, minimal design
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The critical bug was not capturing the return value from start_free_threaded(),
which returns a CaptureControl object with the proper wait() method.
Changes:
- Store CaptureControl from start_free_threaded() return value
- Use CaptureControl.wait() to block until thread finishes (not timeout)
- Remove redundant capture_control storage from frame callback
- Cleanup now properly releases GPU resources and yellow border
Tested: Yellow border now disappears immediately after capture test ends.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add WGC engine with aggressive COM object cleanup (multiple GC passes)
- Persist capture test duration to localStorage
- Show only short error messages in snackbar (details in console)
Note: WGC cleanup still has issues with yellow border persistence - needs further investigation
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Edges with 0 LEDs now:
- Dim to 25% opacity (15% for toggle zones)
- Block interaction (pointer-events: none)
- Keep LED input editable to allow changing from 0
- Prevent test toggle, span drag on disabled edges
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Generic tutorial engine supports absolute (modal) and fixed (viewport)
positioning modes with spotlight backdrop, pulsing ring, and tooltip.
Calibration tutorial covers LED count, corner, direction, offset, span,
test, and toggle inputs. Device tutorial walks through card controls.
Auto-triggers on first calibration open and first device add.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tick labels: round-number ticks (300, 900, etc.) now take priority over
edge boundary labels (288, 933). When they overlap, the boundary label
is suppressed but its tick line is preserved.
Calibration tips: convert single paragraph to bulleted list with
individual i18n keys, add tip about toggling edge inputs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add close X button to all modal headers (acts as Cancel)
- Replace Cancel/Save labels with icon buttons (✕/✓)
- Remove header/footer separator lines, reduce spacing
- Fix canvas re-render on resize via ResizeObserver
- Move calibration hint to top as section-tip
- Increase toggle zones to 16px, make borders more visible
- Differentiate min/max ticks (long) from intermediate (short)
- Sync toggle zones and ticks with span position
- Fix span handle z-index to stay above LED input
- Add total LED label click to toggle edge input visibility
- Remove corner icon scale on hover
- Direction arrows fixed at full-edge midpoint (unaffected by span)
- Span bars fill full edge area with 2px border radius
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Separate test edge toggles into dedicated elements outside the
calibration preview border so they don't conflict with span bar
interactions. Expand span handle hit areas to 16px with 4px visible
indicators. Increase canvas padding to 36px on all sides and
reposition tick labels outside toggle zones.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allow LEDs to cover only a fraction of each screen edge via draggable
span bars in the calibration UI. Per-edge start/end (0.0-1.0) values
control which portion of the screen border is sampled for LED colors.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Switch Devices/Displays from collapsible sections to tab layout
- Remember active tab in localStorage
- Re-render display layout when switching to Displays tab
- Replace floating "+" button with dashed add-device card in grid
- Rename sections to "Devices" and "Displays"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Make Devices and Displays sections collapsible with persistent state
- Move WLED config tip from footer to under Devices heading
- Add theme-aware colors for calibration canvas ticks and chevrons
- Rename sections to "Devices" and "Displays" with emoji prefix icons
- Fix display layout scaling to fill available space
- Remove unused footer-tip and modal code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add intermediate tick labels at nice intervals (5, 10, 25, 50, 100, 250, 500)
with max 5 labels per edge and pixel-based overlap prevention
- Move direction chevrons from outside edge bars to inside the screen area
- Make chevrons filled with green fill and white outline for better contrast
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move total LEDs counter, direction toggle, and offset input into the
screen area of the calibration preview
- Remove description paragraph, standalone offset form, and total LEDs banner
- Add mismatch warning (yellow + ⚠) when configured LEDs ≠ device count
- Use actual display aspect ratio for calibration preview
- Fix offset not updating tick labels (buildSegments now starts at offset)
- Remove max-width constraint on preview, add padding for breathing room
- Clean up unused i18n keys from both locale files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace fullscreen pixel preview with a canvas overlay inside the calibration
modal that shows LED index ticks, direction chevrons, and interactive corner
start position buttons. Fix corner hover centering and disable grow animation
for the active corner.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move WLED Configuration tips from Add Device modal to page footer
- Add WLED Web UI link in footer (auto-populated with first device URL)
- Add WLED Web UI button (globe icon) to device card actions
- Move pixel preview button from device card to calibration modal footer
- Add en/ru i18n keys for new UI elements
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Detect LED chip type (WS2812B, SK6812, etc.) from WLED /json/cfg
- Show RGBW/RGB channel indicator with colored squares on device card
- Move version, display index, LED count to subtitle row under device name
- Add remove button as × icon in top-right corner of card
- Hide latency from card display (still visible in health dot tooltip)
- Fix display layout overflow on narrow viewports
- Add wled_rgbw and wled_led_type to ProcessingState API schema
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace segment-based calibration with core parameters (leds_top/right/bottom/left);
segments are now derived at runtime via lookup tables
- Fix clockwise/counterclockwise edge traversal order for all 8 start_position/layout
combinations (e.g. bottom_left+clockwise now correctly goes up-left first)
- Add pixel layout preview overlay with color-coded edges, LED index labels,
direction arrows, and start position marker
- Move "Add New Device" form into a modal dialog triggered by "+" button
- Add display index selector to device settings modal
- Migrate from requirements.txt to pyproject.toml for dependency management
- Update Dockerfile and docs to use `pip install .`
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add background health checks (GET /json/info) with configurable interval per device
- Auto-detect LED count from WLED device on add (remove led_count from create API)
- Add calibration test mode: toggle edges on/off with colored LEDs via PUT endpoint
- Show WLED firmware version badge and LED count badge on device cards
- Add modal dirty tracking with discard confirmation on close/backdrop click
- Fix layout jump when modals open by compensating for scrollbar width
- Add state_check_interval to settings API and UI
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add DDP client for LED strips >500 LEDs (UDP port 4048), with automatic
fallback from HTTP JSON API when LED count exceeds limit
- Wrap blocking operations (screen capture, image processing) in
asyncio.to_thread() to prevent event loop starvation
- Turn on WLED device and enable live mode when starting DDP streaming
- Add LED strip offset field to calibration (rotates color array to match
physical LED position vs start corner)
- Add server management scripts (start, stop, restart, background start)
- Fix WebUI auth error handling and auto-refresh loop
- Add development API key to default config
- Add i18n translations for offset field (en/ru)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Server fixes:
- Fix numpy uint8 JSON serialization by converting to Python int
- Change WLED payload to flat array format [r,g,b,r,g,b,...]
- Add payload debugging logs (size, LED count, sample data)
Web UI improvements:
- Add comprehensive console logging for device errors
- Log actual error messages from state.errors array
- Log device operations (start/stop/add) with details
- Fix password field form validation warning
The HTTP API may have payload size limitations for large LED counts.
Consider UDP protocols (DDP/E1.31) for better real-time performance.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add footer with author info (name, email, git repository link)
- Replace device action buttons with icons to save space:
- Start/Stop: ▶️/⏹️, Settings: ⚙️, Calibrate: 📐, Remove: 🗑️
- Added hover tooltips with translated text
- Added btn-icon CSS class for compact styling
- Replace native browser confirm() with custom modal dialog:
- Matches app theme and supports translations
- Used for logout and device removal confirmations
- Added confirm.title, confirm.yes, confirm.no translations
- Disable background scrolling when modals are open:
- Added modal-open class to body when any modal opens
- Prevents page scroll behind modals for better UX
- Applied to all modals: login, settings, calibration, confirmation
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Fix Flash of Unstyled Content (FOUC) by hiding page until translations load
- Hide body initially with visibility:hidden
- Show content after translations are applied to avoid English flash
- Fix authenticated indicator layout with white-space:nowrap
- Add "●" symbol to translation files to prevent disappearance on reload
- Enable network access by binding server to 0.0.0.0 in test config
- Simplify test config API keys to single entry
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Updated get_displays() to use get_available_displays() function from screen_capture module
- Removed duplicate display detection code in routes.py
- Now properly returns refresh_rate field in display API responses
- Removed unused get_monitor_names import
This fixes the "undefinedHz" issue in the Web UI by ensuring the backend properly provides refresh rate data.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Created CLAUDE.md with server restart policy and development workflow
- Includes guidelines on when to restart after code changes
- Documents common development tasks with step-by-step instructions
- Provides project structure reference
- Helps prevent issues with running old code after updates
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Added get_monitor_refresh_rates() function in monitor_names.py using Windows ctypes/DEVMODE to detect monitor refresh rates
- Updated DisplayInfo dataclass and Pydantic schema to include refresh_rate field (in Hz)
- Modified get_available_displays() to detect and include refresh rates (defaults to 60Hz on non-Windows or if detection fails)
- Added refresh rate display in Web UI between Resolution and Position
- Added translations for refresh rate label (displays.refresh_rate) in English and Russian locales
- Cross-platform compatible: gracefully falls back to 60Hz default on non-Windows systems
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixed issues where device details and display badges were not updating
when switching languages:
Changes:
- Updated updateAllText() to reload displays and devices when language changes
- Added translations to createDeviceCard() for all dynamic text:
* Device status badges (Processing/Idle)
* Device info labels (URL, LED Count, Display)
* Metrics labels (Actual FPS, Target FPS, Frames, Errors)
* Button labels (Start, Stop, Settings, Calibrate, Remove)
- Updated loadDevices() error messages to use translations
- Added missing translations to locale files:
* device.metrics.actual_fps, target_fps, frames, errors
Now when switching between English and Russian, all device cards and
display information updates correctly, including:
- Primary/Secondary display badges
- Device status badges
- All labels and button text
- Metrics labels when processing
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implemented localization system similar to the media-server project pattern:
- Created locale JSON files for English (en.json) and Russian (ru.json)
- Added complete translations for all UI elements, buttons, labels, and messages
- Implemented locale management system with browser locale detection
- Added language selector dropdown in header
- Applied data-i18n, data-i18n-title, and data-i18n-placeholder attributes
- Translations stored in localStorage and persist across sessions
- Automatic language detection from browser settings
- All dynamic content (displays, devices, modals) now uses translation function
Translations cover:
- Authentication (login/logout)
- Displays (layout visualization, cards, labels)
- Devices (management, status, actions)
- Settings modal (brightness, device configuration)
- Calibration modal (LED mapping, testing)
- Error messages and notifications
- Server status and version information
The implementation uses:
- Simple t(key, params) translation function with parameter substitution
- Async locale loading from /static/locales/{locale}.json
- updateAllText() to refresh all UI elements when language changes
- Fallback to English if translation file fails to load
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Visual display layout visualization showing all monitors in their relative positions
- Displays are scaled proportionally and positioned based on actual coordinates
- Primary displays marked with star icon and green borders
- Secondary displays with gray borders
- Hover effects on display visualization with detailed tooltips
- Color-coded legend explaining primary/secondary displays
- Enhanced display cards with primary/secondary badges
- Added display index to display cards for clarity
- Added lightbulb emoji favicon for browser tab
This makes it much easier to understand multi-monitor setups and identify
which physical monitor corresponds to which display index when configuring
WLED devices.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This is a complete WLED ambient lighting controller that captures screen border pixels
and sends them to WLED devices for immersive ambient lighting effects.
## Server Features:
- FastAPI-based REST API with 17+ endpoints
- Real-time screen capture with multi-monitor support
- Advanced LED calibration system with visual GUI
- API key authentication with labeled tokens
- Per-device brightness control (0-100%)
- Configurable FPS (1-60), border width, and color correction
- Persistent device storage (JSON-based)
- Comprehensive Web UI with dark/light themes
- Docker support with docker-compose
- Windows monitor name detection via WMI (shows "LG ULTRAWIDE" etc.)
## Web UI Features:
- Device management (add, configure, remove WLED devices)
- Real-time status monitoring with FPS metrics
- Settings modal for device configuration
- Visual calibration GUI with edge testing
- Brightness slider per device
- Display selection with friendly monitor names
- Token-based authentication with login/logout
- Responsive button layout
## Calibration System:
- Support for any LED strip layout (clockwise/counterclockwise)
- 4 starting position options (corners)
- Per-edge LED count configuration
- Visual preview with starting position indicator
- Test buttons to light up individual edges
- Smart LED ordering based on start position and direction
## Home Assistant Integration:
- Custom HACS integration
- Switch entities for processing control
- Sensor entities for status and FPS
- Select entities for display selection
- Config flow for easy setup
- Auto-discovery of devices from server
## Technical Stack:
- Python 3.11+
- FastAPI + uvicorn
- mss (screen capture)
- httpx (async WLED client)
- Pydantic (validation)
- WMI (Windows monitor detection)
- Structlog (logging)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>