mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 01:08:12 +00:00
Fix data in old SkyConnect integration config entries or delete them (#141959)
* Delete old SkyConnect integration config entries * Try migrating, if possible * Do not delete config entries, log a failure
This commit is contained in:
parent
a7c43f9b49
commit
2b9c903429
@ -6,14 +6,29 @@ import logging
|
||||
import os.path
|
||||
|
||||
from homeassistant.components.homeassistant_hardware.util import guess_firmware_info
|
||||
from homeassistant.components.usb import USBDevice, async_register_port_event_callback
|
||||
from homeassistant.components.usb import (
|
||||
USBDevice,
|
||||
async_register_port_event_callback,
|
||||
scan_serial_ports,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from homeassistant.exceptions import ConfigEntryNotReady, HomeAssistantError
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from .const import DESCRIPTION, DEVICE, DOMAIN, FIRMWARE, FIRMWARE_VERSION, PRODUCT
|
||||
from .const import (
|
||||
DESCRIPTION,
|
||||
DEVICE,
|
||||
DOMAIN,
|
||||
FIRMWARE,
|
||||
FIRMWARE_VERSION,
|
||||
MANUFACTURER,
|
||||
PID,
|
||||
PRODUCT,
|
||||
SERIAL_NUMBER,
|
||||
VID,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -73,7 +88,7 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
|
||||
"""Migrate old entry."""
|
||||
|
||||
_LOGGER.debug(
|
||||
"Migrating from version %s:%s", config_entry.version, config_entry.minor_version
|
||||
"Migrating from version %s.%s", config_entry.version, config_entry.minor_version
|
||||
)
|
||||
|
||||
if config_entry.version == 1:
|
||||
@ -108,6 +123,43 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
|
||||
minor_version=3,
|
||||
)
|
||||
|
||||
if config_entry.minor_version == 3:
|
||||
# Old SkyConnect config entries were missing keys
|
||||
if any(
|
||||
key not in config_entry.data
|
||||
for key in (VID, PID, MANUFACTURER, PRODUCT, SERIAL_NUMBER)
|
||||
):
|
||||
serial_ports = await hass.async_add_executor_job(scan_serial_ports)
|
||||
serial_ports_info = {port.device: port for port in serial_ports}
|
||||
device = config_entry.data[DEVICE]
|
||||
|
||||
if not (usb_info := serial_ports_info.get(device)):
|
||||
raise HomeAssistantError(
|
||||
f"USB device {device} is missing, cannot migrate"
|
||||
)
|
||||
|
||||
hass.config_entries.async_update_entry(
|
||||
config_entry,
|
||||
data={
|
||||
**config_entry.data,
|
||||
VID: usb_info.vid,
|
||||
PID: usb_info.pid,
|
||||
MANUFACTURER: usb_info.manufacturer,
|
||||
PRODUCT: usb_info.description,
|
||||
DESCRIPTION: usb_info.description,
|
||||
SERIAL_NUMBER: usb_info.serial_number,
|
||||
},
|
||||
version=1,
|
||||
minor_version=4,
|
||||
)
|
||||
else:
|
||||
# Existing entries are migrated by just incrementing the version
|
||||
hass.config_entries.async_update_entry(
|
||||
config_entry,
|
||||
version=1,
|
||||
minor_version=4,
|
||||
)
|
||||
|
||||
_LOGGER.debug(
|
||||
"Migration to version %s.%s successful",
|
||||
config_entry.version,
|
||||
|
@ -81,7 +81,7 @@ class HomeAssistantSkyConnectConfigFlow(
|
||||
"""Handle a config flow for Home Assistant SkyConnect."""
|
||||
|
||||
VERSION = 1
|
||||
MINOR_VERSION = 3
|
||||
MINOR_VERSION = 4
|
||||
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||
"""Initialize the config flow."""
|
||||
|
@ -9,7 +9,15 @@ from homeassistant.components.homeassistant_hardware.util import (
|
||||
ApplicationType,
|
||||
FirmwareInfo,
|
||||
)
|
||||
from homeassistant.components.homeassistant_sky_connect.const import DOMAIN
|
||||
from homeassistant.components.homeassistant_sky_connect.const import (
|
||||
DESCRIPTION,
|
||||
DOMAIN,
|
||||
MANUFACTURER,
|
||||
PID,
|
||||
PRODUCT,
|
||||
SERIAL_NUMBER,
|
||||
VID,
|
||||
)
|
||||
from homeassistant.components.usb import USBDevice
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_STARTED
|
||||
@ -57,7 +65,7 @@ async def test_config_entry_migration_v2(hass: HomeAssistant) -> None:
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
|
||||
assert config_entry.version == 1
|
||||
assert config_entry.minor_version == 3
|
||||
assert config_entry.minor_version == 4
|
||||
assert config_entry.data == {
|
||||
"description": "SkyConnect v1.0",
|
||||
"device": "/dev/serial/by-id/usb-Nabu_Casa_SkyConnect_v1.0_9e2adbd75b8beb119fe564a0f320645d-if00-port0",
|
||||
@ -187,3 +195,102 @@ async def test_usb_device_reactivity(hass: HomeAssistant) -> None:
|
||||
# The integration has reloaded and is now in a failed state
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
assert config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||
|
||||
|
||||
async def test_bad_config_entry_fixing(hass: HomeAssistant) -> None:
|
||||
"""Test fixing/deleting config entries with bad data."""
|
||||
|
||||
# Newly-added ZBT-1
|
||||
new_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id="some_unique_id-9e2adbd75b8beb119fe564a0f320645d",
|
||||
data={
|
||||
"device": "/dev/serial/by-id/usb-Nabu_Casa_SkyConnect_v1.0_9e2adbd75b8beb119fe564a0f320645d-if00-port0",
|
||||
"vid": "10C4",
|
||||
"pid": "EA60",
|
||||
"serial_number": "9e2adbd75b8beb119fe564a0f320645d",
|
||||
"manufacturer": "Nabu Casa",
|
||||
"product": "SkyConnect v1.0",
|
||||
"firmware": "ezsp",
|
||||
"firmware_version": "7.4.4.0 (build 123)",
|
||||
},
|
||||
version=1,
|
||||
minor_version=3,
|
||||
)
|
||||
|
||||
new_entry.add_to_hass(hass)
|
||||
|
||||
# Old config entry, without firmware info
|
||||
old_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id="some_unique_id-3c0ed67c628beb11b1cd64a0f320645d",
|
||||
data={
|
||||
"device": "/dev/serial/by-id/usb-Nabu_Casa_SkyConnect_v1.0_3c0ed67c628beb11b1cd64a0f320645d-if00-port0",
|
||||
"vid": "10C4",
|
||||
"pid": "EA60",
|
||||
"serial_number": "3c0ed67c628beb11b1cd64a0f320645d",
|
||||
"manufacturer": "Nabu Casa",
|
||||
"description": "SkyConnect v1.0",
|
||||
},
|
||||
version=1,
|
||||
minor_version=1,
|
||||
)
|
||||
|
||||
old_entry.add_to_hass(hass)
|
||||
|
||||
# Bad config entry, missing most keys
|
||||
bad_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id="some_unique_id-9f6c4bba657cc9a4f0cea48bc5948562",
|
||||
data={
|
||||
"device": "/dev/serial/by-id/usb-Nabu_Casa_SkyConnect_v1.0_9f6c4bba657cc9a4f0cea48bc5948562-if00-port0",
|
||||
},
|
||||
version=1,
|
||||
minor_version=2,
|
||||
)
|
||||
|
||||
bad_entry.add_to_hass(hass)
|
||||
|
||||
# Bad config entry, missing most keys, but fixable since the device is present
|
||||
fixable_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id="some_unique_id-4f5f3b26d59f8714a78b599690741999",
|
||||
data={
|
||||
"device": "/dev/serial/by-id/usb-Nabu_Casa_SkyConnect_v1.0_4f5f3b26d59f8714a78b599690741999-if00-port0",
|
||||
},
|
||||
version=1,
|
||||
minor_version=2,
|
||||
)
|
||||
|
||||
fixable_entry.add_to_hass(hass)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.homeassistant_sky_connect.scan_serial_ports",
|
||||
return_value=[
|
||||
USBDevice(
|
||||
device="/dev/serial/by-id/usb-Nabu_Casa_SkyConnect_v1.0_4f5f3b26d59f8714a78b599690741999-if00-port0",
|
||||
vid="10C4",
|
||||
pid="EA60",
|
||||
serial_number="4f5f3b26d59f8714a78b599690741999",
|
||||
manufacturer="Nabu Casa",
|
||||
description="SkyConnect v1.0",
|
||||
)
|
||||
],
|
||||
):
|
||||
await async_setup_component(hass, "homeassistant_sky_connect", {})
|
||||
|
||||
assert hass.config_entries.async_get_entry(new_entry.entry_id) is not None
|
||||
assert hass.config_entries.async_get_entry(old_entry.entry_id) is not None
|
||||
assert hass.config_entries.async_get_entry(fixable_entry.entry_id) is not None
|
||||
|
||||
updated_entry = hass.config_entries.async_get_entry(fixable_entry.entry_id)
|
||||
assert updated_entry is not None
|
||||
assert updated_entry.data[VID] == "10C4"
|
||||
assert updated_entry.data[PID] == "EA60"
|
||||
assert updated_entry.data[SERIAL_NUMBER] == "4f5f3b26d59f8714a78b599690741999"
|
||||
assert updated_entry.data[MANUFACTURER] == "Nabu Casa"
|
||||
assert updated_entry.data[PRODUCT] == "SkyConnect v1.0"
|
||||
assert updated_entry.data[DESCRIPTION] == "SkyConnect v1.0"
|
||||
|
||||
untouched_bad_entry = hass.config_entries.async_get_entry(bad_entry.entry_id)
|
||||
assert untouched_bad_entry.minor_version == 3
|
||||
|
Loading…
x
Reference in New Issue
Block a user