Files
MonitorSwitcher/core/switcher.py

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.vcp.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.vcp.get_vcp_feature(VCP_INPUT_SOURCE)
result.append({"index": idx, "current_vcp": current[0]})
except Exception as exc:
logger.warning("Cannot query monitor %d: %s", idx, exc)
result.append({"index": idx, "current_vcp": None})
return result