Skip to content

Commit

Permalink
Process data in coordinator
Browse files Browse the repository at this point in the history
  • Loading branch information
jdejaegh committed Dec 24, 2023
1 parent e2c1dbe commit 7e15ba3
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 38 deletions.
47 changes: 43 additions & 4 deletions custom_components/irm_kmi/coordinator.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Example integration using DataUpdateCoordinator."""

from datetime import timedelta
from datetime import timedelta, datetime
import logging

import async_timeout
Expand All @@ -11,6 +11,7 @@
UpdateFailed,
)

from .const import IRM_KMI_TO_HA_CONDITION_MAP as CDT_MAP
from .api import IrmKmiApiClient, IrmKmiApiError

_LOGGER = logging.getLogger(__name__)
Expand All @@ -27,7 +28,7 @@ def __init__(self, hass, coord: dict):
# Name of the data. For logging purposes.
name="IRM KMI weather",
# Polling interval. Will only be polled if there are subscribers.
update_interval=timedelta(minutes=15),
update_interval=timedelta(seconds=30),
)
self._api_client = IrmKmiApiClient(session=async_get_clientsession(hass))
self._coord = coord
Expand All @@ -45,7 +46,45 @@ async def _async_update_data(self):
# 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_coord(self._coord)
return data
api_data = await self._api_client.get_forecasts_coord(self._coord)
_LOGGER.debug(f"Observation for {api_data.get('cityName', '')}: {api_data.get('obs', '{}')}")

# Process data to get current hour forecast
now_hourly = None
hourly_forecast_data = api_data.get('for', {}).get('hourly')
if not (hourly_forecast_data is None
or not isinstance(hourly_forecast_data, list)
or len(hourly_forecast_data) == 0):

for current in hourly_forecast_data[:2]:
if datetime.now().strftime('%H') == current['hour']:
now_hourly = current
# Get UV index
module_data = api_data.get('module', None)
uv_index = None
if not (module_data is None or not isinstance(module_data, list)):
for module in module_data:
if module.get('type', None) == 'uv':
uv_index = module.get('data', {}).get('levelValue')

# Put everything together
processed_data = {
'current_weather': {
'condition': CDT_MAP.get(
(api_data.get('obs', {}).get('ww'), api_data.get('obs', {}).get('dayNight')), None),
'temperature': api_data.get('obs', {}).get('temp'),
'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_bearing': now_hourly.get('windDirection', 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
},

'hourly_forecast': {

}
}

return processed_data
except IrmKmiApiError as err:
raise UpdateFailed(f"Error communicating with API: {err}")
42 changes: 8 additions & 34 deletions custom_components/irm_kmi/weather.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import logging

from datetime import datetime

from homeassistant.components.weather import WeatherEntity
from homeassistant.const import UnitOfTemperature, UnitOfSpeed, UnitOfPrecipitationDepth, UnitOfPressure
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
)

from .const import IRM_KMI_TO_HA_CONDITION_MAP as CDT_MAP
from .coordinator import IrmKmiCoordinator

_LOGGER = logging.getLogger(__name__)
Expand All @@ -18,7 +15,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
_LOGGER.debug(f"IRM KMI setup. Config: {config}")
coordinator = IrmKmiCoordinator(hass, coord={'lat': config.get("lat"), 'long': config.get("lon")})

await coordinator.async_request_refresh()
await coordinator.async_config_entry_first_refresh()

async_add_entities([IrmKmiWeather(
coordinator,
Expand All @@ -32,28 +29,17 @@ def __init__(self, coordinator: IrmKmiCoordinator, name: str) -> None:
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
for current in data[:2]:
if datetime.now().strftime('%H') == current['hour']:
return current
return None

@property
def name(self) -> str:
return self._name

@property
def condition(self) -> str | None:
irm_condition = (self.coordinator.data.get('obs', {}).get('ww'),
self.coordinator.data.get('obs', {}).get('dayNight'))
return CDT_MAP.get(irm_condition, None)
return self.coordinator.data.get('current_weather').get('condition')

@property
def native_temperature(self) -> float | None:
return self.coordinator.data.get('obs', {}).get('temp')
return self.coordinator.data.get('current_weather').get('temperature')

@property
def native_temperature_unit(self) -> str | None:
Expand All @@ -65,40 +51,28 @@ def native_wind_speed_unit(self) -> str | None:

@property
def native_wind_speed(self) -> float | None:
data = self._current_hour_data()
return data.get('windSpeedKm', None)
return self.coordinator.data.get('current_weather').get('wind_speed')

@property
def native_wind_gust_speed(self) -> float | None:
data = self._current_hour_data()
return data.get('windPeakSpeedKm', None)
return self.coordinator.data.get('current_weather').get('wind_gust_speed')

@property
def wind_bearing(self) -> float | str | None:
data = self._current_hour_data()
return data.get('windDirection', None)
return self.coordinator.data.get('current_weather').get('wind_bearing')

@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)
return self.coordinator.data.get('current_weather').get('pressure')

@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
return self.coordinator.data.get('current_weather').get('uv_index')

0 comments on commit 7e15ba3

Please sign in to comment.