implement change audio config service

This commit is contained in:
Mathieu Broillet 2024-08-30 09:55:51 +02:00
parent 3e13d1ddb7
commit 767d877442
Signed by: mathieu
GPG Key ID: A08E484FE95074C1
4 changed files with 61 additions and 8 deletions

View File

@ -7,7 +7,7 @@ from wakeonlan import send_magic_packet
from custom_components.easy_computer_manager import const, LOGGER
from custom_components.easy_computer_manager.computer.common import OSType, CommandOutput
from custom_components.easy_computer_manager.computer.formatter import format_gnome_monitors_args
from custom_components.easy_computer_manager.computer.formatter import format_gnome_monitors_args, format_pactl_commands
from custom_components.easy_computer_manager.computer.parser import parse_gnome_monitors_output, parse_pactl_output, \
parse_bluetoothctl
@ -35,7 +35,7 @@ class Computer:
asyncio.create_task(self.update())
async def _connect(self) -> None:
async def _connect(self, retried: bool = False) -> None:
"""Open an asynchronous SSH connection."""
try:
client = await asyncssh.connect(
@ -48,6 +48,9 @@ class Computer:
asyncssh.set_log_level("ERROR")
self._connection = client
except (OSError, asyncssh.Error) as exc:
if retried:
await self._connect(retried=True)
else:
raise ValueError(f"Failed to connect to {self.host}: {exc}")
async def _renew_connection(self) -> None:
@ -159,8 +162,12 @@ class Computer:
input_device: str | None = None,
output_device: str | None = None) -> None:
"""Change the audio configuration."""
# Implementation needed
pass
if self.is_linux():
# TODO: other DE support
if self.desktop_environment == 'gnome':
pactl_commands = format_pactl_commands(self.audio_config, volume, mute, input_device, output_device)
for command in pactl_commands:
await self.run_action("set_audio_config", params={"args": command})
async def install_nircmd(self) -> None:
"""Install NirCmd tool (Windows specific)."""

View File

@ -20,3 +20,43 @@ def format_gnome_monitors_args(monitors_config: dict):
args.extend(['-t', settings["transform"]])
return ' '.join(args)
def format_pactl_commands(current_config: {}, volume: int, mute: bool, input_device: str = "@DEFAULT_SOURCE@",
output_device: str = "@DEFAULT_SINK@"):
"""Change audio configuration on the host system."""
commands = []
def get_device_id(device_type, user_device):
for device in current_config[device_type]:
if device['description'] == user_device:
return device['name']
return user_device
# Set default sink and source if not specified
if not output_device:
output_device = "@DEFAULT_SINK@"
if not input_device:
input_device = "@DEFAULT_SOURCE@"
# Set default sink if specified
if output_device and output_device != "@DEFAULT_SINK@":
output_device = get_device_id('sinks', output_device)
commands.append(f"set-default-sink {output_device}")
# Set default source if specified
if input_device and input_device != "@DEFAULT_SOURCE@":
input_device = get_device_id('sources', input_device)
commands.append(f"set-default-source {input_device}")
# Set sink volume if specified
if volume is not None:
commands.append(f"set-sink-volume {output_device} {volume}%")
# Set sink and source mute status if specified
if mute is not None:
commands.append(f"set-sink-mute {output_device} {'yes' if mute else 'no'}")
commands.append(f"set-source-mute {input_device} {'yes' if mute else 'no'}")
return commands

View File

@ -64,6 +64,12 @@ ACTIONS = {
"get_microphones": {
"linux": ["LANG=en_US.UTF-8 pactl list sources"]
},
"set_audio_config": {
"linux": {
"command": "LANG=en_US.UTF-8 pactl %args%",
"params": ["args"]
}
},
"get_bluetooth_devices": {
"linux": {
"command": "bluetoothctl info",