Cleanup duplicate entry data in ESPHome assist_satellite (#143611)

This commit is contained in:
J. Nick Koston 2025-04-24 09:51:58 -10:00 committed by GitHub
parent 3aa1c60fe3
commit a61aff8432
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -42,7 +42,7 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .const import DOMAIN from .const import DOMAIN
from .entity import EsphomeAssistEntity, convert_api_error_ha_error from .entity import EsphomeAssistEntity, convert_api_error_ha_error
from .entry_data import ESPHomeConfigEntry, RuntimeEntryData from .entry_data import ESPHomeConfigEntry
from .enum_mapper import EsphomeEnumMapper from .enum_mapper import EsphomeEnumMapper
from .ffmpeg_proxy import async_create_proxy_url from .ffmpeg_proxy import async_create_proxy_url
@ -96,7 +96,7 @@ async def async_setup_entry(
if entry_data.device_info.voice_assistant_feature_flags_compat( if entry_data.device_info.voice_assistant_feature_flags_compat(
entry_data.api_version entry_data.api_version
): ):
async_add_entities([EsphomeAssistSatellite(entry, entry_data)]) async_add_entities([EsphomeAssistSatellite(entry)])
class EsphomeAssistSatellite( class EsphomeAssistSatellite(
@ -108,17 +108,12 @@ class EsphomeAssistSatellite(
key="assist_satellite", translation_key="assist_satellite" key="assist_satellite", translation_key="assist_satellite"
) )
def __init__( def __init__(self, entry: ESPHomeConfigEntry) -> None:
self,
config_entry: ESPHomeConfigEntry,
entry_data: RuntimeEntryData,
) -> None:
"""Initialize satellite.""" """Initialize satellite."""
super().__init__(entry_data) super().__init__(entry.runtime_data)
self.config_entry = config_entry self.config_entry = entry
self.entry_data = entry_data self.cli = self._entry_data.client
self.cli = self.entry_data.client
self._is_running: bool = True self._is_running: bool = True
self._pipeline_task: asyncio.Task | None = None self._pipeline_task: asyncio.Task | None = None
@ -134,23 +129,23 @@ class EsphomeAssistSatellite(
@property @property
def pipeline_entity_id(self) -> str | None: def pipeline_entity_id(self) -> str | None:
"""Return the entity ID of the pipeline to use for the next conversation.""" """Return the entity ID of the pipeline to use for the next conversation."""
assert self.entry_data.device_info is not None assert self._entry_data.device_info is not None
ent_reg = er.async_get(self.hass) ent_reg = er.async_get(self.hass)
return ent_reg.async_get_entity_id( return ent_reg.async_get_entity_id(
Platform.SELECT, Platform.SELECT,
DOMAIN, DOMAIN,
f"{self.entry_data.device_info.mac_address}-pipeline", f"{self._entry_data.device_info.mac_address}-pipeline",
) )
@property @property
def vad_sensitivity_entity_id(self) -> str | None: def vad_sensitivity_entity_id(self) -> str | None:
"""Return the entity ID of the VAD sensitivity to use for the next conversation.""" """Return the entity ID of the VAD sensitivity to use for the next conversation."""
assert self.entry_data.device_info is not None assert self._entry_data.device_info is not None
ent_reg = er.async_get(self.hass) ent_reg = er.async_get(self.hass)
return ent_reg.async_get_entity_id( return ent_reg.async_get_entity_id(
Platform.SELECT, Platform.SELECT,
DOMAIN, DOMAIN,
f"{self.entry_data.device_info.mac_address}-vad_sensitivity", f"{self._entry_data.device_info.mac_address}-vad_sensitivity",
) )
@callback @callback
@ -196,16 +191,16 @@ class EsphomeAssistSatellite(
_LOGGER.debug("Received satellite configuration: %s", self._satellite_config) _LOGGER.debug("Received satellite configuration: %s", self._satellite_config)
# Inform listeners that config has been updated # Inform listeners that config has been updated
self.entry_data.async_assist_satellite_config_updated(self._satellite_config) self._entry_data.async_assist_satellite_config_updated(self._satellite_config)
async def async_added_to_hass(self) -> None: async def async_added_to_hass(self) -> None:
"""Run when entity about to be added to hass.""" """Run when entity about to be added to hass."""
await super().async_added_to_hass() await super().async_added_to_hass()
assert self.entry_data.device_info is not None assert self._entry_data.device_info is not None
feature_flags = ( feature_flags = (
self.entry_data.device_info.voice_assistant_feature_flags_compat( self._entry_data.device_info.voice_assistant_feature_flags_compat(
self.entry_data.api_version self._entry_data.api_version
) )
) )
if feature_flags & VoiceAssistantFeature.API_AUDIO: if feature_flags & VoiceAssistantFeature.API_AUDIO:
@ -261,7 +256,7 @@ class EsphomeAssistSatellite(
# Update wake word select when config is updated # Update wake word select when config is updated
self.async_on_remove( self.async_on_remove(
self.entry_data.async_register_assist_satellite_set_wake_word_callback( self._entry_data.async_register_assist_satellite_set_wake_word_callback(
self.async_set_wake_word self.async_set_wake_word
) )
) )
@ -283,7 +278,7 @@ class EsphomeAssistSatellite(
data_to_send: dict[str, Any] = {} data_to_send: dict[str, Any] = {}
if event_type == VoiceAssistantEventType.VOICE_ASSISTANT_STT_START: if event_type == VoiceAssistantEventType.VOICE_ASSISTANT_STT_START:
self.entry_data.async_set_assist_pipeline_state(True) self._entry_data.async_set_assist_pipeline_state(True)
elif event_type == VoiceAssistantEventType.VOICE_ASSISTANT_STT_END: elif event_type == VoiceAssistantEventType.VOICE_ASSISTANT_STT_END:
assert event.data is not None assert event.data is not None
data_to_send = {"text": event.data["stt_output"]["text"]} data_to_send = {"text": event.data["stt_output"]["text"]}
@ -305,10 +300,10 @@ class EsphomeAssistSatellite(
url = async_process_play_media_url(self.hass, path) url = async_process_play_media_url(self.hass, path)
data_to_send = {"url": url} data_to_send = {"url": url}
assert self.entry_data.device_info is not None assert self._entry_data.device_info is not None
feature_flags = ( feature_flags = (
self.entry_data.device_info.voice_assistant_feature_flags_compat( self._entry_data.device_info.voice_assistant_feature_flags_compat(
self.entry_data.api_version self._entry_data.api_version
) )
) )
if feature_flags & VoiceAssistantFeature.SPEAKER and ( if feature_flags & VoiceAssistantFeature.SPEAKER and (
@ -344,7 +339,7 @@ class EsphomeAssistSatellite(
elif event_type == VoiceAssistantEventType.VOICE_ASSISTANT_RUN_END: elif event_type == VoiceAssistantEventType.VOICE_ASSISTANT_RUN_END:
if self._tts_streaming_task is None: if self._tts_streaming_task is None:
# No TTS # No TTS
self.entry_data.async_set_assist_pipeline_state(False) self._entry_data.async_set_assist_pipeline_state(False)
self.cli.send_voice_assistant_event(event_type, data_to_send) self.cli.send_voice_assistant_event(event_type, data_to_send)
@ -386,7 +381,7 @@ class EsphomeAssistSatellite(
# Route media through the proxy # Route media through the proxy
format_to_use: MediaPlayerSupportedFormat | None = None format_to_use: MediaPlayerSupportedFormat | None = None
for supported_format in chain( for supported_format in chain(
*self.entry_data.media_player_formats.values() *self._entry_data.media_player_formats.values()
): ):
if supported_format.purpose == MediaPlayerFormatPurpose.ANNOUNCEMENT: if supported_format.purpose == MediaPlayerFormatPurpose.ANNOUNCEMENT:
format_to_use = supported_format format_to_use = supported_format
@ -444,10 +439,10 @@ class EsphomeAssistSatellite(
# API or UDP output audio # API or UDP output audio
port: int = 0 port: int = 0
assert self.entry_data.device_info is not None assert self._entry_data.device_info is not None
feature_flags = ( feature_flags = (
self.entry_data.device_info.voice_assistant_feature_flags_compat( self._entry_data.device_info.voice_assistant_feature_flags_compat(
self.entry_data.api_version self._entry_data.api_version
) )
) )
if (feature_flags & VoiceAssistantFeature.SPEAKER) and not ( if (feature_flags & VoiceAssistantFeature.SPEAKER) and not (
@ -548,7 +543,7 @@ class EsphomeAssistSatellite(
def _update_tts_format(self) -> None: def _update_tts_format(self) -> None:
"""Update the TTS format from the first media player.""" """Update the TTS format from the first media player."""
for supported_format in chain(*self.entry_data.media_player_formats.values()): for supported_format in chain(*self._entry_data.media_player_formats.values()):
# Find first announcement format # Find first announcement format
if supported_format.purpose == MediaPlayerFormatPurpose.ANNOUNCEMENT: if supported_format.purpose == MediaPlayerFormatPurpose.ANNOUNCEMENT:
self._attr_tts_options = { self._attr_tts_options = {
@ -634,7 +629,7 @@ class EsphomeAssistSatellite(
# State change # State change
self.tts_response_finished() self.tts_response_finished()
self.entry_data.async_set_assist_pipeline_state(False) self._entry_data.async_set_assist_pipeline_state(False)
async def _wrap_audio_stream(self) -> AsyncIterable[bytes]: async def _wrap_audio_stream(self) -> AsyncIterable[bytes]:
"""Yield audio chunks from the queue until None.""" """Yield audio chunks from the queue until None."""