Restore homekit_controller BLE broadcast_key from disk (#81211)

* Restore homekit_controller BLE broadcast_key from disk

Some accessories will sleep for a long time and only send broadcasted
events which makes them have very long connection intervals to save
battery. Since we need to connect to get a new broadcast key we now
save the broadcast key between restarts to ensure we can decrypt
the advertisments coming in even though we cannot make a connection
to the device during startup. When we get a disconnected event later
we will try again to connect and the device will be awake which will
trigger a full sync

* bump bump
This commit is contained in:
J. Nick Koston 2022-10-29 14:05:59 -05:00 committed by GitHub
parent 770aefbd52
commit 208150c353
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 16 additions and 20 deletions

View file

@ -15,7 +15,7 @@ from aiohomekit.controller.abstract import (
from aiohomekit.exceptions import AuthenticationError from aiohomekit.exceptions import AuthenticationError
from aiohomekit.model.categories import Categories from aiohomekit.model.categories import Categories
from aiohomekit.model.status_flags import StatusFlags from aiohomekit.model.status_flags import StatusFlags
from aiohomekit.utils import domain_supported, domain_to_name from aiohomekit.utils import domain_supported, domain_to_name, serialize_broadcast_key
import voluptuous as vol import voluptuous as vol
from homeassistant import config_entries from homeassistant import config_entries
@ -577,6 +577,7 @@ class HomekitControllerFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
pairing.id, pairing.id,
accessories_state.config_num, accessories_state.config_num,
accessories_state.accessories.serialize(), accessories_state.accessories.serialize(),
serialize_broadcast_key(accessories_state.broadcast_key),
) )
return self.async_create_entry(title=name, data=pairing_data) return self.async_create_entry(title=name, data=pairing_data)

View file

@ -3,7 +3,7 @@
"name": "HomeKit Controller", "name": "HomeKit Controller",
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/homekit_controller", "documentation": "https://www.home-assistant.io/integrations/homekit_controller",
"requirements": ["aiohomekit==2.2.7"], "requirements": ["aiohomekit==2.2.8"],
"zeroconf": ["_hap._tcp.local.", "_hap._udp.local."], "zeroconf": ["_hap._tcp.local.", "_hap._udp.local."],
"bluetooth": [{ "manufacturer_id": 76, "manufacturer_data_start": [6] }], "bluetooth": [{ "manufacturer_id": 76, "manufacturer_data_start": [6] }],
"dependencies": ["bluetooth", "zeroconf"], "dependencies": ["bluetooth", "zeroconf"],

View file

@ -3,7 +3,9 @@
from __future__ import annotations from __future__ import annotations
import logging import logging
from typing import Any, TypedDict from typing import Any
from aiohomekit.characteristic_cache import Pairing, StorageLayout
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.storage import Store from homeassistant.helpers.storage import Store
@ -16,19 +18,6 @@ ENTITY_MAP_SAVE_DELAY = 10
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
class Pairing(TypedDict):
"""A versioned map of entity metadata as presented by aiohomekit."""
config_num: int
accessories: list[Any]
class StorageLayout(TypedDict):
"""Cached pairing metadata needed by aiohomekit."""
pairings: dict[str, Pairing]
class EntityMapStorage: class EntityMapStorage:
""" """
Holds a cache of entity structure data from a paired HomeKit device. Holds a cache of entity structure data from a paired HomeKit device.
@ -67,11 +56,17 @@ class EntityMapStorage:
@callback @callback
def async_create_or_update_map( def async_create_or_update_map(
self, homekit_id: str, config_num: int, accessories: list[Any] self,
homekit_id: str,
config_num: int,
accessories: list[Any],
broadcast_key: str | None = None,
) -> Pairing: ) -> Pairing:
"""Create a new pairing cache.""" """Create a new pairing cache."""
_LOGGER.debug("Creating or updating entity map for %s", homekit_id) _LOGGER.debug("Creating or updating entity map for %s", homekit_id)
data = Pairing(config_num=config_num, accessories=accessories) data = Pairing(
config_num=config_num, accessories=accessories, broadcast_key=broadcast_key
)
self.storage_data[homekit_id] = data self.storage_data[homekit_id] = data
self._async_schedule_save() self._async_schedule_save()
return data return data

View file

@ -171,7 +171,7 @@ aioguardian==2022.07.0
aioharmony==0.2.9 aioharmony==0.2.9
# homeassistant.components.homekit_controller # homeassistant.components.homekit_controller
aiohomekit==2.2.7 aiohomekit==2.2.8
# homeassistant.components.emulated_hue # homeassistant.components.emulated_hue
# homeassistant.components.http # homeassistant.components.http

View file

@ -155,7 +155,7 @@ aioguardian==2022.07.0
aioharmony==0.2.9 aioharmony==0.2.9
# homeassistant.components.homekit_controller # homeassistant.components.homekit_controller
aiohomekit==2.2.7 aiohomekit==2.2.8
# homeassistant.components.emulated_hue # homeassistant.components.emulated_hue
# homeassistant.components.http # homeassistant.components.http