Remove idle color feature, simplify power to turn-off only, fix settings serial port bug

- Remove static/idle color from entire stack (storage, API, processing, UI, CSS, locales)
- Simplify device power button to turn-off only (send black frame, no toggle)
- Send black frame on serial port close (AdalightClient.close)
- Fix settings modal serial port dropdown showing WLED devices due to stale deviceType

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-21 04:04:28 +03:00
parent 1f6c913343
commit 8a0730d91b
12 changed files with 29 additions and 278 deletions

View File

@@ -100,7 +100,14 @@ class AdalightClient(LEDClient):
raise RuntimeError(f"Failed to open serial port {self._port}: {e}")
async def close(self) -> None:
"""Close the serial port."""
"""Send black frame and close the serial port."""
if self._connected and self._serial and self._serial.is_open and self._led_count > 0:
try:
black = np.zeros((self._led_count, 3), dtype=np.uint8)
frame = self._build_frame(black, brightness=255)
await asyncio.to_thread(self._serial.write, frame)
except Exception as e:
logger.debug(f"Failed to send black frame on close: {e}")
self._connected = False
if self._serial and self._serial.is_open:
try:

View File

@@ -2,10 +2,10 @@
Subclasses only need to override ``device_type`` and ``create_client()``.
All common serial-device logic (COM port validation, discovery, health
checks, power control via black frames, static colour) lives here.
checks, power control via black frames) lives here.
"""
from typing import List, Tuple
from typing import List
import numpy as np
@@ -28,8 +28,7 @@ class SerialDeviceProvider(LEDDeviceProvider):
# manual_led_count: user must specify LED count (can't auto-detect)
# power_control: can blank LEDs by sending all-black pixels
# brightness_control: software brightness (multiplies pixel values before sending)
# static_color: can send a solid colour frame
return {"manual_led_count", "power_control", "brightness_control", "static_color"}
return {"manual_led_count", "power_control", "brightness_control"}
async def check_health(self, url: str, http_client, prev_health=None) -> DeviceHealth:
# Generic serial port health check — enumerate COM ports
@@ -116,31 +115,3 @@ class SerialDeviceProvider(LEDDeviceProvider):
finally:
await client.close()
async def set_color(self, url: str, color: Tuple[int, int, int], **kwargs) -> None:
"""Send a solid color frame to the device.
Accepts optional kwargs:
client: An already-connected LEDClient (e.g. cached idle client).
brightness (int): Software brightness 0-255 (default 255).
led_count (int), baud_rate (int | None).
"""
led_count = kwargs.get("led_count", 0)
if led_count <= 0:
raise ValueError(f"led_count is required to send color frame to {self.device_type} device")
brightness = kwargs.get("brightness", 255)
frame = np.full((led_count, 3), color, dtype=np.uint8)
existing_client = kwargs.get("client")
if existing_client:
await existing_client.send_pixels(frame, brightness=brightness)
else:
baud_rate = kwargs.get("baud_rate")
client = self.create_client(url, led_count=led_count, baud_rate=baud_rate)
try:
await client.connect()
await client.send_pixels(frame, brightness=brightness)
finally:
await client.close()
logger.info(f"{self.device_type} set_color: sent solid {color} to {url}")