Added the ability to Weather Underground to track severe weather alerts (#3505)

*  Added the ability to Weather Underground to track severe weather alerts

*   * Added message on the advisory attr

  * Updated tests

* * Making use of guard clause

* Checking multiple_alerts prior loop

* Using a better way to create dict

* Fixed issue to set to None only the object that failed

* Added unittest

* Split update() method to different calls with their one throttle control to minimize API calls

* Updated unittest and make sure the alert sensor will not return 'unknown' status'

* Removed update() method from state property

* Branch rebased and include Weather Underground attribution

* Update wunderground.py
This commit is contained in:
Marcelo Moreira de Mello authored and Paulus Schoutsen committed 2016-10-14 21:35:27 -07:00
1 parent 1bf5554017
commit 6fcb1b548e
2 files changed
+86 -24

No files matched your search

@@ -19,6 +19,7 @@ from homeassistant.util import Throttle
import homeassistant.helpers.config_validation as cv
_RESOURCE = 'http://api.wunderground.com/api/{}/conditions/q/'
_ALERTS = 'http://api.wunderground.com/api/{}/alerts/q/'
_LOGGER = logging.getLogger(__name__)
CONF_ATTRIBUTION = "Data provided by the WUnderground weather service"
@@ -28,6 +29,7 @@ MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=300)
# Sensor types are defined like: Name, units
SENSOR_TYPES = {
'alerts': ['Alerts', None],
'weather': ['Weather Summary', None],
'station_id': ['Station ID', None],
'feelslike_c': ['Feels Like (°C)', TEMP_CELSIUS],
@@ -57,6 +59,14 @@ SENSOR_TYPES = {
'solarradiation': ['Solar Radiation', None]
}
# Alert Attributes
ALERTS_ATTRS = [
'date',
'description',
'expires',
'message',
]
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_API_KEY): cv.string,
vol.Optional(CONF_PWS_ID): cv.string,
@@ -106,15 +116,31 @@ class WUndergroundSensor(Entity):
return int(self.rest.data[self._condition][:-1])
else:
return self.rest.data[self._condition]
else:
return STATE_UNKNOWN
if self.rest.alerts and self._condition == 'alerts':
return len(self.rest.alerts)
return STATE_UNKNOWN
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
}
attrs = {}
attrs[ATTR_ATTRIBUTION] = CONF_ATTRIBUTION
if not self.rest.alerts or self._condition != 'alerts':
return attrs
multiple_alerts = len(self.rest.alerts) > 1
for data in self.rest.alerts:
for alert in ALERTS_ATTRS:
if data[alert]:
if multiple_alerts:
dkey = alert.capitalize() + '_' + data['type']
else:
dkey = alert.capitalize()
attrs[dkey] = data[alert]
return attrs
@property
def entity_picture(self):
@@ -129,7 +155,10 @@ class WUndergroundSensor(Entity):
def update(self):
"""Update current conditions."""
self.rest.update()
if self._condition == 'alerts':
self.rest.update_alerts()
else:
self.rest.update()
# pylint: disable=too-few-public-methods
@@ -144,9 +173,10 @@ class WUndergroundData(object):
self._latitude = hass.config.latitude
self._longitude = hass.config.longitude
self.data = None
self.alerts = None
def _build_url(self):
url = _RESOURCE.format(self._api_key)
def _build_url(self, baseurl=_RESOURCE):
url = baseurl.format(self._api_key)
if self._pws_id:
url = url + 'pws:{}'.format(self._pws_id)
else:
@@ -168,3 +198,18 @@ class WUndergroundData(object):
_LOGGER.error("Check WUnderground API %s", err.args)
self.data = None
raise
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update_alerts(self):
"""Get the latest alerts data from WUnderground."""
try:
result = requests.get(self._build_url(_ALERTS), timeout=10).json()
if "error" in result['response']:
raise ValueError(result['response']["error"]
["description"])
else:
self.alerts = result["alerts"]
except ValueError as err:
_LOGGER.error("Check WUnderground API %s", err.args)
self.alerts = None
raise