From 25b78ae87872c7c1f4bc9657a6674cbe7a2138dd Mon Sep 17 00:00:00 2001 From: Phil Bruckner Date: Thu, 29 Feb 2024 10:24:23 -0600 Subject: [PATCH] Call TimezoneFinder.timezone_at in executor Add import_executor to manifest.json. --- custom_components/entity_tz/__init__.py | 7 ++++--- custom_components/entity_tz/helpers.py | 17 +++++++++-------- custom_components/entity_tz/manifest.json | 1 + 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/custom_components/entity_tz/__init__.py b/custom_components/entity_tz/__init__.py index 36bddf4..74e14d1 100644 --- a/custom_components/entity_tz/__init__.py +++ b/custom_components/entity_tz/__init__.py @@ -63,8 +63,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: etzd.tz_users[entry.entry_id] = 0 loc_cache_size = len(etzd.loc_users) * LOC_CACHE_PER_CONFIG - _get_location._LRUCacheWrapper__maxsize = max( # type: ignore[attr-defined] # pylint: disable=protected-access - _get_location._LRUCacheWrapper__maxsize, loc_cache_size # type: ignore[attr-defined] # pylint: disable=protected-access + _get_location._LRUCacheWrapper__maxsize = max( # pylint: disable=protected-access + _get_location._LRUCacheWrapper__maxsize, # pylint: disable=protected-access + loc_cache_size, ) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) @@ -98,7 +99,7 @@ async def update_from_entity(event: Event | None = None) -> None: else: entity_loc = None if etzd.tz_users[entry.entry_id]: - entity_tz = get_tz(hass, new_state) + entity_tz = await get_tz(hass, new_state) else: entity_tz = None async_dispatcher_send(hass, signal(entry), entity_loc, entity_tz) diff --git a/custom_components/entity_tz/helpers.py b/custom_components/entity_tz/helpers.py index 2e85fd2..d62132f 100644 --- a/custom_components/entity_tz/helpers.py +++ b/custom_components/entity_tz/helpers.py @@ -1,7 +1,6 @@ """Entity Time Zone Sensor Helpers.""" from __future__ import annotations -import asyncio from collections.abc import Container, Mapping from dataclasses import dataclass from datetime import tzinfo @@ -77,13 +76,16 @@ def etz_data(hass: HomeAssistant) -> ETZData: @lru_cache def _get_tz_from_loc(tzf: TimezoneFinder, lat: float, lng: float) -> tzinfo | None: - """Get time zone from a location.""" + """Get time zone from a location. + + This must be run in an executor since timezone_at may do file I/O. + """ if (tz_name := tzf.timezone_at(lat=lat, lng=lng)) is None: return None return dt_util.get_time_zone(tz_name) -def get_tz(hass: HomeAssistant, state: State | None) -> tzinfo | str | None: +async def get_tz(hass: HomeAssistant, state: State | None) -> tzinfo | str | None: """Get time zone from entity state.""" if not state: return STATE_UNAVAILABLE @@ -93,7 +95,9 @@ def get_tz(hass: HomeAssistant, state: State | None) -> tzinfo | str | None: lng = state.attributes.get(ATTR_LONGITUDE) if lat is None or lng is None: return STATE_UNAVAILABLE - tz = _get_tz_from_loc(etz_data(hass).tzf, round(lat, 4), round(lng, 4)) + tz = await hass.async_add_executor_job( + _get_tz_from_loc, etz_data(hass).tzf, round(lat, 4), round(lng, 4) + ) _LOGGER.debug("Time zone cache: %s", _get_tz_from_loc.cache_info()) return tz @@ -128,11 +132,8 @@ async def update_zones(event: Event | None = None) -> None: zones = [] for state in hass.states.async_all(ZONE_DOMAIN): - if not_ha_tz(get_tz(hass, state)): + if not_ha_tz(await get_tz(hass, state)): zones.append(state.entity_id) - # get_tz, since it might call timezone_at, can take a while, so give other - # tasks a chance to run. - await asyncio.sleep(0) etzd.zones = zones @callback diff --git a/custom_components/entity_tz/manifest.json b/custom_components/entity_tz/manifest.json index e8eebe3..a46ecb6 100644 --- a/custom_components/entity_tz/manifest.json +++ b/custom_components/entity_tz/manifest.json @@ -5,6 +5,7 @@ "config_flow": true, "dependencies": ["zone"], "documentation": "https://github.com/pnbruckner/ha-entity-tz/blob/1.1.0/README.md", + "import_executor": true, "iot_class": "calculated", "issue_tracker": "https://github.com/pnbruckner/ha-entity-tz/issues", "loggers": ["geopy"],