Avoid writing HomeKit state to disk unless its missing (#111970)

This commit is contained in:
J. Nick Koston 2024-03-21 09:19:55 -10:00 committed by GitHub
parent d0708b5b32
commit 9a863638f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 6 deletions

View File

@ -550,8 +550,13 @@ class HomeKit:
self._reset_lock = asyncio.Lock()
self._cancel_reload_dispatcher: CALLBACK_TYPE | None = None
def setup(self, async_zeroconf_instance: AsyncZeroconf, uuid: str) -> None:
"""Set up bridge and accessory driver."""
def setup(self, async_zeroconf_instance: AsyncZeroconf, uuid: str) -> bool:
"""Set up bridge and accessory driver.
Returns True if data was loaded from disk
Returns False if the persistent data was not loaded
"""
assert self.iid_storage is not None
persist_file = get_persist_fullpath_for_entry_id(self.hass, self._entry_id)
self.driver = HomeDriver(
@ -573,6 +578,9 @@ class HomeKit:
# as pyhap uses a random one until state is restored
if os.path.exists(persist_file):
self.driver.load()
return True
return False
async def async_reset_accessories(self, entity_ids: Iterable[str]) -> None:
"""Reset the accessory to load the latest configuration."""
@ -842,7 +850,9 @@ class HomeKit:
# Avoid gather here since it will be I/O bound anyways
await self.aid_storage.async_initialize()
await self.iid_storage.async_initialize()
await self.hass.async_add_executor_job(self.setup, async_zc_instance, uuid)
loaded_from_disk = await self.hass.async_add_executor_job(
self.setup, async_zc_instance, uuid
)
assert self.driver is not None
if not await self._async_create_accessories():
@ -850,8 +860,12 @@ class HomeKit:
self._async_register_bridge()
_LOGGER.debug("Driver start for %s", self._name)
await self.driver.async_start()
async with self.hass.data[PERSIST_LOCK_DATA]:
await self.hass.async_add_executor_job(self.driver.persist)
if not loaded_from_disk:
# If the state was not loaded from disk, it means this is the
# first time the bridge is ever starting up. In this case, we
# need to make sure its persisted to disk.
async with self.hass.data[PERSIST_LOCK_DATA]:
await self.hass.async_add_executor_job(self.driver.persist)
self.status = STATUS_RUNNING
if self.driver.state.paired:

View File

@ -765,9 +765,16 @@ async def test_homekit_start(
f"{PATH_HOMEKIT}.async_show_setup_message"
) as mock_setup_msg, patch(
"pyhap.accessory_driver.AccessoryDriver.async_start"
) as hk_driver_start:
) as hk_driver_start, patch(
"pyhap.accessory_driver.AccessoryDriver.load"
) as load_mock, patch(
"pyhap.accessory_driver.AccessoryDriver.persist"
) as persist_mock, patch(f"{PATH_HOMEKIT}.os.path.exists", return_value=True):
await homekit.async_stop()
await homekit.async_start()
assert load_mock.called
assert not persist_mock.called
device = device_registry.async_get_device(
identifiers={(DOMAIN, entry.entry_id, BRIDGE_SERIAL_NUMBER)}
)