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>
6.9 KiB
Calibration Guide
This guide explains how to calibrate your WLED strip to match your screen layout.
Overview
Calibration maps screen border pixels to LED positions on your WLED strip. Proper calibration ensures that the colors on your LEDs accurately reflect what's on your screen edges.
Understanding LED Layout
Physical Setup
Most WLED ambient lighting setups have LEDs arranged around a TV/monitor:
TOP (40 LEDs)
┌─────────────────┐
│ │
LEFT│ │RIGHT
(40)│ │(30)
│ │
└─────────────────┘
BOTTOM (40 LEDs)
LED Numbering
WLED strips are numbered sequentially. You need to know:
- Starting Position: Where is LED #0?
- Direction: Clockwise or counterclockwise?
- LEDs per Edge: How many LEDs on each side?
Default Calibration
When you attach a device, a default calibration is created:
- Layout: Clockwise
- Start Position: Bottom-left corner
- LED Distribution: Evenly distributed across 4 edges
Example (150 LEDs):
{
"layout": "clockwise",
"start_position": "bottom_left",
"segments": [
{"edge": "bottom", "led_start": 0, "led_count": 38},
{"edge": "right", "led_start": 38, "led_count": 37},
{"edge": "top", "led_start": 75, "led_count": 38, "reverse": true},
{"edge": "left", "led_start": 113, "led_count": 37, "reverse": true}
]
}
Custom Calibration
Step 1: Identify Your LED Layout
- Turn on your WLED device
- Note which LED is #0 (first LED)
- Observe the direction LEDs are numbered
- Count LEDs on each edge
Step 2: Create Calibration Config
Create a calibration configuration matching your setup:
{
"layout": "clockwise",
"start_position": "bottom_left",
"segments": [
{
"edge": "bottom",
"led_start": 0,
"led_count": 50,
"reverse": false
},
{
"edge": "right",
"led_start": 50,
"led_count": 30,
"reverse": false
},
{
"edge": "top",
"led_start": 80,
"led_count": 50,
"reverse": true
},
{
"edge": "left",
"led_start": 130,
"led_count": 30,
"reverse": true
}
]
}
Step 3: Apply Calibration
Update via API:
curl -X PUT http://localhost:8080/api/v1/devices/{device_id}/calibration \
-H "Content-Type: application/json" \
-d @calibration.json
Step 4: Test Calibration
Test each edge to verify:
# Test top edge (should light up top LEDs)
curl -X POST "http://localhost:8080/api/v1/devices/{device_id}/calibration/test?edge=top&color=[255,0,0]"
# Test right edge
curl -X POST "http://localhost:8080/api/v1/devices/{device_id}/calibration/test?edge=right&color=[0,255,0]"
# Test bottom edge
curl -X POST "http://localhost:8080/api/v1/devices/{device_id}/calibration/test?edge=bottom&color=[0,0,255]"
# Test left edge
curl -X POST "http://localhost:8080/api/v1/devices/{device_id}/calibration/test?edge=left&color=[255,255,0]"
Calibration Parameters
Layout
clockwise: LEDs numbered in clockwise directioncounterclockwise: LEDs numbered counter-clockwise
Start Position
Where LED #0 is located:
top_lefttop_rightbottom_left(most common)bottom_right
Segments
Each segment defines one edge of the screen:
edge: Which screen edge (top,right,bottom,left)led_start: First LED index for this edgeled_count: Number of LEDs on this edgereverse: Whether to reverse LED order for this edge
Reverse Flag
The reverse flag is used when LEDs go the opposite direction from screen pixels:
- Top edge: Usually reversed (LEDs go right-to-left)
- Bottom edge: Usually not reversed (LEDs go left-to-right)
- Left edge: Usually reversed (LEDs go bottom-to-top)
- Right edge: Usually not reversed (LEDs go top-to-bottom)
Common Layouts
Standard Clockwise (Bottom-Left Start)
{
"layout": "clockwise",
"start_position": "bottom_left",
"segments": [
{"edge": "bottom", "led_start": 0, "led_count": 40, "reverse": false},
{"edge": "right", "led_start": 40, "led_count": 30, "reverse": false},
{"edge": "top", "led_start": 70, "led_count": 40, "reverse": true},
{"edge": "left", "led_start": 110, "led_count": 40, "reverse": true}
]
}
Counter-Clockwise (Top-Left Start)
{
"layout": "counterclockwise",
"start_position": "top_left",
"segments": [
{"edge": "top", "led_start": 0, "led_count": 50, "reverse": false},
{"edge": "left", "led_start": 50, "led_count": 30, "reverse": false},
{"edge": "bottom", "led_start": 80, "led_count": 50, "reverse": true},
{"edge": "right", "led_start": 130, "led_count": 30, "reverse": true}
]
}
Three-Sided Setup (No Top Edge)
{
"layout": "clockwise",
"start_position": "bottom_left",
"segments": [
{"edge": "bottom", "led_start": 0, "led_count": 50, "reverse": false},
{"edge": "right", "led_start": 50, "led_count": 40, "reverse": false},
{"edge": "left", "led_start": 90, "led_count": 40, "reverse": true}
]
}
Troubleshooting
Colors Don't Match
Problem: LED colors don't match screen content.
Solutions:
- Verify LED start indices don't overlap
- Check reverse flags for each edge
- Test each edge individually
- Verify total LED count matches device
LEDs Light Up Wrong Edge
Problem: Top edge lights up when bottom should.
Solutions:
- Check
led_startvalues for each segment - Verify
layout(clockwise vs counterclockwise) - Confirm
start_positionmatches your physical setup
Corner LEDs Wrong
Problem: Corner LEDs show wrong colors.
Solutions:
- Adjust LED counts per edge
- Ensure segments don't overlap
- Check if corner LEDs should be in adjacent segment
Some LEDs Don't Light Up
Problem: Part of the strip stays dark.
Solutions:
- Verify total LEDs in calibration matches device
- Check for gaps in LED indices
- Ensure all edges are defined if LEDs exist there
Validation
The calibration system automatically validates:
- No duplicate edges
- No overlapping LED indices
- All LED counts are positive
- All start indices are non-negative
If validation fails, you'll receive an error message explaining the issue.
Tips
- Start Simple: Use default calibration first, then customize
- Test Often: Use test endpoint after each change
- Document Your Setup: Save your working calibration
- Physical Labels: Label your LED strip to remember layout
- Photos Help: Take photos of your setup with LED numbers visible
Example Workflow
- Install WLED strip around TV
- Note LED #0 position
- Create device in API (gets default calibration)
- Test default calibration
- Adjust based on test results
- Save final calibration
- Start processing and enjoy!