Rename "satellite enabled" to "mute" (#105619)

This commit is contained in:
Michael Hansen 2023-12-13 02:09:22 -06:00 committed by Franck Nijhof
parent 797af14012
commit 36c56eb32a
No known key found for this signature in database
GPG key ID: D62583BA8AB11CA3
7 changed files with 81 additions and 83 deletions

View file

@ -17,11 +17,11 @@ class SatelliteDevice:
satellite_id: str satellite_id: str
device_id: str device_id: str
is_active: bool = False is_active: bool = False
is_enabled: bool = True is_muted: bool = False
pipeline_name: str | None = None pipeline_name: str | None = None
_is_active_listener: Callable[[], None] | None = None _is_active_listener: Callable[[], None] | None = None
_is_enabled_listener: Callable[[], None] | None = None _is_muted_listener: Callable[[], None] | None = None
_pipeline_listener: Callable[[], None] | None = None _pipeline_listener: Callable[[], None] | None = None
@callback @callback
@ -33,12 +33,12 @@ class SatelliteDevice:
self._is_active_listener() self._is_active_listener()
@callback @callback
def set_is_enabled(self, enabled: bool) -> None: def set_is_muted(self, muted: bool) -> None:
"""Set enabled state.""" """Set muted state."""
if enabled != self.is_enabled: if muted != self.is_muted:
self.is_enabled = enabled self.is_muted = muted
if self._is_enabled_listener is not None: if self._is_muted_listener is not None:
self._is_enabled_listener() self._is_muted_listener()
@callback @callback
def set_pipeline_name(self, pipeline_name: str) -> None: def set_pipeline_name(self, pipeline_name: str) -> None:
@ -54,9 +54,9 @@ class SatelliteDevice:
self._is_active_listener = is_active_listener self._is_active_listener = is_active_listener
@callback @callback
def set_is_enabled_listener(self, is_enabled_listener: Callable[[], None]) -> None: def set_is_muted_listener(self, is_muted_listener: Callable[[], None]) -> None:
"""Listen for updates to is_enabled.""" """Listen for updates to muted status."""
self._is_enabled_listener = is_enabled_listener self._is_muted_listener = is_muted_listener
@callback @callback
def set_pipeline_listener(self, pipeline_listener: Callable[[], None]) -> None: def set_pipeline_listener(self, pipeline_listener: Callable[[], None]) -> None:
@ -70,11 +70,11 @@ class SatelliteDevice:
"binary_sensor", DOMAIN, f"{self.satellite_id}-assist_in_progress" "binary_sensor", DOMAIN, f"{self.satellite_id}-assist_in_progress"
) )
def get_satellite_enabled_entity_id(self, hass: HomeAssistant) -> str | None: def get_muted_entity_id(self, hass: HomeAssistant) -> str | None:
"""Return entity id for satellite enabled switch.""" """Return entity id for satellite muted switch."""
ent_reg = er.async_get(hass) ent_reg = er.async_get(hass)
return ent_reg.async_get_entity_id( return ent_reg.async_get_entity_id(
"switch", DOMAIN, f"{self.satellite_id}-satellite_enabled" "switch", DOMAIN, f"{self.satellite_id}-mute"
) )
def get_pipeline_entity_id(self, hass: HomeAssistant) -> str | None: def get_pipeline_entity_id(self, hass: HomeAssistant) -> str | None:

View file

