55 lines
2.0 KiB
Python
55 lines
2.0 KiB
Python
import logging
|
|
from typing import Callable
|
|
from monitorcontrol import get_monitors
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
VCP_INPUT_SOURCE = 0x60
|
|
|
|
|
|
class MonitorSwitcher:
|
|
def __init__(self, config_manager):
|
|
self._config_manager = config_manager
|
|
self._on_switch_callbacks: list[Callable[[str], None]] = []
|
|
|
|
def apply_profile(self, profile_id: str) -> None:
|
|
profile = self._config_manager.get_profile(profile_id)
|
|
if profile is None:
|
|
logger.warning("Profile not found: %s", profile_id)
|
|
return
|
|
|
|
monitors = list(get_monitors())
|
|
for input_cfg in profile["monitor_inputs"]:
|
|
idx = input_cfg["monitor_index"]
|
|
vcp_value = input_cfg["vcp_value"]
|
|
if idx >= len(monitors):
|
|
logger.warning(
|
|
"Monitor index %d out of range (have %d)", idx, len(monitors)
|
|
)
|
|
continue
|
|
try:
|
|
with monitors[idx] as monitor:
|
|
monitor.set_vcp_feature(VCP_INPUT_SOURCE, vcp_value)
|
|
logger.info("Monitor %d -> VCP input %d", idx, vcp_value)
|
|
except Exception as exc:
|
|
logger.warning("Monitor %d DDC/CI error: %s", idx, exc)
|
|
|
|
self._config_manager.set_active_profile(profile_id)
|
|
for cb in self._on_switch_callbacks:
|
|
cb(profile_id)
|
|
|
|
def on_switch(self, callback: Callable[[str], None]) -> None:
|
|
self._on_switch_callbacks.append(callback)
|
|
|
|
def list_monitors(self) -> list[dict]:
|
|
result = []
|
|
for idx, monitor_handle in enumerate(get_monitors()):
|
|
try:
|
|
with monitor_handle as monitor:
|
|
current = monitor.get_vcp_feature(VCP_INPUT_SOURCE)
|
|
result.append({"index": idx, "current_vcp": current.value})
|
|
except Exception as exc:
|
|
logger.warning("Cannot query monitor %d: %s", idx, exc)
|
|
result.append({"index": idx, "current_vcp": None})
|
|
return result
|