Add option to change the monitors config on the host
This commit is contained in:
parent
b1e457f540
commit
32572ea5a1
@ -14,7 +14,7 @@ import homeassistant.helpers.config_validation as cv
|
|||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import CONF_BROADCAST_ADDRESS, CONF_BROADCAST_PORT, CONF_MAC
|
from homeassistant.const import CONF_BROADCAST_ADDRESS, CONF_BROADCAST_PORT, CONF_MAC
|
||||||
from homeassistant.core import HomeAssistant, ServiceCall
|
from homeassistant.core import HomeAssistant, ServiceCall
|
||||||
from .const import DOMAIN, SERVICE_SEND_MAGIC_PACKET
|
from .const import DOMAIN, SERVICE_SEND_MAGIC_PACKET, SERVICE_CHANGE_MONITORS_CONFIG
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -6,4 +6,5 @@ SERVICE_RESTART_TO_WINDOWS_FROM_LINUX = "restart_to_windows_from_linux"
|
|||||||
SERVICE_RESTART_TO_LINUX_FROM_WINDOWS = "restart_to_linux_from_windows"
|
SERVICE_RESTART_TO_LINUX_FROM_WINDOWS = "restart_to_linux_from_windows"
|
||||||
SERVICE_PUT_COMPUTER_TO_SLEEP = "put_computer_to_sleep"
|
SERVICE_PUT_COMPUTER_TO_SLEEP = "put_computer_to_sleep"
|
||||||
SERVICE_START_COMPUTER_TO_WINDOWS = "start_computer_to_windows"
|
SERVICE_START_COMPUTER_TO_WINDOWS = "start_computer_to_windows"
|
||||||
RESTART_COMPUTER = "restart_computer"
|
SERVICE_RESTART_COMPUTER = "restart_computer"
|
||||||
|
SERVICE_CHANGE_MONITORS_CONFIG = "change_monitors_config"
|
||||||
|
@ -53,3 +53,16 @@ restart_computer:
|
|||||||
target:
|
target:
|
||||||
device:
|
device:
|
||||||
integration: easy_computer_manage
|
integration: easy_computer_manage
|
||||||
|
change_monitors_config:
|
||||||
|
name: Change monitors config
|
||||||
|
description: Change monitors config.
|
||||||
|
fields:
|
||||||
|
monitors_config:
|
||||||
|
name: Monitors config
|
||||||
|
description: Monitors config.
|
||||||
|
required: true
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
target:
|
||||||
|
device:
|
||||||
|
integration: easy_computer_manage
|
@ -35,7 +35,8 @@ from paramiko.ssh_exception import AuthenticationException
|
|||||||
|
|
||||||
from . import utils
|
from . import utils
|
||||||
from .const import SERVICE_RESTART_TO_WINDOWS_FROM_LINUX, SERVICE_PUT_COMPUTER_TO_SLEEP, \
|
from .const import SERVICE_RESTART_TO_WINDOWS_FROM_LINUX, SERVICE_PUT_COMPUTER_TO_SLEEP, \
|
||||||
SERVICE_START_COMPUTER_TO_WINDOWS, RESTART_COMPUTER, SERVICE_RESTART_TO_LINUX_FROM_WINDOWS
|
SERVICE_START_COMPUTER_TO_WINDOWS, SERVICE_RESTART_COMPUTER, SERVICE_RESTART_TO_LINUX_FROM_WINDOWS, \
|
||||||
|
SERVICE_CHANGE_MONITORS_CONFIG
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -114,9 +115,14 @@ async def async_setup_entry(
|
|||||||
SERVICE_START_COMPUTER_TO_WINDOWS,
|
SERVICE_START_COMPUTER_TO_WINDOWS,
|
||||||
)
|
)
|
||||||
platform.async_register_entity_service(
|
platform.async_register_entity_service(
|
||||||
RESTART_COMPUTER,
|
SERVICE_RESTART_COMPUTER,
|
||||||
{},
|
{},
|
||||||
RESTART_COMPUTER,
|
SERVICE_RESTART_COMPUTER,
|
||||||
|
)
|
||||||
|
platform.async_register_entity_service(
|
||||||
|
SERVICE_CHANGE_MONITORS_CONFIG,
|
||||||
|
{},
|
||||||
|
SERVICE_CHANGE_MONITORS_CONFIG,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -249,6 +255,10 @@ class ComputerSwitch(SwitchEntity):
|
|||||||
else:
|
else:
|
||||||
utils.restart_system(self._connection)
|
utils.restart_system(self._connection)
|
||||||
|
|
||||||
|
def change_monitors_config(self, yaml_config: str) -> None:
|
||||||
|
"""Change the monitors configuration using a YAML config file."""
|
||||||
|
utils.change_monitors_config(self._connection, yaml_config)
|
||||||
|
|
||||||
def update(self) -> None:
|
def update(self) -> None:
|
||||||
"""Ping the computer to see if it is online and update the state."""
|
"""Ping the computer to see if it is online and update the state."""
|
||||||
ping_cmd = [
|
ping_cmd = [
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
|
|
||||||
import fabric2
|
import fabric2
|
||||||
|
import yaml
|
||||||
from fabric2 import Connection
|
from fabric2 import Connection
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -202,3 +204,74 @@ def restart_to_windows_from_linux(connection: Connection):
|
|||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
"Could not restart system running on %s to Windows from Linux, system does not appear to be a Linux-based OS.",
|
"Could not restart system running on %s to Windows from Linux, system does not appear to be a Linux-based OS.",
|
||||||
connection.host)
|
connection.host)
|
||||||
|
|
||||||
|
|
||||||
|
def change_monitors_config(connection: Connection, monitors_config: str):
|
||||||
|
"""From a YAML config, changes the monitors configuration on the host, only works on Linux and Gnome (for now)."""
|
||||||
|
# TODO: Add support for Windows
|
||||||
|
|
||||||
|
if is_unix_system(connection):
|
||||||
|
command_parts = ["gnome-monitor-config", "set"]
|
||||||
|
|
||||||
|
# Convert str to dict (yaml)
|
||||||
|
monitors_config = yaml.safe_load(monitors_config)
|
||||||
|
|
||||||
|
for monitor, settings in monitors_config.get('monitors', {}).items():
|
||||||
|
if settings.get('enabled', False):
|
||||||
|
if 'primary' in settings and settings['primary']:
|
||||||
|
command_parts.append(f'-LpM {monitor}')
|
||||||
|
else:
|
||||||
|
command_parts.append(f'-LM {monitor}')
|
||||||
|
|
||||||
|
if 'position' in settings:
|
||||||
|
command_parts.append(f'-x {settings["position"][0]} -y {settings["position"][1]}')
|
||||||
|
|
||||||
|
if 'mode' in settings:
|
||||||
|
command_parts.append(f'-m {settings["mode"]}')
|
||||||
|
|
||||||
|
if 'scale' in settings:
|
||||||
|
command_parts.append(f'-s {settings["scale"]}')
|
||||||
|
|
||||||
|
if 'transform' in settings:
|
||||||
|
command_parts.append(f'-t {settings["transform"]}')
|
||||||
|
|
||||||
|
command = ' '.join(command_parts)
|
||||||
|
|
||||||
|
_LOGGER.debug("Running command: %s", command)
|
||||||
|
result = connection.run(command)
|
||||||
|
|
||||||
|
if result.return_code == 0:
|
||||||
|
_LOGGER.info("Successfully changed monitors config on system running on %s.", connection.host)
|
||||||
|
else:
|
||||||
|
_LOGGER.error("Could not change monitors config on system running on %s", connection.host)
|
||||||
|
# TODO : add useful debug info
|
||||||
|
else:
|
||||||
|
_LOGGER.error("Not implemented yet.")
|
||||||
|
|
||||||
|
|
||||||
|
def parse_gnome_monitor_config(output):
|
||||||
|
# SHOULD NOT BE USED YET, STILL IN DEVELOPMENT
|
||||||
|
"""Parse the output of the gnome-monitor-config command to get the current monitor configuration."""
|
||||||
|
|
||||||
|
monitors = []
|
||||||
|
current_monitor = None
|
||||||
|
|
||||||
|
for line in output.split('\n'):
|
||||||
|
monitor_match = re.match(r'^Monitor \[ (.+?) \] (ON|OFF)$', line)
|
||||||
|
if monitor_match:
|
||||||
|
if current_monitor:
|
||||||
|
monitors.append(current_monitor)
|
||||||
|
source, status = monitor_match.groups()
|
||||||
|
current_monitor = {'source': source, 'status': status, 'names': [], 'resolutions': []}
|
||||||
|
elif current_monitor:
|
||||||
|
display_name_match = re.match(r'^\s+display-name: (.+)$', line)
|
||||||
|
resolution_match = re.match(r'^\s+(\d+x\d+@\d+(?:\.\d+)?).*$', line)
|
||||||
|
if display_name_match:
|
||||||
|
current_monitor['names'].append(display_name_match.group(1).replace('"', ''))
|
||||||
|
elif resolution_match:
|
||||||
|
current_monitor['resolutions'].append(resolution_match.group(1))
|
||||||
|
|
||||||
|
if current_monitor:
|
||||||
|
monitors.append(current_monitor)
|
||||||
|
|
||||||
|
return monitors
|
||||||
|
Loading…
Reference in New Issue
Block a user