From d65119bbb35144b8af2a2c68ade4b5b538759f8a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 15 Jul 2023 06:38:42 -1000 Subject: [PATCH] Avoid writing state in homekit_controller for unrelated aid/iids (#96583) --- .../components/homekit_controller/connection.py | 2 +- .../components/homekit_controller/entity.py | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/homekit_controller/connection.py b/homeassistant/components/homekit_controller/connection.py index b937e7f2e0b..314db187b6a 100644 --- a/homeassistant/components/homekit_controller/connection.py +++ b/homeassistant/components/homekit_controller/connection.py @@ -768,7 +768,7 @@ class HKDevice: self.entity_map.process_changes(new_values_dict) - async_dispatcher_send(self.hass, self.signal_state_updated) + async_dispatcher_send(self.hass, self.signal_state_updated, new_values_dict) async def get_characteristics(self, *args: Any, **kwargs: Any) -> dict[str, Any]: """Read latest state from homekit accessory.""" diff --git a/homeassistant/components/homekit_controller/entity.py b/homeassistant/components/homekit_controller/entity.py index 6171e9406a0..5a687020eb6 100644 --- a/homeassistant/components/homekit_controller/entity.py +++ b/homeassistant/components/homekit_controller/entity.py @@ -11,6 +11,7 @@ from aiohomekit.model.characteristics import ( ) from aiohomekit.model.services import Service, ServicesTypes +from homeassistant.core import callback from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import DeviceInfo, Entity from homeassistant.helpers.typing import ConfigType @@ -30,6 +31,7 @@ class HomeKitEntity(Entity): self._aid = devinfo["aid"] self._iid = devinfo["iid"] self._char_name: str | None = None + self.all_characteristics: set[tuple[int, int]] = set() self.setup() super().__init__() @@ -51,13 +53,23 @@ class HomeKitEntity(Entity): """Return a Service model that this entity is attached to.""" return self.accessory.services.iid(self._iid) + @callback + def _async_state_changed( + self, new_values_dict: dict[tuple[int, int], dict[str, Any]] | None = None + ) -> None: + """Handle when characteristics change value.""" + if new_values_dict is None or self.all_characteristics.intersection( + new_values_dict + ): + self.async_write_ha_state() + async def async_added_to_hass(self) -> None: """Entity added to hass.""" self.async_on_remove( async_dispatcher_connect( self.hass, self._accessory.signal_state_updated, - self.async_write_ha_state, + self._async_state_changed, ) ) @@ -105,6 +117,9 @@ class HomeKitEntity(Entity): for char in service.characteristics.filter(char_types=char_types): self._setup_characteristic(char) + self.all_characteristics.update(self.pollable_characteristics) + self.all_characteristics.update(self.watchable_characteristics) + def _setup_characteristic(self, char: Characteristic) -> None: """Configure an entity based on a HomeKit characteristics metadata.""" # Build up a list of (aid, iid) tuples to poll on update()