- New display service with DDC/CI brightness and power control via screen_brightness_control and monitorcontrol - New /api/display/* endpoints (monitors, brightness, power) - Display tab in WebUI with per-monitor brightness sliders and power toggle - EDID resolution parsing to distinguish same-name monitors - Throttled brightness slider (50ms) matching volume control pattern Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
60 lines
1.6 KiB
Python
60 lines
1.6 KiB
Python
"""Display brightness and power control API endpoints."""
|
|
|
|
import logging
|
|
|
|
from fastapi import APIRouter, Depends
|
|
from pydantic import BaseModel, Field
|
|
|
|
from ..auth import verify_token
|
|
from ..services.display_service import (
|
|
get_brightness,
|
|
list_monitors,
|
|
set_brightness,
|
|
set_power,
|
|
)
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
router = APIRouter(prefix="/api/display", tags=["display"])
|
|
|
|
|
|
class BrightnessRequest(BaseModel):
|
|
brightness: int = Field(ge=0, le=100)
|
|
|
|
|
|
class PowerRequest(BaseModel):
|
|
on: bool
|
|
|
|
|
|
@router.get("/monitors")
|
|
async def get_monitors(
|
|
refresh: bool = False, _: str = Depends(verify_token)
|
|
) -> list[dict]:
|
|
"""List all connected monitors with brightness and power info."""
|
|
monitors = list_monitors(force_refresh=refresh)
|
|
logger.debug("Found %d monitors", len(monitors))
|
|
return [m.to_dict() for m in monitors]
|
|
|
|
|
|
@router.post("/brightness/{monitor_id}")
|
|
async def set_monitor_brightness(
|
|
monitor_id: int, request: BrightnessRequest, _: str = Depends(verify_token)
|
|
) -> dict:
|
|
"""Set brightness for a specific monitor."""
|
|
success = set_brightness(monitor_id, request.brightness)
|
|
if success:
|
|
logger.info("Set monitor %d brightness to %d", monitor_id, request.brightness)
|
|
return {"success": success}
|
|
|
|
|
|
@router.post("/power/{monitor_id}")
|
|
async def set_monitor_power(
|
|
monitor_id: int, request: PowerRequest, _: str = Depends(verify_token)
|
|
) -> dict:
|
|
"""Turn a monitor on or off."""
|
|
action = "on" if request.on else "off"
|
|
success = set_power(monitor_id, request.on)
|
|
if success:
|
|
logger.info("Set monitor %d power %s", monitor_id, action)
|
|
return {"success": success}
|