"""Support for the Yahoo! Weather service.""" from datetime import timedelta import logging import voluptuous as vol from homeassistant.components.weather import ( ATTR_FORECAST_CONDITION, ATTR_FORECAST_TEMP, ATTR_FORECAST_TEMP_LOW, ATTR_FORECAST_TIME, PLATFORM_SCHEMA, WeatherEntity, ) from homeassistant.const import CONF_NAME, STATE_UNKNOWN, TEMP_CELSIUS import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) DATA_CONDITION = "yahoo_condition" ATTRIBUTION = "Weather details provided by Yahoo! Inc." CONF_WOEID = "woeid" DEFAULT_NAME = "Yweather" SCAN_INTERVAL = timedelta(minutes=10) CONDITION_CLASSES = { "clear-night": [31, 33], "cloudy": [26, 27, 28], "fog": [20, 21], "hail": [17, 35], "lightning": [], "lightning-rainy": [3, 4, 37, 38, 39, 45, 47], "partlycloudy": [29, 30, 44], "pouring": [], "rainy": [9, 10, 11, 12, 40], "snowy": [8, 13, 14, 15, 16, 41, 42, 43, 46], "snowy-rainy": [5, 6, 7, 18], "sunny": [25, 32, 34, 36], "windy": [23, 24], "windy-variant": [], "exceptional": [0, 1, 2, 19, 22], } PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Optional(CONF_WOEID): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, } ) def setup_platform(hass, config, add_entities, discovery_info=None): """Set up the Yahoo! weather platform.""" from yahooweather import get_woeid, UNIT_C, UNIT_F unit = hass.config.units.temperature_unit woeid = config.get(CONF_WOEID) 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 # create condition helper if DATA_CONDITION not in hass.data: hass.data[DATA_CONDITION] = [str(x) for x in range(0, 50)] for cond, condlst in CONDITION_CLASSES.items(): for condi in condlst: hass.data[DATA_CONDITION][condi] = cond add_entities([YahooWeatherWeather(yahoo_api, name, unit)], True) class YahooWeatherWeather(WeatherEntity): """Representation of Yahoo! weather data.""" def __init__(self, weather_data, name, unit): """Initialize the sensor.""" self._name = name self._data = weather_data self._unit = unit @property def name(self): """Return the name of the sensor.""" return self._name @property def condition(self): """Return the current condition.""" try: return self.hass.data[DATA_CONDITION][int(self._data.yahoo.Now["code"])] except (ValueError, IndexError): return STATE_UNKNOWN @property def temperature(self): """Return the temperature.""" return int(self._data.yahoo.Now["temp"]) @property def temperature_unit(self): """Return the unit of measurement.""" return self._unit @property def pressure(self): """Return the pressure.""" return round(float(self._data.yahoo.Atmosphere["pressure"]) / 33.8637526, 2) @property def humidity(self): """Return the humidity.""" return int(self._data.yahoo.Atmosphere["humidity"]) @property def visibility(self): """Return the visibility.""" return round(float(self._data.yahoo.Atmosphere["visibility"]) / 1.61, 2) @property def wind_speed(self): """Return the wind speed.""" return round(float(self._data.yahoo.Wind["speed"]) / 1.61, 2) @property def wind_bearing(self): """Return the wind direction.""" return int(self._data.yahoo.Wind["direction"]) @property def attribution(self): """Return the attribution.""" return ATTRIBUTION @property def forecast(self): """Return the forecast array.""" try: return [ { ATTR_FORECAST_TIME: v["date"], ATTR_FORECAST_TEMP: int(v["high"]), ATTR_FORECAST_TEMP_LOW: int(v["low"]), ATTR_FORECAST_CONDITION: self.hass.data[DATA_CONDITION][ int(v["code"]) ], } for v in self._data.yahoo.Forecast ] except (ValueError, IndexError): return STATE_UNKNOWN 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: """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()