Rework API input CSS: segments, remove led_count, HAOS light, test preview
API Input CSS rework:
- Remove led_count field from ApiInputColorStripSource (always auto-sizes)
- Add segment-based payload: solid, per_pixel, gradient modes
- Segments applied in order (last wins on overlap), auto-grow buffer
- Backward compatible: legacy {"colors": [...]} still works
- Pydantic validation: mode-specific field requirements
Test preview:
- Enable test preview button on api_input cards
- Hide LED/FPS controls for api_input (sender controls those)
- Show input source selector for all CSS tests (preselected)
- FPS sparkline chart using shared createFpsSparkline (same as target cards)
- Server only sends frames when push_generation changes (no idle frames)
HAOS integration:
- New light.py: ApiInputLight entity per api_input source (RGB + brightness)
- turn_on pushes solid segment, turn_off pushes fallback color
- Register wled_screen_controller.set_leds service for arbitrary segments
- New services.yaml with field definitions
- Coordinator: push_colors() and push_segments() methods
- Platform.LIGHT added to platforms list
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -792,16 +792,14 @@ class ApiInputColorStripSource(ColorStripSource):
|
||||
External clients push [R,G,B] arrays via REST POST or WebSocket. The stream
|
||||
buffers the latest frame and serves it to targets. When no data has been
|
||||
received within `timeout` seconds, LEDs revert to `fallback_color`.
|
||||
LED count auto-sizes from the connected device when led_count == 0.
|
||||
LED count auto-sizes from the connected device via configure().
|
||||
"""
|
||||
|
||||
led_count: int = 0 # 0 = auto-size from device
|
||||
fallback_color: list = field(default_factory=lambda: [0, 0, 0]) # [R, G, B]
|
||||
timeout: float = 5.0 # seconds before reverting to fallback
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
d = super().to_dict()
|
||||
d["led_count"] = self.led_count
|
||||
d["fallback_color"] = list(self.fallback_color)
|
||||
d["timeout"] = self.timeout
|
||||
return d
|
||||
@@ -810,14 +808,14 @@ class ApiInputColorStripSource(ColorStripSource):
|
||||
def create_from_kwargs(cls, *, id: str, name: str, source_type: str,
|
||||
created_at: datetime, updated_at: datetime,
|
||||
description=None, clock_id=None, tags=None,
|
||||
led_count=0, fallback_color=None, timeout=None,
|
||||
fallback_color=None, timeout=None,
|
||||
**_kwargs):
|
||||
fb = _validate_rgb(fallback_color, [0, 0, 0])
|
||||
return cls(
|
||||
id=id, name=name, source_type="api_input",
|
||||
created_at=created_at, updated_at=updated_at,
|
||||
description=description, clock_id=clock_id, tags=tags or [],
|
||||
led_count=led_count, fallback_color=fb,
|
||||
fallback_color=fb,
|
||||
timeout=float(timeout) if timeout is not None else 5.0,
|
||||
)
|
||||
|
||||
@@ -827,8 +825,6 @@ class ApiInputColorStripSource(ColorStripSource):
|
||||
self.fallback_color = fallback_color
|
||||
if kwargs.get("timeout") is not None:
|
||||
self.timeout = float(kwargs["timeout"])
|
||||
if kwargs.get("led_count") is not None:
|
||||
self.led_count = kwargs["led_count"]
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
Reference in New Issue
Block a user