Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run TimezoneFinder.timezone_at & imports in executor #8

Merged
merged 2 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
name: With hassfest
steps:
- name: 📥 Checkout the repository
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: 🏃 Hassfest validation
uses: "home-assistant/actions/hassfest@master"
Expand Down
7 changes: 4 additions & 3 deletions custom_components/entity_tz/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
17 changes: 9 additions & 8 deletions custom_components/entity_tz/helpers.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions custom_components/entity_tz/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
Expand Down