add audio config service (not tested yet)
This commit is contained in:
parent
adc3ea0211
commit
258ea2b9b6
@ -9,3 +9,4 @@ SERVICE_START_COMPUTER_TO_WINDOWS = "start_computer_to_windows"
|
||||
SERVICE_RESTART_COMPUTER = "restart_computer"
|
||||
SERVICE_CHANGE_MONITORS_CONFIG = "change_monitors_config"
|
||||
SERVICE_STEAM_BIG_PICTURE = "steam_big_picture"
|
||||
SERVICE_CHANGE_AUDIO_CONFIG = "change_audio_config"
|
||||
|
@ -97,3 +97,37 @@ steam_big_picture:
|
||||
value: stop
|
||||
- label: Exit and go back to the desktop Steam UI
|
||||
value: exit
|
||||
change_audio_config:
|
||||
name: Change audio config
|
||||
description: Change audio config (volume, mute, input, output).
|
||||
target:
|
||||
entity:
|
||||
integration: easy_computer_manager
|
||||
domain: switch
|
||||
fields:
|
||||
volume:
|
||||
name: Volume
|
||||
description: The volume to set.
|
||||
example: 50
|
||||
selector:
|
||||
number:
|
||||
min: 0
|
||||
max: 100
|
||||
mute:
|
||||
name: Mute
|
||||
description: Mute the audio.
|
||||
example: true
|
||||
selector:
|
||||
boolean:
|
||||
input_device:
|
||||
name: Input device
|
||||
description: The ID/name/description of the input device.
|
||||
example: "Kraken 7.1 Chroma Stéréo analogique"
|
||||
selector:
|
||||
text:
|
||||
output_output:
|
||||
name: Output device
|
||||
description: The ID/name/description of the output device.
|
||||
example: "Starship/Matisse HD Audio Controller Stéréo analogique"
|
||||
selector:
|
||||
text:
|
@ -37,7 +37,7 @@ from paramiko.ssh_exception import AuthenticationException
|
||||
from . import utils
|
||||
from .const import SERVICE_RESTART_TO_WINDOWS_FROM_LINUX, SERVICE_PUT_COMPUTER_TO_SLEEP, \
|
||||
SERVICE_START_COMPUTER_TO_WINDOWS, SERVICE_RESTART_COMPUTER, SERVICE_RESTART_TO_LINUX_FROM_WINDOWS, \
|
||||
SERVICE_CHANGE_MONITORS_CONFIG, SERVICE_STEAM_BIG_PICTURE
|
||||
SERVICE_CHANGE_MONITORS_CONFIG, SERVICE_STEAM_BIG_PICTURE, SERVICE_CHANGE_AUDIO_CONFIG
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -96,19 +96,20 @@ async def async_setup_entry(
|
||||
|
||||
platform = entity_platform.async_get_current_platform()
|
||||
|
||||
services = [SERVICE_RESTART_TO_WINDOWS_FROM_LINUX,
|
||||
basic_services = [SERVICE_RESTART_TO_WINDOWS_FROM_LINUX,
|
||||
SERVICE_RESTART_TO_LINUX_FROM_WINDOWS,
|
||||
SERVICE_PUT_COMPUTER_TO_SLEEP,
|
||||
SERVICE_START_COMPUTER_TO_WINDOWS,
|
||||
SERVICE_RESTART_COMPUTER]
|
||||
|
||||
for service in services:
|
||||
for service in basic_services:
|
||||
platform.async_register_entity_service(
|
||||
service,
|
||||
{},
|
||||
service,
|
||||
)
|
||||
|
||||
# Register the service to change the monitors configuration
|
||||
platform.async_register_entity_service(
|
||||
SERVICE_CHANGE_MONITORS_CONFIG,
|
||||
make_entity_service_schema(
|
||||
@ -116,6 +117,8 @@ async def async_setup_entry(
|
||||
),
|
||||
SERVICE_CHANGE_MONITORS_CONFIG,
|
||||
)
|
||||
|
||||
# Register the service to control Steam Big Picture mode
|
||||
platform.async_register_entity_service(
|
||||
SERVICE_STEAM_BIG_PICTURE,
|
||||
make_entity_service_schema(
|
||||
@ -124,6 +127,18 @@ async def async_setup_entry(
|
||||
SERVICE_STEAM_BIG_PICTURE,
|
||||
)
|
||||
|
||||
# Register the service to change the audio configuration
|
||||
platform.async_register_entity_service(
|
||||
SERVICE_CHANGE_AUDIO_CONFIG,
|
||||
make_entity_service_schema(
|
||||
{vol.Optional("volume"): int,
|
||||
vol.Optional("mute"): bool,
|
||||
vol.Optional("input_device"): str,
|
||||
vol.Optional("output_device"): str}
|
||||
),
|
||||
SERVICE_CHANGE_AUDIO_CONFIG,
|
||||
)
|
||||
|
||||
|
||||
class ComputerSwitch(SwitchEntity):
|
||||
"""Representation of a computer switch."""
|
||||
@ -269,6 +284,10 @@ class ComputerSwitch(SwitchEntity):
|
||||
else:
|
||||
raise HomeAssistantError("You must specify an action.")
|
||||
|
||||
def change_audio_config(self, volume: int, mute: bool, input_device: str, output_device: str) -> None:
|
||||
"""Change the audio configuration using a YAML config file."""
|
||||
utils.change_audio_config(self._connection, volume, mute, input_device, output_device)
|
||||
|
||||
def update(self) -> None:
|
||||
"""Ping the computer to see if it is online and update the state."""
|
||||
ping_cmd = [
|
||||
|
@ -350,3 +350,91 @@ def steam_big_picture(connection: Connection, action: str):
|
||||
|
||||
if result is None or result.return_code != 0:
|
||||
raise HomeAssistantError(f"Could not {action} Steam Big Picture on system running at {connection.host}.")
|
||||
|
||||
|
||||
def get_audio_config(connection: Connection):
|
||||
if is_unix_system(connection):
|
||||
config = {'sinks': [], 'sources': []}
|
||||
|
||||
def parse_device_info(lines, device_type):
|
||||
devices = []
|
||||
current_device = {}
|
||||
|
||||
for line in lines:
|
||||
if line.startswith(f"{device_type} #"):
|
||||
if current_device and "Monitor" not in current_device['description']:
|
||||
devices.append(current_device)
|
||||
current_device = {'id': int(re.search(r'#(\d+)', line).group(1))}
|
||||
elif line.startswith(" Name:"):
|
||||
current_device['name'] = line.split(":")[1].strip()
|
||||
elif line.startswith(" State:"):
|
||||
current_device['state'] = line.split(":")[1].strip()
|
||||
elif line.startswith(" Description:"):
|
||||
current_device['description'] = line.split(":")[1].strip()
|
||||
|
||||
if current_device:
|
||||
devices.append(current_device)
|
||||
|
||||
return devices
|
||||
|
||||
# Get sinks
|
||||
result = connection.run("LANG=en_US.UTF-8 pactl list sinks")
|
||||
if result.return_code != 0:
|
||||
raise HomeAssistantError(f"Could not get audio sinks on system running at {connection.host}.")
|
||||
config['sinks'] = parse_device_info(result.stdout.split('\n'), 'Sink')
|
||||
|
||||
# Get sources
|
||||
result = connection.run("LANG=en_US.UTF-8 pactl list sources")
|
||||
if result.return_code != 0:
|
||||
raise HomeAssistantError(f"Could not get audio sources on system running at {connection.host}.")
|
||||
config['sources'] = parse_device_info(result.stdout.split('\n'), 'Source')
|
||||
|
||||
return config
|
||||
else:
|
||||
raise HomeAssistantError("Not implemented yet for Windows OS.")
|
||||
|
||||
|
||||
def change_audio_config(connection: Connection, volume: int, mute: bool, input_device: str = "@DEFAULT_SOURCE@",
|
||||
output_device: str = "@DEFAULT_SINK@"):
|
||||
"""Change audio configuration on the host system."""
|
||||
|
||||
if is_unix_system(connection):
|
||||
current_config = get_audio_config(connection)
|
||||
executable = "pactl"
|
||||
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 if specified
|
||||
if output_device and output_device != "@DEFAULT_SINK@":
|
||||
output_device = get_device_id('sinks', output_device)
|
||||
commands.append(f"{executable} 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"{executable} set-default-source {input_device}")
|
||||
|
||||
# Set sink volume if specified
|
||||
if volume is not None:
|
||||
commands.append(f"{executable} set-sink-volume {output_device} {volume}%")
|
||||
|
||||
# Set sink and source mute status if specified
|
||||
if mute is not None:
|
||||
commands.append(f"{executable} set-sink-mute {output_device} {'yes' if mute else 'no'}")
|
||||
commands.append(f"{executable} set-source-mute {output_device} {'yes' if mute else 'no'}")
|
||||
|
||||
# Execute commands
|
||||
for command in commands:
|
||||
_LOGGER.debug("Running command: %s", command)
|
||||
result = connection.run(command)
|
||||
|
||||
if result.return_code != 0:
|
||||
raise HomeAssistantError("Could not change audio config on system running on %s, check logs with debug",
|
||||
connection.host)
|
||||
else:
|
||||
raise HomeAssistantError("Not implemented yet for Windows OS.")
|
||||
|
Loading…
Reference in New Issue
Block a user