From 596c6ae6e9523b8ba4f235cc413a2919a3b493d8 Mon Sep 17 00:00:00 2001 From: Erik Date: Thu, 15 Feb 2024 19:58:30 +0100 Subject: [PATCH 1/2] Don't add fritz entities with update_before_add --- homeassistant/components/fritz/binary_sensor.py | 2 +- homeassistant/components/fritz/common.py | 9 +++++---- homeassistant/components/fritz/sensor.py | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/fritz/binary_sensor.py b/homeassistant/components/fritz/binary_sensor.py index 00e9f406ed4cb7..f703fadb4b85ce 100644 --- a/homeassistant/components/fritz/binary_sensor.py +++ b/homeassistant/components/fritz/binary_sensor.py @@ -68,7 +68,7 @@ async def async_setup_entry( if description.is_suitable(connection_info) ] - async_add_entities(entities, True) + async_add_entities(entities) class FritzBoxBinarySensor(FritzBoxBaseCoordinatorEntity, BinarySensorEntity): diff --git a/homeassistant/components/fritz/common.py b/homeassistant/components/fritz/common.py index c9acd60b23c6e8..caa00cd3cca9be 100644 --- a/homeassistant/components/fritz/common.py +++ b/homeassistant/components/fritz/common.py @@ -305,6 +305,10 @@ def unregister_entity_updates() -> None: if key not in self._entity_update_functions: _LOGGER.debug("register entity %s for updates", key) self._entity_update_functions[key] = update_fn + if self.fritz_status: + self.data["entity_states"][key] = update_fn( + self.fritz_status, self.data["entity_states"].get(key) + ) return unregister_entity_updates async def _async_update_data(self) -> UpdateCoordinatorDataType: @@ -317,10 +321,7 @@ async def _async_update_data(self) -> UpdateCoordinatorDataType: await self.async_scan_devices() for key in list(self._entity_update_functions): _LOGGER.debug("update entity %s", key) - entity_data["entity_states"][ - key - ] = await self.hass.async_add_executor_job( - self._entity_update_functions[key], + entity_data["entity_states"][key] = self._entity_update_functions[key]( self.fritz_status, self.data["entity_states"].get(key), ) diff --git a/homeassistant/components/fritz/sensor.py b/homeassistant/components/fritz/sensor.py index 53a299cd576745..980d86e2455ca0 100644 --- a/homeassistant/components/fritz/sensor.py +++ b/homeassistant/components/fritz/sensor.py @@ -298,7 +298,7 @@ async def async_setup_entry( if description.is_suitable(connection_info) ] - async_add_entities(entities, True) + async_add_entities(entities) class FritzBoxSensor(FritzBoxBaseCoordinatorEntity, SensorEntity): From a322e487898eb39a282134d55b05a0acc85afbc7 Mon Sep 17 00:00:00 2001 From: mib1185 Date: Thu, 15 Feb 2024 20:09:57 +0000 Subject: [PATCH 2/2] indeed `fritz_status` does i/o on every prperty access --- homeassistant/components/fritz/common.py | 29 ++++++++++++++++-------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/fritz/common.py b/homeassistant/components/fritz/common.py index caa00cd3cca9be..3d287b57384f34 100644 --- a/homeassistant/components/fritz/common.py +++ b/homeassistant/components/fritz/common.py @@ -291,7 +291,7 @@ def setup(self) -> None: self.has_call_deflections = "X_AVM-DE_OnTel1" in self.connection.services - def register_entity_updates( + async def async_register_entity_updates( self, key: str, update_fn: Callable[[FritzStatus, StateType], Any] ) -> Callable[[], None]: """Register an entity to be updated by coordinator.""" @@ -306,8 +306,10 @@ def unregister_entity_updates() -> None: _LOGGER.debug("register entity %s for updates", key) self._entity_update_functions[key] = update_fn if self.fritz_status: - self.data["entity_states"][key] = update_fn( - self.fritz_status, self.data["entity_states"].get(key) + self.data["entity_states"][ + key + ] = await self.hass.async_add_executor_job( + update_fn, self.fritz_status, self.data["entity_states"].get(key) ) return unregister_entity_updates @@ -321,7 +323,10 @@ async def _async_update_data(self) -> UpdateCoordinatorDataType: await self.async_scan_devices() for key in list(self._entity_update_functions): _LOGGER.debug("update entity %s", key) - entity_data["entity_states"][key] = self._entity_update_functions[key]( + entity_data["entity_states"][ + key + ] = await self.hass.async_add_executor_job( + self._entity_update_functions[key], self.fritz_status, self.data["entity_states"].get(key), ) @@ -1122,16 +1127,20 @@ def __init__( ) -> None: """Init device info class.""" super().__init__(avm_wrapper) - if description.value_fn is not None: - self.async_on_remove( - avm_wrapper.register_entity_updates( - description.key, description.value_fn - ) - ) self.entity_description = description self._device_name = device_name self._attr_unique_id = f"{avm_wrapper.unique_id}-{description.key}" + async def async_added_to_hass(self) -> None: + """When entity is added to hass.""" + await super().async_added_to_hass() + if self.entity_description.value_fn is not None: + self.async_on_remove( + await self.coordinator.async_register_entity_updates( + self.entity_description.key, self.entity_description.value_fn + ) + ) + @property def device_info(self) -> DeviceInfo: """Return the device information."""