From dc4115b92ca5b189d0f37cf3bcf1859ee1c42c73 Mon Sep 17 00:00:00 2001 From: Jules Dejaeghere Date: Sat, 23 Dec 2023 19:46:00 +0100 Subject: [PATCH] Add more attributes to current weather entity --- custom_components/irm_kmi/api.py | 11 +++-- custom_components/irm_kmi/coordinator.py | 7 +-- custom_components/irm_kmi/weather.py | 61 ++++++++++++++++++++++-- 3 files changed, 69 insertions(+), 10 deletions(-) diff --git a/custom_components/irm_kmi/api.py b/custom_components/irm_kmi/api.py index 5add773..c3680de 100644 --- a/custom_components/irm_kmi/api.py +++ b/custom_components/irm_kmi/api.py @@ -40,10 +40,7 @@ def _api_key(method_name: str): class IrmKmiApiClient: """Sample API Client.""" - def __init__( - self, - session: aiohttp.ClientSession, - ) -> None: + def __init__(self, session: aiohttp.ClientSession) -> None: """Sample API Client.""" self._session = session self._base_url = "https://app.meteo.be/services/appv4/" @@ -55,6 +52,12 @@ class IrmKmiApiClient: "s": "getForecasts"} ) + async def get_forecasts_coord(self, coord: dict) -> any: + """Get forecasts for given city.""" + return await self._api_wrapper( + params={"s": "getForecasts"} | coord + ) + async def _api_wrapper( self, params: dict, diff --git a/custom_components/irm_kmi/coordinator.py b/custom_components/irm_kmi/coordinator.py index db8a7a5..eaec5be 100644 --- a/custom_components/irm_kmi/coordinator.py +++ b/custom_components/irm_kmi/coordinator.py @@ -15,10 +15,11 @@ from .api import IrmKmiApiClient, IrmKmiApiError _LOGGER = logging.getLogger(__name__) + class IrmKmiCoordinator(DataUpdateCoordinator): """Coordinator to update data from IRM KMI""" - def __init__(self, hass, city_id): + def __init__(self, hass, coord: dict): """Initialize my coordinator.""" super().__init__( hass, @@ -29,7 +30,7 @@ class IrmKmiCoordinator(DataUpdateCoordinator): update_interval=timedelta(seconds=30), ) self._api_client = IrmKmiApiClient(session=async_get_clientsession(hass)) - self._city_id = city_id + self._coord = coord async def _async_update_data(self): """Fetch data from API endpoint. @@ -44,7 +45,7 @@ class IrmKmiCoordinator(DataUpdateCoordinator): # 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. - data = await self._api_client.get_forecasts_city(city_id=self._city_id) + data = await self._api_client.get_forecasts_coord(self._coord) return data except IrmKmiApiError as err: raise UpdateFailed(f"Error communicating with API: {err}") diff --git a/custom_components/irm_kmi/weather.py b/custom_components/irm_kmi/weather.py index f1c2349..140aea6 100644 --- a/custom_components/irm_kmi/weather.py +++ b/custom_components/irm_kmi/weather.py @@ -1,7 +1,9 @@ import logging +from datetime import datetime + from homeassistant.components.weather import WeatherEntity -from homeassistant.const import UnitOfTemperature +from homeassistant.const import UnitOfTemperature, UnitOfSpeed, UnitOfPrecipitationDepth, UnitOfPressure from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, ) @@ -14,7 +16,8 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): _LOGGER.debug(f"IRM KMI setup. Config: {config}") - coordinator = IrmKmiCoordinator(hass, city_id=config.get("city_id")) + coordinator = IrmKmiCoordinator(hass, coord={'lat': config.get("lat"), 'long': config.get("lon")}) + await coordinator.async_request_refresh() async_add_entities([IrmKmiWeather( @@ -29,6 +32,14 @@ class IrmKmiWeather(CoordinatorEntity, WeatherEntity): super().__init__(coordinator) self._name = name + def _current_hour_data(self) -> dict | None: + data = self.coordinator.data.get('for', {}).get('hourly') + if data is None or not isinstance(data, list) or len(data) == 0: + return None + data = data[0] + if datetime.now().strftime('%H') != data['hour']: + return None + return data @property def name(self) -> str: return self._name @@ -44,5 +55,49 @@ class IrmKmiWeather(CoordinatorEntity, WeatherEntity): return self.coordinator.data.get('obs', {}).get('temp') @property - def native_temperature_unit(self) -> str: + def native_temperature_unit(self) -> str | None: return UnitOfTemperature.CELSIUS + + @property + def native_wind_speed_unit(self) -> str | None: + return UnitOfSpeed.KILOMETERS_PER_HOUR + + @property + def native_wind_speed(self) -> float | None: + data = self._current_hour_data() + return data.get('windSpeedKm', None) + + @property + def native_wind_gust_speed(self) -> float | None: + data = self._current_hour_data() + return data.get('windPeakSpeedKm', None) + + @property + def wind_bearing(self) -> float | str | None: + data = self._current_hour_data() + return data.get('windDirection', None) + + @property + def native_precipitation_unit(self) -> str | None: + return UnitOfPrecipitationDepth.MILLIMETERS + + @property + def native_pressure(self) -> float | None: + data = self._current_hour_data() + return data.get('pressure', None) + + @property + def native_pressure_unit(self) -> str | None: + return UnitOfPressure.HPA + + @property + def uv_index(self) -> float | None: + data = self.coordinator.data.get('module', None) + if data is None or not isinstance(data, list): + return None + + for module in data: + if module.get('type', None) == 'uv': + return module.get('data', {}).get('levelValue') + + return None