diff --git a/homeassistant/components/weather/openweathermap.py b/homeassistant/components/weather/openweathermap.py index 909f123b52c..8354757ff33 100644 --- a/homeassistant/components/weather/openweathermap.py +++ b/homeassistant/components/weather/openweathermap.py @@ -11,10 +11,10 @@ import voluptuous as vol from homeassistant.components.weather import ( ATTR_FORECAST_CONDITION, ATTR_FORECAST_PRECIPITATION, ATTR_FORECAST_TEMP, - ATTR_FORECAST_TIME, PLATFORM_SCHEMA, WeatherEntity) + ATTR_FORECAST_TEMP_LOW, ATTR_FORECAST_TIME, PLATFORM_SCHEMA, WeatherEntity) from homeassistant.const import ( - CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME, STATE_UNKNOWN, - TEMP_CELSIUS) + CONF_API_KEY, TEMP_CELSIUS, CONF_LATITUDE, CONF_LONGITUDE, CONF_MODE, + CONF_NAME, STATE_UNKNOWN) import homeassistant.helpers.config_validation as cv from homeassistant.util import Throttle @@ -22,20 +22,25 @@ REQUIREMENTS = ['pyowm==2.8.0'] _LOGGER = logging.getLogger(__name__) +ATTR_FORECAST_WIND_SPEED = 'wind_speed' +ATTR_FORECAST_WIND_BEARING = 'wind_bearing' + ATTRIBUTION = 'Data provided by OpenWeatherMap' +FORECAST_MODE = ['hourly', 'daily'] + DEFAULT_NAME = 'OpenWeatherMap' MIN_TIME_BETWEEN_FORECAST_UPDATES = timedelta(minutes=30) MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=10) CONDITION_CLASSES = { - 'cloudy': [804], + 'cloudy': [803, 804], 'fog': [701, 741], 'hail': [906], 'lightning': [210, 211, 212, 221], 'lightning-rainy': [200, 201, 202, 230, 231, 232], - 'partlycloudy': [801, 802, 803], + 'partlycloudy': [801, 802], 'pouring': [504, 314, 502, 503, 522], 'rainy': [300, 301, 302, 310, 311, 312, 313, 500, 501, 520, 521], 'snowy': [600, 601, 602, 611, 612, 620, 621, 622], @@ -51,6 +56,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_API_KEY): cv.string, vol.Optional(CONF_LATITUDE): cv.latitude, vol.Optional(CONF_LONGITUDE): cv.longitude, + vol.Optional(CONF_MODE, default='hourly'): vol.In(FORECAST_MODE), vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, }) @@ -62,6 +68,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): longitude = config.get(CONF_LONGITUDE, round(hass.config.longitude, 5)) latitude = config.get(CONF_LATITUDE, round(hass.config.latitude, 5)) name = config.get(CONF_NAME) + mode = config.get(CONF_MODE) try: owm = pyowm.OWM(config.get(CONF_API_KEY)) @@ -69,20 +76,21 @@ def setup_platform(hass, config, add_devices, discovery_info=None): _LOGGER.error("Error while connecting to OpenWeatherMap") return False - data = WeatherData(owm, latitude, longitude) + data = WeatherData(owm, latitude, longitude, mode) add_devices([OpenWeatherMapWeather( - name, data, hass.config.units.temperature_unit)], True) + name, data, hass.config.units.temperature_unit, mode)], True) class OpenWeatherMapWeather(WeatherEntity): """Implementation of an OpenWeatherMap sensor.""" - def __init__(self, name, owm, temperature_unit): + def __init__(self, name, owm, temperature_unit, mode): """Initialize the sensor.""" self._name = name self._owm = owm self._temperature_unit = temperature_unit + self._mode = mode self.data = None self.forecast_data = None @@ -140,15 +148,34 @@ class OpenWeatherMapWeather(WeatherEntity): """Return the forecast array.""" data = [] for entry in self.forecast_data.get_weathers(): - data.append({ - ATTR_FORECAST_TIME: entry.get_reference_time('unix') * 1000, - ATTR_FORECAST_TEMP: - entry.get_temperature('celsius').get('temp'), - ATTR_FORECAST_PRECIPITATION: entry.get_rain().get('3h'), - ATTR_FORECAST_CONDITION: - [k for k, v in CONDITION_CLASSES.items() - if entry.get_weather_code() in v][0] - }) + if self._mode == 'daily': + data.append({ + ATTR_FORECAST_TIME: + entry.get_reference_time('unix') * 1000, + ATTR_FORECAST_TEMP: + entry.get_temperature('celsius').get('day'), + ATTR_FORECAST_TEMP_LOW: + entry.get_temperature('celsius').get('night'), + ATTR_FORECAST_WIND_SPEED: + entry.get_wind().get('speed'), + ATTR_FORECAST_WIND_BEARING: + entry.get_wind().get('deg'), + ATTR_FORECAST_CONDITION: + [k for k, v in CONDITION_CLASSES.items() + if entry.get_weather_code() in v][0] + }) + else: + data.append({ + ATTR_FORECAST_TIME: + entry.get_reference_time('unix') * 1000, + ATTR_FORECAST_TEMP: + entry.get_temperature('celsius').get('temp'), + ATTR_FORECAST_PRECIPITATION: + entry.get_rain().get('3h'), + ATTR_FORECAST_CONDITION: + [k for k, v in CONDITION_CLASSES.items() + if entry.get_weather_code() in v][0] + }) return data def update(self): @@ -169,8 +196,9 @@ class OpenWeatherMapWeather(WeatherEntity): class WeatherData(object): """Get the latest data from OpenWeatherMap.""" - def __init__(self, owm, latitude, longitude): + def __init__(self, owm, latitude, longitude, mode): """Initialize the data object.""" + self._mode = mode self.owm = owm self.latitude = latitude self.longitude = longitude @@ -193,8 +221,14 @@ class WeatherData(object): from pyowm.exceptions.api_call_error import APICallError try: - fcd = self.owm.three_hours_forecast_at_coords( - self.latitude, self.longitude) + if self._mode == 'daily': + fcd = self.owm.daily_forecast_at_coords( + self.latitude, self.longitude, 15 + ) + else: + fcd = self.owm.three_hours_forecast_at_coords( + self.latitude, self.longitude + ) except APICallError: _LOGGER.error("Exception when calling OWM web API " "to update forecast")