diff --git a/homeassistant/components/homekit_controller/__init__.py b/homeassistant/components/homekit_controller/__init__.py index 37dd648dedb..b2ccad9a457 100644 --- a/homeassistant/components/homekit_controller/__init__.py +++ b/homeassistant/components/homekit_controller/__init__.py @@ -31,7 +31,7 @@ from homeassistant.helpers.typing import ConfigType from .config_flow import normalize_hkid from .connection import HKDevice, valid_serial_number from .const import ENTITY_MAP, KNOWN_DEVICES, TRIGGERS -from .storage import async_get_entity_storage +from .storage import EntityMapStorage, async_get_entity_storage from .utils import async_get_controller, folded_name _LOGGER = logging.getLogger(__name__) @@ -269,7 +269,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: hkid = entry.data["AccessoryPairingID"] if hkid in hass.data[KNOWN_DEVICES]: - connection = hass.data[KNOWN_DEVICES][hkid] + connection: HKDevice = hass.data[KNOWN_DEVICES][hkid] await connection.async_unload() return True @@ -280,7 +280,8 @@ async def async_remove_entry(hass: HomeAssistant, entry: ConfigEntry) -> None: hkid = entry.data["AccessoryPairingID"] # Remove cached type data from .storage/homekit_controller-entity-map - hass.data[ENTITY_MAP].async_delete_map(hkid) + entity_map_storage: EntityMapStorage = hass.data[ENTITY_MAP] + entity_map_storage.async_delete_map(hkid) controller = await async_get_controller(hass) diff --git a/homeassistant/components/homekit_controller/config_flow.py b/homeassistant/components/homekit_controller/config_flow.py index d5ce8c37e7c..eba531b917c 100644 --- a/homeassistant/components/homekit_controller/config_flow.py +++ b/homeassistant/components/homekit_controller/config_flow.py @@ -597,7 +597,7 @@ class HomekitControllerFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): entity_storage = await async_get_entity_storage(self.hass) assert self.unique_id is not None entity_storage.async_create_or_update_map( - self.unique_id, + pairing.id, accessories_state.config_num, accessories_state.accessories.serialize(), ) diff --git a/homeassistant/components/homekit_controller/manifest.json b/homeassistant/components/homekit_controller/manifest.json index ac1be576906..5aff66fe757 100644 --- a/homeassistant/components/homekit_controller/manifest.json +++ b/homeassistant/components/homekit_controller/manifest.json @@ -3,7 +3,7 @@ "name": "HomeKit Controller", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/homekit_controller", - "requirements": ["aiohomekit==1.2.3"], + "requirements": ["aiohomekit==1.2.4"], "zeroconf": ["_hap._tcp.local.", "_hap._udp.local."], "bluetooth": [{ "manufacturer_id": 76, "manufacturer_data_start": [6] }], "dependencies": ["bluetooth", "zeroconf"], diff --git a/homeassistant/components/homekit_controller/storage.py b/homeassistant/components/homekit_controller/storage.py index 8c0628c97f6..51d8ce4ffd3 100644 --- a/homeassistant/components/homekit_controller/storage.py +++ b/homeassistant/components/homekit_controller/storage.py @@ -2,6 +2,7 @@ from __future__ import annotations +import logging from typing import Any, TypedDict from homeassistant.core import HomeAssistant, callback @@ -12,6 +13,7 @@ from .const import DOMAIN, ENTITY_MAP ENTITY_MAP_STORAGE_KEY = f"{DOMAIN}-entity-map" ENTITY_MAP_STORAGE_VERSION = 1 ENTITY_MAP_SAVE_DELAY = 10 +_LOGGER = logging.getLogger(__name__) class Pairing(TypedDict): @@ -68,6 +70,7 @@ class EntityMapStorage: self, homekit_id: str, config_num: int, accessories: list[Any] ) -> Pairing: """Create a new pairing cache.""" + _LOGGER.debug("Creating or updating entity map for %s", homekit_id) data = Pairing(config_num=config_num, accessories=accessories) self.storage_data[homekit_id] = data self._async_schedule_save() @@ -76,11 +79,17 @@ class EntityMapStorage: @callback def async_delete_map(self, homekit_id: str) -> None: """Delete pairing cache.""" - if homekit_id not in self.storage_data: - return - - self.storage_data.pop(homekit_id) - self._async_schedule_save() + removed_one = False + # Previously there was a bug where a lowercase homekit_id was stored + # in the storage. We need to account for that. + for hkid in (homekit_id, homekit_id.lower()): + if hkid not in self.storage_data: + continue + _LOGGER.debug("Deleting entity map for %s", hkid) + self.storage_data.pop(hkid) + removed_one = True + if removed_one: + self._async_schedule_save() @callback def _async_schedule_save(self) -> None: diff --git a/requirements_all.txt b/requirements_all.txt index 8a1ef4cd991..2893d0e943c 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -168,7 +168,7 @@ aioguardian==2022.07.0 aioharmony==0.2.9 # homeassistant.components.homekit_controller -aiohomekit==1.2.3 +aiohomekit==1.2.4 # homeassistant.components.emulated_hue # homeassistant.components.http diff --git a/requirements_test_all.txt b/requirements_test_all.txt index a67eb65f2e9..df4ee525846 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -152,7 +152,7 @@ aioguardian==2022.07.0 aioharmony==0.2.9 # homeassistant.components.homekit_controller -aiohomekit==1.2.3 +aiohomekit==1.2.4 # homeassistant.components.emulated_hue # homeassistant.components.http diff --git a/tests/components/homekit_controller/test_config_flow.py b/tests/components/homekit_controller/test_config_flow.py index 78d3c609a9c..e72d9452e52 100644 --- a/tests/components/homekit_controller/test_config_flow.py +++ b/tests/components/homekit_controller/test_config_flow.py @@ -14,6 +14,7 @@ from homeassistant import config_entries from homeassistant.components import zeroconf from homeassistant.components.homekit_controller import config_flow from homeassistant.components.homekit_controller.const import KNOWN_DEVICES +from homeassistant.components.homekit_controller.storage import async_get_entity_storage from homeassistant.data_entry_flow import ( RESULT_TYPE_ABORT, RESULT_TYPE_FORM, @@ -1071,6 +1072,8 @@ async def test_bluetooth_valid_device_discovery_paired(hass, controller): async def test_bluetooth_valid_device_discovery_unpaired(hass, controller): """Test bluetooth discovery with a homekit device and discovery works.""" setup_mock_accessory(controller) + storage = await async_get_entity_storage(hass) + with patch( "homeassistant.components.homekit_controller.config_flow.aiohomekit_const.BLE_TRANSPORT_SUPPORTED", True, @@ -1083,6 +1086,7 @@ async def test_bluetooth_valid_device_discovery_unpaired(hass, controller): assert result["type"] == RESULT_TYPE_FORM assert result["step_id"] == "pair" + assert storage.get_map("00:00:00:00:00:00") is None assert get_flow_context(hass, result) == { "source": config_entries.SOURCE_BLUETOOTH, @@ -1098,3 +1102,5 @@ async def test_bluetooth_valid_device_discovery_unpaired(hass, controller): assert result3["type"] == FlowResultType.CREATE_ENTRY assert result3["title"] == "Koogeek-LS1-20833F" assert result3["data"] == {} + + assert storage.get_map("00:00:00:00:00:00") is not None