mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-22 16:46:29 +00:00
Reload Pulseaudio modules on hardware change (#4638)
* Reload Pulseaudio modules on hardware change In the past the audio plug-in restarted Pulseaudio on hardware change. This broke with the s6 updates. However, it also turns out that this is quite racy: The Supervisor reloads audio data much too quickly, when Supervisor isn't restarted yet. Instead, let's reload the relevant modules from Supervisor itself. This works well with a USB microphone on Home Assistant Green. Related change: https://github.com/home-assistant/plugin-audio/pull/153 * Fix linter issue
This commit is contained in:
parent
7c576da32c
commit
a390500309
@ -175,4 +175,4 @@ class HostManager(CoreSysAttributes):
|
|||||||
async def _hardware_events(self, device: Device) -> None:
|
async def _hardware_events(self, device: Device) -> None:
|
||||||
"""Process hardware requests."""
|
"""Process hardware requests."""
|
||||||
if self.sys_hardware.policy.is_match_cgroup(PolicyGroup.AUDIO, device):
|
if self.sys_hardware.policy.is_match_cgroup(PolicyGroup.AUDIO, device):
|
||||||
await self.sound.update()
|
await self.sound.update(reload_pulse=True)
|
||||||
|
@ -15,6 +15,9 @@ _LOGGER: logging.Logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
PULSE_NAME = "supervisor"
|
PULSE_NAME = "supervisor"
|
||||||
|
|
||||||
|
PULSE_ALSA_MODULE = "module-alsa-card"
|
||||||
|
PULSE_UDEV_MODULE = "module-udev-detect"
|
||||||
|
|
||||||
|
|
||||||
class StreamType(StrEnum):
|
class StreamType(StrEnum):
|
||||||
"""INPUT/OUTPUT type of source."""
|
"""INPUT/OUTPUT type of source."""
|
||||||
@ -235,9 +238,9 @@ class SoundControl(CoreSysAttributes):
|
|||||||
@Job(
|
@Job(
|
||||||
name="sound_control_update",
|
name="sound_control_update",
|
||||||
limit=JobExecutionLimit.THROTTLE_WAIT,
|
limit=JobExecutionLimit.THROTTLE_WAIT,
|
||||||
throttle_period=timedelta(seconds=10),
|
throttle_period=timedelta(seconds=2),
|
||||||
)
|
)
|
||||||
async def update(self):
|
async def update(self, reload_pulse: bool = False):
|
||||||
"""Update properties over dbus."""
|
"""Update properties over dbus."""
|
||||||
_LOGGER.info("Updating PulseAudio information")
|
_LOGGER.info("Updating PulseAudio information")
|
||||||
|
|
||||||
@ -348,11 +351,32 @@ class SoundControl(CoreSysAttributes):
|
|||||||
f"Error while processing pulse update: {err}", _LOGGER.error
|
f"Error while processing pulse update: {err}", _LOGGER.error
|
||||||
) from err
|
) from err
|
||||||
except PulseError as err:
|
except PulseError as err:
|
||||||
_LOGGER.debug("Can't update PulseAudio data: %s", err)
|
_LOGGER.warning("Can't update PulseAudio data: %s", err)
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def _reload_pulse_modules():
|
||||||
|
try:
|
||||||
|
with Pulse(PULSE_NAME) as pulse:
|
||||||
|
modules = pulse.module_list()
|
||||||
|
for alsa_module in filter(
|
||||||
|
lambda x: x.name == PULSE_ALSA_MODULE, modules
|
||||||
|
):
|
||||||
|
pulse.module_unload(alsa_module.index)
|
||||||
|
udev_module = next(
|
||||||
|
filter(lambda x: x.name == PULSE_UDEV_MODULE, modules)
|
||||||
|
)
|
||||||
|
pulse.module_unload(udev_module.index)
|
||||||
|
# And now reload
|
||||||
|
pulse.module_load(PULSE_UDEV_MODULE)
|
||||||
|
except StopIteration:
|
||||||
|
_LOGGER.warning("Can't reload PulseAudio modules.")
|
||||||
|
except PulseError as err:
|
||||||
|
_LOGGER.warning("Can't reload PulseAudio modules: %s", err)
|
||||||
|
|
||||||
# Update data from pulse server
|
# Update data from pulse server
|
||||||
|
if reload_pulse:
|
||||||
|
await self.sys_run_in_executor(_reload_pulse_modules)
|
||||||
data: PulseData = await self.sys_run_in_executor(_get_pulse_data)
|
data: PulseData = await self.sys_run_in_executor(_get_pulse_data)
|
||||||
self._applications = data.applications
|
self._applications = data.applications
|
||||||
self._cards = data.cards
|
self._cards = data.cards
|
||||||
|
Loading…
x
Reference in New Issue
Block a user