261 lines
7.9 KiB
Python
261 lines
7.9 KiB
Python
"""Tests for the NWS weather component."""
|
|
from homeassistant.components.nws.weather import ATTR_FORECAST_PRECIP_PROB
|
|
from homeassistant.components.weather import (
|
|
ATTR_FORECAST,
|
|
ATTR_FORECAST_CONDITION,
|
|
ATTR_FORECAST_TEMP,
|
|
ATTR_FORECAST_TIME,
|
|
ATTR_FORECAST_WIND_BEARING,
|
|
ATTR_FORECAST_WIND_SPEED,
|
|
ATTR_WEATHER_HUMIDITY,
|
|
ATTR_WEATHER_PRESSURE,
|
|
ATTR_WEATHER_TEMPERATURE,
|
|
ATTR_WEATHER_VISIBILITY,
|
|
ATTR_WEATHER_WIND_BEARING,
|
|
ATTR_WEATHER_WIND_SPEED,
|
|
)
|
|
from homeassistant.const import (
|
|
LENGTH_KILOMETERS,
|
|
LENGTH_METERS,
|
|
LENGTH_MILES,
|
|
PRESSURE_HPA,
|
|
PRESSURE_INHG,
|
|
PRESSURE_PA,
|
|
TEMP_CELSIUS,
|
|
TEMP_FAHRENHEIT,
|
|
)
|
|
from homeassistant.setup import async_setup_component
|
|
from homeassistant.util.distance import convert as convert_distance
|
|
from homeassistant.util.pressure import convert as convert_pressure
|
|
from homeassistant.util.temperature import convert as convert_temperature
|
|
from homeassistant.util.unit_system import IMPERIAL_SYSTEM, METRIC_SYSTEM
|
|
|
|
from tests.common import assert_setup_component, load_fixture
|
|
|
|
EXP_OBS_IMP = {
|
|
ATTR_WEATHER_TEMPERATURE: round(
|
|
convert_temperature(26.7, TEMP_CELSIUS, TEMP_FAHRENHEIT)
|
|
),
|
|
ATTR_WEATHER_WIND_BEARING: 190,
|
|
ATTR_WEATHER_WIND_SPEED: round(
|
|
convert_distance(2.6, LENGTH_METERS, LENGTH_MILES) * 3600
|
|
),
|
|
ATTR_WEATHER_PRESSURE: round(
|
|
convert_pressure(101040, PRESSURE_PA, PRESSURE_INHG), 2
|
|
),
|
|
ATTR_WEATHER_VISIBILITY: round(
|
|
convert_distance(16090, LENGTH_METERS, LENGTH_MILES)
|
|
),
|
|
ATTR_WEATHER_HUMIDITY: 64,
|
|
}
|
|
|
|
EXP_OBS_METR = {
|
|
ATTR_WEATHER_TEMPERATURE: round(26.7),
|
|
ATTR_WEATHER_WIND_BEARING: 190,
|
|
ATTR_WEATHER_WIND_SPEED: round(
|
|
convert_distance(2.6, LENGTH_METERS, LENGTH_KILOMETERS) * 3600
|
|
),
|
|
ATTR_WEATHER_PRESSURE: round(convert_pressure(101040, PRESSURE_PA, PRESSURE_HPA)),
|
|
ATTR_WEATHER_VISIBILITY: round(
|
|
convert_distance(16090, LENGTH_METERS, LENGTH_KILOMETERS)
|
|
),
|
|
ATTR_WEATHER_HUMIDITY: 64,
|
|
}
|
|
|
|
EXP_FORE_IMP = {
|
|
ATTR_FORECAST_CONDITION: "lightning-rainy",
|
|
ATTR_FORECAST_TIME: "2019-08-12T20:00:00-04:00",
|
|
ATTR_FORECAST_TEMP: 70,
|
|
ATTR_FORECAST_WIND_SPEED: 10,
|
|
ATTR_FORECAST_WIND_BEARING: 180,
|
|
ATTR_FORECAST_PRECIP_PROB: 90,
|
|
}
|
|
|
|
EXP_FORE_METR = {
|
|
ATTR_FORECAST_CONDITION: "lightning-rainy",
|
|
ATTR_FORECAST_TIME: "2019-08-12T20:00:00-04:00",
|
|
ATTR_FORECAST_TEMP: round(convert_temperature(70, TEMP_FAHRENHEIT, TEMP_CELSIUS)),
|
|
ATTR_FORECAST_WIND_SPEED: round(
|
|
convert_distance(10, LENGTH_MILES, LENGTH_KILOMETERS)
|
|
),
|
|
ATTR_FORECAST_WIND_BEARING: 180,
|
|
ATTR_FORECAST_PRECIP_PROB: 90,
|
|
}
|
|
|
|
|
|
MINIMAL_CONFIG = {
|
|
"weather": {
|
|
"platform": "nws",
|
|
"api_key": "x@example.com",
|
|
"latitude": 40.0,
|
|
"longitude": -85.0,
|
|
}
|
|
}
|
|
|
|
INVALID_CONFIG = {
|
|
"weather": {"platform": "nws", "api_key": "x@example.com", "latitude": 40.0}
|
|
}
|
|
|
|
STAURL = "https://api.weather.gov/points/{},{}/stations"
|
|
OBSURL = "https://api.weather.gov/stations/{}/observations/"
|
|
FORCURL = "https://api.weather.gov/points/{},{}/forecast"
|
|
|
|
|
|
async def test_imperial(hass, aioclient_mock):
|
|
"""Test with imperial units."""
|
|
aioclient_mock.get(
|
|
STAURL.format(40.0, -85.0), text=load_fixture("nws-weather-sta-valid.json")
|
|
)
|
|
aioclient_mock.get(
|
|
OBSURL.format("KMIE"), text=load_fixture("nws-weather-obs-valid.json")
|
|
)
|
|
aioclient_mock.get(
|
|
FORCURL.format(40.0, -85.0), text=load_fixture("nws-weather-fore-valid.json")
|
|
)
|
|
|
|
hass.config.units = IMPERIAL_SYSTEM
|
|
|
|
with assert_setup_component(1, "weather"):
|
|
await async_setup_component(hass, "weather", MINIMAL_CONFIG)
|
|
|
|
state = hass.states.get("weather.kmie")
|
|
assert state
|
|
assert state.state == "sunny"
|
|
|
|
data = state.attributes
|
|
for key, value in EXP_OBS_IMP.items():
|
|
assert data.get(key) == value
|
|
assert state.attributes.get("friendly_name") == "KMIE"
|
|
forecast = data.get(ATTR_FORECAST)
|
|
for key, value in EXP_FORE_IMP.items():
|
|
assert forecast[0].get(key) == value
|
|
|
|
|
|
async def test_metric(hass, aioclient_mock):
|
|
"""Test with metric units."""
|
|
aioclient_mock.get(
|
|
STAURL.format(40.0, -85.0), text=load_fixture("nws-weather-sta-valid.json")
|
|
)
|
|
aioclient_mock.get(
|
|
OBSURL.format("KMIE"), text=load_fixture("nws-weather-obs-valid.json")
|
|
)
|
|
aioclient_mock.get(
|
|
FORCURL.format(40.0, -85.0), text=load_fixture("nws-weather-fore-valid.json")
|
|
)
|
|
|
|
hass.config.units = METRIC_SYSTEM
|
|
|
|
with assert_setup_component(1, "weather"):
|
|
await async_setup_component(hass, "weather", MINIMAL_CONFIG)
|
|
|
|
state = hass.states.get("weather.kmie")
|
|
assert state
|
|
assert state.state == "sunny"
|
|
|
|
data = state.attributes
|
|
for key, value in EXP_OBS_METR.items():
|
|
assert data.get(key) == value
|
|
assert state.attributes.get("friendly_name") == "KMIE"
|
|
forecast = data.get(ATTR_FORECAST)
|
|
for key, value in EXP_FORE_METR.items():
|
|
assert forecast[0].get(key) == value
|
|
|
|
|
|
async def test_none(hass, aioclient_mock):
|
|
"""Test with imperial units."""
|
|
aioclient_mock.get(
|
|
STAURL.format(40.0, -85.0), text=load_fixture("nws-weather-sta-valid.json")
|
|
)
|
|
aioclient_mock.get(
|
|
OBSURL.format("KMIE"), text=load_fixture("nws-weather-obs-null.json")
|
|
)
|
|
aioclient_mock.get(
|
|
FORCURL.format(40.0, -85.0), text=load_fixture("nws-weather-fore-null.json")
|
|
)
|
|
|
|
hass.config.units = IMPERIAL_SYSTEM
|
|
|
|
with assert_setup_component(1, "weather"):
|
|
await async_setup_component(hass, "weather", MINIMAL_CONFIG)
|
|
|
|
state = hass.states.get("weather.kmie")
|
|
assert state
|
|
assert state.state == "unknown"
|
|
|
|
data = state.attributes
|
|
for key in EXP_OBS_IMP:
|
|
assert data.get(key) is None
|
|
assert state.attributes.get("friendly_name") == "KMIE"
|
|
forecast = data.get(ATTR_FORECAST)
|
|
for key in EXP_FORE_IMP:
|
|
assert forecast[0].get(key) is None
|
|
|
|
|
|
async def test_fail_obs(hass, aioclient_mock):
|
|
"""Test failing observation/forecast update."""
|
|
aioclient_mock.get(
|
|
STAURL.format(40.0, -85.0), text=load_fixture("nws-weather-sta-valid.json")
|
|
)
|
|
aioclient_mock.get(
|
|
OBSURL.format("KMIE"),
|
|
text=load_fixture("nws-weather-obs-valid.json"),
|
|
status=400,
|
|
)
|
|
aioclient_mock.get(
|
|
FORCURL.format(40.0, -85.0),
|
|
text=load_fixture("nws-weather-fore-valid.json"),
|
|
status=400,
|
|
)
|
|
|
|
hass.config.units = IMPERIAL_SYSTEM
|
|
|
|
with assert_setup_component(1, "weather"):
|
|
await async_setup_component(hass, "weather", MINIMAL_CONFIG)
|
|
|
|
state = hass.states.get("weather.kmie")
|
|
assert state
|
|
|
|
|
|
async def test_fail_stn(hass, aioclient_mock):
|
|
"""Test failing station update."""
|
|
aioclient_mock.get(
|
|
STAURL.format(40.0, -85.0),
|
|
text=load_fixture("nws-weather-sta-valid.json"),
|
|
status=400,
|
|
)
|
|
aioclient_mock.get(
|
|
OBSURL.format("KMIE"), text=load_fixture("nws-weather-obs-valid.json")
|
|
)
|
|
aioclient_mock.get(
|
|
FORCURL.format(40.0, -85.0), text=load_fixture("nws-weather-fore-valid.json")
|
|
)
|
|
|
|
hass.config.units = IMPERIAL_SYSTEM
|
|
|
|
with assert_setup_component(1, "weather"):
|
|
await async_setup_component(hass, "weather", MINIMAL_CONFIG)
|
|
|
|
state = hass.states.get("weather.kmie")
|
|
assert state is None
|
|
|
|
|
|
async def test_invalid_config(hass, aioclient_mock):
|
|
"""Test invalid config.."""
|
|
aioclient_mock.get(
|
|
STAURL.format(40.0, -85.0), text=load_fixture("nws-weather-sta-valid.json")
|
|
)
|
|
aioclient_mock.get(
|
|
OBSURL.format("KMIE"), text=load_fixture("nws-weather-obs-valid.json")
|
|
)
|
|
aioclient_mock.get(
|
|
FORCURL.format(40.0, -85.0), text=load_fixture("nws-weather-fore-valid.json")
|
|
)
|
|
|
|
hass.config.units = IMPERIAL_SYSTEM
|
|
|
|
with assert_setup_component(0, "weather"):
|
|
await async_setup_component(hass, "weather", INVALID_CONFIG)
|
|
|
|
state = hass.states.get("weather.kmie")
|
|
assert state is None
|