@ -49,7 +49,6 @@ class WyomingSatellite:
self.hass = hass self.hass = hass
self.service = service self.service = service
self.device = device self.device = device
self.is_enabled = True
self.is_running = True self.is_running = True
self._client: AsyncTcpClient | None = None self._client: AsyncTcpClient | None = None
@ -57,9 +56,9 @@ class WyomingSatellite:
self._is_pipeline_running = False self._is_pipeline_running = False
self._audio_queue: asyncio.Queue[bytes | None] = asyncio.Queue() self._audio_queue: asyncio.Queue[bytes | None] = asyncio.Queue()
self._pipeline_id: str | None = None self._pipeline_id: str | None = None
self._enabled_changed_event = asyncio.Event() self._muted_changed_event = asyncio.Event()
self.device.set_is_enabled_listener(self._enabled_changed) self.device.set_is_muted_listener(self._muted_changed)
self.device.set_pipeline_listener(self._pipeline_changed) self.device.set_pipeline_listener(self._pipeline_changed)
async def run(self) -> None: async def run(self) -> None:
@ -69,11 +68,11 @@ class WyomingSatellite:
try: try:
while self.is_running: while self.is_running:
try: try:
# Check if satellite has been disabled # Check if satellite has been muted
while not self.device.is_enabled: while self.device.is_muted:
await self.on_disabled() await self.on_muted()
if not self.is_running: if not self.is_running:
# Satellite was stopped while waiting to be enabled # Satellite was stopped while waiting to be unmuted
return return
# Connect and run pipeline loop # Connect and run pipeline loop
@ -92,8 +91,8 @@ class WyomingSatellite:
"""Signal satellite task to stop running.""" """Signal satellite task to stop running."""
self.is_running = False self.is_running = False
# Unblock waiting for enabled # Unblock waiting for unmuted
self._enabled_changed_event.set() self._muted_changed_event.set()
async def on_restart(self) -> None: async def on_restart(self) -> None:
"""Block until pipeline loop will be restarted.""" """Block until pipeline loop will be restarted."""
@ -111,9 +110,9 @@ class WyomingSatellite:
) )
await asyncio.sleep(_RECONNECT_SECONDS) await asyncio.sleep(_RECONNECT_SECONDS)
async def on_disabled(self) -> None: async def on_muted(self) -> None:
"""Block until device may be enabled again.""" """Block until device may be unmated again."""
await self._enabled_changed_event.wait() await self._muted_changed_event.wait()
async def on_stopped(self) -> None: async def on_stopped(self) -> None:
"""Run when run() has fully stopped.""" """Run when run() has fully stopped."""
@ -121,15 +120,14 @@ class WyomingSatellite:
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
def _enabled_changed(self) -> None: def _muted_changed(self) -> None:
"""Run when device enabled status changes.""" """Run when device muted status changes."""
if self.device.is_muted:
if not self.device.is_enabled:
# Cancel any running pipeline # Cancel any running pipeline
self._audio_queue.put_nowait(None) self._audio_queue.put_nowait(None)
self._enabled_changed_event.set() self._muted_changed_event.set()
self._enabled_changed_event.clear() self._muted_changed_event.clear()
def _pipeline_changed(self) -> None: def _pipeline_changed(self) -> None:
"""Run when device pipeline changes.""" """Run when device pipeline changes."""
@ -141,7 +139,7 @@ class WyomingSatellite:
"""Run pipelines until an error occurs.""" """Run pipelines until an error occurs."""
self.device.set_is_active(False) self.device.set_is_active(False)
while self.is_running and self.is_enabled: while self.is_running and (not self.device.is_muted):
try: try:
await self._connect() await self._connect()
break break
@ -151,7 +149,7 @@ class WyomingSatellite:
assert self._client is not None assert self._client is not None
_LOGGER.debug("Connected to satellite") _LOGGER.debug("Connected to satellite")
if (not self.is_running) or (not self.is_enabled): if (not self.is_running) or self.device.is_muted:
# Run was cancelled or satellite was disabled during connection # Run was cancelled or satellite was disabled during connection
return return
@ -160,7 +158,7 @@ class WyomingSatellite:
# Wait until we get RunPipeline event # Wait until we get RunPipeline event
run_pipeline: RunPipeline | None = None run_pipeline: RunPipeline | None = None
while self.is_running and self.is_enabled: while self.is_running and (not self.device.is_muted):
run_event = await self._client.read_event() run_event = await self._client.read_event()
if run_event is None: if run_event is None:
raise ConnectionResetError("Satellite disconnected") raise ConnectionResetError("Satellite disconnected")
@ -174,7 +172,7 @@ class WyomingSatellite:
assert run_pipeline is not None assert run_pipeline is not None
_LOGGER.debug("Received run information: %s", run_pipeline) _LOGGER.debug("Received run information: %s", run_pipeline)
if (not self.is_running) or (not self.is_enabled): if (not self.is_running) or self.device.is_muted:
# Run was cancelled or satellite was disabled while waiting for # Run was cancelled or satellite was disabled while waiting for
# RunPipeline event. # RunPipeline event.
return return
@ -189,7 +187,7 @@ class WyomingSatellite:
raise ValueError(f"Invalid end stage: {end_stage}") raise ValueError(f"Invalid end stage: {end_stage}")
# Each loop is a pipeline run # Each loop is a pipeline run
while self.is_running and self.is_enabled: while self.is_running and (not self.device.is_muted):
# Use select to get pipeline each time in case it's changed # Use select to get pipeline each time in case it's changed
pipeline_id = pipeline_select.get_chosen_pipeline( pipeline_id = pipeline_select.get_chosen_pipeline(
self.hass, self.hass,

View file

@ -42,8 +42,8 @@
} }
}, },
"switch": { "switch": {
"satellite_enabled": { "mute": {
"name": "Satellite enabled" "name": "Mute"
} }
} }
} }

