mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-27 02:56:31 +00:00
Prevent using pulseaudio on event loop (#1536)
* Prevent using pulseaudio on event loop * Fix name overwrite * Fix value
This commit is contained in:
parent
8a6ea7ab50
commit
19ca836b78
@ -29,7 +29,7 @@ from ..const import (
|
|||||||
)
|
)
|
||||||
from ..coresys import CoreSysAttributes
|
from ..coresys import CoreSysAttributes
|
||||||
from ..exceptions import APIError
|
from ..exceptions import APIError
|
||||||
from ..host.sound import SourceType
|
from ..host.sound import StreamType
|
||||||
from .utils import api_process, api_process_raw, api_validate
|
from .utils import api_process, api_process_raw, api_validate
|
||||||
|
|
||||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||||
@ -115,7 +115,7 @@ class APIAudio(CoreSysAttributes):
|
|||||||
@api_process
|
@api_process
|
||||||
async def set_volume(self, request: web.Request) -> None:
|
async def set_volume(self, request: web.Request) -> None:
|
||||||
"""Set audio volume on stream."""
|
"""Set audio volume on stream."""
|
||||||
source: SourceType = SourceType(request.match_info.get("source"))
|
source: StreamType = StreamType(request.match_info.get("source"))
|
||||||
body = await api_validate(SCHEMA_VOLUME, request)
|
body = await api_validate(SCHEMA_VOLUME, request)
|
||||||
|
|
||||||
await asyncio.shield(
|
await asyncio.shield(
|
||||||
@ -125,7 +125,7 @@ class APIAudio(CoreSysAttributes):
|
|||||||
@api_process
|
@api_process
|
||||||
async def set_default(self, request: web.Request) -> None:
|
async def set_default(self, request: web.Request) -> None:
|
||||||
"""Set audio default stream."""
|
"""Set audio default stream."""
|
||||||
source: SourceType = SourceType(request.match_info.get("source"))
|
source: StreamType = StreamType(request.match_info.get("source"))
|
||||||
body = await api_validate(SCHEMA_DEFAULT, request)
|
body = await api_validate(SCHEMA_DEFAULT, request)
|
||||||
|
|
||||||
await asyncio.shield(self.sys_host.sound.set_default(source, body[ATTR_NAME]))
|
await asyncio.shield(self.sys_host.sound.set_default(source, body[ATTR_NAME]))
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
"""Pulse host control."""
|
"""Pulse host control."""
|
||||||
|
from datetime import timedelta
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
import logging
|
import logging
|
||||||
from typing import List
|
from typing import List
|
||||||
@ -8,13 +9,14 @@ from pulsectl import Pulse, PulseError, PulseIndexError, PulseOperationFailed
|
|||||||
|
|
||||||
from ..coresys import CoreSys, CoreSysAttributes
|
from ..coresys import CoreSys, CoreSysAttributes
|
||||||
from ..exceptions import PulseAudioError
|
from ..exceptions import PulseAudioError
|
||||||
|
from ..utils import AsyncThrottle
|
||||||
|
|
||||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
PULSE_NAME = "supervisor"
|
PULSE_NAME = "supervisor"
|
||||||
|
|
||||||
|
|
||||||
class SourceType(str, Enum):
|
class StreamType(str, Enum):
|
||||||
"""INPUT/OUTPUT type of source."""
|
"""INPUT/OUTPUT type of source."""
|
||||||
|
|
||||||
INPUT = "input"
|
INPUT = "input"
|
||||||
@ -74,11 +76,13 @@ class SoundControl(CoreSysAttributes):
|
|||||||
"""Return a list of available output streams."""
|
"""Return a list of available output streams."""
|
||||||
return self._outputs
|
return self._outputs
|
||||||
|
|
||||||
async def set_default(self, source: SourceType, name: str) -> None:
|
async def set_default(self, stream_type: StreamType, name: str) -> None:
|
||||||
"""Set a stream to default input/output."""
|
"""Set a stream to default input/output."""
|
||||||
|
|
||||||
|
def _set_default():
|
||||||
try:
|
try:
|
||||||
with Pulse(PULSE_NAME) as pulse:
|
with Pulse(PULSE_NAME) as pulse:
|
||||||
if source == SourceType.OUTPUT:
|
if stream_type == StreamType.INPUT:
|
||||||
# Get source and set it as default
|
# Get source and set it as default
|
||||||
source = pulse.get_source_by_name(name)
|
source = pulse.get_source_by_name(name)
|
||||||
pulse.source_default_set(source)
|
pulse.source_default_set(source)
|
||||||
@ -93,33 +97,41 @@ class SoundControl(CoreSysAttributes):
|
|||||||
_LOGGER.error("Can't set %s as default: %s", name, err)
|
_LOGGER.error("Can't set %s as default: %s", name, err)
|
||||||
raise PulseAudioError() from None
|
raise PulseAudioError() from None
|
||||||
|
|
||||||
# Reload data
|
# Run and Reload data
|
||||||
|
await self.sys_run_in_executor(_set_default)
|
||||||
await self.update()
|
await self.update()
|
||||||
|
|
||||||
async def set_volume(self, source: SourceType, name: str, volume: float) -> None:
|
async def set_volume(
|
||||||
|
self, stream_type: StreamType, name: str, volume: float
|
||||||
|
) -> None:
|
||||||
"""Set a stream to volume input/output."""
|
"""Set a stream to volume input/output."""
|
||||||
|
|
||||||
|
def _set_volume():
|
||||||
try:
|
try:
|
||||||
with Pulse(PULSE_NAME) as pulse:
|
with Pulse(PULSE_NAME) as pulse:
|
||||||
if source == SourceType.OUTPUT:
|
if stream_type == StreamType.INPUT:
|
||||||
# Get source and set it as default
|
# Get source and set it as default
|
||||||
source = pulse.get_source_by_name(name)
|
stream = pulse.get_source_by_name(name)
|
||||||
else:
|
else:
|
||||||
# Get sink and set it as default
|
# Get sink and set it as default
|
||||||
source = pulse.get_sink_by_name(name)
|
stream = pulse.get_sink_by_name(name)
|
||||||
|
|
||||||
pulse.volume_set_all_chans(source, volume)
|
pulse.volume_set_all_chans(stream, volume)
|
||||||
except PulseIndexError:
|
except PulseIndexError:
|
||||||
_LOGGER.error("Can't find %s profile %s", source, name)
|
_LOGGER.error("Can't find %s profile %s", stream_type, name)
|
||||||
raise PulseAudioError() from None
|
raise PulseAudioError() from None
|
||||||
except PulseError as err:
|
except PulseError as err:
|
||||||
_LOGGER.error("Can't set %s volume: %s", name, err)
|
_LOGGER.error("Can't set %s volume: %s", name, err)
|
||||||
raise PulseAudioError() from None
|
raise PulseAudioError() from None
|
||||||
|
|
||||||
# Reload data
|
# Run and Reload data
|
||||||
|
await self.sys_run_in_executor(_set_volume)
|
||||||
await self.update()
|
await self.update()
|
||||||
|
|
||||||
async def ativate_profile(self, card_name: str, profile_name: str) -> None:
|
async def ativate_profile(self, card_name: str, profile_name: str) -> None:
|
||||||
"""Set a profile to volume input/output."""
|
"""Set a profile to volume input/output."""
|
||||||
|
|
||||||
|
def _activate_profile():
|
||||||
try:
|
try:
|
||||||
with Pulse(PULSE_NAME) as pulse:
|
with Pulse(PULSE_NAME) as pulse:
|
||||||
card = pulse.get_sink_by_name(card_name)
|
card = pulse.get_sink_by_name(card_name)
|
||||||
@ -134,12 +146,16 @@ class SoundControl(CoreSysAttributes):
|
|||||||
)
|
)
|
||||||
raise PulseAudioError() from None
|
raise PulseAudioError() from None
|
||||||
|
|
||||||
# Reload data
|
# Run and Reload data
|
||||||
|
await self.sys_run_in_executor(_activate_profile)
|
||||||
await self.update()
|
await self.update()
|
||||||
|
|
||||||
|
@AsyncThrottle(timedelta(seconds=10))
|
||||||
async def update(self):
|
async def update(self):
|
||||||
"""Update properties over dbus."""
|
"""Update properties over dbus."""
|
||||||
_LOGGER.info("Update PulseAudio information")
|
_LOGGER.info("Update PulseAudio information")
|
||||||
|
|
||||||
|
def _update():
|
||||||
try:
|
try:
|
||||||
with Pulse(PULSE_NAME) as pulse:
|
with Pulse(PULSE_NAME) as pulse:
|
||||||
server = pulse.server_info()
|
server = pulse.server_info()
|
||||||
@ -197,3 +213,6 @@ class SoundControl(CoreSysAttributes):
|
|||||||
raise PulseAudioError() from None
|
raise PulseAudioError() from None
|
||||||
except PulseError as err:
|
except PulseError as err:
|
||||||
_LOGGER.debug("Can't update PulseAudio data: %s", err)
|
_LOGGER.debug("Can't update PulseAudio data: %s", err)
|
||||||
|
|
||||||
|
# Run update from pulse server
|
||||||
|
await self.sys_run_in_executor(_update)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user