29d9b95885
Profiles monitor running processes and foreground windows to automatically start/stop targets when conditions are met. Includes profile engine, platform detector (WMI), REST API, process browser endpoint, and calibration persistence fix. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
116 lines
3.4 KiB
Python
116 lines
3.4 KiB
Python
"""System routes: health, version, displays."""
|
|
|
|
import sys
|
|
from datetime import datetime
|
|
|
|
from fastapi import APIRouter, HTTPException
|
|
|
|
from wled_controller import __version__
|
|
from wled_controller.api.auth import AuthRequired
|
|
from wled_controller.api.schemas.system import (
|
|
DisplayInfo,
|
|
DisplayListResponse,
|
|
HealthResponse,
|
|
ProcessListResponse,
|
|
VersionResponse,
|
|
)
|
|
from wled_controller.core.capture.screen_capture import get_available_displays
|
|
from wled_controller.utils import get_logger
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/health", response_model=HealthResponse, tags=["Health"])
|
|
async def health_check():
|
|
"""Check service health status.
|
|
|
|
Returns basic health information including status, version, and timestamp.
|
|
"""
|
|
logger.info("Health check requested")
|
|
|
|
return HealthResponse(
|
|
status="healthy",
|
|
timestamp=datetime.utcnow(),
|
|
version=__version__,
|
|
)
|
|
|
|
|
|
@router.get("/api/v1/version", response_model=VersionResponse, tags=["Info"])
|
|
async def get_version():
|
|
"""Get version information.
|
|
|
|
Returns application version, Python version, and API version.
|
|
"""
|
|
logger.info("Version info requested")
|
|
|
|
return VersionResponse(
|
|
version=__version__,
|
|
python_version=f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
|
|
api_version="v1",
|
|
)
|
|
|
|
|
|
@router.get("/api/v1/config/displays", response_model=DisplayListResponse, tags=["Config"])
|
|
async def get_displays(_: AuthRequired):
|
|
"""Get list of available displays.
|
|
|
|
Returns information about all available monitors/displays that can be captured.
|
|
"""
|
|
logger.info("Listing available displays")
|
|
|
|
try:
|
|
# Get available displays with all metadata (name, refresh rate, etc.)
|
|
display_dataclasses = get_available_displays()
|
|
|
|
# Convert dataclass DisplayInfo to Pydantic DisplayInfo
|
|
displays = [
|
|
DisplayInfo(
|
|
index=d.index,
|
|
name=d.name,
|
|
width=d.width,
|
|
height=d.height,
|
|
x=d.x,
|
|
y=d.y,
|
|
is_primary=d.is_primary,
|
|
refresh_rate=d.refresh_rate,
|
|
)
|
|
for d in display_dataclasses
|
|
]
|
|
|
|
logger.info(f"Found {len(displays)} displays")
|
|
|
|
return DisplayListResponse(
|
|
displays=displays,
|
|
count=len(displays),
|
|
)
|
|
|
|
except Exception as e:
|
|
logger.error(f"Failed to get displays: {e}")
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=f"Failed to retrieve display information: {str(e)}"
|
|
)
|
|
|
|
|
|
@router.get("/api/v1/system/processes", response_model=ProcessListResponse, tags=["Config"])
|
|
async def get_running_processes(_: AuthRequired):
|
|
"""Get list of currently running process names.
|
|
|
|
Returns a sorted list of unique process names for use in profile conditions.
|
|
"""
|
|
from wled_controller.core.profiles.platform_detector import PlatformDetector
|
|
|
|
try:
|
|
detector = PlatformDetector()
|
|
processes = await detector.get_running_processes()
|
|
sorted_procs = sorted(processes)
|
|
return ProcessListResponse(processes=sorted_procs, count=len(sorted_procs))
|
|
except Exception as e:
|
|
logger.error(f"Failed to get processes: {e}")
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=f"Failed to retrieve process list: {str(e)}"
|
|
)
|