Add DDP protocol support, fix event loop blocking, and add LED offset calibration
Some checks failed
Validate / validate (push) Failing after 8s
Some checks failed
Validate / validate (push) Failing after 8s
- 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>
This commit is contained in:
@@ -32,6 +32,7 @@ class CalibrationConfig:
|
||||
layout: Literal["clockwise", "counterclockwise"]
|
||||
start_position: Literal["top_left", "top_right", "bottom_left", "bottom_right"]
|
||||
segments: List[CalibrationSegment]
|
||||
offset: int = 0 # Physical LED offset from start corner (number of LEDs from LED 0 to start corner)
|
||||
|
||||
def validate(self) -> bool:
|
||||
"""Validate calibration configuration.
|
||||
@@ -181,7 +182,14 @@ class PixelMapper:
|
||||
color = self._calc_color(pixel_segment)
|
||||
led_colors[led_idx] = color
|
||||
|
||||
logger.debug(f"Mapped border pixels to {total_leds} LED colors")
|
||||
# Apply physical LED offset by rotating the array
|
||||
# Offset = number of LEDs from LED 0 to the start corner
|
||||
# Physical LED[i] should get calibration color[(i - offset) % total]
|
||||
offset = self.calibration.offset % total_leds if total_leds > 0 else 0
|
||||
if offset > 0:
|
||||
led_colors = led_colors[total_leds - offset:] + led_colors[:total_leds - offset]
|
||||
|
||||
logger.debug(f"Mapped border pixels to {total_leds} LED colors (offset={offset})")
|
||||
return led_colors
|
||||
|
||||
def test_calibration(self, edge: str, color: Tuple[int, int, int]) -> List[Tuple[int, int, int]]:
|
||||
@@ -309,6 +317,7 @@ def calibration_from_dict(data: dict) -> CalibrationConfig:
|
||||
layout=data["layout"],
|
||||
start_position=data["start_position"],
|
||||
segments=segments,
|
||||
offset=data.get("offset", 0),
|
||||
)
|
||||
|
||||
config.validate()
|
||||
@@ -332,6 +341,7 @@ def calibration_to_dict(config: CalibrationConfig) -> dict:
|
||||
return {
|
||||
"layout": config.layout,
|
||||
"start_position": config.start_position,
|
||||
"offset": config.offset,
|
||||
"segments": [
|
||||
{
|
||||
"edge": seg.edge,
|
||||
|
||||
Reference in New Issue
Block a user