mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
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 init
This commit is contained in:
parent
ad5a396c10
commit
e6a6c3ceb6
@ -78,7 +78,7 @@ async def async_setup(hass: HomeAssistant, config: dict):
|
|||||||
|
|
||||||
for component in PLATFORMS:
|
for component in PLATFORMS:
|
||||||
hass.async_create_task(
|
hass.async_create_task(
|
||||||
discovery.async_load_platform(hass, component, DOMAIN, {}, config)
|
discovery.async_load_platform(hass, component, DOMAIN, entry, config)
|
||||||
)
|
)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
@ -129,18 +129,21 @@ class NwsData:
|
|||||||
return self.nws.forecast_hourly
|
return self.nws.forecast_hourly
|
||||||
|
|
||||||
@staticmethod
|
@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:
|
try:
|
||||||
_LOGGER.debug("Updating %s for station %s", update_type, station_name)
|
_LOGGER.debug("Updating %s for station %s", update_type, station_name)
|
||||||
await update_call()
|
await update_call()
|
||||||
|
|
||||||
if success:
|
if not previous_success:
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"Success updating %s for station %s", update_type, station_name
|
"Success updating %s for station %s", update_type, station_name
|
||||||
)
|
)
|
||||||
success = True
|
success = True
|
||||||
except (aiohttp.ClientError, asyncio.TimeoutError) as err:
|
except (aiohttp.ClientError, asyncio.TimeoutError) as err:
|
||||||
if success:
|
if previous_success:
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"Error updating %s for station %s: %s",
|
"Error updating %s for station %s: %s",
|
||||||
update_type,
|
update_type,
|
||||||
@ -148,23 +151,24 @@ class NwsData:
|
|||||||
err,
|
err,
|
||||||
)
|
)
|
||||||
success = False
|
success = False
|
||||||
|
return success
|
||||||
|
|
||||||
async def async_update(self, now=None):
|
async def async_update(self, now=None):
|
||||||
"""Update all data."""
|
"""Update all data."""
|
||||||
|
|
||||||
await self._async_update_item(
|
self.update_observation_success = await self._async_update_item(
|
||||||
self.nws.update_observation,
|
self.nws.update_observation,
|
||||||
"observation",
|
"observation",
|
||||||
self.station,
|
self.station,
|
||||||
self.update_observation_success,
|
self.update_observation_success,
|
||||||
)
|
)
|
||||||
await self._async_update_item(
|
self.update_forecast_success = await self._async_update_item(
|
||||||
self.nws.update_forecast,
|
self.nws.update_forecast,
|
||||||
"forecast",
|
"forecast",
|
||||||
self.station,
|
self.station,
|
||||||
self.update_forecast_success,
|
self.update_forecast_success,
|
||||||
)
|
)
|
||||||
await self._async_update_item(
|
self.update_forecast_hourly_success = await self._async_update_item(
|
||||||
self.nws.update_forecast_hourly,
|
self.nws.update_forecast_hourly,
|
||||||
"forecast_hourly",
|
"forecast_hourly",
|
||||||
self.station,
|
self.station,
|
||||||
|
@ -73,11 +73,13 @@ def convert_condition(time, weather):
|
|||||||
return cond, max(prec_probs)
|
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."""
|
"""Set up the NWS weather platform."""
|
||||||
latitude = config.get(CONF_LATITUDE, hass.config.latitude)
|
if discovery_info is None:
|
||||||
longitude = config.get(CONF_LONGITUDE, hass.config.longitude)
|
return
|
||||||
station = config.get(CONF_STATION)
|
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)]
|
nws_data = hass.data[DOMAIN][base_unique_id(latitude, longitude)]
|
||||||
|
|
||||||
@ -134,7 +136,7 @@ class NWSWeather(WeatherEntity):
|
|||||||
else:
|
else:
|
||||||
self._forecast = self.nws.forecast_hourly
|
self._forecast = self.nws.forecast_hourly
|
||||||
|
|
||||||
self.async_schedule_update_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def should_poll(self) -> bool:
|
def should_poll(self) -> bool:
|
||||||
|
@ -31,7 +31,12 @@ DUPLICATE_CONFIG = {
|
|||||||
async def test_no_config(hass, mock_simple_nws):
|
async def test_no_config(hass, mock_simple_nws):
|
||||||
"""Test that nws does not setup with no config."""
|
"""Test that nws does not setup with no config."""
|
||||||
with assert_setup_component(0):
|
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
|
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."""
|
"""Test that nws setup with minimal config."""
|
||||||
hass.config.latitude = 40.0
|
hass.config.latitude = 40.0
|
||||||
hass.config.longitude = -75.0
|
hass.config.longitude = -75.0
|
||||||
with assert_setup_component(1):
|
with assert_setup_component(1, DOMAIN):
|
||||||
assert await async_setup_component(hass, DOMAIN, MINIMAL_CONFIG) is True
|
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 DOMAIN in hass.data
|
||||||
assert nws.base_unique_id(40.0, -75.0) in hass.data[DOMAIN]
|
assert nws.base_unique_id(40.0, -75.0) in hass.data[DOMAIN]
|
||||||
|
|
||||||
|
|
||||||
async def test_successful_latlon_config(hass, mock_simple_nws):
|
async def test_successful_latlon_config(hass, mock_simple_nws):
|
||||||
"""Test that nws setup with latlon config."""
|
"""Test that nws setup with latlon config."""
|
||||||
with assert_setup_component(1):
|
with assert_setup_component(1, DOMAIN):
|
||||||
assert await async_setup_component(hass, DOMAIN, LATLON_CONFIG) is True
|
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 DOMAIN in hass.data
|
||||||
assert nws.base_unique_id(45.0, -75.0) in hass.data[DOMAIN]
|
assert nws.base_unique_id(45.0, -75.0) in hass.data[DOMAIN]
|
||||||
|
|
||||||
|
|
||||||
async def test_successful_full_config(hass, mock_simple_nws):
|
async def test_successful_full_config(hass, mock_simple_nws):
|
||||||
"""Test that nws setup with full config."""
|
"""Test that nws setup with full config."""
|
||||||
with assert_setup_component(1):
|
with assert_setup_component(1, DOMAIN):
|
||||||
assert await async_setup_component(hass, DOMAIN, FULL_CONFIG) is True
|
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 DOMAIN in hass.data
|
||||||
assert nws.base_unique_id(45.0, -75.0) in hass.data[DOMAIN]
|
assert nws.base_unique_id(45.0, -75.0) in hass.data[DOMAIN]
|
||||||
|
|
||||||
|
|
||||||
async def test_unsuccessful_duplicate_config(hass, mock_simple_nws):
|
async def test_unsuccessful_duplicate_config(hass, mock_simple_nws):
|
||||||
"""Test that nws setup with duplicate config."""
|
"""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
|
assert len(hass.data[DOMAIN]) == 1
|
||||||
|
@ -21,16 +21,6 @@ from tests.components.nws.const import (
|
|||||||
NONE_OBSERVATION,
|
NONE_OBSERVATION,
|
||||||
)
|
)
|
||||||
|
|
||||||
HOURLY_CONFIG = {
|
|
||||||
"weather": {
|
|
||||||
"platform": "nws",
|
|
||||||
"api_key": "x@example.com",
|
|
||||||
"latitude": 40.0,
|
|
||||||
"longitude": -85.0,
|
|
||||||
"mode": "hourly",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"units,result_observation,result_forecast",
|
"units,result_observation,result_forecast",
|
||||||
@ -40,7 +30,7 @@ HOURLY_CONFIG = {
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_imperial_metric(
|
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."""
|
"""Test with imperial and metric units."""
|
||||||
hass.config.units = units
|
hass.config.units = units
|
||||||
@ -73,6 +63,9 @@ async def test_imperial_metric(
|
|||||||
for key, value in result_forecast.items():
|
for key, value in result_forecast.items():
|
||||||
assert forecast[0].get(key) == value
|
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):
|
async def test_none_values(hass, mock_simple_nws):
|
||||||
"""Test with none values in observation and forecast dicts."""
|
"""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)
|
assert await async_setup_component(hass, nws.DOMAIN, MINIMAL_CONFIG)
|
||||||
await hass.async_block_till_done()
|
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
|
instance.update_observation.side_effect = None
|
||||||
|
|
||||||
future_time = dt_util.utcnow() + timedelta(minutes=15)
|
future_time = dt_util.utcnow() + timedelta(minutes=15)
|
||||||
async_fire_time_changed(hass, future_time)
|
async_fire_time_changed(hass, future_time)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert "Error updating observation" in caplog.text
|
assert "Error updating observation for station ABC" not in caplog.text
|
||||||
assert "Success updating observation" in caplog.text
|
assert "Success updating observation for station ABC" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
async def test_error_forecast(hass, caplog, mock_simple_nws):
|
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)
|
assert await async_setup_component(hass, nws.DOMAIN, MINIMAL_CONFIG)
|
||||||
await hass.async_block_till_done()
|
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
|
instance.update_forecast.side_effect = None
|
||||||
|
|
||||||
future_time = dt_util.utcnow() + timedelta(minutes=15)
|
future_time = dt_util.utcnow() + timedelta(minutes=15)
|
||||||
async_fire_time_changed(hass, future_time)
|
async_fire_time_changed(hass, future_time)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert "Error updating forecast" in caplog.text
|
assert "Error updating forecast for station ABC" not in caplog.text
|
||||||
assert "Success updating forecast" in caplog.text
|
assert "Success updating forecast for station ABC" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
async def test_error_forecast_hourly(hass, caplog, mock_simple_nws):
|
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)
|
assert await async_setup_component(hass, nws.DOMAIN, MINIMAL_CONFIG)
|
||||||
await hass.async_block_till_done()
|
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
|
instance.update_forecast_hourly.side_effect = None
|
||||||
|
|
||||||
future_time = dt_util.utcnow() + timedelta(minutes=15)
|
future_time = dt_util.utcnow() + timedelta(minutes=15)
|
||||||
async_fire_time_changed(hass, future_time)
|
async_fire_time_changed(hass, future_time)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert "Error updating forecast_hourly" in caplog.text
|
assert "Error updating forecast_hourly for station ABC" not in caplog.text
|
||||||
assert "Success updating forecast_hourly" in caplog.text
|
assert "Success updating forecast_hourly for station ABC" in caplog.text
|
||||||
|
Loading…
x
Reference in New Issue
Block a user