Fix nws platform setup and data update. (#34106)
* add test and fix tests for update logging. * Fix update logging. * Remove assert is True * guard against platform config and use async_write_ha_state * fix discovery info passing to platform * Improve testing for entities in initpull/34123/head
parent
ad5a396c10
commit
e6a6c3ceb6
|
@ -78,7 +78,7 @@ async def async_setup(hass: HomeAssistant, config: dict):
|
|||
|
||||
for component in PLATFORMS:
|
||||
hass.async_create_task(
|
||||
discovery.async_load_platform(hass, component, DOMAIN, {}, config)
|
||||
discovery.async_load_platform(hass, component, DOMAIN, entry, config)
|
||||
)
|
||||
|
||||
return True
|
||||
|
@ -129,18 +129,21 @@ class NwsData:
|
|||
return self.nws.forecast_hourly
|
||||
|
||||
@staticmethod
|
||||
async def _async_update_item(update_call, update_type, station_name, success):
|
||||
async def _async_update_item(
|
||||
update_call, update_type, station_name, previous_success
|
||||
):
|
||||
"""Update item and handle logging."""
|
||||
try:
|
||||
_LOGGER.debug("Updating %s for station %s", update_type, station_name)
|
||||
await update_call()
|
||||
|
||||
if success:
|
||||
if not previous_success:
|
||||
_LOGGER.warning(
|
||||
"Success updating %s for station %s", update_type, station_name
|
||||
)
|
||||
success = True
|
||||
success = True
|
||||
except (aiohttp.ClientError, asyncio.TimeoutError) as err:
|
||||
if success:
|
||||
if previous_success:
|
||||
_LOGGER.warning(
|
||||
"Error updating %s for station %s: %s",
|
||||
update_type,
|
||||
|
@ -148,23 +151,24 @@ class NwsData:
|
|||
err,
|
||||
)
|
||||
success = False
|
||||
return success
|
||||
|
||||
async def async_update(self, now=None):
|
||||
"""Update all data."""
|
||||
|
||||
await self._async_update_item(
|
||||
self.update_observation_success = await self._async_update_item(
|
||||
self.nws.update_observation,
|
||||
"observation",
|
||||
self.station,
|
||||
self.update_observation_success,
|
||||
)
|
||||
await self._async_update_item(
|
||||
self.update_forecast_success = await self._async_update_item(
|
||||
self.nws.update_forecast,
|
||||
"forecast",
|
||||
self.station,
|
||||
self.update_forecast_success,
|
||||
)
|
||||
await self._async_update_item(
|
||||
self.update_forecast_hourly_success = await self._async_update_item(
|
||||
self.nws.update_forecast_hourly,
|
||||
"forecast_hourly",
|
||||
self.station,
|
||||
|
|
|
@ -73,11 +73,13 @@ def convert_condition(time, weather):
|
|||
return cond, max(prec_probs)
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info):
|
||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
||||
"""Set up the NWS weather platform."""
|
||||
latitude = config.get(CONF_LATITUDE, hass.config.latitude)
|
||||
longitude = config.get(CONF_LONGITUDE, hass.config.longitude)
|
||||
station = config.get(CONF_STATION)
|
||||
if discovery_info is None:
|
||||
return
|
||||
latitude = discovery_info.get(CONF_LATITUDE, hass.config.latitude)
|
||||
longitude = discovery_info.get(CONF_LONGITUDE, hass.config.longitude)
|
||||
station = discovery_info.get(CONF_STATION)
|
||||
|
||||
nws_data = hass.data[DOMAIN][base_unique_id(latitude, longitude)]
|
||||
|
||||
|
@ -134,7 +136,7 @@ class NWSWeather(WeatherEntity):
|
|||
else:
|
||||
self._forecast = self.nws.forecast_hourly
|
||||
|
||||
self.async_schedule_update_ha_state()
|
||||
self.async_write_ha_state()
|
||||
|
||||
@property
|
||||
def should_poll(self) -> bool:
|
||||
|
|
|
@ -31,7 +31,12 @@ DUPLICATE_CONFIG = {
|
|||
async def test_no_config(hass, mock_simple_nws):
|
||||
"""Test that nws does not setup with no config."""
|
||||
with assert_setup_component(0):
|
||||
assert await async_setup_component(hass, DOMAIN, {}) is True
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
entity_registry = await hass.helpers.entity_registry.async_get_registry()
|
||||
assert len(entity_registry.entities) == 0
|
||||
|
||||
assert DOMAIN not in hass.data
|
||||
|
||||
|
||||
|
@ -39,29 +44,49 @@ async def test_successful_minimal_config(hass, mock_simple_nws):
|
|||
"""Test that nws setup with minimal config."""
|
||||
hass.config.latitude = 40.0
|
||||
hass.config.longitude = -75.0
|
||||
with assert_setup_component(1):
|
||||
assert await async_setup_component(hass, DOMAIN, MINIMAL_CONFIG) is True
|
||||
with assert_setup_component(1, DOMAIN):
|
||||
assert await async_setup_component(hass, DOMAIN, MINIMAL_CONFIG)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
entity_registry = await hass.helpers.entity_registry.async_get_registry()
|
||||
assert len(entity_registry.entities) == 2
|
||||
|
||||
assert DOMAIN in hass.data
|
||||
assert nws.base_unique_id(40.0, -75.0) in hass.data[DOMAIN]
|
||||
|
||||
|
||||
async def test_successful_latlon_config(hass, mock_simple_nws):
|
||||
"""Test that nws setup with latlon config."""
|
||||
with assert_setup_component(1):
|
||||
assert await async_setup_component(hass, DOMAIN, LATLON_CONFIG) is True
|
||||
with assert_setup_component(1, DOMAIN):
|
||||
assert await async_setup_component(hass, DOMAIN, LATLON_CONFIG)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
entity_registry = await hass.helpers.entity_registry.async_get_registry()
|
||||
assert len(entity_registry.entities) == 2
|
||||
|
||||
assert DOMAIN in hass.data
|
||||
assert nws.base_unique_id(45.0, -75.0) in hass.data[DOMAIN]
|
||||
|
||||
|
||||
async def test_successful_full_config(hass, mock_simple_nws):
|
||||
"""Test that nws setup with full config."""
|
||||
with assert_setup_component(1):
|
||||
assert await async_setup_component(hass, DOMAIN, FULL_CONFIG) is True
|
||||
with assert_setup_component(1, DOMAIN):
|
||||
assert await async_setup_component(hass, DOMAIN, FULL_CONFIG)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
entity_registry = await hass.helpers.entity_registry.async_get_registry()
|
||||
assert len(entity_registry.entities) == 2
|
||||
|
||||
assert DOMAIN in hass.data
|
||||
assert nws.base_unique_id(45.0, -75.0) in hass.data[DOMAIN]
|
||||
|
||||
|
||||
async def test_unsuccessful_duplicate_config(hass, mock_simple_nws):
|
||||
"""Test that nws setup with duplicate config."""
|
||||
assert await async_setup_component(hass, DOMAIN, DUPLICATE_CONFIG) is True
|
||||
assert await async_setup_component(hass, DOMAIN, DUPLICATE_CONFIG)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
entity_registry = await hass.helpers.entity_registry.async_get_registry()
|
||||
assert len(entity_registry.entities) == 2
|
||||
|
||||
assert len(hass.data[DOMAIN]) == 1
|
||||
|
|
|
@ -21,16 +21,6 @@ from tests.components.nws.const import (
|
|||
NONE_OBSERVATION,
|
||||
)
|
||||
|
||||
HOURLY_CONFIG = {
|
||||
"weather": {
|
||||
"platform": "nws",
|
||||
"api_key": "x@example.com",
|
||||
"latitude": 40.0,
|
||||
"longitude": -85.0,
|
||||
"mode": "hourly",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"units,result_observation,result_forecast",
|
||||
|
@ -40,7 +30,7 @@ HOURLY_CONFIG = {
|
|||
],
|
||||
)
|
||||
async def test_imperial_metric(
|
||||
hass, units, result_observation, result_forecast, mock_simple_nws
|
||||
hass, units, result_observation, result_forecast, mock_simple_nws, caplog
|
||||
):
|
||||
"""Test with imperial and metric units."""
|
||||
hass.config.units = units
|
||||
|
@ -73,6 +63,9 @@ async def test_imperial_metric(
|
|||
for key, value in result_forecast.items():
|
||||
assert forecast[0].get(key) == value
|
||||
|
||||
assert "Error updating observation" not in caplog.text
|
||||
assert "Success updating observation" not in caplog.text
|
||||
|
||||
|
||||
async def test_none_values(hass, mock_simple_nws):
|
||||
"""Test with none values in observation and forecast dicts."""
|
||||
|
@ -136,14 +129,18 @@ async def test_error_observation(hass, mock_simple_nws, caplog):
|
|||
assert await async_setup_component(hass, nws.DOMAIN, MINIMAL_CONFIG)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert "Error updating observation for station ABC" in caplog.text
|
||||
assert "Success updating observation for station ABC" not in caplog.text
|
||||
caplog.clear()
|
||||
|
||||
instance.update_observation.side_effect = None
|
||||
|
||||
future_time = dt_util.utcnow() + timedelta(minutes=15)
|
||||
async_fire_time_changed(hass, future_time)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert "Error updating observation" in caplog.text
|
||||
assert "Success updating observation" in caplog.text
|
||||
assert "Error updating observation for station ABC" not in caplog.text
|
||||
assert "Success updating observation for station ABC" in caplog.text
|
||||
|
||||
|
||||
async def test_error_forecast(hass, caplog, mock_simple_nws):
|
||||
|
@ -154,14 +151,18 @@ async def test_error_forecast(hass, caplog, mock_simple_nws):
|
|||
assert await async_setup_component(hass, nws.DOMAIN, MINIMAL_CONFIG)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert "Error updating forecast for station ABC" in caplog.text
|
||||
assert "Success updating forecast for station ABC" not in caplog.text
|
||||
caplog.clear()
|
||||
|
||||
instance.update_forecast.side_effect = None
|
||||
|
||||
future_time = dt_util.utcnow() + timedelta(minutes=15)
|
||||
async_fire_time_changed(hass, future_time)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert "Error updating forecast" in caplog.text
|
||||
assert "Success updating forecast" in caplog.text
|
||||
assert "Error updating forecast for station ABC" not in caplog.text
|
||||
assert "Success updating forecast for station ABC" in caplog.text
|
||||
|
||||
|
||||
async def test_error_forecast_hourly(hass, caplog, mock_simple_nws):
|
||||
|
@ -172,11 +173,15 @@ async def test_error_forecast_hourly(hass, caplog, mock_simple_nws):
|
|||
assert await async_setup_component(hass, nws.DOMAIN, MINIMAL_CONFIG)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert "Error updating forecast_hourly for station ABC" in caplog.text
|
||||
assert "Success updating forecast_hourly for station ABC" not in caplog.text
|
||||
caplog.clear()
|
||||
|
||||
instance.update_forecast_hourly.side_effect = None
|
||||
|
||||
future_time = dt_util.utcnow() + timedelta(minutes=15)
|
||||
async_fire_time_changed(hass, future_time)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert "Error updating forecast_hourly" in caplog.text
|
||||
assert "Success updating forecast_hourly" in caplog.text
|
||||
assert "Error updating forecast_hourly for station ABC" not in caplog.text
|
||||
assert "Success updating forecast_hourly for station ABC" in caplog.text
|
||||
|
|
Loading…
Reference in New Issue