diff --git a/homeassistant/components/sonos/switch.py b/homeassistant/components/sonos/switch.py index 84a0eb6c324..f2108697684 100644 --- a/homeassistant/components/sonos/switch.py +++ b/homeassistant/components/sonos/switch.py @@ -8,7 +8,7 @@ from soco.exceptions import SoCoException, SoCoSlaveException, SoCoUPnPException from homeassistant.components.switch import ENTITY_ID_FORMAT, SwitchEntity from homeassistant.config_entries import ConfigEntry -from homeassistant.const import ATTR_TIME +from homeassistant.const import ATTR_TIME, Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.dispatcher import async_dispatcher_connect @@ -120,6 +120,10 @@ async def async_setup_entry( available_soco_attributes, speaker ) for feature_type in available_features: + if feature_type == ATTR_SPEECH_ENHANCEMENT: + async_migrate_speech_enhancement_entity_unique_id( + hass, config_entry, speaker + ) _LOGGER.debug( "Creating %s switch on %s", FRIENDLY_NAMES[feature_type], @@ -351,3 +355,48 @@ class SonosAlarmEntity(SonosEntity, SwitchEntity): await self.hass.async_add_executor_job(self.alarm.save) except (OSError, SoCoException, SoCoUPnPException) as exc: _LOGGER.error("Could not update %s: %s", self.entity_id, exc) + + +@callback +def async_migrate_speech_enhancement_entity_unique_id( + hass: HomeAssistant, + config_entry: ConfigEntry, + speaker: SonosSpeaker, +) -> None: + """Migrate Speech Enhancement switch entity unique_id.""" + entity_registry = er.async_get(hass) + registry_entries = er.async_entries_for_config_entry( + entity_registry, config_entry.entry_id + ) + + speech_enhancement_entries = [ + entry + for entry in registry_entries + if entry.domain == Platform.SWITCH + and entry.original_icon == FEATURE_ICONS[ATTR_SPEECH_ENHANCEMENT] + and entry.unique_id.startswith(speaker.soco.uid) + ] + + if len(speech_enhancement_entries) > 1: + _LOGGER.warning( + "Migration of Speech Enhancement switches on %s failed, manual cleanup required: %s", + speaker.zone_name, + [e.entity_id for e in speech_enhancement_entries], + ) + return + + if len(speech_enhancement_entries) == 1: + old_entry = speech_enhancement_entries[0] + if old_entry.unique_id.endswith("dialog_level"): + return + + new_unique_id = f"{speaker.soco.uid}-{ATTR_SPEECH_ENHANCEMENT}" + _LOGGER.debug( + "Migrating unique_id for %s from %s to %s", + old_entry.entity_id, + old_entry.unique_id, + new_unique_id, + ) + entity_registry.async_update_entity( + old_entry.entity_id, new_unique_id=new_unique_id + )