View file

@ -29,17 +29,17 @@ async def async_setup_entry(
# Setup is only forwarded for satellites # Setup is only forwarded for satellites
assert item.satellite is not None assert item.satellite is not None
async_add_entities([WyomingSatelliteEnabledSwitch(item.satellite.device)]) async_add_entities([WyomingSatelliteMuteSwitch(item.satellite.device)])
class WyomingSatelliteEnabledSwitch( class WyomingSatelliteMuteSwitch(
WyomingSatelliteEntity, restore_state.RestoreEntity, SwitchEntity WyomingSatelliteEntity, restore_state.RestoreEntity, SwitchEntity
): ):
"""Entity to represent if satellite is enabled.""" """Entity to represent if satellite is muted."""
entity_description = SwitchEntityDescription( entity_description = SwitchEntityDescription(
key="satellite_enabled", key="mute",
translation_key="satellite_enabled", translation_key="mute",
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
) )
@ -49,17 +49,17 @@ class WyomingSatelliteEnabledSwitch(
state = await self.async_get_last_state() state = await self.async_get_last_state()
# Default to on # Default to off
self._attr_is_on = (state is None) or (state.state == STATE_ON) self._attr_is_on = (state is not None) and (state.state == STATE_ON)
async def async_turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn on.""" """Turn on."""
self._attr_is_on = True self._attr_is_on = True
self.async_write_ha_state() self.async_write_ha_state()
self._device.set_is_enabled(True) self._device.set_is_muted(True)
async def async_turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn off.""" """Turn off."""
self._attr_is_on = False self._attr_is_on = False
self.async_write_ha_state() self.async_write_ha_state()
self._device.set_is_enabled(False) self._device.set_is_muted(False)

View file

@ -5,7 +5,7 @@ from homeassistant.components.assist_pipeline.select import OPTION_PREFERRED
from homeassistant.components.wyoming import DOMAIN from homeassistant.components.wyoming import DOMAIN
from homeassistant.components.wyoming.devices import SatelliteDevice from homeassistant.components.wyoming.devices import SatelliteDevice
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import STATE_OFF, STATE_ON from homeassistant.const import STATE_OFF
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr from homeassistant.helpers import device_registry as dr
@ -34,11 +34,11 @@ async def test_device_registry_info(
assert assist_in_progress_state is not None assert assist_in_progress_state is not None
assert assist_in_progress_state.state == STATE_OFF assert assist_in_progress_state.state == STATE_OFF
satellite_enabled_id = satellite_device.get_satellite_enabled_entity_id(hass) muted_id = satellite_device.get_muted_entity_id(hass)
assert satellite_enabled_id assert muted_id
satellite_enabled_state = hass.states.get(satellite_enabled_id) muted_state = hass.states.get(muted_id)
assert satellite_enabled_state is not None assert muted_state is not None
assert satellite_enabled_state.state == STATE_ON assert muted_state.state == STATE_OFF
pipeline_entity_id = satellite_device.get_pipeline_entity_id(hass) pipeline_entity_id = satellite_device.get_pipeline_entity_id(hass)
assert pipeline_entity_id assert pipeline_entity_id
@ -59,9 +59,9 @@ async def test_remove_device_registry_entry(
assert assist_in_progress_id assert assist_in_progress_id
assert hass.states.get(assist_in_progress_id) is not None assert hass.states.get(assist_in_progress_id) is not None
satellite_enabled_id = satellite_device.get_satellite_enabled_entity_id(hass) muted_id = satellite_device.get_muted_entity_id(hass)
assert satellite_enabled_id assert muted_id
assert hass.states.get(satellite_enabled_id) is not None assert hass.states.get(muted_id) is not None
pipeline_entity_id = satellite_device.get_pipeline_entity_id(hass) pipeline_entity_id = satellite_device.get_pipeline_entity_id(hass)
assert pipeline_entity_id assert pipeline_entity_id
@ -74,5 +74,5 @@ async def test_remove_device_registry_entry(
# Everything should be gone # Everything should be gone
assert hass.states.get(assist_in_progress_id) is None assert hass.states.get(assist_in_progress_id) is None
assert hass.states.get(satellite_enabled_id) is None assert hass.states.get(muted_id) is None
assert hass.states.get(pipeline_entity_id) is None assert hass.states.get(pipeline_entity_id) is None

View file

@ -196,7 +196,7 @@ async def test_satellite_pipeline(hass: HomeAssistant) -> None:
await mock_client.detect_event.wait() await mock_client.detect_event.wait()
assert not device.is_active assert not device.is_active
assert device.is_enabled assert not device.is_muted
# Wake word is detected # Wake word is detected
event_callback( event_callback(
@ -312,36 +312,36 @@ async def test_satellite_pipeline(hass: HomeAssistant) -> None:
await hass.async_block_till_done() await hass.async_block_till_done()
async def test_satellite_disabled(hass: HomeAssistant) -> None: async def test_satellite_muted(hass: HomeAssistant) -> None:
"""Test callback for a satellite that has been disabled.""" """Test callback for a satellite that has been muted."""
on_disabled_event = asyncio.Event() on_muted_event = asyncio.Event()
original_make_satellite = wyoming._make_satellite original_make_satellite = wyoming._make_satellite
def make_disabled_satellite( def make_muted_satellite(
hass: HomeAssistant, config_entry: ConfigEntry, service: WyomingService hass: HomeAssistant, config_entry: ConfigEntry, service: WyomingService
): ):
satellite = original_make_satellite(hass, config_entry, service) satellite = original_make_satellite(hass, config_entry, service)
satellite.device.set_is_enabled(False) satellite.device.set_is_muted(True)
return satellite return satellite
async def on_disabled(self): async def on_muted(self):
self.device.set_is_enabled(True) self.device.set_is_muted(False)
on_disabled_event.set() on_muted_event.set()
with patch( with patch(
"homeassistant.components.wyoming.data.load_wyoming_info", "homeassistant.components.wyoming.data.load_wyoming_info",
return_value=SATELLITE_INFO, return_value=SATELLITE_INFO,
), patch( ), patch(
"homeassistant.components.wyoming._make_satellite", make_disabled_satellite "homeassistant.components.wyoming._make_satellite", make_muted_satellite
), patch( ), patch(
"homeassistant.components.wyoming.satellite.WyomingSatellite.on_disabled", "homeassistant.components.wyoming.satellite.WyomingSatellite.on_muted",
on_disabled, on_muted,
): ):
await setup_config_entry(hass) await setup_config_entry(hass)
async with asyncio.timeout(1): async with asyncio.timeout(1):
await on_disabled_event.wait() await on_muted_event.wait()
async def test_satellite_restart(hass: HomeAssistant) -> None: async def test_satellite_restart(hass: HomeAssistant) -> None:

View file

@ -5,28 +5,28 @@ from homeassistant.const import STATE_OFF, STATE_ON
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
async def test_satellite_enabled( async def test_muted(
hass: HomeAssistant, hass: HomeAssistant,
satellite_config_entry: ConfigEntry, satellite_config_entry: ConfigEntry,
satellite_device: SatelliteDevice, satellite_device: SatelliteDevice,
) -> None: ) -> None:
"""Test satellite enabled.""" """Test satellite muted."""
satellite_enabled_id = satellite_device.get_satellite_enabled_entity_id(hass) muted_id = satellite_device.get_muted_entity_id(hass)
assert satellite_enabled_id assert muted_id
state = hass.states.get(satellite_enabled_id) state = hass.states.get(muted_id)
assert state is not None assert state is not None
assert state.state == STATE_ON assert state.state == STATE_OFF
assert satellite_device.is_enabled assert not satellite_device.is_muted
await hass.services.async_call( await hass.services.async_call(
"switch", "switch",
"turn_off", "turn_on",
{"entity_id": satellite_enabled_id}, {"entity_id": muted_id},
blocking=True, blocking=True,
) )
state = hass.states.get(satellite_enabled_id) state = hass.states.get(muted_id)
assert state is not None assert state is not None
assert state.state == STATE_OFF assert state.state == STATE_ON
assert not satellite_device.is_enabled assert satellite_device.is_muted