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

@@ -22,7 +22,6 @@ from wled_controller.api.schemas.devices import (
DeviceUpdate,
DiscoveredDeviceResponse,
DiscoverDevicesResponse,
StaticColorUpdate,
)
from wled_controller.core.processing.processor_manager import ProcessorManager
from wled_controller.storage import DeviceStore
@@ -45,7 +44,6 @@ def _device_to_response(device) -> DeviceResponse:
enabled=device.enabled,
baud_rate=device.baud_rate,
auto_shutdown=device.auto_shutdown,
static_color=list(device.static_color) if device.static_color else None,
capabilities=sorted(get_device_capabilities(device.device_type)),
created_at=device.created_at,
updated_at=device.updated_at,
@@ -399,13 +397,6 @@ async def set_device_brightness(
if ds:
ds.hardware_brightness = bri
# If device is idle with a static color, re-send it at the new brightness
if ds and ds.static_color is not None and not manager.is_device_processing(device_id):
try:
await manager.send_static_color(device_id, ds.static_color)
except Exception:
pass
return {"brightness": bri}
except Exception as e:
logger.error(f"Failed to set brightness for {device_id}: {e}")
@@ -465,11 +456,7 @@ async def set_device_power(
# For serial devices, use the cached idle client to avoid port conflicts
ds = manager._devices.get(device_id)
if device.device_type in ("adalight", "ambiled") and ds:
if on:
# Restore idle state (static color or stay dark)
if ds.static_color is not None:
await manager.send_static_color(device_id, ds.static_color)
else:
if not on:
await manager._send_clear_pixels(device_id)
ds.power_on = on
else:
@@ -484,61 +471,3 @@ async def set_device_power(
raise HTTPException(status_code=502, detail=f"Failed to reach device: {e}")
# ===== STATIC COLOR ENDPOINTS =====
@router.get("/api/v1/devices/{device_id}/color", tags=["Settings"])
async def get_device_color(
device_id: str,
_auth: AuthRequired,
store: DeviceStore = Depends(get_device_store),
):
"""Get the static idle color for a device."""
device = store.get_device(device_id)
if not device:
raise HTTPException(status_code=404, detail=f"Device {device_id} not found")
if "static_color" not in get_device_capabilities(device.device_type):
raise HTTPException(status_code=400, detail="Static color is not supported for this device type")
return {"color": list(device.static_color) if device.static_color else None}
@router.put("/api/v1/devices/{device_id}/color", tags=["Settings"])
async def set_device_color(
device_id: str,
body: StaticColorUpdate,
_auth: AuthRequired,
store: DeviceStore = Depends(get_device_store),
manager: ProcessorManager = Depends(get_processor_manager),
):
"""Set or clear the static idle color for a device."""
device = store.get_device(device_id)
if not device:
raise HTTPException(status_code=404, detail=f"Device {device_id} not found")
if "static_color" not in get_device_capabilities(device.device_type):
raise HTTPException(status_code=400, detail="Static color is not supported for this device type")
color = None
if body.color is not None:
if len(body.color) != 3 or not all(isinstance(c, int) and 0 <= c <= 255 for c in body.color):
raise HTTPException(status_code=400, detail="color must be [R, G, B] with values 0-255")
color = tuple(body.color)
store.set_static_color(device_id, color)
# Update runtime state
ds = manager._devices.get(device_id)
if ds:
ds.static_color = color
# If device is idle, apply the change immediately
if not manager.is_device_processing(device_id):
try:
if color is not None:
await manager.send_static_color(device_id, color)
else:
await manager.clear_device(device_id)
except Exception as e:
logger.warning(f"Failed to apply color change immediately: {e}")
return {"color": list(color) if color else None}