From 71b56363d38e5d9bd0d1d3182ac66596fdfd80bd Mon Sep 17 00:00:00 2001 From: Nick Whyte Date: Tue, 30 Oct 2018 21:56:00 +1100 Subject: [PATCH] Reverse out change #14234 BOM Weather throttle fix (#17468) * Reverse out change #14234 BOM Weather throttle fix Reverted back to original throttle code to ensure sensors are updated on time. * Fixed lint issues * Review as a commit * Use last_updated for attributes * lint * lint --- homeassistant/components/sensor/bom.py | 44 ++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/sensor/bom.py b/homeassistant/components/sensor/bom.py index 11685c7ff68..6f7bc56cca9 100644 --- a/homeassistant/components/sensor/bom.py +++ b/homeassistant/components/sensor/bom.py @@ -17,13 +17,13 @@ import zipfile import requests import voluptuous as vol +import homeassistant.helpers.config_validation as cv from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import ( CONF_MONITORED_CONDITIONS, TEMP_CELSIUS, CONF_NAME, ATTR_ATTRIBUTION, CONF_LATITUDE, CONF_LONGITUDE) from homeassistant.helpers.entity import Entity from homeassistant.util import Throttle -import homeassistant.helpers.config_validation as cv _RESOURCE = 'http://www.bom.gov.au/fwo/{}/{}.{}.json' _LOGGER = logging.getLogger(__name__) @@ -39,7 +39,7 @@ CONF_STATION = 'station' CONF_ZONE_ID = 'zone_id' CONF_WMO_ID = 'wmo_id' -MIN_TIME_BETWEEN_UPDATES = datetime.timedelta(minutes=35) +MIN_TIME_BETWEEN_UPDATES = datetime.timedelta(seconds=60) SENSOR_TYPES = { 'wmo': ['wmo', None], @@ -159,9 +159,7 @@ class BOMCurrentSensor(Entity): """Return the state attributes of the device.""" attr = { ATTR_ATTRIBUTION: CONF_ATTRIBUTION, - ATTR_LAST_UPDATE: datetime.datetime.strptime( - str(self.bom_data.latest_data['local_date_time_full']), - '%Y%m%d%H%M%S'), + ATTR_LAST_UPDATE: self.bom_data.last_updated, ATTR_SENSOR_ID: self._condition, ATTR_STATION_ID: self.bom_data.latest_data['wmo'], ATTR_STATION_NAME: self.bom_data.latest_data['name'], @@ -188,6 +186,7 @@ class BOMCurrentData: self._hass = hass self._zone_id, self._wmo_id = station_id.split('.') self._data = None + self.last_updated = None def _build_url(self): """Build the URL for the requests.""" @@ -211,17 +210,50 @@ class BOMCurrentData: for the latest value that is not `-`. Iterators are used in this method to avoid iterating needlessly - iterating through the entire BOM provided dataset. + through the entire BOM provided dataset. """ condition_readings = (entry[condition] for entry in self._data) return next((x for x in condition_readings if x != '-'), None) + def should_update(self): + """Determine whether an update should occur. + + BOM provides updated data every 30 minutes. We manually define + refreshing logic here rather than a throttle to keep updates + in lock-step with BOM. + + If 35 minutes has passed since the last BOM data update, then + an update should be done. + """ + if self.last_updated is None: + # Never updated before, therefore an update should occur. + return True + + now = datetime.datetime.now() + update_due_at = self.last_updated + datetime.timedelta(minutes=35) + return now > update_due_at + @Throttle(MIN_TIME_BETWEEN_UPDATES) def update(self): """Get the latest data from BOM.""" + if not self.should_update(): + _LOGGER.debug( + "BOM was updated %s minutes ago, skipping update as" + " < 35 minutes, Now: %s, LastUpdate: %s", + (datetime.datetime.now() - self.last_updated), + datetime.datetime.now(), self.last_updated) + return + try: result = requests.get(self._build_url(), timeout=10).json() self._data = result['observations']['data'] + + # set lastupdate using self._data[0] as the first element in the + # array is the latest date in the json + self.last_updated = datetime.datetime.strptime( + str(self._data[0]['local_date_time_full']), '%Y%m%d%H%M%S') + return + except ValueError as err: _LOGGER.error("Check BOM %s", err.args) self._data = None