From ef2f816509ecafff6183b4fc057aea8c022eacf7 Mon Sep 17 00:00:00 2001 From: Matthew Flamm Date: Wed, 8 May 2024 12:00:15 -0400 Subject: [PATCH 1/6] avoid retry in setup --- homeassistant/components/nws/__init__.py | 84 ++++++++++++++++-------- 1 file changed, 56 insertions(+), 28 deletions(-) diff --git a/homeassistant/components/nws/__init__.py b/homeassistant/components/nws/__init__.py index 840d4d917f731d..ab729bdd088e36 100644 --- a/homeassistant/components/nws/__init__.py +++ b/homeassistant/components/nws/__init__.py @@ -2,6 +2,7 @@ from __future__ import annotations +from collections.abc import Awaitable, Callable from dataclasses import dataclass import datetime import logging @@ -58,36 +59,52 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: nws_data = SimpleNWS(latitude, longitude, api_key, client_session) await nws_data.set_station(station) - async def update_observation() -> None: - """Retrieve recent observations.""" - await call_with_retry( - nws_data.update_observation, - RETRY_INTERVAL, - RETRY_STOP, - start_time=utcnow() - UPDATE_TIME_PERIOD, - ) - - async def update_forecast() -> None: - """Retrieve twice-daily forecsat.""" - await call_with_retry( - nws_data.update_forecast, - RETRY_INTERVAL, - RETRY_STOP, - ) - - async def update_forecast_hourly() -> None: - """Retrieve hourly forecast.""" - await call_with_retry( - nws_data.update_forecast_hourly, - RETRY_INTERVAL, - RETRY_STOP, - ) - + def setup_update_observation( + retry_interval, retry_stop + ) -> Callable[[], Awaitable[None]]: + async def update_observation() -> None: + """Retrieve recent observations.""" + await call_with_retry( + nws_data.update_observation, + retry_interval, + retry_stop, + start_time=utcnow() - UPDATE_TIME_PERIOD, + ) + + return update_observation + + def setup_update_forecast( + retry_interval, retry_stop + ) -> Callable[[], Awaitable[None]]: + async def update_forecast() -> None: + """Retrieve twice-daily forecsat.""" + await call_with_retry( + nws_data.update_forecast, + retry_interval, + retry_stop, + ) + + return update_forecast + + def setup_update_forecast_hourly( + retry_interval, retry_stop + ) -> Callable[[], Awaitable[None]]: + async def update_forecast_hourly() -> None: + """Retrieve hourly forecast.""" + await call_with_retry( + nws_data.update_forecast_hourly, + retry_interval, + retry_stop, + ) + + return update_forecast_hourly + + # Don't use retries in setup coordinator_observation = TimestampDataUpdateCoordinator( hass, _LOGGER, name=f"NWS observation station {station}", - update_method=update_observation, + update_method=setup_update_observation(0, 0), update_interval=DEFAULT_SCAN_INTERVAL, request_refresh_debouncer=debounce.Debouncer( hass, _LOGGER, cooldown=DEBOUNCE_TIME, immediate=True @@ -98,7 +115,7 @@ async def update_forecast_hourly() -> None: hass, _LOGGER, name=f"NWS forecast station {station}", - update_method=update_forecast, + update_method=setup_update_forecast(0, 0), update_interval=DEFAULT_SCAN_INTERVAL, request_refresh_debouncer=debounce.Debouncer( hass, _LOGGER, cooldown=DEBOUNCE_TIME, immediate=True @@ -109,7 +126,7 @@ async def update_forecast_hourly() -> None: hass, _LOGGER, name=f"NWS forecast hourly station {station}", - update_method=update_forecast_hourly, + update_method=setup_update_forecast_hourly(0, 0), update_interval=DEFAULT_SCAN_INTERVAL, request_refresh_debouncer=debounce.Debouncer( hass, _LOGGER, cooldown=DEBOUNCE_TIME, immediate=True @@ -128,6 +145,17 @@ async def update_forecast_hourly() -> None: await coordinator_forecast.async_refresh() await coordinator_forecast_hourly.async_refresh() + # Use retries + coordinator_observation.update_method = setup_update_observation( + RETRY_INTERVAL, RETRY_STOP + ) + coordinator_forecast.update_method = setup_update_forecast( + RETRY_INTERVAL, RETRY_STOP + ) + coordinator_forecast_hourly.update_method = setup_update_forecast_hourly( + RETRY_INTERVAL, RETRY_STOP + ) + await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True From e48c642b12eaed8f6e169d9c8f3542b227b521c3 Mon Sep 17 00:00:00 2001 From: Matthew Flamm Date: Wed, 8 May 2024 12:03:03 -0400 Subject: [PATCH 2/6] more typing --- homeassistant/components/nws/__init__.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/nws/__init__.py b/homeassistant/components/nws/__init__.py index ab729bdd088e36..89b35ae1f5d5d9 100644 --- a/homeassistant/components/nws/__init__.py +++ b/homeassistant/components/nws/__init__.py @@ -60,7 +60,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: await nws_data.set_station(station) def setup_update_observation( - retry_interval, retry_stop + retry_interval: datetime.timedelta | float, + retry_stop: datetime.timedelta | float, ) -> Callable[[], Awaitable[None]]: async def update_observation() -> None: """Retrieve recent observations.""" @@ -74,7 +75,8 @@ async def update_observation() -> None: return update_observation def setup_update_forecast( - retry_interval, retry_stop + retry_interval: datetime.timedelta | float, + retry_stop: datetime.timedelta | float, ) -> Callable[[], Awaitable[None]]: async def update_forecast() -> None: """Retrieve twice-daily forecsat.""" @@ -87,7 +89,8 @@ async def update_forecast() -> None: return update_forecast def setup_update_forecast_hourly( - retry_interval, retry_stop + retry_interval: datetime.timedelta | float, + retry_stop: datetime.timedelta | float, ) -> Callable[[], Awaitable[None]]: async def update_forecast_hourly() -> None: """Retrieve hourly forecast.""" From e150fdc5d50a0ffae518dbbd364c1328f330f3c7 Mon Sep 17 00:00:00 2001 From: MatthewFlamm <39341281+MatthewFlamm@users.noreply.github.com> Date: Wed, 8 May 2024 12:14:55 -0400 Subject: [PATCH 3/6] Use async naming convention Co-authored-by: J. Nick Koston --- homeassistant/components/nws/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/nws/__init__.py b/homeassistant/components/nws/__init__.py index 89b35ae1f5d5d9..069e97478a4aab 100644 --- a/homeassistant/components/nws/__init__.py +++ b/homeassistant/components/nws/__init__.py @@ -59,7 +59,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: nws_data = SimpleNWS(latitude, longitude, api_key, client_session) await nws_data.set_station(station) - def setup_update_observation( + def async_setup_update_observation( retry_interval: datetime.timedelta | float, retry_stop: datetime.timedelta | float, ) -> Callable[[], Awaitable[None]]: From dc6e9a84c973aa42039f9c5a7b43236a141dbadd Mon Sep 17 00:00:00 2001 From: Matthew Flamm Date: Wed, 8 May 2024 12:17:10 -0400 Subject: [PATCH 4/6] more naming convention --- homeassistant/components/nws/__init__.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/nws/__init__.py b/homeassistant/components/nws/__init__.py index 069e97478a4aab..a4cdebcbe5e95d 100644 --- a/homeassistant/components/nws/__init__.py +++ b/homeassistant/components/nws/__init__.py @@ -74,7 +74,7 @@ async def update_observation() -> None: return update_observation - def setup_update_forecast( + def async_setup_update_forecast( retry_interval: datetime.timedelta | float, retry_stop: datetime.timedelta | float, ) -> Callable[[], Awaitable[None]]: @@ -88,7 +88,7 @@ async def update_forecast() -> None: return update_forecast - def setup_update_forecast_hourly( + def async_setup_update_forecast_hourly( retry_interval: datetime.timedelta | float, retry_stop: datetime.timedelta | float, ) -> Callable[[], Awaitable[None]]: @@ -107,7 +107,7 @@ async def update_forecast_hourly() -> None: hass, _LOGGER, name=f"NWS observation station {station}", - update_method=setup_update_observation(0, 0), + update_method=async_setup_update_observation(0, 0), update_interval=DEFAULT_SCAN_INTERVAL, request_refresh_debouncer=debounce.Debouncer( hass, _LOGGER, cooldown=DEBOUNCE_TIME, immediate=True @@ -118,7 +118,7 @@ async def update_forecast_hourly() -> None: hass, _LOGGER, name=f"NWS forecast station {station}", - update_method=setup_update_forecast(0, 0), + update_method=async_setup_update_forecast(0, 0), update_interval=DEFAULT_SCAN_INTERVAL, request_refresh_debouncer=debounce.Debouncer( hass, _LOGGER, cooldown=DEBOUNCE_TIME, immediate=True @@ -129,7 +129,7 @@ async def update_forecast_hourly() -> None: hass, _LOGGER, name=f"NWS forecast hourly station {station}", - update_method=setup_update_forecast_hourly(0, 0), + update_method=async_setup_update_forecast_hourly(0, 0), update_interval=DEFAULT_SCAN_INTERVAL, request_refresh_debouncer=debounce.Debouncer( hass, _LOGGER, cooldown=DEBOUNCE_TIME, immediate=True @@ -149,13 +149,13 @@ async def update_forecast_hourly() -> None: await coordinator_forecast_hourly.async_refresh() # Use retries - coordinator_observation.update_method = setup_update_observation( + coordinator_observation.update_method = async_setup_update_observation( RETRY_INTERVAL, RETRY_STOP ) - coordinator_forecast.update_method = setup_update_forecast( + coordinator_forecast.update_method = async_setup_update_forecast( RETRY_INTERVAL, RETRY_STOP ) - coordinator_forecast_hourly.update_method = setup_update_forecast_hourly( + coordinator_forecast_hourly.update_method = async_setup_update_forecast_hourly( RETRY_INTERVAL, RETRY_STOP ) From 4b4f423b72ccc98889a0c25465c0b4e9d86aee20 Mon Sep 17 00:00:00 2001 From: Matthew Flamm Date: Wed, 8 May 2024 13:12:20 -0400 Subject: [PATCH 5/6] use partial --- homeassistant/components/nws/__init__.py | 48 ++++++++++-------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/homeassistant/components/nws/__init__.py b/homeassistant/components/nws/__init__.py index a4cdebcbe5e95d..fa2ed4f4112424 100644 --- a/homeassistant/components/nws/__init__.py +++ b/homeassistant/components/nws/__init__.py @@ -5,6 +5,7 @@ from collections.abc import Awaitable, Callable from dataclasses import dataclass import datetime +from functools import partial import logging from pynws import SimpleNWS, call_with_retry @@ -63,44 +64,35 @@ def async_setup_update_observation( retry_interval: datetime.timedelta | float, retry_stop: datetime.timedelta | float, ) -> Callable[[], Awaitable[None]]: - async def update_observation() -> None: - """Retrieve recent observations.""" - await call_with_retry( - nws_data.update_observation, - retry_interval, - retry_stop, - start_time=utcnow() - UPDATE_TIME_PERIOD, - ) - - return update_observation + return partial( + call_with_retry, + nws_data.update_observation, + retry_interval, + retry_stop, + start_time=utcnow() - UPDATE_TIME_PERIOD, + ) def async_setup_update_forecast( retry_interval: datetime.timedelta | float, retry_stop: datetime.timedelta | float, ) -> Callable[[], Awaitable[None]]: - async def update_forecast() -> None: - """Retrieve twice-daily forecsat.""" - await call_with_retry( - nws_data.update_forecast, - retry_interval, - retry_stop, - ) - - return update_forecast + return partial( + call_with_retry, + nws_data.update_forecast, + retry_interval, + retry_stop, + ) def async_setup_update_forecast_hourly( retry_interval: datetime.timedelta | float, retry_stop: datetime.timedelta | float, ) -> Callable[[], Awaitable[None]]: - async def update_forecast_hourly() -> None: - """Retrieve hourly forecast.""" - await call_with_retry( - nws_data.update_forecast_hourly, - retry_interval, - retry_stop, - ) - - return update_forecast_hourly + return partial( + call_with_retry, + nws_data.update_forecast_hourly, + retry_interval, + retry_stop, + ) # Don't use retries in setup coordinator_observation = TimestampDataUpdateCoordinator( From f6f743d46383c735133988af21d93062754ad617 Mon Sep 17 00:00:00 2001 From: Matthew Flamm Date: Wed, 8 May 2024 13:18:18 -0400 Subject: [PATCH 6/6] revert changes for observation --- homeassistant/components/nws/__init__.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/nws/__init__.py b/homeassistant/components/nws/__init__.py index fa2ed4f4112424..df8cb4c329c2ac 100644 --- a/homeassistant/components/nws/__init__.py +++ b/homeassistant/components/nws/__init__.py @@ -64,13 +64,16 @@ def async_setup_update_observation( retry_interval: datetime.timedelta | float, retry_stop: datetime.timedelta | float, ) -> Callable[[], Awaitable[None]]: - return partial( - call_with_retry, - nws_data.update_observation, - retry_interval, - retry_stop, - start_time=utcnow() - UPDATE_TIME_PERIOD, - ) + async def update_observation() -> None: + """Retrieve recent observations.""" + await call_with_retry( + nws_data.update_observation, + retry_interval, + retry_stop, + start_time=utcnow() - UPDATE_TIME_PERIOD, + ) + + return update_observation def async_setup_update_forecast( retry_interval: datetime.timedelta | float,