diff --git a/homeassistant/components/steam_online/__init__.py b/homeassistant/components/steam_online/__init__.py index 838b0b450e13..8d4464e06c25 100644 --- a/homeassistant/components/steam_online/__init__.py +++ b/homeassistant/components/steam_online/__init__.py @@ -1,7 +1,8 @@ """The Steam integration.""" from homeassistant.const import Platform -from homeassistant.core import HomeAssistant +from homeassistant.core import HomeAssistant, callback +from homeassistant.helpers import entity_registry as er from .coordinator import SteamConfigEntry, SteamDataUpdateCoordinator @@ -21,3 +22,22 @@ async def async_setup_entry(hass: HomeAssistant, entry: SteamConfigEntry) -> boo async def async_unload_entry(hass: HomeAssistant, entry: SteamConfigEntry) -> bool: """Unload a config entry.""" return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) + + +async def async_migrate_entry(hass: HomeAssistant, entry: SteamConfigEntry) -> bool: + """Migrate old entry.""" + + if entry.version < 2: + # Migrate entity unique id + + @callback + def migrate_unique_id(entity_entry: er.RegistryEntry) -> dict[str, str] | None: + if entity_entry.unique_id.startswith("sensor.steam_"): + new = entity_entry.unique_id.removeprefix("sensor.steam_") + "_account" + return {"new_unique_id": new} + return None + + await er.async_migrate_entries(hass, entry.entry_id, migrate_unique_id) + hass.config_entries.async_update_entry(entry, version=2) + + return True diff --git a/homeassistant/components/steam_online/config_flow.py b/homeassistant/components/steam_online/config_flow.py index 0c8b991d56ce..4ee306544a9e 100644 --- a/homeassistant/components/steam_online/config_flow.py +++ b/homeassistant/components/steam_online/config_flow.py @@ -41,6 +41,8 @@ def validate_input(user_input: dict[str, str]) -> dict[str, str | int]: class SteamFlowHandler(ConfigFlow, domain=DOMAIN): """Handle a config flow for Steam.""" + VERSION = 2 + @staticmethod @callback @override @@ -150,7 +152,7 @@ class SteamOptionsFlowHandler(OptionsFlowWithReload): for _id in self.options[CONF_ACCOUNTS]: if _id not in user_input[CONF_ACCOUNTS] and ( entity_id := er.async_get(self.hass).async_get_entity_id( - Platform.SENSOR, DOMAIN, f"sensor.steam_{_id}" + Platform.SENSOR, DOMAIN, f"{_id}_account" ) ): er.async_get(self.hass).async_remove(entity_id) diff --git a/homeassistant/components/steam_online/entity.py b/homeassistant/components/steam_online/entity.py index bd13888ac7f3..be8eebde909b 100644 --- a/homeassistant/components/steam_online/entity.py +++ b/homeassistant/components/steam_online/entity.py @@ -1,5 +1,6 @@ """Entity classes for the Steam integration.""" +from homeassistant.components.sensor import SensorEntityDescription from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -12,9 +13,17 @@ class SteamEntity(CoordinatorEntity[SteamDataUpdateCoordinator]): _attr_has_entity_name = True - def __init__(self, coordinator: SteamDataUpdateCoordinator) -> None: + def __init__( + self, + coordinator: SteamDataUpdateCoordinator, + steamid: str, + description: SensorEntityDescription, + ) -> None: """Initialize a Steam entity.""" super().__init__(coordinator) + self._steamid = steamid + self.entity_description = description + self._attr_unique_id = f"{steamid}_{description.key}" self._attr_device_info = DeviceInfo( configuration_url="https://store.steampowered.com", entry_type=DeviceEntryType.SERVICE, diff --git a/homeassistant/components/steam_online/sensor.py b/homeassistant/components/steam_online/sensor.py index 944ab275fd63..636a8f034648 100644 --- a/homeassistant/components/steam_online/sensor.py +++ b/homeassistant/components/steam_online/sensor.py @@ -80,10 +80,7 @@ class SteamSensorEntity(SteamEntity, SensorEntity): description: SteamSensorEntityDescription, ) -> None: """Initialize the sensor.""" - super().__init__(coordinator) - self._steamid = steamid - self.entity_description = description - self._attr_unique_id = f"sensor.steam_{steamid}" + super().__init__(coordinator, steamid, description) self._attr_name = self.entity_description.name_fn(coordinator.data[steamid]) @property diff --git a/tests/components/steam_online/conftest.py b/tests/components/steam_online/conftest.py index 8fe5ed46e333..a71782eda153 100644 --- a/tests/components/steam_online/conftest.py +++ b/tests/components/steam_online/conftest.py @@ -20,6 +20,7 @@ def mock_config_entry() -> MockConfigEntry: data=CONF_DATA, options=CONF_OPTIONS, unique_id=ACCOUNT_1, + version=2, ) diff --git a/tests/components/steam_online/snapshots/test_sensor.ambr b/tests/components/steam_online/snapshots/test_sensor.ambr index f906dc4faf54..598b4efa875d 100644 --- a/tests/components/steam_online/snapshots/test_sensor.ambr +++ b/tests/components/steam_online/snapshots/test_sensor.ambr @@ -32,7 +32,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': , - 'unique_id': 'sensor.steam_12345678901234567', + 'unique_id': '12345678901234567_account', 'unit_of_measurement': None, }) # --- diff --git a/tests/components/steam_online/test_init.py b/tests/components/steam_online/test_init.py index 261092e22aec..7f626f6a99cc 100644 --- a/tests/components/steam_online/test_init.py +++ b/tests/components/steam_online/test_init.py @@ -7,8 +7,11 @@ import steam.api from homeassistant.components.steam_online.const import DEFAULT_NAME, DOMAIN from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState +from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers import device_registry as dr +from homeassistant.helpers import device_registry as dr, entity_registry as er + +from . import ACCOUNT_1, ACCOUNT_NAME_1, CONF_DATA, CONF_OPTIONS from tests.common import MockConfigEntry @@ -95,3 +98,40 @@ async def test_device_info( assert device.identifiers == {(DOMAIN, config_entry.entry_id)} assert device.manufacturer == DEFAULT_NAME assert device.name == DEFAULT_NAME + + +@pytest.mark.usefixtures("steam_api") +async def test_migrate_entry( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, +) -> None: + """Test entry migration.""" + config_entry = MockConfigEntry( + domain=DOMAIN, + data=CONF_DATA, + options=CONF_OPTIONS, + unique_id=ACCOUNT_1, + version=1, + ) + + config_entry.add_to_hass(hass) + + assert config_entry.version == 1 + + sensor = entity_registry.async_get_or_create( + domain=Platform.SENSOR, + platform=DOMAIN, + unique_id=f"sensor.steam_{ACCOUNT_1}", + config_entry=config_entry, + original_name=ACCOUNT_NAME_1, + ) + + assert sensor.unique_id == f"sensor.steam_{ACCOUNT_1}" + + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + assert config_entry.version == 2 + + assert (sensor := entity_registry.async_get(sensor.entity_id)) + assert sensor.unique_id == f"{ACCOUNT_1}_account"