Migrate tradfri device identifier

This commit is contained in:
Martin Hjelmare 2022-06-23 13:28:45 +02:00
parent f323289d2a
commit 951ae92668
4 changed files with 81 additions and 2 deletions

View File

@ -21,6 +21,7 @@ from homeassistant.helpers.event import async_track_time_interval
from .const import CONF_GATEWAY_ID, CONF_IDENTITY, CONF_KEY, DOMAIN, LOGGER
from .coordinator import TradfriDeviceDataUpdateCoordinator
from .migration import migrate_device_identifier
from .models import TradfriData
PLATFORMS = [
@ -39,6 +40,9 @@ async def async_setup_entry(
entry: ConfigEntry,
) -> bool:
"""Create a gateway."""
# Migrate old integer device identifier to string, added in core-2022.7.0.
migrate_device_identifier(hass, entry)
factory = await APIFactory.init(
entry.data[CONF_HOST],
psk_id=entry.data[CONF_IDENTITY],
@ -151,7 +155,7 @@ def remove_stale_devices(
if identifier[0] != DOMAIN:
continue
# The device id in the identifier is not copied from integer to string
# The device id in the identifier was not copied from integer to string
# when setting entity device info. Copy here to make sure it's a string.
_id = str(identifier[1])

View File

@ -59,7 +59,7 @@ class TradfriBaseEntity(CoordinatorEntity[TradfriDeviceDataUpdateCoordinator]):
info = self._device.device_info
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, self._device_id)},
identifiers={(DOMAIN, str(self._device.id))},
manufacturer=info.manufacturer,
model=info.model_number,
name=self._device.name,

View File

@ -0,0 +1,32 @@
"""Provide migration tools for the Tradfri integration."""
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
import homeassistant.helpers.device_registry as dr
from .const import DOMAIN
@callback
def migrate_device_identifier(hass: HomeAssistant, config_entry: ConfigEntry) -> None:
"""Migrate device identifier to new format."""
device_registry = dr.async_get(hass)
device_entries = dr.async_entries_for_config_entry(
device_registry, config_entry.entry_id
)
for device_entry in device_entries:
device_identifiers = set(device_entry.identifiers)
for identifier in device_entry.identifiers:
if identifier[0] == DOMAIN and isinstance(
identifier[1], int # type: ignore[unreachable]
):
device_identifiers.remove(identifier) # type: ignore[unreachable]
# Copy pytradfri device id to string.
device_identifiers.add((DOMAIN, str(identifier[1])))
break
if device_identifiers != device_entry.identifiers:
device_registry.async_update_device(
device_entry.id, new_identifiers=device_identifiers
)

View File

@ -0,0 +1,43 @@
"""Test the tradfri migration tools."""
from unittest.mock import MagicMock
from homeassistant.components.tradfri.const import DOMAIN
from homeassistant.core import HomeAssistant
import homeassistant.helpers.device_registry as dr
from . import GATEWAY_ID
from tests.common import MockConfigEntry
async def test_migrate_device_identifier(
hass: HomeAssistant, mock_api_factory: MagicMock
) -> None:
"""Test migrate device identifier."""
entry = MockConfigEntry(
domain=DOMAIN,
data={
"host": "mock-host",
"identity": "mock-identity",
"key": "mock-key",
"gateway_id": GATEWAY_ID,
},
)
entry.add_to_hass(hass)
device_registry = dr.async_get(hass)
device_entry = device_registry.async_get_or_create(
config_entry_id=entry.entry_id,
identifiers={(DOMAIN, 1)}, # type: ignore[arg-type]
)
assert device_entry.identifiers == {(DOMAIN, 1)} # type: ignore[comparison-overlap]
# FIXME: We need to mock the pytradfri device on the gateway.
assert await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
migrated_device_entry = device_registry.async_get(device_entry.id)
assert migrated_device_entry
assert migrated_device_entry.identifiers == {(DOMAIN, "1")}