Fix Adalight power toggle using cached idle client and tracked state
Serial devices now route power on/off through the cached idle client instead of opening a new serial connection (which caused PermissionError). Adds tracked power_on state to DeviceState since Adalight has no hardware power query. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -401,6 +401,7 @@ async def get_device_power(
|
||||
device_id: str,
|
||||
_auth: AuthRequired,
|
||||
store: DeviceStore = Depends(get_device_store),
|
||||
manager: ProcessorManager = Depends(get_processor_manager),
|
||||
):
|
||||
"""Get current power state from the device."""
|
||||
device = store.get_device(device_id)
|
||||
@@ -410,6 +411,11 @@ async def get_device_power(
|
||||
raise HTTPException(status_code=400, detail=f"Power control is not supported for {device.device_type} devices")
|
||||
|
||||
try:
|
||||
# Serial devices: use tracked state (no hardware query available)
|
||||
ds = manager._devices.get(device_id)
|
||||
if device.device_type in ("adalight", "ambiled") and ds:
|
||||
return {"on": ds.power_on}
|
||||
|
||||
provider = get_provider(device.device_type)
|
||||
on = await provider.get_power(device.url)
|
||||
return {"on": on}
|
||||
@@ -424,6 +430,7 @@ async def set_device_power(
|
||||
body: dict,
|
||||
_auth: AuthRequired,
|
||||
store: DeviceStore = Depends(get_device_store),
|
||||
manager: ProcessorManager = Depends(get_processor_manager),
|
||||
):
|
||||
"""Turn device on or off."""
|
||||
device = store.get_device(device_id)
|
||||
@@ -437,11 +444,22 @@ async def set_device_power(
|
||||
raise HTTPException(status_code=400, detail="'on' must be a boolean")
|
||||
|
||||
try:
|
||||
provider = get_provider(device.device_type)
|
||||
await provider.set_power(
|
||||
device.url, on,
|
||||
led_count=device.led_count, baud_rate=device.baud_rate,
|
||||
)
|
||||
# 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:
|
||||
await manager._send_clear_pixels(device_id)
|
||||
ds.power_on = on
|
||||
else:
|
||||
provider = get_provider(device.device_type)
|
||||
await provider.set_power(
|
||||
device.url, on,
|
||||
led_count=device.led_count, baud_rate=device.baud_rate,
|
||||
)
|
||||
return {"on": on}
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to set power for {device_id}: {e}")
|
||||
|
||||
@@ -55,6 +55,8 @@ class DeviceState:
|
||||
# Calibration test mode (works independently of target processing)
|
||||
test_mode_active: bool = False
|
||||
test_mode_edges: Dict[str, Tuple[int, int, int]] = field(default_factory=dict)
|
||||
# Tracked power state for serial devices (no hardware query)
|
||||
power_on: bool = True
|
||||
|
||||
|
||||
class ProcessorManager:
|
||||
|
||||
Reference in New Issue
Block a user