Remove Yahoo Weather integration (#34501)
This commit is contained in:
parent
5f2a9ed965
commit
220baed33a
9 changed files with 0 additions and 801 deletions
|
@ -1 +0,0 @@
|
|||
"""The yweather component."""
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"domain": "yweather",
|
||||
"name": "Yahoo Weather",
|
||||
"documentation": "https://www.home-assistant.io/integrations/yweather",
|
||||
"requirements": ["yahooweather==0.10"],
|
||||
"codeowners": []
|
||||
}
|
|
@ -1,200 +0,0 @@
|
|||
"""Support for the Yahoo! Weather service."""
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
from yahooweather import ( # pylint: disable=import-error
|
||||
UNIT_C,
|
||||
UNIT_F,
|
||||
YahooWeather,
|
||||
get_woeid,
|
||||
)
|
||||
|
||||
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||
from homeassistant.const import (
|
||||
ATTR_ATTRIBUTION,
|
||||
CONF_MONITORED_CONDITIONS,
|
||||
CONF_NAME,
|
||||
TEMP_CELSIUS,
|
||||
UNIT_PERCENTAGE,
|
||||
)
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.util import Throttle
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
ATTRIBUTION = "Weather details provided by Yahoo! Inc."
|
||||
|
||||
CONF_FORECAST = "forecast"
|
||||
|
||||
CONF_WOEID = "woeid"
|
||||
|
||||
DEFAULT_NAME = "Yweather"
|
||||
|
||||
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=10)
|
||||
|
||||
SENSOR_TYPES = {
|
||||
"weather_current": ["Current", None],
|
||||
"weather": ["Condition", None],
|
||||
"temperature": ["Temperature", "temperature"],
|
||||
"temp_min": ["Temperature min", "temperature"],
|
||||
"temp_max": ["Temperature max", "temperature"],
|
||||
"wind_speed": ["Wind speed", "speed"],
|
||||
"humidity": ["Humidity", UNIT_PERCENTAGE],
|
||||
"pressure": ["Pressure", "pressure"],
|
||||
"visibility": ["Visibility", "distance"],
|
||||
}
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||
{
|
||||
vol.Optional(CONF_WOEID): 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)
|
||||
),
|
||||
vol.Required(CONF_MONITORED_CONDITIONS, default=[]): [vol.In(SENSOR_TYPES)],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
"""Set up the Yahoo! weather sensor."""
|
||||
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
|
||||
|
||||
SENSOR_TYPES["temperature"][1] = unit
|
||||
SENSOR_TYPES["temp_min"][1] = unit
|
||||
SENSOR_TYPES["temp_max"][1] = unit
|
||||
|
||||
# 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.critical("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
|
||||
|
||||
dev = []
|
||||
for variable in config[CONF_MONITORED_CONDITIONS]:
|
||||
dev.append(YahooWeatherSensor(yahoo_api, name, forecast, variable))
|
||||
|
||||
add_entities(dev, True)
|
||||
|
||||
|
||||
class YahooWeatherSensor(Entity):
|
||||
"""Implementation of the Yahoo! weather sensor."""
|
||||
|
||||
def __init__(self, weather_data, name, forecast, sensor_type):
|
||||
"""Initialize the sensor."""
|
||||
self._client = name
|
||||
self._name = SENSOR_TYPES[sensor_type][0]
|
||||
self._type = sensor_type
|
||||
self._state = None
|
||||
self._unit = SENSOR_TYPES[sensor_type][1]
|
||||
self._data = weather_data
|
||||
self._forecast = forecast
|
||||
self._code = None
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor."""
|
||||
return f"{self._client} {self._name}"
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state of the device."""
|
||||
return self._state
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""Return the unit of measurement of this entity, if any."""
|
||||
return self._data.yahoo.Units.get(self._unit, self._unit)
|
||||
|
||||
@property
|
||||
def entity_picture(self):
|
||||
"""Return the entity picture to use in the frontend, if any."""
|
||||
if self._code is None or "weather" not in self._type:
|
||||
return None
|
||||
|
||||
return self._data.yahoo.getWeatherImage(self._code)
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return the state attributes."""
|
||||
attrs = {ATTR_ATTRIBUTION: ATTRIBUTION}
|
||||
|
||||
if self._code is not None and "weather" in self._type:
|
||||
attrs["condition_code"] = self._code
|
||||
|
||||
return attrs
|
||||
|
||||
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
|
||||
|
||||
# Default code for weather image
|
||||
self._code = self._data.yahoo.Now["code"]
|
||||
|
||||
# Read data
|
||||
if self._type == "weather_current":
|
||||
self._state = self._data.yahoo.Now["text"]
|
||||
elif self._type == "weather":
|
||||
self._code = self._data.yahoo.Forecast[self._forecast]["code"]
|
||||
self._state = self._data.yahoo.Forecast[self._forecast]["text"]
|
||||
elif self._type == "temperature":
|
||||
self._state = self._data.yahoo.Now["temp"]
|
||||
elif self._type == "temp_min":
|
||||
self._code = self._data.yahoo.Forecast[self._forecast]["code"]
|
||||
self._state = self._data.yahoo.Forecast[self._forecast]["low"]
|
||||
elif self._type == "temp_max":
|
||||
self._code = self._data.yahoo.Forecast[self._forecast]["code"]
|
||||
self._state = self._data.yahoo.Forecast[self._forecast]["high"]
|
||||
elif self._type == "wind_speed":
|
||||
self._state = round(float(self._data.yahoo.Wind["speed"]) / 1.61, 2)
|
||||
elif self._type == "humidity":
|
||||
self._state = self._data.yahoo.Atmosphere["humidity"]
|
||||
elif self._type == "pressure":
|
||||
self._state = round(
|
||||
float(self._data.yahoo.Atmosphere["pressure"]) / 33.8637526, 2
|
||||
)
|
||||
elif self._type == "visibility":
|
||||
self._state = round(
|
||||
float(self._data.yahoo.Atmosphere["visibility"]) / 1.61, 2
|
||||
)
|
||||
|
||||
|
||||
class YahooWeatherData:
|
||||
"""Handle Yahoo! API object and limit updates."""
|
||||
|
||||
def __init__(self, woeid, temp_unit):
|
||||
"""Initialize the data object."""
|
||||
self._yahoo = YahooWeather(woeid, temp_unit)
|
||||
|
||||
@property
|
||||
def yahoo(self):
|
||||
"""Return Yahoo! API object."""
|
||||
return self._yahoo
|
||||
|
||||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||
def update(self):
|
||||
"""Get the latest data from Yahoo!."""
|
||||
return self._yahoo.updateWeather()
|
|
@ -1,195 +0,0 @@
|
|||
"""Support for the Yahoo! Weather service."""
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
from yahooweather import ( # pylint: disable=import-error
|
||||
UNIT_C,
|
||||
UNIT_F,
|
||||
YahooWeather,
|
||||
get_woeid,
|
||||
)
|
||||
|
||||
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."""
|
||||
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."""
|
||||
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()
|
|
@ -2161,9 +2161,6 @@ xs1-api-client==2.3.5
|
|||
# homeassistant.components.yandex_transport
|
||||
ya_ma==0.3.8
|
||||
|
||||
# homeassistant.components.yweather
|
||||
yahooweather==0.10
|
||||
|
||||
# homeassistant.components.yale_smart_alarm
|
||||
yalesmartalarmclient==0.1.6
|
||||
|
||||
|
|
|
@ -819,9 +819,6 @@ xmltodict==0.12.0
|
|||
# homeassistant.components.yandex_transport
|
||||
ya_ma==0.3.8
|
||||
|
||||
# homeassistant.components.yweather
|
||||
yahooweather==0.10
|
||||
|
||||
# homeassistant.components.zeroconf
|
||||
zeroconf==0.25.1
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
"""Tests for the yweather component."""
|
|
@ -1,229 +0,0 @@
|
|||
"""The tests for the Yahoo weather sensor component."""
|
||||
import json
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.setup import setup_component
|
||||
|
||||
from tests.common import MockDependency, get_test_home_assistant, load_fixture
|
||||
|
||||
VALID_CONFIG_MINIMAL = {
|
||||
"sensor": {"platform": "yweather", "monitored_conditions": ["weather"]}
|
||||
}
|
||||
|
||||
VALID_CONFIG_ALL = {
|
||||
"sensor": {
|
||||
"platform": "yweather",
|
||||
"monitored_conditions": [
|
||||
"weather",
|
||||
"weather_current",
|
||||
"temperature",
|
||||
"temp_min",
|
||||
"temp_max",
|
||||
"wind_speed",
|
||||
"pressure",
|
||||
"visibility",
|
||||
"humidity",
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
BAD_CONF_RAW = {
|
||||
"sensor": {
|
||||
"platform": "yweather",
|
||||
"woeid": "12345",
|
||||
"monitored_conditions": ["weather"],
|
||||
}
|
||||
}
|
||||
|
||||
BAD_CONF_DATA = {
|
||||
"sensor": {
|
||||
"platform": "yweather",
|
||||
"woeid": "111",
|
||||
"monitored_conditions": ["weather"],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def _yql_queryMock(yql): # pylint: disable=invalid-name
|
||||
"""Mock yahoo query language query."""
|
||||
return (
|
||||
'{"query": {"count": 1, "created": "2017-11-17T13:40:47Z", '
|
||||
'"lang": "en-US", "results": {"place": {"woeid": "23511632"}}}}'
|
||||
)
|
||||
|
||||
|
||||
def get_woeidMock(lat, lon): # pylint: disable=invalid-name
|
||||
"""Mock get woeid Where On Earth Identifiers."""
|
||||
return "23511632"
|
||||
|
||||
|
||||
def get_woeidNoneMock(lat, lon): # pylint: disable=invalid-name
|
||||
"""Mock get woeid Where On Earth Identifiers."""
|
||||
return None
|
||||
|
||||
|
||||
class YahooWeatherMock:
|
||||
"""Mock class for the YahooWeather object."""
|
||||
|
||||
def __init__(self, woeid, temp_unit):
|
||||
"""Initialize Telnet object."""
|
||||
self.woeid = woeid
|
||||
self.temp_unit = temp_unit
|
||||
self._data = json.loads(load_fixture("yahooweather.json"))
|
||||
|
||||
# pylint: disable=no-self-use
|
||||
def updateWeather(self): # pylint: disable=invalid-name
|
||||
"""Return sample values."""
|
||||
return True
|
||||
|
||||
@property
|
||||
def RawData(self): # pylint: disable=invalid-name
|
||||
"""Raw Data."""
|
||||
if self.woeid == "12345":
|
||||
return json.loads("[]")
|
||||
return self._data
|
||||
|
||||
@property
|
||||
def Units(self): # pylint: disable=invalid-name
|
||||
"""Return dict with units."""
|
||||
return self._data["query"]["results"]["channel"]["units"]
|
||||
|
||||
@property
|
||||
def Now(self): # pylint: disable=invalid-name
|
||||
"""Return current weather data."""
|
||||
if self.woeid == "111":
|
||||
raise ValueError
|
||||
return self._data["query"]["results"]["channel"]["item"]["condition"]
|
||||
|
||||
@property
|
||||
def Atmosphere(self): # pylint: disable=invalid-name
|
||||
"""Atmosphere weather data."""
|
||||
return self._data["query"]["results"]["channel"]["atmosphere"]
|
||||
|
||||
@property
|
||||
def Wind(self): # pylint: disable=invalid-name
|
||||
"""Wind weather data."""
|
||||
return self._data["query"]["results"]["channel"]["wind"]
|
||||
|
||||
@property
|
||||
def Forecast(self): # pylint: disable=invalid-name
|
||||
"""Forecast data 0-5 Days."""
|
||||
return self._data["query"]["results"]["channel"]["item"]["forecast"]
|
||||
|
||||
def getWeatherImage(self, code): # pylint: disable=invalid-name
|
||||
"""Create a link to weather image from yahoo code."""
|
||||
return f"https://l.yimg.com/a/i/us/we/52/{code}.gif"
|
||||
|
||||
|
||||
class TestWeather(unittest.TestCase):
|
||||
"""Test the Yahoo weather component."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up things to be run when tests are started."""
|
||||
self.hass = get_test_home_assistant()
|
||||
|
||||
def tearDown(self):
|
||||
"""Stop down everything that was started."""
|
||||
self.hass.stop()
|
||||
|
||||
@MockDependency("yahooweather")
|
||||
@patch("yahooweather._yql_query", new=_yql_queryMock)
|
||||
@patch("yahooweather.get_woeid", new=get_woeidMock)
|
||||
@patch("yahooweather.YahooWeather", new=YahooWeatherMock)
|
||||
def test_setup_minimal(self, mock_yahooweather):
|
||||
"""Test for minimal weather sensor config."""
|
||||
assert setup_component(self.hass, "sensor", VALID_CONFIG_MINIMAL)
|
||||
|
||||
state = self.hass.states.get("sensor.yweather_condition")
|
||||
assert state is not None
|
||||
|
||||
assert state.state == "Mostly Cloudy"
|
||||
assert state.attributes.get("friendly_name") == "Yweather Condition"
|
||||
|
||||
@MockDependency("yahooweather")
|
||||
@patch("yahooweather._yql_query", new=_yql_queryMock)
|
||||
@patch("yahooweather.get_woeid", new=get_woeidMock)
|
||||
@patch("yahooweather.YahooWeather", new=YahooWeatherMock)
|
||||
def test_setup_all(self, mock_yahooweather):
|
||||
"""Test for all weather data attributes."""
|
||||
assert setup_component(self.hass, "sensor", VALID_CONFIG_ALL)
|
||||
|
||||
state = self.hass.states.get("sensor.yweather_condition")
|
||||
assert state is not None
|
||||
assert state.state == "Mostly Cloudy"
|
||||
assert state.attributes.get("condition_code") == "28"
|
||||
assert state.attributes.get("friendly_name") == "Yweather Condition"
|
||||
|
||||
state = self.hass.states.get("sensor.yweather_current")
|
||||
assert state is not None
|
||||
assert state.state == "Cloudy"
|
||||
assert state.attributes.get("friendly_name") == "Yweather Current"
|
||||
|
||||
state = self.hass.states.get("sensor.yweather_temperature")
|
||||
assert state is not None
|
||||
assert state.state == "18"
|
||||
assert state.attributes.get("friendly_name") == "Yweather Temperature"
|
||||
|
||||
state = self.hass.states.get("sensor.yweather_temperature_max")
|
||||
assert state is not None
|
||||
assert state.state == "23"
|
||||
assert state.attributes.get("friendly_name") == "Yweather Temperature max"
|
||||
|
||||
state = self.hass.states.get("sensor.yweather_temperature_min")
|
||||
assert state is not None
|
||||
assert state.state == "16"
|
||||
assert state.attributes.get("friendly_name") == "Yweather Temperature min"
|
||||
|
||||
state = self.hass.states.get("sensor.yweather_wind_speed")
|
||||
assert state is not None
|
||||
assert state.state == "3.94"
|
||||
assert state.attributes.get("friendly_name") == "Yweather Wind speed"
|
||||
|
||||
state = self.hass.states.get("sensor.yweather_pressure")
|
||||
assert state is not None
|
||||
assert state.state == "1000.0"
|
||||
assert state.attributes.get("friendly_name") == "Yweather Pressure"
|
||||
|
||||
state = self.hass.states.get("sensor.yweather_visibility")
|
||||
assert state is not None
|
||||
assert state.state == "14.23"
|
||||
assert state.attributes.get("friendly_name") == "Yweather Visibility"
|
||||
|
||||
state = self.hass.states.get("sensor.yweather_humidity")
|
||||
assert state is not None
|
||||
assert state.state == "71"
|
||||
assert state.attributes.get("friendly_name") == "Yweather Humidity"
|
||||
|
||||
@MockDependency("yahooweather")
|
||||
@patch("yahooweather._yql_query", new=_yql_queryMock)
|
||||
@patch("yahooweather.get_woeid", new=get_woeidNoneMock)
|
||||
@patch("yahooweather.YahooWeather", new=YahooWeatherMock)
|
||||
def test_setup_bad_woied(self, mock_yahooweather):
|
||||
"""Test for bad woeid."""
|
||||
assert setup_component(self.hass, "sensor", VALID_CONFIG_MINIMAL)
|
||||
|
||||
state = self.hass.states.get("sensor.yweather_condition")
|
||||
assert state is None
|
||||
|
||||
@MockDependency("yahooweather")
|
||||
@patch("yahooweather._yql_query", new=_yql_queryMock)
|
||||
@patch("yahooweather.get_woeid", new=get_woeidMock)
|
||||
@patch("yahooweather.YahooWeather", new=YahooWeatherMock)
|
||||
def test_setup_bad_raw(self, mock_yahooweather):
|
||||
"""Test for bad RawData."""
|
||||
assert setup_component(self.hass, "sensor", BAD_CONF_RAW)
|
||||
|
||||
state = self.hass.states.get("sensor.yweather_condition")
|
||||
assert state is not None
|
||||
|
||||
@MockDependency("yahooweather")
|
||||
@patch("yahooweather._yql_query", new=_yql_queryMock)
|
||||
@patch("yahooweather.get_woeid", new=get_woeidMock)
|
||||
@patch("yahooweather.YahooWeather", new=YahooWeatherMock)
|
||||
def test_setup_bad_data(self, mock_yahooweather):
|
||||
"""Test for bad data."""
|
||||
assert setup_component(self.hass, "sensor", BAD_CONF_DATA)
|
||||
|
||||
state = self.hass.states.get("sensor.yweather_condition")
|
||||
assert state is None
|
|
@ -1,162 +0,0 @@
|
|||
"""The tests for the Yahoo weather component."""
|
||||
import json
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.components.weather import (
|
||||
ATTR_WEATHER_HUMIDITY,
|
||||
ATTR_WEATHER_PRESSURE,
|
||||
ATTR_WEATHER_TEMPERATURE,
|
||||
ATTR_WEATHER_WIND_BEARING,
|
||||
ATTR_WEATHER_WIND_SPEED,
|
||||
)
|
||||
from homeassistant.setup import setup_component
|
||||
from homeassistant.util.unit_system import METRIC_SYSTEM
|
||||
|
||||
from tests.common import MockDependency, get_test_home_assistant, load_fixture
|
||||
|
||||
|
||||
def _yql_queryMock(yql): # pylint: disable=invalid-name
|
||||
"""Mock yahoo query language query."""
|
||||
return (
|
||||
'{"query": {"count": 1, "created": "2017-11-17T13:40:47Z", '
|
||||
'"lang": "en-US", "results": {"place": {"woeid": "23511632"}}}}'
|
||||
)
|
||||
|
||||
|
||||
def get_woeidMock(lat, lon): # pylint: disable=invalid-name
|
||||
"""Mock get woeid Where On Earth Identifiers."""
|
||||
return "23511632"
|
||||
|
||||
|
||||
class YahooWeatherMock:
|
||||
"""Mock class for the YahooWeather object."""
|
||||
|
||||
def __init__(self, woeid, temp_unit):
|
||||
"""Initialize Telnet object."""
|
||||
self.woeid = woeid
|
||||
self.temp_unit = temp_unit
|
||||
self._data = json.loads(load_fixture("yahooweather.json"))
|
||||
|
||||
# pylint: disable=no-self-use
|
||||
def updateWeather(self): # pylint: disable=invalid-name
|
||||
"""Return sample values."""
|
||||
return True
|
||||
|
||||
@property
|
||||
def RawData(self): # pylint: disable=invalid-name
|
||||
"""Return raw Data."""
|
||||
if self.woeid == "12345":
|
||||
return json.loads("[]")
|
||||
return self._data
|
||||
|
||||
@property
|
||||
def Now(self): # pylint: disable=invalid-name
|
||||
"""Return current weather data."""
|
||||
if self.woeid == "111":
|
||||
raise ValueError
|
||||
return self._data["query"]["results"]["channel"]["item"]["condition"]
|
||||
|
||||
@property
|
||||
def Atmosphere(self): # pylint: disable=invalid-name
|
||||
"""Return atmosphere weather data."""
|
||||
return self._data["query"]["results"]["channel"]["atmosphere"]
|
||||
|
||||
@property
|
||||
def Wind(self): # pylint: disable=invalid-name
|
||||
"""Return wind weather data."""
|
||||
return self._data["query"]["results"]["channel"]["wind"]
|
||||
|
||||
@property
|
||||
def Forecast(self): # pylint: disable=invalid-name
|
||||
"""Return forecast data 0-5 Days."""
|
||||
if self.woeid == "123123":
|
||||
raise ValueError
|
||||
return self._data["query"]["results"]["channel"]["item"]["forecast"]
|
||||
|
||||
|
||||
class TestWeather(unittest.TestCase):
|
||||
"""Test the Yahoo weather component."""
|
||||
|
||||
DEVICES = []
|
||||
|
||||
def add_entities(self, devices):
|
||||
"""Mock add devices."""
|
||||
for device in devices:
|
||||
device.update()
|
||||
self.DEVICES.append(device)
|
||||
|
||||
def setUp(self):
|
||||
"""Set up things to be run when tests are started."""
|
||||
self.hass = get_test_home_assistant()
|
||||
self.hass.config.units = METRIC_SYSTEM
|
||||
|
||||
def tearDown(self):
|
||||
"""Stop down everything that was started."""
|
||||
self.hass.stop()
|
||||
|
||||
@MockDependency("yahooweather")
|
||||
@patch("yahooweather._yql_query", new=_yql_queryMock)
|
||||
@patch("yahooweather.get_woeid", new=get_woeidMock)
|
||||
@patch("yahooweather.YahooWeather", new=YahooWeatherMock)
|
||||
def test_setup(self, mock_yahooweather):
|
||||
"""Test for typical weather data attributes."""
|
||||
assert setup_component(
|
||||
self.hass, "weather", {"weather": {"platform": "yweather"}}
|
||||
)
|
||||
|
||||
state = self.hass.states.get("weather.yweather")
|
||||
assert state is not None
|
||||
|
||||
assert state.state == "cloudy"
|
||||
|
||||
data = state.attributes
|
||||
assert data.get(ATTR_WEATHER_TEMPERATURE) == 18.0
|
||||
assert data.get(ATTR_WEATHER_HUMIDITY) == 71
|
||||
assert data.get(ATTR_WEATHER_PRESSURE) == 1000.0
|
||||
assert data.get(ATTR_WEATHER_WIND_SPEED) == 3.94
|
||||
assert data.get(ATTR_WEATHER_WIND_BEARING) == 0
|
||||
assert state.attributes.get("friendly_name") == "Yweather"
|
||||
|
||||
@MockDependency("yahooweather")
|
||||
@patch("yahooweather._yql_query", new=_yql_queryMock)
|
||||
@patch("yahooweather.get_woeid", new=get_woeidMock)
|
||||
@patch("yahooweather.YahooWeather", new=YahooWeatherMock)
|
||||
def test_setup_no_data(self, mock_yahooweather):
|
||||
"""Test for note receiving data."""
|
||||
assert setup_component(
|
||||
self.hass,
|
||||
"weather",
|
||||
{"weather": {"platform": "yweather", "woeid": "12345"}},
|
||||
)
|
||||
|
||||
state = self.hass.states.get("weather.yweather")
|
||||
assert state is not None
|
||||
|
||||
@MockDependency("yahooweather")
|
||||
@patch("yahooweather._yql_query", new=_yql_queryMock)
|
||||
@patch("yahooweather.get_woeid", new=get_woeidMock)
|
||||
@patch("yahooweather.YahooWeather", new=YahooWeatherMock)
|
||||
def test_setup_bad_data(self, mock_yahooweather):
|
||||
"""Test for bad forecast data."""
|
||||
assert setup_component(
|
||||
self.hass,
|
||||
"weather",
|
||||
{"weather": {"platform": "yweather", "woeid": "123123"}},
|
||||
)
|
||||
|
||||
state = self.hass.states.get("weather.yweather")
|
||||
assert state is None
|
||||
|
||||
@MockDependency("yahooweather")
|
||||
@patch("yahooweather._yql_query", new=_yql_queryMock)
|
||||
@patch("yahooweather.get_woeid", new=get_woeidMock)
|
||||
@patch("yahooweather.YahooWeather", new=YahooWeatherMock)
|
||||
def test_setup_condition_error(self, mock_yahooweather):
|
||||
"""Test for bad forecast data."""
|
||||
assert setup_component(
|
||||
self.hass, "weather", {"weather": {"platform": "yweather", "woeid": "111"}}
|
||||
)
|
||||
|
||||
state = self.hass.states.get("weather.yweather")
|
||||
assert state is None
|
Loading…
Add table
Reference in a new issue