Add display refresh rate detection and display
Some checks failed
Validate / validate (push) Failing after 8s

- Added get_monitor_refresh_rates() function in monitor_names.py using Windows ctypes/DEVMODE to detect monitor refresh rates
- Updated DisplayInfo dataclass and Pydantic schema to include refresh_rate field (in Hz)
- Modified get_available_displays() to detect and include refresh rates (defaults to 60Hz on non-Windows or if detection fails)
- Added refresh rate display in Web UI between Resolution and Position
- Added translations for refresh rate label (displays.refresh_rate) in English and Russian locales
- Cross-platform compatible: gracefully falls back to 60Hz default on non-Windows systems

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-06 17:18:35 +03:00
parent c40c8b9d26
commit c1259a9a7f
7 changed files with 105 additions and 3 deletions

View File

@@ -7,7 +7,7 @@ import mss
import numpy as np
from PIL import Image
from wled_controller.utils import get_logger, get_monitor_names
from wled_controller.utils import get_logger, get_monitor_names, get_monitor_refresh_rates
logger = get_logger(__name__)
@@ -23,6 +23,7 @@ class DisplayInfo:
x: int
y: int
is_primary: bool
refresh_rate: int # in Hz
@dataclass
@@ -58,6 +59,9 @@ def get_available_displays() -> List[DisplayInfo]:
# Get friendly monitor names (Windows only, falls back to generic names)
monitor_names = get_monitor_names()
# Get monitor refresh rates (Windows only, falls back to 60Hz)
refresh_rates = get_monitor_refresh_rates()
with mss.mss() as sct:
displays = []
@@ -66,6 +70,9 @@ def get_available_displays() -> List[DisplayInfo]:
# Use friendly name from WMI if available, otherwise generic name
friendly_name = monitor_names.get(idx, f"Display {idx}")
# Use detected refresh rate or default to 60Hz
refresh_rate = refresh_rates.get(idx, 60)
display_info = DisplayInfo(
index=idx,
name=friendly_name,
@@ -74,6 +81,7 @@ def get_available_displays() -> List[DisplayInfo]:
x=monitor["left"],
y=monitor["top"],
is_primary=(idx == 0),
refresh_rate=refresh_rate,
)
displays.append(display_info)