Add Yahoo! weather platform (#7939)
This commit is contained in:
parent
b87e31617a
commit
d38acfbd39
4 changed files with 202 additions and 4 deletions
|
@ -506,6 +506,7 @@ omit =
|
|||
homeassistant/components/weather/buienradar.py
|
||||
homeassistant/components/weather/metoffice.py
|
||||
homeassistant/components/weather/openweathermap.py
|
||||
homeassistant/components/weather/yweather.py
|
||||
homeassistant/components/weather/zamg.py
|
||||
homeassistant/components/zeroconf.py
|
||||
homeassistant/components/zwave/util.py
|
||||
|
|
|
@ -22,16 +22,17 @@ DOMAIN = 'weather'
|
|||
ENTITY_ID_FORMAT = DOMAIN + '.{}'
|
||||
|
||||
ATTR_CONDITION_CLASS = 'condition_class'
|
||||
ATTR_FORECAST = 'forecast'
|
||||
ATTR_FORECAST_TEMP = 'temperature'
|
||||
ATTR_FORECAST_TIME = 'datetime'
|
||||
ATTR_WEATHER_ATTRIBUTION = 'attribution'
|
||||
ATTR_WEATHER_HUMIDITY = 'humidity'
|
||||
ATTR_WEATHER_OZONE = 'ozone'
|
||||
ATTR_WEATHER_PRESSURE = 'pressure'
|
||||
ATTR_WEATHER_TEMPERATURE = 'temperature'
|
||||
ATTR_WEATHER_VISIBILITY = 'visibility'
|
||||
ATTR_WEATHER_WIND_BEARING = 'wind_bearing'
|
||||
ATTR_WEATHER_WIND_SPEED = 'wind_speed'
|
||||
ATTR_FORECAST = 'forecast'
|
||||
ATTR_FORECAST_TEMP = 'temperature'
|
||||
ATTR_FORECAST_TIME = 'datetime'
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
|
@ -45,7 +46,7 @@ def async_setup(hass, config):
|
|||
|
||||
# pylint: disable=no-member, no-self-use
|
||||
class WeatherEntity(Entity):
|
||||
"""ABC for a weather data."""
|
||||
"""ABC for weather data."""
|
||||
|
||||
@property
|
||||
def temperature(self):
|
||||
|
@ -87,6 +88,11 @@ class WeatherEntity(Entity):
|
|||
"""Return the attribution."""
|
||||
return None
|
||||
|
||||
@property
|
||||
def visibility(self):
|
||||
"""Return the visibility."""
|
||||
return None
|
||||
|
||||
@property
|
||||
def forecast(self):
|
||||
"""Return the forecast."""
|
||||
|
@ -116,6 +122,10 @@ class WeatherEntity(Entity):
|
|||
if wind_speed is not None:
|
||||
data[ATTR_WEATHER_WIND_SPEED] = wind_speed
|
||||
|
||||
visibility = self.visibility
|
||||
if visibility is not None:
|
||||
data[ATTR_WEATHER_VISIBILITY] = visibility
|
||||
|
||||
attribution = self.attribution
|
||||
if attribution is not None:
|
||||
data[ATTR_WEATHER_ATTRIBUTION] = attribution
|
||||
|
|
186
homeassistant/components/weather/yweather.py
Normal file
186
homeassistant/components/weather/yweather.py
Normal file
|
@ -0,0 +1,186 @@
|
|||
"""
|
||||
Support for the Yahoo! Weather service.
|
||||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
https://home-assistant.io/components/weather.yweather/
|
||||
"""
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.components.weather import (
|
||||
WeatherEntity, PLATFORM_SCHEMA, ATTR_FORECAST_TEMP)
|
||||
from homeassistant.const import (TEMP_CELSIUS, CONF_NAME, STATE_UNKNOWN)
|
||||
|
||||
REQUIREMENTS = ["yahooweather==0.8"]
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
ATTR_FORECAST_CONDITION = 'condition'
|
||||
ATTRIBUTION = "Weather details provided by Yahoo! Inc."
|
||||
|
||||
CONF_FORECAST = 'forecast'
|
||||
CONF_WOEID = 'woeid'
|
||||
|
||||
DEFAULT_NAME = 'Yweather'
|
||||
|
||||
SCAN_INTERVAL = timedelta(minutes=10)
|
||||
|
||||
CONDITION_CLASSES = {
|
||||
'cloudy': [26, 27, 28, 29, 30],
|
||||
'fog': [19, 20, 21, 22, 23],
|
||||
'hail': [17, 18, 35],
|
||||
'lightning': [37],
|
||||
'lightning-rainy': [38, 39],
|
||||
'partlycloudy': [44],
|
||||
'pouring': [40, 45],
|
||||
'rainy': [9, 11, 12],
|
||||
'snowy': [8, 13, 14, 15, 16, 41, 42, 43],
|
||||
'snowy-rainy': [5, 6, 7, 10, 46, 47],
|
||||
'sunny': [32],
|
||||
'windy': [24],
|
||||
'windy-variant': [],
|
||||
'exceptional': [0, 1, 2, 3, 4, 25, 36],
|
||||
}
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Optional(CONF_WOEID, default=None): cv.string,
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
vol.Optional(CONF_FORECAST, default=0):
|
||||
vol.All(vol.Coerce(int), vol.Range(min=0, max=5)),
|
||||
})
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Yahoo! weather platform."""
|
||||
from yahooweather import get_woeid, UNIT_C, UNIT_F
|
||||
|
||||
unit = hass.config.units.temperature_unit
|
||||
woeid = config.get(CONF_WOEID)
|
||||
forecast = config.get(CONF_FORECAST)
|
||||
name = config.get(CONF_NAME)
|
||||
|
||||
yunit = UNIT_C if unit == TEMP_CELSIUS else UNIT_F
|
||||
|
||||
# If not exists a customer WOEID/calculation from Home Assistant
|
||||
if woeid is None:
|
||||
woeid = get_woeid(hass.config.latitude, hass.config.longitude)
|
||||
if woeid is None:
|
||||
_LOGGER.warning("Can't retrieve WOEID from Yahoo!")
|
||||
return False
|
||||
|
||||
yahoo_api = YahooWeatherData(woeid, yunit)
|
||||
|
||||
if not yahoo_api.update():
|
||||
_LOGGER.critical("Can't retrieve weather data from Yahoo!")
|
||||
return False
|
||||
|
||||
if forecast >= len(yahoo_api.yahoo.Forecast):
|
||||
_LOGGER.error("Yahoo! only support %d days forecast",
|
||||
len(yahoo_api.yahoo.Forecast))
|
||||
return False
|
||||
|
||||
add_devices([YahooWeatherWeather(yahoo_api, name, forecast)], True)
|
||||
|
||||
|
||||
class YahooWeatherWeather(WeatherEntity):
|
||||
"""Representation of Yahoo! weather data."""
|
||||
|
||||
def __init__(self, weather_data, name, forecast):
|
||||
"""Initialize the sensor."""
|
||||
self._name = name
|
||||
self._data = weather_data
|
||||
self._forecast = forecast
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def condition(self):
|
||||
"""Return the current condition."""
|
||||
try:
|
||||
return [k for k, v in CONDITION_CLASSES.items() if
|
||||
int(self._data.yahoo.Now['code']) in v][0]
|
||||
except IndexError:
|
||||
return STATE_UNKNOWN
|
||||
|
||||
@property
|
||||
def temperature(self):
|
||||
"""Return the temperature."""
|
||||
return self._data.yahoo.Now['temp']
|
||||
|
||||
@property
|
||||
def temperature_unit(self):
|
||||
"""Return the unit of measurement."""
|
||||
return TEMP_CELSIUS
|
||||
|
||||
@property
|
||||
def pressure(self):
|
||||
"""Return the pressure."""
|
||||
return self._data.yahoo.Atmosphere['pressure']
|
||||
|
||||
@property
|
||||
def humidity(self):
|
||||
"""Return the humidity."""
|
||||
return self._data.yahoo.Atmosphere['humidity']
|
||||
|
||||
@property
|
||||
def visibility(self):
|
||||
"""Return the visibility."""
|
||||
return self._data.yahoo.Atmosphere['visibility']
|
||||
|
||||
@property
|
||||
def wind_speed(self):
|
||||
"""Return the wind speed."""
|
||||
return self._data.yahoo.Wind['speed']
|
||||
|
||||
@property
|
||||
def attribution(self):
|
||||
"""Return the attribution."""
|
||||
return ATTRIBUTION
|
||||
|
||||
@property
|
||||
def forecast(self):
|
||||
"""Return the forecast array."""
|
||||
try:
|
||||
forecast_condition = \
|
||||
[k for k, v in CONDITION_CLASSES.items() if
|
||||
int(self._data.yahoo.Forecast[self._forecast]['code'])
|
||||
in v][0]
|
||||
except IndexError:
|
||||
return STATE_UNKNOWN
|
||||
|
||||
return [{
|
||||
ATTR_FORECAST_CONDITION: forecast_condition,
|
||||
ATTR_FORECAST_TEMP:
|
||||
self._data.yahoo.Forecast[self._forecast]['high'],
|
||||
}]
|
||||
|
||||
def update(self):
|
||||
"""Get the latest data from Yahoo! and updates the states."""
|
||||
self._data.update()
|
||||
if not self._data.yahoo.RawData:
|
||||
_LOGGER.info("Don't receive weather data from Yahoo!")
|
||||
return
|
||||
|
||||
|
||||
class YahooWeatherData(object):
|
||||
"""Handle the Yahoo! API object and limit updates."""
|
||||
|
||||
def __init__(self, woeid, temp_unit):
|
||||
"""Initialize the data object."""
|
||||
from yahooweather import YahooWeather
|
||||
self._yahoo = YahooWeather(woeid, temp_unit)
|
||||
|
||||
@property
|
||||
def yahoo(self):
|
||||
"""Return Yahoo! API object."""
|
||||
return self._yahoo
|
||||
|
||||
def update(self):
|
||||
"""Get the latest data from Yahoo!."""
|
||||
return self._yahoo.updateWeather()
|
|
@ -898,6 +898,7 @@ xmltodict==0.11.0
|
|||
yahoo-finance==1.4.0
|
||||
|
||||
# homeassistant.components.sensor.yweather
|
||||
# homeassistant.components.weather.yweather
|
||||
yahooweather==0.8
|
||||
|
||||
# homeassistant.components.light.yeelight
|
||||
|
|
Loading…
Add table
Reference in a new issue