From ada781025b27c4a9ad7e32c4a80329381dd240f7 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 25 Mar 2024 00:28:26 -1000 Subject: [PATCH] Avoid homekit random id generation for existing entries (#114144) --- homeassistant/components/homekit/__init__.py | 3 +++ homeassistant/components/homekit/accessories.py | 5 ++++- homeassistant/components/homekit/const.py | 1 + tests/components/homekit/test_accessories.py | 5 ++++- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/homekit/__init__.py b/homeassistant/components/homekit/__init__.py index 7d1297e1307..51b3f5f376d 100644 --- a/homeassistant/components/homekit/__init__.py +++ b/homeassistant/components/homekit/__init__.py @@ -12,6 +12,7 @@ import socket from typing import Any, cast from aiohttp import web +from pyhap import util as pyhap_util from pyhap.characteristic import Characteristic from pyhap.const import STANDALONE_AID from pyhap.loader import get_loader @@ -580,6 +581,8 @@ class HomeKit: self.driver.load() return True + # If there is no persist file, we need to generate a mac + self.driver.state.mac = pyhap_util.generate_mac() return False async def async_reset_accessories(self, entity_ids: Iterable[str]) -> None: diff --git a/homeassistant/components/homekit/accessories.py b/homeassistant/components/homekit/accessories.py index f39bf32744a..63575189946 100644 --- a/homeassistant/components/homekit/accessories.py +++ b/homeassistant/components/homekit/accessories.py @@ -72,6 +72,7 @@ from .const import ( CONF_LINKED_BATTERY_SENSOR, CONF_LOW_BATTERY_THRESHOLD, DEFAULT_LOW_BATTERY_THRESHOLD, + EMPTY_MAC, EVENT_HOMEKIT_CHANGED, HK_CHARGING, HK_NOT_CHARGABLE, @@ -683,7 +684,9 @@ class HomeDriver(AccessoryDriver): # type: ignore[misc] **kwargs: Any, ) -> None: """Initialize a AccessoryDriver object.""" - super().__init__(**kwargs) + # Always set an empty mac of pyhap will incur + # the cost of generating a new one for every driver + super().__init__(**kwargs, mac=EMPTY_MAC) self.hass = hass self.entry_id = entry_id self._bridge_name = bridge_name diff --git a/homeassistant/components/homekit/const.py b/homeassistant/components/homekit/const.py index 5a7ee1d9576..149d2aedd67 100644 --- a/homeassistant/components/homekit/const.py +++ b/homeassistant/components/homekit/const.py @@ -10,6 +10,7 @@ PERSIST_LOCK_DATA = f"{DOMAIN}_persist_lock" HOMEKIT_FILE = ".homekit.state" SHUTDOWN_TIMEOUT = 30 CONF_ENTRY_INDEX = "index" +EMPTY_MAC = "00:00:00:00:00:00" # ### Codecs #### VIDEO_CODEC_COPY = "copy" diff --git a/tests/components/homekit/test_accessories.py b/tests/components/homekit/test_accessories.py index a148ab9f61c..5d8b940a7cd 100644 --- a/tests/components/homekit/test_accessories.py +++ b/tests/components/homekit/test_accessories.py @@ -28,6 +28,7 @@ from homeassistant.components.homekit.const import ( CONF_LINKED_BATTERY_CHARGING_SENSOR, CONF_LINKED_BATTERY_SENSOR, CONF_LOW_BATTERY_THRESHOLD, + EMPTY_MAC, MANUFACTURER, SERV_ACCESSORY_INFO, ) @@ -747,7 +748,9 @@ def test_home_driver(iid_storage) -> None: persist_file=path, ) - mock_driver.assert_called_with(address=ip_address, port=port, persist_file=path) + mock_driver.assert_called_with( + address=ip_address, port=port, persist_file=path, mac=EMPTY_MAC + ) driver.state = Mock(pincode=pin, paired=False) xhm_uri_mock = Mock(return_value="X-HM://0") driver.accessory = Mock(display_name="any", xhm_uri=xhm_uri_mock)