mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +00:00
Add precipitation to OpenWeatherMap forecast (#13971)
* add initial precipitation support * move attr to component * remove blank line * add forecast attributes to platform and update demo * add tests * break long lines * calc lower temp correctly * move all new attributes to component * convert temp low only when existing
This commit is contained in:
parent
d352dee9b7
commit
8e7f500f28
@ -22,7 +22,10 @@ ENTITY_ID_FORMAT = DOMAIN + '.{}'
|
|||||||
|
|
||||||
ATTR_CONDITION_CLASS = 'condition_class'
|
ATTR_CONDITION_CLASS = 'condition_class'
|
||||||
ATTR_FORECAST = 'forecast'
|
ATTR_FORECAST = 'forecast'
|
||||||
|
ATTR_FORECAST_CONDITION = 'condition'
|
||||||
|
ATTR_FORECAST_PRECIPITATION = 'precipitation'
|
||||||
ATTR_FORECAST_TEMP = 'temperature'
|
ATTR_FORECAST_TEMP = 'temperature'
|
||||||
|
ATTR_FORECAST_TEMP_LOW = 'templow'
|
||||||
ATTR_FORECAST_TIME = 'datetime'
|
ATTR_FORECAST_TIME = 'datetime'
|
||||||
ATTR_WEATHER_ATTRIBUTION = 'attribution'
|
ATTR_WEATHER_ATTRIBUTION = 'attribution'
|
||||||
ATTR_WEATHER_HUMIDITY = 'humidity'
|
ATTR_WEATHER_HUMIDITY = 'humidity'
|
||||||
@ -144,6 +147,10 @@ class WeatherEntity(Entity):
|
|||||||
forecast_entry[ATTR_FORECAST_TEMP] = show_temp(
|
forecast_entry[ATTR_FORECAST_TEMP] = show_temp(
|
||||||
self.hass, forecast_entry[ATTR_FORECAST_TEMP],
|
self.hass, forecast_entry[ATTR_FORECAST_TEMP],
|
||||||
self.temperature_unit, self.precision)
|
self.temperature_unit, self.precision)
|
||||||
|
if ATTR_FORECAST_TEMP_LOW in forecast_entry:
|
||||||
|
forecast_entry[ATTR_FORECAST_TEMP_LOW] = show_temp(
|
||||||
|
self.hass, forecast_entry[ATTR_FORECAST_TEMP_LOW],
|
||||||
|
self.temperature_unit, self.precision)
|
||||||
forecast.append(forecast_entry)
|
forecast.append(forecast_entry)
|
||||||
|
|
||||||
data[ATTR_FORECAST] = forecast
|
data[ATTR_FORECAST] = forecast
|
||||||
|
@ -10,7 +10,8 @@ import asyncio
|
|||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.weather import (
|
from homeassistant.components.weather import (
|
||||||
WeatherEntity, PLATFORM_SCHEMA, ATTR_FORECAST_TEMP, ATTR_FORECAST_TIME)
|
WeatherEntity, PLATFORM_SCHEMA, ATTR_FORECAST_CONDITION,
|
||||||
|
ATTR_FORECAST_TEMP, ATTR_FORECAST_TEMP_LOW, ATTR_FORECAST_TIME)
|
||||||
from homeassistant.const import \
|
from homeassistant.const import \
|
||||||
CONF_NAME, TEMP_CELSIUS, CONF_LATITUDE, CONF_LONGITUDE
|
CONF_NAME, TEMP_CELSIUS, CONF_LATITUDE, CONF_LONGITUDE
|
||||||
from homeassistant.helpers import config_validation as cv
|
from homeassistant.helpers import config_validation as cv
|
||||||
@ -28,9 +29,6 @@ DEFAULT_TIMEFRAME = 60
|
|||||||
|
|
||||||
CONF_FORECAST = 'forecast'
|
CONF_FORECAST = 'forecast'
|
||||||
|
|
||||||
ATTR_FORECAST_CONDITION = 'condition'
|
|
||||||
ATTR_FORECAST_TEMP_LOW = 'templow'
|
|
||||||
|
|
||||||
|
|
||||||
CONDITION_CLASSES = {
|
CONDITION_CLASSES = {
|
||||||
'cloudy': ['c', 'p'],
|
'cloudy': ['c', 'p'],
|
||||||
|
@ -7,7 +7,8 @@ https://home-assistant.io/components/demo/
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from homeassistant.components.weather import (
|
from homeassistant.components.weather import (
|
||||||
WeatherEntity, ATTR_FORECAST_TEMP, ATTR_FORECAST_TIME)
|
WeatherEntity, ATTR_FORECAST_CONDITION, ATTR_FORECAST_PRECIPITATION,
|
||||||
|
ATTR_FORECAST_TEMP, ATTR_FORECAST_TEMP_LOW, ATTR_FORECAST_TIME)
|
||||||
from homeassistant.const import (TEMP_CELSIUS, TEMP_FAHRENHEIT)
|
from homeassistant.const import (TEMP_CELSIUS, TEMP_FAHRENHEIT)
|
||||||
|
|
||||||
CONDITION_CLASSES = {
|
CONDITION_CLASSES = {
|
||||||
@ -32,9 +33,15 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||||||
"""Set up the Demo weather."""
|
"""Set up the Demo weather."""
|
||||||
add_devices([
|
add_devices([
|
||||||
DemoWeather('South', 'Sunshine', 21.6414, 92, 1099, 0.5, TEMP_CELSIUS,
|
DemoWeather('South', 'Sunshine', 21.6414, 92, 1099, 0.5, TEMP_CELSIUS,
|
||||||
[22, 19, 15, 12, 14, 18, 21]),
|
[['rainy', 1, 22, 15], ['rainy', 5, 19, 8],
|
||||||
|
['cloudy', 0, 15, 9], ['sunny', 0, 12, 6],
|
||||||
|
['partlycloudy', 2, 14, 7], ['rainy', 15, 18, 7],
|
||||||
|
['fog', 0.2, 21, 12]]),
|
||||||
DemoWeather('North', 'Shower rain', -12, 54, 987, 4.8, TEMP_FAHRENHEIT,
|
DemoWeather('North', 'Shower rain', -12, 54, 987, 4.8, TEMP_FAHRENHEIT,
|
||||||
[-10, -13, -18, -23, -19, -14, -9])
|
[['snowy', 2, -10, -15], ['partlycloudy', 1, -13, -14],
|
||||||
|
['sunny', 0, -18, -22], ['sunny', 0.1, -23, -23],
|
||||||
|
['snowy', 4, -19, -20], ['sunny', 0.3, -14, -19],
|
||||||
|
['sunny', 0, -9, -12]])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
@ -108,7 +115,10 @@ class DemoWeather(WeatherEntity):
|
|||||||
for entry in self._forecast:
|
for entry in self._forecast:
|
||||||
data_dict = {
|
data_dict = {
|
||||||
ATTR_FORECAST_TIME: reftime.isoformat(),
|
ATTR_FORECAST_TIME: reftime.isoformat(),
|
||||||
ATTR_FORECAST_TEMP: entry
|
ATTR_FORECAST_CONDITION: entry[0],
|
||||||
|
ATTR_FORECAST_PRECIPITATION: entry[1],
|
||||||
|
ATTR_FORECAST_TEMP: entry[2],
|
||||||
|
ATTR_FORECAST_TEMP_LOW: entry[3]
|
||||||
}
|
}
|
||||||
reftime = reftime + timedelta(hours=4)
|
reftime = reftime + timedelta(hours=4)
|
||||||
forecast_data.append(data_dict)
|
forecast_data.append(data_dict)
|
||||||
|
@ -6,14 +6,13 @@ https://home-assistant.io/components/weather.ecobee/
|
|||||||
"""
|
"""
|
||||||
from homeassistant.components import ecobee
|
from homeassistant.components import ecobee
|
||||||
from homeassistant.components.weather import (
|
from homeassistant.components.weather import (
|
||||||
WeatherEntity, ATTR_FORECAST_TEMP, ATTR_FORECAST_TIME)
|
WeatherEntity, ATTR_FORECAST_CONDITION, ATTR_FORECAST_TEMP,
|
||||||
|
ATTR_FORECAST_TEMP_LOW, ATTR_FORECAST_TIME)
|
||||||
from homeassistant.const import (TEMP_FAHRENHEIT)
|
from homeassistant.const import (TEMP_FAHRENHEIT)
|
||||||
|
|
||||||
|
|
||||||
DEPENDENCIES = ['ecobee']
|
DEPENDENCIES = ['ecobee']
|
||||||
|
|
||||||
ATTR_FORECAST_CONDITION = 'condition'
|
|
||||||
ATTR_FORECAST_TEMP_LOW = 'templow'
|
|
||||||
ATTR_FORECAST_TEMP_HIGH = 'temphigh'
|
ATTR_FORECAST_TEMP_HIGH = 'temphigh'
|
||||||
ATTR_FORECAST_PRESSURE = 'pressure'
|
ATTR_FORECAST_PRESSURE = 'pressure'
|
||||||
ATTR_FORECAST_VISIBILITY = 'visibility'
|
ATTR_FORECAST_VISIBILITY = 'visibility'
|
||||||
|
@ -10,7 +10,8 @@ import logging
|
|||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.weather import (
|
from homeassistant.components.weather import (
|
||||||
ATTR_FORECAST_TEMP, ATTR_FORECAST_TIME, PLATFORM_SCHEMA, WeatherEntity)
|
ATTR_FORECAST_CONDITION, ATTR_FORECAST_PRECIPITATION, ATTR_FORECAST_TEMP,
|
||||||
|
ATTR_FORECAST_TIME, PLATFORM_SCHEMA, WeatherEntity)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME, STATE_UNKNOWN,
|
CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME, STATE_UNKNOWN,
|
||||||
TEMP_CELSIUS)
|
TEMP_CELSIUS)
|
||||||
@ -21,7 +22,6 @@ REQUIREMENTS = ['pyowm==2.8.0']
|
|||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
ATTR_FORECAST_CONDITION = 'condition'
|
|
||||||
ATTRIBUTION = 'Data provided by OpenWeatherMap'
|
ATTRIBUTION = 'Data provided by OpenWeatherMap'
|
||||||
|
|
||||||
DEFAULT_NAME = 'OpenWeatherMap'
|
DEFAULT_NAME = 'OpenWeatherMap'
|
||||||
@ -144,6 +144,7 @@ class OpenWeatherMapWeather(WeatherEntity):
|
|||||||
ATTR_FORECAST_TIME: entry.get_reference_time('unix') * 1000,
|
ATTR_FORECAST_TIME: entry.get_reference_time('unix') * 1000,
|
||||||
ATTR_FORECAST_TEMP:
|
ATTR_FORECAST_TEMP:
|
||||||
entry.get_temperature('celsius').get('temp'),
|
entry.get_temperature('celsius').get('temp'),
|
||||||
|
ATTR_FORECAST_PRECIPITATION: entry.get_rain().get('3h'),
|
||||||
ATTR_FORECAST_CONDITION:
|
ATTR_FORECAST_CONDITION:
|
||||||
[k for k, v in CONDITION_CLASSES.items()
|
[k for k, v in CONDITION_CLASSES.items()
|
||||||
if entry.get_weather_code() in v][0]
|
if entry.get_weather_code() in v][0]
|
||||||
|
@ -10,7 +10,8 @@ import logging
|
|||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.weather import (
|
from homeassistant.components.weather import (
|
||||||
ATTR_FORECAST_TEMP, ATTR_FORECAST_TIME, PLATFORM_SCHEMA, WeatherEntity)
|
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
|
from homeassistant.const import CONF_NAME, STATE_UNKNOWN, TEMP_CELSIUS
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
@ -20,10 +21,8 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
|
|
||||||
DATA_CONDITION = 'yahoo_condition'
|
DATA_CONDITION = 'yahoo_condition'
|
||||||
|
|
||||||
ATTR_FORECAST_CONDITION = 'condition'
|
|
||||||
ATTRIBUTION = "Weather details provided by Yahoo! Inc."
|
ATTRIBUTION = "Weather details provided by Yahoo! Inc."
|
||||||
|
|
||||||
ATTR_FORECAST_TEMP_LOW = 'templow'
|
|
||||||
|
|
||||||
CONF_WOEID = 'woeid'
|
CONF_WOEID = 'woeid'
|
||||||
|
|
||||||
|
@ -5,7 +5,8 @@ from homeassistant.components import weather
|
|||||||
from homeassistant.components.weather import (
|
from homeassistant.components.weather import (
|
||||||
ATTR_WEATHER_ATTRIBUTION, ATTR_WEATHER_HUMIDITY, ATTR_WEATHER_OZONE,
|
ATTR_WEATHER_ATTRIBUTION, ATTR_WEATHER_HUMIDITY, ATTR_WEATHER_OZONE,
|
||||||
ATTR_WEATHER_PRESSURE, ATTR_WEATHER_TEMPERATURE, ATTR_WEATHER_WIND_BEARING,
|
ATTR_WEATHER_PRESSURE, ATTR_WEATHER_TEMPERATURE, ATTR_WEATHER_WIND_BEARING,
|
||||||
ATTR_WEATHER_WIND_SPEED, ATTR_FORECAST, ATTR_FORECAST_TEMP)
|
ATTR_WEATHER_WIND_SPEED, ATTR_FORECAST, ATTR_FORECAST_CONDITION,
|
||||||
|
ATTR_FORECAST_PRECIPITATION, ATTR_FORECAST_TEMP, ATTR_FORECAST_TEMP_LOW)
|
||||||
from homeassistant.util.unit_system import METRIC_SYSTEM
|
from homeassistant.util.unit_system import METRIC_SYSTEM
|
||||||
from homeassistant.setup import setup_component
|
from homeassistant.setup import setup_component
|
||||||
|
|
||||||
@ -45,8 +46,17 @@ class TestWeather(unittest.TestCase):
|
|||||||
assert data.get(ATTR_WEATHER_OZONE) is None
|
assert data.get(ATTR_WEATHER_OZONE) is None
|
||||||
assert data.get(ATTR_WEATHER_ATTRIBUTION) == \
|
assert data.get(ATTR_WEATHER_ATTRIBUTION) == \
|
||||||
'Powered by Home Assistant'
|
'Powered by Home Assistant'
|
||||||
|
assert data.get(ATTR_FORECAST)[0].get(ATTR_FORECAST_CONDITION) == \
|
||||||
|
'rainy'
|
||||||
|
assert data.get(ATTR_FORECAST)[0].get(ATTR_FORECAST_PRECIPITATION) == 1
|
||||||
assert data.get(ATTR_FORECAST)[0].get(ATTR_FORECAST_TEMP) == 22
|
assert data.get(ATTR_FORECAST)[0].get(ATTR_FORECAST_TEMP) == 22
|
||||||
|
assert data.get(ATTR_FORECAST)[0].get(ATTR_FORECAST_TEMP_LOW) == 15
|
||||||
|
assert data.get(ATTR_FORECAST)[6].get(ATTR_FORECAST_CONDITION) == \
|
||||||
|
'fog'
|
||||||
|
assert data.get(ATTR_FORECAST)[6].get(ATTR_FORECAST_PRECIPITATION) \
|
||||||
|
== 0.2
|
||||||
assert data.get(ATTR_FORECAST)[6].get(ATTR_FORECAST_TEMP) == 21
|
assert data.get(ATTR_FORECAST)[6].get(ATTR_FORECAST_TEMP) == 21
|
||||||
|
assert data.get(ATTR_FORECAST)[6].get(ATTR_FORECAST_TEMP_LOW) == 12
|
||||||
assert len(data.get(ATTR_FORECAST)) == 7
|
assert len(data.get(ATTR_FORECAST)) == 7
|
||||||
|
|
||||||
def test_temperature_convert(self):
|
def test_temperature_convert(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user