"""Tests for the NWS weather component.""" from homeassistant.components.nws.weather import ATTR_FORECAST_PRECIP_PROB from homeassistant.components.weather import ( ATTR_WEATHER_HUMIDITY, ATTR_WEATHER_PRESSURE, ATTR_WEATHER_TEMPERATURE, ATTR_WEATHER_VISIBILITY, ATTR_WEATHER_WIND_BEARING, ATTR_WEATHER_WIND_SPEED, ) from homeassistant.components.weather import ( ATTR_FORECAST, ATTR_FORECAST_CONDITION, ATTR_FORECAST_TEMP, ATTR_FORECAST_TIME, ATTR_FORECAST_WIND_BEARING, ATTR_FORECAST_WIND_SPEED, ) from homeassistant.const import ( LENGTH_KILOMETERS, LENGTH_METERS, LENGTH_MILES, PRESSURE_INHG, PRESSURE_PA, PRESSURE_HPA, TEMP_CELSIUS, TEMP_FAHRENHEIT, ) from homeassistant.util.pressure import convert as convert_pressure from homeassistant.util.distance import convert as convert_distance from homeassistant.util.unit_system import IMPERIAL_SYSTEM, METRIC_SYSTEM from homeassistant.util.temperature import convert as convert_temperature from homeassistant.setup import async_setup_component from tests.common import load_fixture, assert_setup_component 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