mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Migrate unique ID in vesync switches (#137099)
This commit is contained in:
parent
b5662ded2c
commit
37461d727a
@ -7,6 +7,7 @@ from pyvesync import VeSync
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
|
||||
from homeassistant.core import HomeAssistant, ServiceCall
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
|
||||
from .common import async_generate_device_list
|
||||
@ -91,3 +92,37 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
hass.data.pop(DOMAIN)
|
||||
|
||||
return unload_ok
|
||||
|
||||
|
||||
async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
||||
"""Migrate old entry."""
|
||||
_LOGGER.debug(
|
||||
"Migrating VeSync config entry: %s minor version: %s",
|
||||
config_entry.version,
|
||||
config_entry.minor_version,
|
||||
)
|
||||
if config_entry.minor_version == 1:
|
||||
# Migrate switch/outlets entity to a new unique ID
|
||||
_LOGGER.debug("Migrating VeSync config entry from version 1 to version 2")
|
||||
entity_registry = er.async_get(hass)
|
||||
registry_entries = er.async_entries_for_config_entry(
|
||||
entity_registry, config_entry.entry_id
|
||||
)
|
||||
for reg_entry in registry_entries:
|
||||
if "-" not in reg_entry.unique_id and reg_entry.entity_id.startswith(
|
||||
Platform.SWITCH
|
||||
):
|
||||
_LOGGER.debug(
|
||||
"Migrating switch/outlet entity from unique_id: %s to unique_id: %s",
|
||||
reg_entry.unique_id,
|
||||
reg_entry.unique_id + "-device_status",
|
||||
)
|
||||
entity_registry.async_update_entity(
|
||||
reg_entry.entity_id,
|
||||
new_unique_id=reg_entry.unique_id + "-device_status",
|
||||
)
|
||||
else:
|
||||
_LOGGER.debug("Skipping entity with unique_id: %s", reg_entry.unique_id)
|
||||
hass.config_entries.async_update_entry(config_entry, minor_version=2)
|
||||
|
||||
return True
|
||||
|
@ -24,6 +24,7 @@ class VeSyncFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
"""Handle a config flow."""
|
||||
|
||||
VERSION = 1
|
||||
MINOR_VERSION = 2
|
||||
|
||||
@callback
|
||||
def _show_form(self, errors: dict[str, str] | None = None) -> ConfigFlowResult:
|
||||
|
@ -83,6 +83,7 @@ class VeSyncSwitchHA(VeSyncBaseSwitch, SwitchEntity):
|
||||
) -> None:
|
||||
"""Initialize the VeSync switch device."""
|
||||
super().__init__(plug, coordinator)
|
||||
self._attr_unique_id = f"{super().unique_id}-device_status"
|
||||
self.smartplug = plug
|
||||
|
||||
|
||||
@ -94,4 +95,5 @@ class VeSyncLightSwitch(VeSyncBaseSwitch, SwitchEntity):
|
||||
) -> None:
|
||||
"""Initialize Light Switch device class."""
|
||||
super().__init__(switch, coordinator)
|
||||
self._attr_unique_id = f"{super().unique_id}-device_status"
|
||||
self.switch = switch
|
||||
|
@ -153,3 +153,25 @@ async def humidifier_config_entry(
|
||||
await hass.async_block_till_done()
|
||||
|
||||
return entry
|
||||
|
||||
|
||||
@pytest.fixture(name="switch_old_id_config_entry")
|
||||
async def switch_old_id_config_entry(
|
||||
hass: HomeAssistant, requests_mock: requests_mock.Mocker, config
|
||||
) -> MockConfigEntry:
|
||||
"""Create a mock VeSync config entry for `switch` with the old unique ID approach."""
|
||||
entry = MockConfigEntry(
|
||||
title="VeSync",
|
||||
domain=DOMAIN,
|
||||
data=config[DOMAIN],
|
||||
version=1,
|
||||
minor_version=1,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
wall_switch = "Wall Switch"
|
||||
humidifer = "Humidifier 200s"
|
||||
|
||||
mock_multiple_device_responses(requests_mock, [wall_switch, humidifer])
|
||||
|
||||
return entry
|
||||
|
@ -367,7 +367,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'outlet',
|
||||
'unique_id': 'outlet-device_status',
|
||||
'unit_of_measurement': None,
|
||||
}),
|
||||
])
|
||||
@ -525,7 +525,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'switch',
|
||||
'unique_id': 'switch-device_status',
|
||||
'unit_of_measurement': None,
|
||||
}),
|
||||
])
|
||||
|
@ -10,6 +10,9 @@ from homeassistant.components.vesync.const import DOMAIN, VS_DEVICES, VS_MANAGER
|
||||
from homeassistant.config_entries import ConfigEntry, ConfigEntryState
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_async_setup_entry__not_login(
|
||||
@ -125,3 +128,55 @@ async def test_async_new_device_discovery(
|
||||
assert manager.login.call_count == 1
|
||||
assert hass.data[DOMAIN][VS_MANAGER] == manager
|
||||
assert hass.data[DOMAIN][VS_DEVICES] == [fan, humidifier]
|
||||
|
||||
|
||||
async def test_migrate_config_entry(
|
||||
hass: HomeAssistant,
|
||||
switch_old_id_config_entry: MockConfigEntry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test migration of config entry. Only migrates switches to a new unique_id."""
|
||||
switch: er.RegistryEntry = entity_registry.async_get_or_create(
|
||||
domain="switch",
|
||||
platform="vesync",
|
||||
unique_id="switch",
|
||||
config_entry=switch_old_id_config_entry,
|
||||
suggested_object_id="switch",
|
||||
)
|
||||
|
||||
humidifer: er.RegistryEntry = entity_registry.async_get_or_create(
|
||||
domain="humidifer",
|
||||
platform="vesync",
|
||||
unique_id="humidifer",
|
||||
config_entry=switch_old_id_config_entry,
|
||||
suggested_object_id="humidifer",
|
||||
)
|
||||
|
||||
assert switch.unique_id == "switch"
|
||||
assert switch_old_id_config_entry.minor_version == 1
|
||||
assert humidifer.unique_id == "humidifer"
|
||||
|
||||
await hass.config_entries.async_setup(switch_old_id_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert switch_old_id_config_entry.minor_version == 2
|
||||
|
||||
migrated_switch = entity_registry.async_get(switch.entity_id)
|
||||
assert migrated_switch is not None
|
||||
assert migrated_switch.entity_id.startswith("switch")
|
||||
assert migrated_switch.unique_id == "switch-device_status"
|
||||
# Confirm humidifer was not impacted
|
||||
migrated_humidifer = entity_registry.async_get(humidifer.entity_id)
|
||||
assert migrated_humidifer is not None
|
||||
assert migrated_humidifer.unique_id == "humidifer"
|
||||
|
||||
# Assert that only one entity exists in the switch domain
|
||||
switch_entities = [
|
||||
e for e in entity_registry.entities.values() if e.domain == "switch"
|
||||
]
|
||||
assert len(switch_entities) == 1
|
||||
|
||||
humidifer_entities = [
|
||||
e for e in entity_registry.entities.values() if e.domain == "humidifer"
|
||||
]
|
||||
assert len(humidifer_entities) == 1
|
||||
|
Loading…
x
Reference in New Issue
Block a user