From 5f53d16ce2022fdea169b3d8e5dde2b5505e4195 Mon Sep 17 00:00:00 2001 From: Jules Dejaeghere Date: Sun, 23 Jun 2024 12:43:45 +0200 Subject: [PATCH 1/2] Fix daily forecast sunset sunrise type Fix #49 --- custom_components/irm_kmi/coordinator.py | 4 ++-- custom_components/irm_kmi/data.py | 4 ++-- custom_components/irm_kmi/sensor.py | 9 +++++---- tests/test_coordinator.py | 21 ++++++++++----------- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/custom_components/irm_kmi/coordinator.py b/custom_components/irm_kmi/coordinator.py index b433c3a..39e576f 100644 --- a/custom_components/irm_kmi/coordinator.py +++ b/custom_components/irm_kmi/coordinator.py @@ -440,8 +440,8 @@ class IrmKmiCoordinator(TimestampDataUpdateCoordinator): wind_bearing=wind_bearing, is_daytime=is_daytime, text=f.get('text', {}).get(lang, ""), - sunrise=sunrise, - sunset=sunset + sunrise=sunrise.isoformat() if sunrise is not None else None, + sunset=sunset.isoformat() if sunset is not None else None ) # Swap temperature and templow if needed if (forecast['native_templow'] is not None diff --git a/custom_components/irm_kmi/data.py b/custom_components/irm_kmi/data.py index 566155f..ea7d32d 100644 --- a/custom_components/irm_kmi/data.py +++ b/custom_components/irm_kmi/data.py @@ -10,8 +10,8 @@ class IrmKmiForecast(Forecast): # TODO: add condition_2 as well and evolution to match data from the API? text: str | None - sunrise: datetime | None - sunset: datetime | None + sunrise: str | None + sunset: str | None class IrmKmiRadarForecast(Forecast): diff --git a/custom_components/irm_kmi/sensor.py b/custom_components/irm_kmi/sensor.py index 577ea2a..64aaf0f 100644 --- a/custom_components/irm_kmi/sensor.py +++ b/custom_components/irm_kmi/sensor.py @@ -1,5 +1,5 @@ """Sensor for pollen from the IRM KMI""" -import datetime +from datetime import datetime import logging from homeassistant.components import sensor @@ -74,7 +74,7 @@ class IrmKmiNextWarning(CoordinatorEntity, SensorEntity): self._attr_translation_key = f"next_warning" @property - def native_value(self) -> datetime.datetime | None: + def native_value(self) -> datetime | None: """Return the timestamp for the start of the next warning. Is None when no future warning are available""" if self.coordinator.data.get('warnings') is None: return None @@ -124,12 +124,13 @@ class IrmKmiNextSunMove(CoordinatorEntity, SensorEntity): self._attr_icon = 'mdi:weather-sunset-down' if move == 'sunset' else 'mdi:weather-sunset-up' @property - def native_value(self) -> datetime.datetime | None: + def native_value(self) -> datetime | None: """Return the timestamp for the next sunrise or sunset""" now = dt.now() data: list[IrmKmiForecast] = self.coordinator.data.get('daily_forecast') - upcoming = [f.get(self._move) for f in data if f.get(self._move) >= now] + upcoming = [datetime.fromisoformat(f.get(self._move)) for f in data + if f.get(self._move) is not None and datetime.fromisoformat(f.get(self._move)) >= now] if len(upcoming) > 0: return upcoming[0] diff --git a/tests/test_coordinator.py b/tests/test_coordinator.py index dd6704b..95fa4d9 100644 --- a/tests/test_coordinator.py +++ b/tests/test_coordinator.py @@ -102,7 +102,6 @@ async def test_daily_forecast( assert len(result) == 8 assert result[0]['datetime'] == '2023-12-26' assert not result[0]['is_daytime'] - tz = zoneinfo.ZoneInfo(key='Europe/Brussels') expected = IrmKmiForecast( datetime='2023-12-27', condition=ATTR_CONDITION_PARTLYCLOUDY, @@ -115,8 +114,8 @@ async def test_daily_forecast( wind_bearing=180, is_daytime=True, text='Bar', - sunrise=datetime.fromisoformat("2023-12-27T08:44:00+01:00").astimezone(tz), - sunset=datetime.fromisoformat("2023-12-27T16:43:00+01:00").astimezone(tz) + sunrise="2023-12-27T08:44:00+01:00", + sunset="2023-12-27T16:43:00+01:00" ) assert result[1] == expected @@ -365,14 +364,14 @@ async def test_sunrise_sunset_nl( coordinator = IrmKmiCoordinator(hass, mock_config_entry) result = await coordinator.daily_list_to_forecast(api_data) - assert result[0]['sunrise'].isoformat() == '2024-06-09T05:19:28+02:00' - assert result[0]['sunset'].isoformat() == '2024-06-09T22:01:09+02:00' + assert result[0]['sunrise'] == '2024-06-09T05:19:28+02:00' + assert result[0]['sunset'] == '2024-06-09T22:01:09+02:00' assert result[1]['sunrise'] is None assert result[1]['sunset'] is None - assert result[2]['sunrise'].isoformat() == '2024-06-10T05:19:08+02:00' - assert result[2]['sunset'].isoformat() == '2024-06-10T22:01:53+02:00' + assert result[2]['sunrise'] == '2024-06-10T05:19:08+02:00' + assert result[2]['sunset'] == '2024-06-10T22:01:53+02:00' @freeze_time("2023-12-26T18:30:00+01:00") @@ -385,8 +384,8 @@ async def test_sunrise_sunset_be( coordinator = IrmKmiCoordinator(hass, mock_config_entry) result = await coordinator.daily_list_to_forecast(api_data) - assert result[1]['sunrise'].isoformat() == '2023-12-27T08:44:00+01:00' - assert result[1]['sunset'].isoformat() == '2023-12-27T16:43:00+01:00' + assert result[1]['sunrise'] == '2023-12-27T08:44:00+01:00' + assert result[1]['sunset'] == '2023-12-27T16:43:00+01:00' - assert result[2]['sunrise'].isoformat() == '2023-12-28T08:45:00+01:00' - assert result[2]['sunset'].isoformat() == '2023-12-28T16:43:00+01:00' + assert result[2]['sunrise'] == '2023-12-28T08:45:00+01:00' + assert result[2]['sunset'] == '2023-12-28T16:43:00+01:00' From 62e9e5fb9feb6803f3cee3977f08f945f46979c5 Mon Sep 17 00:00:00 2001 From: Jules Dejaeghere Date: Sun, 23 Jun 2024 13:40:50 +0200 Subject: [PATCH 2/2] Fix edge case in current weather --- custom_components/irm_kmi/coordinator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/irm_kmi/coordinator.py b/custom_components/irm_kmi/coordinator.py index 39e576f..ba9eb55 100644 --- a/custom_components/irm_kmi/coordinator.py +++ b/custom_components/irm_kmi/coordinator.py @@ -212,7 +212,7 @@ class IrmKmiCoordinator(TimestampDataUpdateCoordinator): or not isinstance(hourly_forecast_data, list) or len(hourly_forecast_data) == 0): - for current in hourly_forecast_data[:2]: + for current in hourly_forecast_data[:4]: if now.strftime('%H') == current['hour']: now_hourly = current break @@ -278,7 +278,7 @@ class IrmKmiCoordinator(TimestampDataUpdateCoordinator): if current_weather['condition'] is None: try: current_weather['condition'] = CDT_MAP.get((int(now_hourly.get('ww')), now_hourly.get('dayNight'))) - except (TypeError, ValueError): + except (TypeError, ValueError, AttributeError): current_weather['condition'] = None return current_weather