Migrate wolflink config_entry unique_id to string (#125653)
* Migrate wolflink config_entry unique_id to string * Move CONFIG to const * isinstance * Migrate identifiers * Use async_migrate_entry
This commit is contained in:
parent
745a05d984
commit
2f38731f62
6 changed files with 109 additions and 11 deletions
|
@ -11,6 +11,7 @@ from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
|
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import ConfigEntryNotReady
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
|
from homeassistant.helpers import device_registry as dr
|
||||||
from homeassistant.helpers.httpx_client import get_async_client
|
from homeassistant.helpers.httpx_client import get_async_client
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||||
|
|
||||||
|
@ -30,6 +31,7 @@ PLATFORMS = [Platform.SENSOR]
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
"""Set up Wolf SmartSet Service from a config entry."""
|
"""Set up Wolf SmartSet Service from a config entry."""
|
||||||
|
|
||||||
username = entry.data[CONF_USERNAME]
|
username = entry.data[CONF_USERNAME]
|
||||||
password = entry.data[CONF_PASSWORD]
|
password = entry.data[CONF_PASSWORD]
|
||||||
device_name = entry.data[DEVICE_NAME]
|
device_name = entry.data[DEVICE_NAME]
|
||||||
|
@ -125,6 +127,32 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
return unload_ok
|
return unload_ok
|
||||||
|
|
||||||
|
|
||||||
|
async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
|
"""Migrate old entry."""
|
||||||
|
# convert unique_id to string
|
||||||
|
if entry.version == 1 and entry.minor_version == 1:
|
||||||
|
if isinstance(entry.unique_id, int):
|
||||||
|
hass.config_entries.async_update_entry(
|
||||||
|
entry, unique_id=str(entry.unique_id)
|
||||||
|
)
|
||||||
|
device_registry = dr.async_get(hass)
|
||||||
|
for device in dr.async_entries_for_config_entry(
|
||||||
|
device_registry, entry.entry_id
|
||||||
|
):
|
||||||
|
new_identifiers = set()
|
||||||
|
for identifier in device.identifiers:
|
||||||
|
if identifier[0] == DOMAIN:
|
||||||
|
new_identifiers.add((DOMAIN, str(identifier[1])))
|
||||||
|
else:
|
||||||
|
new_identifiers.add(identifier)
|
||||||
|
device_registry.async_update_device(
|
||||||
|
device.id, new_identifiers=new_identifiers
|
||||||
|
)
|
||||||
|
hass.config_entries.async_update_entry(entry, minor_version=2)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
async def fetch_parameters(client: WolfClient, gateway_id: int, device_id: int):
|
async def fetch_parameters(client: WolfClient, gateway_id: int, device_id: int):
|
||||||
"""Fetch all available parameters with usage of WolfClient.
|
"""Fetch all available parameters with usage of WolfClient.
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ class WolfLinkConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||||
"""Handle a config flow for Wolf SmartSet Service."""
|
"""Handle a config flow for Wolf SmartSet Service."""
|
||||||
|
|
||||||
VERSION = 1
|
VERSION = 1
|
||||||
|
MINOR_VERSION = 2
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
"""Initialize with empty username and password."""
|
"""Initialize with empty username and password."""
|
||||||
|
@ -66,7 +67,7 @@ class WolfLinkConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||||
device for device in self.fetched_systems if device.name == device_name
|
device for device in self.fetched_systems if device.name == device_name
|
||||||
]
|
]
|
||||||
device_id = system[0].id
|
device_id = system[0].id
|
||||||
await self.async_set_unique_id(device_id)
|
await self.async_set_unique_id(str(device_id))
|
||||||
self._abort_if_unique_id_configured()
|
self._abort_if_unique_id_configured()
|
||||||
return self.async_create_entry(
|
return self.async_create_entry(
|
||||||
title=user_input[DEVICE_NAME],
|
title=user_input[DEVICE_NAME],
|
||||||
|
|
|
@ -63,7 +63,7 @@ class WolfLinkSensor(CoordinatorEntity, SensorEntity):
|
||||||
self._attr_unique_id = f"{device_id}:{wolf_object.parameter_id}"
|
self._attr_unique_id = f"{device_id}:{wolf_object.parameter_id}"
|
||||||
self._state = None
|
self._state = None
|
||||||
self._attr_device_info = DeviceInfo(
|
self._attr_device_info = DeviceInfo(
|
||||||
identifiers={(DOMAIN, device_id)},
|
identifiers={(DOMAIN, str(device_id))},
|
||||||
configuration_url="https://www.wolf-smartset.com/",
|
configuration_url="https://www.wolf-smartset.com/",
|
||||||
manufacturer=MANUFACTURER,
|
manufacturer=MANUFACTURER,
|
||||||
)
|
)
|
||||||
|
|
16
tests/components/wolflink/const.py
Normal file
16
tests/components/wolflink/const.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
"""Constants for the Wolf SmartSet Service tests."""
|
||||||
|
|
||||||
|
from homeassistant.components.wolflink.const import (
|
||||||
|
DEVICE_GATEWAY,
|
||||||
|
DEVICE_ID,
|
||||||
|
DEVICE_NAME,
|
||||||
|
)
|
||||||
|
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||||
|
|
||||||
|
CONFIG = {
|
||||||
|
DEVICE_NAME: "test-device",
|
||||||
|
DEVICE_ID: 1234,
|
||||||
|
DEVICE_GATEWAY: 5678,
|
||||||
|
CONF_USERNAME: "test-username",
|
||||||
|
CONF_PASSWORD: "test-password",
|
||||||
|
}
|
|
@ -17,15 +17,9 @@ from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.data_entry_flow import FlowResultType
|
from homeassistant.data_entry_flow import FlowResultType
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from .const import CONFIG
|
||||||
|
|
||||||
CONFIG = {
|
from tests.common import MockConfigEntry
|
||||||
DEVICE_NAME: "test-device",
|
|
||||||
DEVICE_ID: 1234,
|
|
||||||
DEVICE_GATEWAY: 5678,
|
|
||||||
CONF_USERNAME: "test-username",
|
|
||||||
CONF_PASSWORD: "test-password",
|
|
||||||
}
|
|
||||||
|
|
||||||
INPUT_CONFIG = {
|
INPUT_CONFIG = {
|
||||||
CONF_USERNAME: CONFIG[CONF_USERNAME],
|
CONF_USERNAME: CONFIG[CONF_USERNAME],
|
||||||
|
@ -134,7 +128,7 @@ async def test_already_configured_error(hass: HomeAssistant) -> None:
|
||||||
patch("homeassistant.components.wolflink.async_setup_entry", return_value=True),
|
patch("homeassistant.components.wolflink.async_setup_entry", return_value=True),
|
||||||
):
|
):
|
||||||
MockConfigEntry(
|
MockConfigEntry(
|
||||||
domain=DOMAIN, unique_id=CONFIG[DEVICE_ID], data=CONFIG
|
domain=DOMAIN, unique_id=str(CONFIG[DEVICE_ID]), data=CONFIG
|
||||||
).add_to_hass(hass)
|
).add_to_hass(hass)
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
|
59
tests/components/wolflink/test_init.py
Normal file
59
tests/components/wolflink/test_init.py
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
"""Test the Wolf SmartSet Service."""
|
||||||
|
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from httpx import RequestError
|
||||||
|
|
||||||
|
from homeassistant.components.wolflink.const import DEVICE_ID, DOMAIN, MANUFACTURER
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import device_registry as dr
|
||||||
|
|
||||||
|
from .const import CONFIG
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
|
async def test_unique_id_migration(
|
||||||
|
hass: HomeAssistant, device_registry: dr.DeviceRegistry
|
||||||
|
) -> None:
|
||||||
|
"""Test already configured while creating entry."""
|
||||||
|
config_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN, unique_id=CONFIG[DEVICE_ID], data=CONFIG
|
||||||
|
)
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
device_id = device_registry.async_get_or_create(
|
||||||
|
config_entry_id=config_entry.entry_id,
|
||||||
|
identifiers={(DOMAIN, CONFIG[DEVICE_ID])},
|
||||||
|
configuration_url="https://www.wolf-smartset.com/",
|
||||||
|
manufacturer=MANUFACTURER,
|
||||||
|
).id
|
||||||
|
|
||||||
|
assert config_entry.version == 1
|
||||||
|
assert config_entry.minor_version == 1
|
||||||
|
assert config_entry.unique_id == 1234
|
||||||
|
assert (
|
||||||
|
hass.config_entries.async_entry_for_domain_unique_id(DOMAIN, 1234)
|
||||||
|
is config_entry
|
||||||
|
)
|
||||||
|
assert hass.config_entries.async_entry_for_domain_unique_id(DOMAIN, "1234") is None
|
||||||
|
assert device_registry.async_get(device_id).identifiers == {(DOMAIN, 1234)}
|
||||||
|
|
||||||
|
with (
|
||||||
|
patch(
|
||||||
|
"homeassistant.components.wolflink.fetch_parameters",
|
||||||
|
side_effect=RequestError("Unable to fetch parameters"),
|
||||||
|
),
|
||||||
|
):
|
||||||
|
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||||
|
|
||||||
|
assert config_entry.version == 1
|
||||||
|
assert config_entry.minor_version == 2
|
||||||
|
assert config_entry.unique_id == "1234"
|
||||||
|
assert (
|
||||||
|
hass.config_entries.async_entry_for_domain_unique_id(DOMAIN, "1234")
|
||||||
|
is config_entry
|
||||||
|
)
|
||||||
|
assert hass.config_entries.async_entry_for_domain_unique_id(DOMAIN, 1234) is None
|
||||||
|
|
||||||
|
assert device_registry.async_get(device_id).identifiers == {(DOMAIN, "1234")}
|
Loading…
Add table
Reference in a new issue