mirror of
https://github.com/jdejaegh/irm-kmi-ha.git
synced 2025-06-27 03:35:56 +02:00
Fetch sunrise and sunset time for daily forecast
This commit is contained in:
parent
48ad275cf9
commit
0059b2f78f
3 changed files with 75 additions and 7 deletions
|
@ -19,16 +19,18 @@ from homeassistant.util import dt
|
|||
from homeassistant.util.dt import utcnow
|
||||
|
||||
from .api import IrmKmiApiClient, IrmKmiApiError
|
||||
from .const import CONF_DARK_MODE, CONF_STYLE, DOMAIN, IRM_KMI_NAME, WEEKDAYS
|
||||
from .const import CONF_DARK_MODE, CONF_STYLE, DOMAIN, IRM_KMI_NAME
|
||||
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
|
||||
from .const import (OPTION_STYLE_SATELLITE, OUT_OF_BENELUX, STYLE_TO_PARAM_MAP,
|
||||
WEEKDAYS)
|
||||
from .data import (AnimationFrameData, CurrentWeatherData, IrmKmiForecast,
|
||||
IrmKmiRadarForecast, ProcessedCoordinatorData,
|
||||
RadarAnimationData, WarningData)
|
||||
from .pollen import PollenParser
|
||||
from .rain_graph import RainGraph
|
||||
from .utils import disable_from_config, get_config_value, preferred_language, next_weekday
|
||||
from .utils import (disable_from_config, get_config_value, next_weekday,
|
||||
preferred_language)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -351,14 +353,14 @@ class IrmKmiCoordinator(TimestampDataUpdateCoordinator):
|
|||
IrmKmiRadarForecast(
|
||||
datetime=f.get("time"),
|
||||
native_precipitation=f.get('value'),
|
||||
rain_forecast_max=round(f.get('positionHigher')*ratio, 2),
|
||||
rain_forecast_min=round(f.get('positionLower')*ratio, 2),
|
||||
rain_forecast_max=round(f.get('positionHigher') * ratio, 2),
|
||||
rain_forecast_min=round(f.get('positionLower') * ratio, 2),
|
||||
might_rain=f.get('positionHigher') > 0
|
||||
)
|
||||
)
|
||||
return forecast
|
||||
|
||||
async def daily_list_to_forecast(self, data: List[dict] | None) -> List[Forecast] | None:
|
||||
async def daily_list_to_forecast(self, data: List[dict] | None) -> List[IrmKmiForecast] | None:
|
||||
"""Parse data from the API to create a list of daily forecasts"""
|
||||
if data is None or not isinstance(data, list) or len(data) == 0:
|
||||
return None
|
||||
|
@ -403,6 +405,28 @@ class IrmKmiCoordinator(TimestampDataUpdateCoordinator):
|
|||
elif day_name == 'Tomorrow':
|
||||
forecast_day = dt.now(tz) + timedelta(days=1)
|
||||
|
||||
sunrise_sec = f.get('dawnRiseSeconds', None)
|
||||
if sunrise_sec is None:
|
||||
sunrise_sec = f.get('sunRise', None)
|
||||
sunrise = None
|
||||
if sunrise_sec is not None:
|
||||
try:
|
||||
sunrise = (forecast_day.replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=tz)
|
||||
+ timedelta(seconds=float(sunrise_sec)))
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
|
||||
sunset_sec = f.get('dawnSetSeconds', None)
|
||||
if sunset_sec is None:
|
||||
sunset_sec = f.get('sunSet', None)
|
||||
sunset = None
|
||||
if sunset_sec is not None:
|
||||
try:
|
||||
sunset = (forecast_day.replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=tz)
|
||||
+ timedelta(seconds=float(sunset_sec)))
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
|
||||
forecast = IrmKmiForecast(
|
||||
datetime=(forecast_day.strftime('%Y-%m-%d')),
|
||||
condition=CDT_MAP.get((f.get('ww1', None), f.get('dayNight', None)), None),
|
||||
|
@ -415,6 +439,8 @@ class IrmKmiCoordinator(TimestampDataUpdateCoordinator):
|
|||
wind_bearing=wind_bearing,
|
||||
is_daytime=is_daytime,
|
||||
text=f.get('text', {}).get(lang, ""),
|
||||
sunrise=sunrise,
|
||||
sunset=sunset
|
||||
)
|
||||
# Swap temperature and templow if needed
|
||||
if (forecast['native_templow'] is not None
|
||||
|
|
|
@ -10,6 +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
|
||||
|
||||
|
||||
class IrmKmiRadarForecast(Forecast):
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import zoneinfo
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from freezegun import freeze_time
|
||||
|
@ -101,7 +102,7 @@ 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,
|
||||
|
@ -114,6 +115,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)
|
||||
)
|
||||
|
||||
assert result[1] == expected
|
||||
|
@ -350,3 +353,40 @@ async def test_current_condition_forecast_nl() -> None:
|
|||
uv_index=6
|
||||
)
|
||||
assert result == expected
|
||||
|
||||
|
||||
@freeze_time("2024-06-09T13:40:00+00:00")
|
||||
async def test_sunrise_sunset_nl(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry
|
||||
) -> None:
|
||||
api_data = get_api_data("forecast_ams_no_ww.json").get('for', {}).get('daily')
|
||||
|
||||
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[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'
|
||||
|
||||
|
||||
@freeze_time("2023-12-26T18:30:00+01:00")
|
||||
async def test_sunrise_sunset_be(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry
|
||||
) -> None:
|
||||
api_data = get_api_data("forecast.json").get('for', {}).get('daily')
|
||||
|
||||
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[2]['sunrise'].isoformat() == '2023-12-28T08:45:00+01:00'
|
||||
assert result[2]['sunset'].isoformat() == '2023-12-28T16:43:00+01:00'
|
||||
|
|
Loading…
Add table
Reference in a new issue