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
This commit is contained in:
Nick Whyte 2018-10-30 21:56:00 +11:00 committed by Paulus Schoutsen
parent f400925825
commit 71b56363d3

View File

@ -17,13 +17,13 @@ import zipfile
import requests import requests
import voluptuous as vol import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.const import ( from homeassistant.const import (
CONF_MONITORED_CONDITIONS, TEMP_CELSIUS, CONF_NAME, ATTR_ATTRIBUTION, CONF_MONITORED_CONDITIONS, TEMP_CELSIUS, CONF_NAME, ATTR_ATTRIBUTION,
CONF_LATITUDE, CONF_LONGITUDE) CONF_LATITUDE, CONF_LONGITUDE)
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.util import Throttle from homeassistant.util import Throttle
import homeassistant.helpers.config_validation as cv
_RESOURCE = 'http://www.bom.gov.au/fwo/{}/{}.{}.json' _RESOURCE = 'http://www.bom.gov.au/fwo/{}/{}.{}.json'
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -39,7 +39,7 @@ CONF_STATION = 'station'
CONF_ZONE_ID = 'zone_id' CONF_ZONE_ID = 'zone_id'
CONF_WMO_ID = 'wmo_id' CONF_WMO_ID = 'wmo_id'
MIN_TIME_BETWEEN_UPDATES = datetime.timedelta(minutes=35) MIN_TIME_BETWEEN_UPDATES = datetime.timedelta(seconds=60)
SENSOR_TYPES = { SENSOR_TYPES = {
'wmo': ['wmo', None], 'wmo': ['wmo', None],
@ -159,9 +159,7 @@ class BOMCurrentSensor(Entity):
"""Return the state attributes of the device.""" """Return the state attributes of the device."""
attr = { attr = {
ATTR_ATTRIBUTION: CONF_ATTRIBUTION, ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
ATTR_LAST_UPDATE: datetime.datetime.strptime( ATTR_LAST_UPDATE: self.bom_data.last_updated,
str(self.bom_data.latest_data['local_date_time_full']),
'%Y%m%d%H%M%S'),
ATTR_SENSOR_ID: self._condition, ATTR_SENSOR_ID: self._condition,
ATTR_STATION_ID: self.bom_data.latest_data['wmo'], ATTR_STATION_ID: self.bom_data.latest_data['wmo'],
ATTR_STATION_NAME: self.bom_data.latest_data['name'], ATTR_STATION_NAME: self.bom_data.latest_data['name'],
@ -188,6 +186,7 @@ class BOMCurrentData:
self._hass = hass self._hass = hass
self._zone_id, self._wmo_id = station_id.split('.') self._zone_id, self._wmo_id = station_id.split('.')
self._data = None self._data = None
self.last_updated = None
def _build_url(self): def _build_url(self):
"""Build the URL for the requests.""" """Build the URL for the requests."""
@ -211,17 +210,50 @@ class BOMCurrentData:
for the latest value that is not `-`. for the latest value that is not `-`.
Iterators are used in this method to avoid iterating needlessly 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) condition_readings = (entry[condition] for entry in self._data)
return next((x for x in condition_readings if x != '-'), None) 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) @Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self): def update(self):
"""Get the latest data from BOM.""" """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: try:
result = requests.get(self._build_url(), timeout=10).json() result = requests.get(self._build_url(), timeout=10).json()
self._data = result['observations']['data'] 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: except ValueError as err:
_LOGGER.error("Check BOM %s", err.args) _LOGGER.error("Check BOM %s", err.args)
self._data = None self._data = None