From 23d7330a2fadaff22c483c0c84c926b5c9151d6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Sat, 27 Mar 2021 22:33:24 +0100 Subject: [PATCH] Discard outdated data reported by AEMET stations (#48417) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * aemet: achieve 100% test coverage Signed-off-by: Álvaro Fernández Rojas * aemet: discard outdated station data Signed-off-by: Álvaro Fernández Rojas * aemet: fix AemetSensor/AemetForecastSensor inheritance AbstractAemetSensor already inherits SensorEntity. Signed-off-by: Álvaro Fernández Rojas --- homeassistant/components/aemet/sensor.py | 11 +++--- .../aemet/weather_update_coordinator.py | 39 ++++++++++++------- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/homeassistant/components/aemet/sensor.py b/homeassistant/components/aemet/sensor.py index 199b254cb1e..6f43d66e011 100644 --- a/homeassistant/components/aemet/sensor.py +++ b/homeassistant/components/aemet/sensor.py @@ -1,6 +1,4 @@ """Support for the AEMET OpenData service.""" -from homeassistant.components.sensor import SensorEntity - from .abstract_aemet_sensor import AbstractAemetSensor from .const import ( DOMAIN, @@ -58,7 +56,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities): async_add_entities(entities) -class AemetSensor(AbstractAemetSensor, SensorEntity): +class AemetSensor(AbstractAemetSensor): """Implementation of an AEMET OpenData sensor.""" def __init__( @@ -81,7 +79,7 @@ class AemetSensor(AbstractAemetSensor, SensorEntity): return self._weather_coordinator.data.get(self._sensor_type) -class AemetForecastSensor(AbstractAemetSensor, SensorEntity): +class AemetForecastSensor(AbstractAemetSensor): """Implementation of an AEMET OpenData forecast sensor.""" def __init__( @@ -108,9 +106,10 @@ class AemetForecastSensor(AbstractAemetSensor, SensorEntity): @property def state(self): """Return the state of the device.""" + forecast = None forecasts = self._weather_coordinator.data.get( FORECAST_MODE_ATTR_API[self._forecast_mode] ) if forecasts: - return forecasts[0].get(self._sensor_type) - return None + forecast = forecasts[0].get(self._sensor_type) + return forecast diff --git a/homeassistant/components/aemet/weather_update_coordinator.py b/homeassistant/components/aemet/weather_update_coordinator.py index ab098dae17c..a9af8f25f1c 100644 --- a/homeassistant/components/aemet/weather_update_coordinator.py +++ b/homeassistant/components/aemet/weather_update_coordinator.py @@ -82,6 +82,7 @@ from .const import ( _LOGGER = logging.getLogger(__name__) +STATION_MAX_DELTA = timedelta(hours=2) WEATHER_UPDATE_INTERVAL = timedelta(minutes=10) @@ -241,6 +242,7 @@ class WeatherUpdateCoordinator(DataUpdateCoordinator): weather_response.hourly[ATTR_DATA][0][AEMET_ATTR_ELABORATED] ) now = dt_util.now() + now_utc = dt_util.utcnow() hour = now.hour # Get current day @@ -253,10 +255,18 @@ class WeatherUpdateCoordinator(DataUpdateCoordinator): day = cur_day break - # Get station data + # Get latest station data station_data = None + station_dt = None if weather_response.station: - station_data = weather_response.station[ATTR_DATA][-1] + for _station_data in weather_response.station[ATTR_DATA]: + if AEMET_ATTR_STATION_DATE in _station_data: + _station_dt = dt_util.parse_datetime( + _station_data[AEMET_ATTR_STATION_DATE] + "Z" + ) + if not station_dt or _station_dt > station_dt: + station_data = _station_data + station_dt = _station_dt condition = None humidity = None @@ -299,17 +309,20 @@ class WeatherUpdateCoordinator(DataUpdateCoordinator): # Overwrite weather values with closest station data (if present) if station_data: - if AEMET_ATTR_STATION_DATE in station_data: - station_dt = dt_util.parse_datetime( - station_data[AEMET_ATTR_STATION_DATE] + "Z" - ) - station_timestamp = dt_util.as_utc(station_dt).isoformat() - if AEMET_ATTR_STATION_HUMIDITY in station_data: - humidity = format_float(station_data[AEMET_ATTR_STATION_HUMIDITY]) - if AEMET_ATTR_STATION_PRESSURE_SEA in station_data: - pressure = format_float(station_data[AEMET_ATTR_STATION_PRESSURE_SEA]) - if AEMET_ATTR_STATION_TEMPERATURE in station_data: - temperature = format_float(station_data[AEMET_ATTR_STATION_TEMPERATURE]) + station_timestamp = dt_util.as_utc(station_dt).isoformat() + if (now_utc - station_dt) <= STATION_MAX_DELTA: + if AEMET_ATTR_STATION_HUMIDITY in station_data: + humidity = format_float(station_data[AEMET_ATTR_STATION_HUMIDITY]) + if AEMET_ATTR_STATION_PRESSURE_SEA in station_data: + pressure = format_float( + station_data[AEMET_ATTR_STATION_PRESSURE_SEA] + ) + if AEMET_ATTR_STATION_TEMPERATURE in station_data: + temperature = format_float( + station_data[AEMET_ATTR_STATION_TEMPERATURE] + ) + else: + _LOGGER.warning("Station data is outdated") # Get forecast from weather data forecast_daily = self._get_daily_forecast_from_weather_response(