diff --git a/custom_components/irm_kmi/const.py b/custom_components/irm_kmi/const.py index 9b26ec6..d1fa951 100644 --- a/custom_components/irm_kmi/const.py +++ b/custom_components/irm_kmi/const.py @@ -155,3 +155,5 @@ 'de': 'Königliche Meteorologische Institut von Belgien', 'en': 'Royal Meteorological Institute of Belgium' } + +WEEKDAYS = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] diff --git a/custom_components/irm_kmi/coordinator.py b/custom_components/irm_kmi/coordinator.py index 6854a14..1d96d0e 100644 --- a/custom_components/irm_kmi/coordinator.py +++ b/custom_components/irm_kmi/coordinator.py @@ -19,7 +19,7 @@ from homeassistant.util.dt import utcnow from .api import IrmKmiApiClient, IrmKmiApiError -from .const import CONF_DARK_MODE, CONF_STYLE, DOMAIN, IRM_KMI_NAME +from .const import CONF_DARK_MODE, CONF_STYLE, DOMAIN, IRM_KMI_NAME, WEEKDAYS from .const import IRM_KMI_TO_HA_CONDITION_MAP as CDT_MAP from .const import MAP_WARNING_ID_TO_SLUG as SLUG_MAP from .const import OPTION_STYLE_SATELLITE, OUT_OF_BENELUX, STYLE_TO_PARAM_MAP @@ -28,7 +28,7 @@ RadarAnimationData, WarningData) from .pollen import PollenParser from .rain_graph import RainGraph -from .utils import disable_from_config, get_config_value, preferred_language +from .utils import disable_from_config, get_config_value, preferred_language, next_weekday _LOGGER = logging.getLogger(__name__) @@ -356,10 +356,9 @@ async def daily_list_to_forecast(self, data: List[dict] | None) -> List[Forecast return None forecasts = list() - n_days = 0 lang = preferred_language(self.hass, self._config_entry) tz = await dt.async_get_time_zone('Europe/Brussels') - now = dt.now(tz) + forecast_day = dt.now(tz) for (idx, f) in enumerate(data): precipitation = None @@ -384,9 +383,12 @@ async def daily_list_to_forecast(self, data: List[dict] | None) -> List[Forecast pass is_daytime = f.get('dayNight', None) == 'd' + day_name = f.get('dayName', {}).get('en', None) + if day_name in WEEKDAYS: + forecast_day = next_weekday(forecast_day, WEEKDAYS.index(day_name)) + forecast = IrmKmiForecast( - datetime=(now + timedelta(days=n_days)).strftime('%Y-%m-%d') if is_daytime else now.strftime( - '%Y-%m-%d'), + datetime=(forecast_day.strftime('%Y-%m-%d')), condition=CDT_MAP.get((f.get('ww1', None), f.get('dayNight', None)), None), native_precipitation=precipitation, native_temperature=f.get('tempMax', None), @@ -406,8 +408,6 @@ async def daily_list_to_forecast(self, data: List[dict] | None) -> List[Forecast (forecast['native_temperature'], forecast['native_templow']) forecasts.append(forecast) - if is_daytime or idx == 0: - n_days += 1 return forecasts diff --git a/custom_components/irm_kmi/utils.py b/custom_components/irm_kmi/utils.py index e9bb7af..d735e63 100644 --- a/custom_components/irm_kmi/utils.py +++ b/custom_components/irm_kmi/utils.py @@ -1,4 +1,5 @@ import logging +from datetime import timedelta from typing import Any from homeassistant.config_entries import ConfigEntry @@ -38,3 +39,10 @@ def preferred_language(hass: HomeAssistant, config_entry: ConfigEntry) -> str: return hass.config.language if hass.config.language in LANGS else 'en' return get_config_value(config_entry, CONF_LANGUAGE_OVERRIDE) + + +def next_weekday(current, weekday): + days_ahead = weekday - current.weekday() + if days_ahead < 0: + days_ahead += 7 + return current + timedelta(days_ahead) diff --git a/tests/test_coordinator.py b/tests/test_coordinator.py index df0f746..8571609 100644 --- a/tests/test_coordinator.py +++ b/tests/test_coordinator.py @@ -86,7 +86,7 @@ async def test_current_weather_nl() -> None: assert expected == result -@freeze_time(datetime.fromisoformat('2023-12-26T18:30:00.028724')) +@freeze_time(datetime.fromisoformat('2023-12-26T18:30:00+01:00')) async def test_daily_forecast( hass: HomeAssistant, mock_config_entry: MockConfigEntry @@ -99,6 +99,8 @@ async def test_daily_forecast( assert isinstance(result, list) assert len(result) == 8 + assert result[0]['datetime'] == '2023-12-26' + assert not result[0]['is_daytime'] expected = IrmKmiForecast( datetime='2023-12-27', @@ -193,6 +195,29 @@ async def test_hourly_forecast_midnight_bug() -> None: assert result[24]['datetime'] == '2024-06-01T00:00:00+02:00' +@freeze_time(datetime.fromisoformat('2024-05-31T00:10:00+02:00')) +async def test_daily_forecast_midnight_bug( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry +) -> None: + coordinator = IrmKmiCoordinator(hass, mock_config_entry) + + api_data = get_api_data("midnight-bug-31-05-2024T00-13.json").get('for', {}).get('daily') + result = await coordinator.daily_list_to_forecast(api_data) + + assert result[0]['datetime'] == '2024-05-31' + assert not result[0]['is_daytime'] + + assert result[1]['datetime'] == '2024-05-31' + assert result[1]['is_daytime'] + + assert result[2]['datetime'] == '2024-06-01' + assert result[2]['is_daytime'] + + assert result[3]['datetime'] == '2024-06-02' + assert result[3]['is_daytime'] + + async def test_refresh_succeed_even_when_pollen_and_radar_fail( hass: HomeAssistant, mock_config_entry: MockConfigEntry,