mirror of
https://github.com/jdejaegh/irm-kmi-ha.git
synced 2025-06-27 11:39:26 +02:00
Add daily forecast
This commit is contained in:
parent
7e15ba34f6
commit
1c50c78f7a
2 changed files with 53 additions and 9 deletions
|
@ -2,9 +2,11 @@
|
||||||
|
|
||||||
from datetime import timedelta, datetime
|
from datetime import timedelta, datetime
|
||||||
import logging
|
import logging
|
||||||
|
from typing import List
|
||||||
|
|
||||||
import async_timeout
|
import async_timeout
|
||||||
|
|
||||||
|
from homeassistant.components.weather import Forecast
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
from homeassistant.helpers.update_coordinator import (
|
from homeassistant.helpers.update_coordinator import (
|
||||||
DataUpdateCoordinator,
|
DataUpdateCoordinator,
|
||||||
|
@ -17,6 +19,40 @@ from .api import IrmKmiApiClient, IrmKmiApiError
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def daily_dict_to_forecast(data: List[dict] | None) -> List[Forecast] | None:
|
||||||
|
if data is None or not isinstance(data, list) or len(data) == 0:
|
||||||
|
return None
|
||||||
|
|
||||||
|
forecasts = list()
|
||||||
|
n_days = 0
|
||||||
|
|
||||||
|
for f in data:
|
||||||
|
precipitation = None
|
||||||
|
if f.get('precipQuantity', None) is not None:
|
||||||
|
precipitation = float(f.get('precipQuantity'))
|
||||||
|
|
||||||
|
is_daytime = f.get('dayNight', None) == 'd'
|
||||||
|
|
||||||
|
forecast = Forecast(
|
||||||
|
datetime=(datetime.now() + timedelta(days=n_days)).strftime('%Y-%m-%d')
|
||||||
|
if is_daytime else datetime.now().strftime('%Y-%m-%d'),
|
||||||
|
condition=CDT_MAP.get((f.get('ww1'), f.get('dayNight')), None),
|
||||||
|
native_precipitation=precipitation,
|
||||||
|
native_temperature=f.get('tempMax', None),
|
||||||
|
native_templow=f.get('tempMin', None),
|
||||||
|
native_wind_gust_speed=f.get('wind', {}).get('peakSpeed'),
|
||||||
|
native_wind_speed=f.get('wind', {}).get('speed'),
|
||||||
|
precipitation_probability=f.get('precipChance', None),
|
||||||
|
wind_bearing=f.get('wind', {}).get('dirText', {}).get('en'),
|
||||||
|
is_daytime=is_daytime,
|
||||||
|
)
|
||||||
|
forecasts.append(forecast)
|
||||||
|
if is_daytime:
|
||||||
|
n_days += 1
|
||||||
|
|
||||||
|
return forecasts
|
||||||
|
|
||||||
|
|
||||||
class IrmKmiCoordinator(DataUpdateCoordinator):
|
class IrmKmiCoordinator(DataUpdateCoordinator):
|
||||||
"""Coordinator to update data from IRM KMI"""
|
"""Coordinator to update data from IRM KMI"""
|
||||||
|
|
||||||
|
@ -43,9 +79,6 @@ class IrmKmiCoordinator(DataUpdateCoordinator):
|
||||||
# Note: asyncio.TimeoutError and aiohttp.ClientError are already
|
# Note: asyncio.TimeoutError and aiohttp.ClientError are already
|
||||||
# handled by the data update coordinator.
|
# handled by the data update coordinator.
|
||||||
async with async_timeout.timeout(10):
|
async with async_timeout.timeout(10):
|
||||||
# Grab active context variables to limit data required to be fetched from API
|
|
||||||
# Note: using context is not required if there is no need or ability to limit
|
|
||||||
# data retrieved from API.
|
|
||||||
api_data = await self._api_client.get_forecasts_coord(self._coord)
|
api_data = await self._api_client.get_forecasts_coord(self._coord)
|
||||||
_LOGGER.debug(f"Observation for {api_data.get('cityName', '')}: {api_data.get('obs', '{}')}")
|
_LOGGER.debug(f"Observation for {api_data.get('cityName', '')}: {api_data.get('obs', '{}')}")
|
||||||
|
|
||||||
|
@ -75,14 +108,11 @@ class IrmKmiCoordinator(DataUpdateCoordinator):
|
||||||
'temperature': api_data.get('obs', {}).get('temp'),
|
'temperature': api_data.get('obs', {}).get('temp'),
|
||||||
'wind_speed': now_hourly.get('windSpeedKm', None) if now_hourly is not None else None,
|
'wind_speed': now_hourly.get('windSpeedKm', None) if now_hourly is not None else None,
|
||||||
'wind_gust_speed': now_hourly.get('windPeakSpeedKm', None) if now_hourly is not None else None,
|
'wind_gust_speed': now_hourly.get('windPeakSpeedKm', None) if now_hourly is not None else None,
|
||||||
'wind_bearing': now_hourly.get('windDirection', None) if now_hourly is not None else None,
|
'wind_bearing': now_hourly.get('windDirectionText', {}).get('en') if now_hourly is not None else None,
|
||||||
'pressure': now_hourly.get('pressure', None) if now_hourly is not None else None,
|
'pressure': now_hourly.get('pressure', None) if now_hourly is not None else None,
|
||||||
'uv_index': uv_index
|
'uv_index': uv_index
|
||||||
},
|
},
|
||||||
|
'daily_forecast': daily_dict_to_forecast(api_data.get('for', {}).get('daily'))
|
||||||
'hourly_forecast': {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return processed_data
|
return processed_data
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
|
from typing import List
|
||||||
|
|
||||||
from homeassistant.components.weather import WeatherEntity
|
from homeassistant.components.weather import WeatherEntity, WeatherEntityFeature, Forecast
|
||||||
from homeassistant.const import UnitOfTemperature, UnitOfSpeed, UnitOfPrecipitationDepth, UnitOfPressure
|
from homeassistant.const import UnitOfTemperature, UnitOfSpeed, UnitOfPrecipitationDepth, UnitOfPressure
|
||||||
from homeassistant.helpers.update_coordinator import (
|
from homeassistant.helpers.update_coordinator import (
|
||||||
CoordinatorEntity,
|
CoordinatorEntity,
|
||||||
|
@ -29,6 +30,12 @@ class IrmKmiWeather(CoordinatorEntity, WeatherEntity):
|
||||||
super().__init__(coordinator)
|
super().__init__(coordinator)
|
||||||
self._name = name
|
self._name = name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_features(self) -> WeatherEntityFeature:
|
||||||
|
features = WeatherEntityFeature(0)
|
||||||
|
features |= WeatherEntityFeature.FORECAST_TWICE_DAILY
|
||||||
|
return features
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return self._name
|
return self._name
|
||||||
|
@ -76,3 +83,10 @@ class IrmKmiWeather(CoordinatorEntity, WeatherEntity):
|
||||||
@property
|
@property
|
||||||
def uv_index(self) -> float | None:
|
def uv_index(self) -> float | None:
|
||||||
return self.coordinator.data.get('current_weather').get('uv_index')
|
return self.coordinator.data.get('current_weather').get('uv_index')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def forecast(self) -> list[Forecast] | None:
|
||||||
|
return self.coordinator.data.get('daily_forecast')
|
||||||
|
|
||||||
|
async def async_forecast_twice_daily(self) -> List[Forecast] | None:
|
||||||
|
return self.coordinator.data.get('daily_forecast')
|
||||||
|
|
Loading…
Add table
Reference in a new issue