diff --git a/homeassistant/components/nws/weather.py b/homeassistant/components/nws/weather.py index 025a3640ec6..0c76c31887c 100644 --- a/homeassistant/components/nws/weather.py +++ b/homeassistant/components/nws/weather.py @@ -85,17 +85,15 @@ async def async_setup_entry( entity_registry = er.async_get(hass) nws_data: NWSData = hass.data[DOMAIN][entry.entry_id] - entities = [NWSWeather(entry.data, nws_data, DAYNIGHT)] - - # Add hourly entity to legacy config entries - if entity_registry.async_get_entity_id( + # Remove hourly entity from legacy config entries + if entity_id := entity_registry.async_get_entity_id( WEATHER_DOMAIN, DOMAIN, _calculate_unique_id(entry.data, HOURLY), ): - entities.append(NWSWeather(entry.data, nws_data, HOURLY)) + entity_registry.async_remove(entity_id) - async_add_entities(entities, False) + async_add_entities([NWSWeather(entry.data, nws_data)], False) if TYPE_CHECKING: @@ -130,7 +128,6 @@ class NWSWeather(CoordinatorWeatherEntity): self, entry_data: MappingProxyType[str, Any], nws_data: NWSData, - mode: str, ) -> None: """Initialise the platform with a data instance and station name.""" super().__init__( @@ -143,23 +140,17 @@ class NWSWeather(CoordinatorWeatherEntity): self.nws = nws_data.api latitude = entry_data[CONF_LATITUDE] longitude = entry_data[CONF_LONGITUDE] - if mode == DAYNIGHT: - self.coordinator_forecast_legacy = nws_data.coordinator_forecast - else: - self.coordinator_forecast_legacy = nws_data.coordinator_forecast_hourly + self.coordinator_forecast_legacy = nws_data.coordinator_forecast self.station = self.nws.station - self.mode = mode - self._attr_entity_registry_enabled_default = mode == DAYNIGHT - self.observation: dict[str, Any] | None = None self._forecast_hourly: list[dict[str, Any]] | None = None self._forecast_legacy: list[dict[str, Any]] | None = None self._forecast_twice_daily: list[dict[str, Any]] | None = None - self._attr_unique_id = _calculate_unique_id(entry_data, mode) + self._attr_unique_id = _calculate_unique_id(entry_data, DAYNIGHT) self._attr_device_info = device_info(latitude, longitude) - self._attr_name = f"{self.station} {self.mode.title()}" + self._attr_name = self.station async def async_added_to_hass(self) -> None: """Set up a listener and load data.""" @@ -194,10 +185,7 @@ class NWSWeather(CoordinatorWeatherEntity): @callback def _handle_legacy_forecast_coordinator_update(self) -> None: """Handle updated data from the legacy forecast coordinator.""" - if self.mode == DAYNIGHT: - self._forecast_legacy = self.nws.forecast - else: - self._forecast_legacy = self.nws.forecast_hourly + self._forecast_legacy = self.nws.forecast self.async_write_ha_state() @property @@ -314,7 +302,7 @@ class NWSWeather(CoordinatorWeatherEntity): @property def forecast(self) -> list[Forecast] | None: """Return forecast.""" - return self._forecast(self._forecast_legacy, self.mode) + return self._forecast(self._forecast_legacy, DAYNIGHT) @callback def _async_forecast_hourly(self) -> list[Forecast] | None: diff --git a/tests/components/nws/snapshots/test_weather.ambr b/tests/components/nws/snapshots/test_weather.ambr index 0db2311085c..f4669f47615 100644 --- a/tests/components/nws/snapshots/test_weather.ambr +++ b/tests/components/nws/snapshots/test_weather.ambr @@ -1,213 +1,4 @@ # serializer version: 1 -# name: test_forecast_service - dict({ - 'forecast': list([ - dict({ - 'condition': 'lightning-rainy', - 'datetime': '2019-08-12T20:00:00-04:00', - 'detailed_description': 'A detailed forecast.', - 'dew_point': -15.6, - 'humidity': 75, - 'is_daytime': False, - 'precipitation_probability': 89, - 'temperature': -12.2, - 'wind_bearing': 180, - 'wind_speed': 16.09, - }), - ]), - }) -# --- -# name: test_forecast_service.1 - dict({ - 'forecast': list([ - dict({ - 'condition': 'lightning-rainy', - 'datetime': '2019-08-12T20:00:00-04:00', - 'detailed_description': 'A detailed forecast.', - 'dew_point': -15.6, - 'humidity': 75, - 'precipitation_probability': 89, - 'temperature': -12.2, - 'wind_bearing': 180, - 'wind_speed': 16.09, - }), - ]), - }) -# --- -# name: test_forecast_service.2 - dict({ - 'forecast': list([ - dict({ - 'condition': 'lightning-rainy', - 'datetime': '2019-08-12T20:00:00-04:00', - 'detailed_description': 'A detailed forecast.', - 'dew_point': -15.6, - 'humidity': 75, - 'is_daytime': False, - 'precipitation_probability': 89, - 'temperature': -12.2, - 'wind_bearing': 180, - 'wind_speed': 16.09, - }), - ]), - }) -# --- -# name: test_forecast_service.3 - dict({ - 'forecast': list([ - dict({ - 'condition': 'lightning-rainy', - 'datetime': '2019-08-12T20:00:00-04:00', - 'detailed_description': 'A detailed forecast.', - 'dew_point': -15.6, - 'humidity': 75, - 'precipitation_probability': 89, - 'temperature': -12.2, - 'wind_bearing': 180, - 'wind_speed': 16.09, - }), - ]), - }) -# --- -# name: test_forecast_service.4 - dict({ - 'forecast': list([ - dict({ - 'condition': 'lightning-rainy', - 'datetime': '2019-08-12T20:00:00-04:00', - 'detailed_description': 'A detailed forecast.', - 'dew_point': -15.6, - 'humidity': 75, - 'precipitation_probability': 89, - 'temperature': -12.2, - 'wind_bearing': 180, - 'wind_speed': 16.09, - }), - ]), - }) -# --- -# name: test_forecast_service.5 - dict({ - 'forecast': list([ - dict({ - 'condition': 'lightning-rainy', - 'datetime': '2019-08-12T20:00:00-04:00', - 'detailed_description': 'A detailed forecast.', - 'dew_point': -15.6, - 'humidity': 75, - 'precipitation_probability': 89, - 'temperature': -12.2, - 'wind_bearing': 180, - 'wind_speed': 16.09, - }), - ]), - }) -# --- -# name: test_forecast_service[forecast] - dict({ - 'weather.abc_daynight': dict({ - 'forecast': list([ - dict({ - 'condition': 'lightning-rainy', - 'datetime': '2019-08-12T20:00:00-04:00', - 'detailed_description': 'A detailed forecast.', - 'dew_point': -15.6, - 'humidity': 75, - 'is_daytime': False, - 'precipitation_probability': 89, - 'temperature': -12.2, - 'wind_bearing': 180, - 'wind_speed': 16.09, - }), - ]), - }), - }) -# --- -# name: test_forecast_service[forecast].1 - dict({ - 'weather.abc_daynight': dict({ - 'forecast': list([ - dict({ - 'condition': 'lightning-rainy', - 'datetime': '2019-08-12T20:00:00-04:00', - 'detailed_description': 'A detailed forecast.', - 'dew_point': -15.6, - 'humidity': 75, - 'precipitation_probability': 89, - 'temperature': -12.2, - 'wind_bearing': 180, - 'wind_speed': 16.09, - }), - ]), - }), - }) -# --- -# name: test_forecast_service[forecast].2 - dict({ - 'weather.abc_daynight': dict({ - 'forecast': list([ - dict({ - 'condition': 'lightning-rainy', - 'datetime': '2019-08-12T20:00:00-04:00', - 'detailed_description': 'A detailed forecast.', - 'dew_point': -15.6, - 'humidity': 75, - 'is_daytime': False, - 'precipitation_probability': 89, - 'temperature': -12.2, - 'wind_bearing': 180, - 'wind_speed': 16.09, - }), - ]), - }), - }) -# --- -# name: test_forecast_service[forecast].3 - dict({ - 'weather.abc_daynight': dict({ - 'forecast': list([ - dict({ - 'condition': 'lightning-rainy', - 'datetime': '2019-08-12T20:00:00-04:00', - 'detailed_description': 'A detailed forecast.', - 'dew_point': -15.6, - 'humidity': 75, - 'precipitation_probability': 89, - 'temperature': -12.2, - 'wind_bearing': 180, - 'wind_speed': 16.09, - }), - ]), - }), - }) -# --- -# name: test_forecast_service[forecast].4 - dict({ - 'weather.abc_daynight': dict({ - 'forecast': list([ - dict({ - 'condition': 'lightning-rainy', - 'datetime': '2019-08-12T20:00:00-04:00', - 'detailed_description': 'A detailed forecast.', - 'dew_point': -15.6, - 'humidity': 75, - 'precipitation_probability': 89, - 'temperature': -12.2, - 'wind_bearing': 180, - 'wind_speed': 16.09, - }), - ]), - }), - }) -# --- -# name: test_forecast_service[forecast].5 - dict({ - 'weather.abc_daynight': dict({ - 'forecast': list([ - ]), - }), - }) -# --- # name: test_forecast_service[get_forecast] dict({ 'forecast': list([ @@ -303,7 +94,7 @@ # --- # name: test_forecast_service[get_forecasts] dict({ - 'weather.abc_daynight': dict({ + 'weather.abc': dict({ 'forecast': list([ dict({ 'condition': 'lightning-rainy', @@ -323,7 +114,7 @@ # --- # name: test_forecast_service[get_forecasts].1 dict({ - 'weather.abc_daynight': dict({ + 'weather.abc': dict({ 'forecast': list([ dict({ 'condition': 'lightning-rainy', @@ -342,7 +133,7 @@ # --- # name: test_forecast_service[get_forecasts].2 dict({ - 'weather.abc_daynight': dict({ + 'weather.abc': dict({ 'forecast': list([ dict({ 'condition': 'lightning-rainy', @@ -362,7 +153,7 @@ # --- # name: test_forecast_service[get_forecasts].3 dict({ - 'weather.abc_daynight': dict({ + 'weather.abc': dict({ 'forecast': list([ dict({ 'condition': 'lightning-rainy', @@ -381,7 +172,7 @@ # --- # name: test_forecast_service[get_forecasts].4 dict({ - 'weather.abc_daynight': dict({ + 'weather.abc': dict({ 'forecast': list([ dict({ 'condition': 'lightning-rainy', @@ -400,13 +191,13 @@ # --- # name: test_forecast_service[get_forecasts].5 dict({ - 'weather.abc_daynight': dict({ + 'weather.abc': dict({ 'forecast': list([ ]), }), }) # --- -# name: test_forecast_subscription[hourly-weather.abc_daynight] +# name: test_forecast_subscription[hourly-weather.abc] list([ dict({ 'condition': 'lightning-rainy', @@ -421,7 +212,7 @@ }), ]) # --- -# name: test_forecast_subscription[hourly-weather.abc_daynight].1 +# name: test_forecast_subscription[hourly-weather.abc].1 list([ dict({ 'condition': 'lightning-rainy', @@ -436,97 +227,3 @@ }), ]) # --- -# name: test_forecast_subscription[hourly] - list([ - dict({ - 'condition': 'lightning-rainy', - 'datetime': '2019-08-12T20:00:00-04:00', - 'detailed_description': 'A detailed forecast.', - 'dew_point': -15.6, - 'humidity': 75, - 'precipitation_probability': 89, - 'temperature': -12.2, - 'wind_bearing': 180, - 'wind_speed': 16.09, - }), - ]) -# --- -# name: test_forecast_subscription[hourly].1 - list([ - dict({ - 'condition': 'lightning-rainy', - 'datetime': '2019-08-12T20:00:00-04:00', - 'detailed_description': 'A detailed forecast.', - 'dew_point': -15.6, - 'humidity': 75, - 'precipitation_probability': 89, - 'temperature': -12.2, - 'wind_bearing': 180, - 'wind_speed': 16.09, - }), - ]) -# --- -# name: test_forecast_subscription[twice_daily-weather.abc_hourly] - list([ - dict({ - 'condition': 'lightning-rainy', - 'datetime': '2019-08-12T20:00:00-04:00', - 'detailed_description': 'A detailed forecast.', - 'dew_point': -15.6, - 'humidity': 75, - 'is_daytime': False, - 'precipitation_probability': 89, - 'temperature': -12.2, - 'wind_bearing': 180, - 'wind_speed': 16.09, - }), - ]) -# --- -# name: test_forecast_subscription[twice_daily-weather.abc_hourly].1 - list([ - dict({ - 'condition': 'lightning-rainy', - 'datetime': '2019-08-12T20:00:00-04:00', - 'detailed_description': 'A detailed forecast.', - 'dew_point': -15.6, - 'humidity': 75, - 'is_daytime': False, - 'precipitation_probability': 89, - 'temperature': -12.2, - 'wind_bearing': 180, - 'wind_speed': 16.09, - }), - ]) -# --- -# name: test_forecast_subscription[twice_daily] - list([ - dict({ - 'condition': 'lightning-rainy', - 'datetime': '2019-08-12T20:00:00-04:00', - 'detailed_description': 'A detailed forecast.', - 'dew_point': -15.6, - 'humidity': 75, - 'is_daytime': False, - 'precipitation_probability': 89, - 'temperature': -12.2, - 'wind_bearing': 180, - 'wind_speed': 16.09, - }), - ]) -# --- -# name: test_forecast_subscription[twice_daily].1 - list([ - dict({ - 'condition': 'lightning-rainy', - 'datetime': '2019-08-12T20:00:00-04:00', - 'detailed_description': 'A detailed forecast.', - 'dew_point': -15.6, - 'humidity': 75, - 'is_daytime': False, - 'precipitation_probability': 89, - 'temperature': -12.2, - 'wind_bearing': 180, - 'wind_speed': 16.09, - }), - ]) -# --- diff --git a/tests/components/nws/test_weather.py b/tests/components/nws/test_weather.py index b2c67cb58f9..da365c52ffc 100644 --- a/tests/components/nws/test_weather.py +++ b/tests/components/nws/test_weather.py @@ -59,16 +59,6 @@ async def test_imperial_metric( no_sensor, ) -> None: """Test with imperial and metric units.""" - # enable the hourly entity - registry = er.async_get(hass) - registry.async_get_or_create( - WEATHER_DOMAIN, - nws.DOMAIN, - "35_-75_hourly", - suggested_object_id="abc_hourly", - disabled_by=None, - ) - hass.config.units = units entry = MockConfigEntry( domain=nws.DOMAIN, @@ -78,20 +68,7 @@ async def test_imperial_metric( await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() - state = hass.states.get("weather.abc_hourly") - - assert state - assert state.state == ATTR_CONDITION_SUNNY - - data = state.attributes - for key, value in result_observation.items(): - assert data.get(key) == value - - forecast = data.get(ATTR_FORECAST) - for key, value in result_forecast.items(): - assert forecast[0].get(key) == value - - state = hass.states.get("weather.abc_daynight") + state = hass.states.get("weather.abc") assert state assert state.state == ATTR_CONDITION_SUNNY @@ -118,7 +95,7 @@ async def test_night_clear(hass: HomeAssistant, mock_simple_nws, no_sensor) -> N await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() - state = hass.states.get("weather.abc_daynight") + state = hass.states.get("weather.abc") assert state.state == ATTR_CONDITION_CLEAR_NIGHT @@ -136,7 +113,7 @@ async def test_none_values(hass: HomeAssistant, mock_simple_nws, no_sensor) -> N await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() - state = hass.states.get("weather.abc_daynight") + state = hass.states.get("weather.abc") assert state.state == STATE_UNKNOWN data = state.attributes for key in WEATHER_EXPECTED_OBSERVATION_IMPERIAL: @@ -161,7 +138,7 @@ async def test_none(hass: HomeAssistant, mock_simple_nws, no_sensor) -> None: await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() - state = hass.states.get("weather.abc_daynight") + state = hass.states.get("weather.abc") assert state assert state.state == STATE_UNKNOWN @@ -187,8 +164,7 @@ async def test_error_station(hass: HomeAssistant, mock_simple_nws, no_sensor) -> await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() - assert hass.states.get("weather.abc_hourly") is None - assert hass.states.get("weather.abc_daynight") is None + assert hass.states.get("weather.abc") is None async def test_entity_refresh(hass: HomeAssistant, mock_simple_nws, no_sensor) -> None: @@ -211,7 +187,7 @@ async def test_entity_refresh(hass: HomeAssistant, mock_simple_nws, no_sensor) - await hass.services.async_call( "homeassistant", "update_entity", - {"entity_id": "weather.abc_daynight"}, + {"entity_id": "weather.abc"}, blocking=True, ) await hass.async_block_till_done() @@ -250,7 +226,7 @@ async def test_error_observation( instance.update_observation.assert_called_once() - state = hass.states.get("weather.abc_daynight") + state = hass.states.get("weather.abc") assert state assert state.state == STATE_UNAVAILABLE @@ -261,7 +237,7 @@ async def test_error_observation( assert instance.update_observation.call_count == 2 - state = hass.states.get("weather.abc_daynight") + state = hass.states.get("weather.abc") assert state assert state.state == ATTR_CONDITION_SUNNY @@ -273,7 +249,7 @@ async def test_error_observation( assert instance.update_observation.call_count == 3 - state = hass.states.get("weather.abc_daynight") + state = hass.states.get("weather.abc") assert state assert state.state == ATTR_CONDITION_SUNNY @@ -281,7 +257,7 @@ async def test_error_observation( increment_time(timedelta(minutes=10)) await hass.async_block_till_done() - state = hass.states.get("weather.abc_daynight") + state = hass.states.get("weather.abc") assert state assert state.state == STATE_UNAVAILABLE @@ -301,7 +277,7 @@ async def test_error_forecast(hass: HomeAssistant, mock_simple_nws, no_sensor) - instance.update_forecast.assert_called_once() - state = hass.states.get("weather.abc_daynight") + state = hass.states.get("weather.abc") assert state assert state.state == STATE_UNAVAILABLE @@ -312,50 +288,7 @@ async def test_error_forecast(hass: HomeAssistant, mock_simple_nws, no_sensor) - assert instance.update_forecast.call_count == 2 - state = hass.states.get("weather.abc_daynight") - assert state - assert state.state == ATTR_CONDITION_SUNNY - - -async def test_error_forecast_hourly( - hass: HomeAssistant, mock_simple_nws, no_sensor -) -> None: - """Test error during update forecast hourly.""" - instance = mock_simple_nws.return_value - instance.update_forecast_hourly.side_effect = aiohttp.ClientError - - # enable the hourly entity - registry = er.async_get(hass) - registry.async_get_or_create( - WEATHER_DOMAIN, - nws.DOMAIN, - "35_-75_hourly", - suggested_object_id="abc_hourly", - disabled_by=None, - ) - - entry = MockConfigEntry( - domain=nws.DOMAIN, - data=NWS_CONFIG, - ) - entry.add_to_hass(hass) - await hass.config_entries.async_setup(entry.entry_id) - await hass.async_block_till_done() - - state = hass.states.get("weather.abc_hourly") - assert state - assert state.state == STATE_UNAVAILABLE - - instance.update_forecast_hourly.assert_called_once() - - instance.update_forecast_hourly.side_effect = None - - async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=1)) - await hass.async_block_till_done() - - assert instance.update_forecast_hourly.call_count == 2 - - state = hass.states.get("weather.abc_hourly") + state = hass.states.get("weather.abc") assert state assert state.state == ATTR_CONDITION_SUNNY @@ -378,30 +311,6 @@ async def test_new_config_entry(hass: HomeAssistant, no_sensor) -> None: assert len(er.async_entries_for_config_entry(registry, entry.entry_id)) == 1 -async def test_legacy_config_entry(hass: HomeAssistant, no_sensor) -> None: - """Test the expected entities are created.""" - registry = er.async_get(hass) - # Pre-create the hourly entity - registry.async_get_or_create( - WEATHER_DOMAIN, - nws.DOMAIN, - "35_-75_hourly", - ) - - entry = MockConfigEntry( - domain=nws.DOMAIN, - data=NWS_CONFIG, - ) - entry.add_to_hass(hass) - - await hass.config_entries.async_setup(entry.entry_id) - await hass.async_block_till_done() - - assert len(hass.states.async_entity_ids("weather")) == 2 - entry = hass.config_entries.async_entries()[0] - assert len(er.async_entries_for_config_entry(registry, entry.entry_id)) == 2 - - @pytest.mark.parametrize( ("service"), [ @@ -437,7 +346,7 @@ async def test_forecast_service( WEATHER_DOMAIN, service, { - "entity_id": "weather.abc_daynight", + "entity_id": "weather.abc", "type": forecast_type, }, blocking=True, @@ -464,7 +373,7 @@ async def test_forecast_service( WEATHER_DOMAIN, service, { - "entity_id": "weather.abc_daynight", + "entity_id": "weather.abc", "type": forecast_type, }, blocking=True, @@ -487,7 +396,7 @@ async def test_forecast_service( WEATHER_DOMAIN, service, { - "entity_id": "weather.abc_daynight", + "entity_id": "weather.abc", "type": "hourly", }, blocking=True, @@ -504,7 +413,7 @@ async def test_forecast_service( WEATHER_DOMAIN, service, { - "entity_id": "weather.abc_daynight", + "entity_id": "weather.abc", "type": "hourly", }, blocking=True, @@ -515,7 +424,7 @@ async def test_forecast_service( @pytest.mark.parametrize( ("forecast_type", "entity_id"), - [("hourly", "weather.abc_daynight"), ("twice_daily", "weather.abc_hourly")], + [("hourly", "weather.abc")], ) async def test_forecast_subscription( hass: HomeAssistant,