Fix FPS drops caused by brightness endpoint polling WLED device

The GET /devices/{id}/brightness endpoint was making an HTTP request to
the ESP32 over WiFi on every frontend poll (~3s), causing 150ms async
event loop jitter that froze the LED processing loop. Cache brightness
server-side after first fetch/set, add frontend dedup guard, reduce
get_device_info() frequency, and add processing loop timing diagnostics.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-21 02:43:03 +03:00
parent b14da85f3b
commit 7c0c064453
4 changed files with 91 additions and 4 deletions

View File

@@ -331,16 +331,29 @@ async def get_device_brightness(
store: DeviceStore = Depends(get_device_store),
manager: ProcessorManager = Depends(get_processor_manager),
):
"""Get current brightness from the device."""
"""Get current brightness from the device.
Uses a server-side cache to avoid polling the physical device on every
frontend request — hitting the ESP32 over WiFi in the async event loop
causes ~150 ms jitter in the processing loop.
"""
device = store.get_device(device_id)
if not device:
raise HTTPException(status_code=404, detail=f"Device {device_id} not found")
if "brightness_control" not in get_device_capabilities(device.device_type):
raise HTTPException(status_code=400, detail=f"Brightness control is not supported for {device.device_type} devices")
# Return cached hardware brightness if available (updated by SET endpoint)
ds = manager._devices.get(device_id)
if ds and ds.hardware_brightness is not None:
return {"brightness": ds.hardware_brightness}
try:
provider = get_provider(device.device_type)
bri = await provider.get_brightness(device.url)
# Cache the result so subsequent polls don't hit the device
if ds:
ds.hardware_brightness = bri
return {"brightness": bri}
except NotImplementedError:
# Provider has no hardware brightness; use software brightness
@@ -381,8 +394,12 @@ async def set_device_brightness(
if device_id in manager._devices:
manager._devices[device_id].software_brightness = bri
# If device is idle with a static color, re-send it at the new brightness
# Update cached hardware brightness
ds = manager._devices.get(device_id)
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)