Remove legacy get forecast service from Weather (#118664)
* Remove legacy get forecast service from Weather * Fix tests * Fix test --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>pull/119858/head
parent
75e8fc0f9c
commit
b6b6248713
|
@ -37,7 +37,6 @@ from homeassistant.helpers.config_validation import ( # noqa: F401
|
|||
)
|
||||
from homeassistant.helpers.entity import ABCCachedProperties, Entity, EntityDescription
|
||||
from homeassistant.helpers.entity_component import EntityComponent
|
||||
import homeassistant.helpers.issue_registry as ir
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
from homeassistant.helpers.update_coordinator import (
|
||||
CoordinatorEntity,
|
||||
|
@ -123,8 +122,6 @@ SCAN_INTERVAL = timedelta(seconds=30)
|
|||
|
||||
ROUNDING_PRECISION = 2
|
||||
|
||||
LEGACY_SERVICE_GET_FORECAST: Final = "get_forecast"
|
||||
"""Deprecated: please use SERVICE_GET_FORECASTS."""
|
||||
SERVICE_GET_FORECASTS: Final = "get_forecasts"
|
||||
|
||||
_ObservationUpdateCoordinatorT = TypeVar(
|
||||
|
@ -204,17 +201,6 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
component = hass.data[DOMAIN] = EntityComponent[WeatherEntity](
|
||||
_LOGGER, DOMAIN, hass, SCAN_INTERVAL
|
||||
)
|
||||
component.async_register_legacy_entity_service(
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
{vol.Required("type"): vol.In(("daily", "hourly", "twice_daily"))},
|
||||
async_get_forecast_service,
|
||||
required_features=[
|
||||
WeatherEntityFeature.FORECAST_DAILY,
|
||||
WeatherEntityFeature.FORECAST_HOURLY,
|
||||
WeatherEntityFeature.FORECAST_TWICE_DAILY,
|
||||
],
|
||||
supports_response=SupportsResponse.ONLY,
|
||||
)
|
||||
component.async_register_entity_service(
|
||||
SERVICE_GET_FORECASTS,
|
||||
{vol.Required("type"): vol.In(("daily", "hourly", "twice_daily"))},
|
||||
|
@ -1012,32 +998,6 @@ def raise_unsupported_forecast(entity_id: str, forecast_type: str) -> None:
|
|||
)
|
||||
|
||||
|
||||
async def async_get_forecast_service(
|
||||
weather: WeatherEntity, service_call: ServiceCall
|
||||
) -> ServiceResponse:
|
||||
"""Get weather forecast.
|
||||
|
||||
Deprecated: please use async_get_forecasts_service.
|
||||
"""
|
||||
_LOGGER.warning(
|
||||
"Detected use of service 'weather.get_forecast'. "
|
||||
"This is deprecated and will stop working in Home Assistant 2024.6. "
|
||||
"Use 'weather.get_forecasts' instead which supports multiple entities",
|
||||
)
|
||||
ir.async_create_issue(
|
||||
weather.hass,
|
||||
DOMAIN,
|
||||
"deprecated_service_weather_get_forecast",
|
||||
breaks_in_ha_version="2024.6.0",
|
||||
is_fixable=True,
|
||||
is_persistent=False,
|
||||
issue_domain=weather.platform.platform_name,
|
||||
severity=ir.IssueSeverity.WARNING,
|
||||
translation_key="deprecated_service_weather_get_forecast",
|
||||
)
|
||||
return await async_get_forecasts_service(weather, service_call)
|
||||
|
||||
|
||||
async def async_get_forecasts_service(
|
||||
weather: WeatherEntity, service_call: ServiceCall
|
||||
) -> ServiceResponse:
|
||||
|
|
|
@ -11,7 +11,6 @@ from homeassistant.components.accuweather.const import UPDATE_INTERVAL_DAILY_FOR
|
|||
from homeassistant.components.weather import (
|
||||
ATTR_FORECAST_CONDITION,
|
||||
DOMAIN as WEATHER_DOMAIN,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
SERVICE_GET_FORECASTS,
|
||||
)
|
||||
from homeassistant.const import ATTR_ENTITY_ID, STATE_UNAVAILABLE, Platform
|
||||
|
@ -109,10 +108,7 @@ async def test_unsupported_condition_icon_data(
|
|||
|
||||
@pytest.mark.parametrize(
|
||||
("service"),
|
||||
[
|
||||
SERVICE_GET_FORECASTS,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
],
|
||||
[SERVICE_GET_FORECASTS],
|
||||
)
|
||||
async def test_forecast_service(
|
||||
hass: HomeAssistant,
|
||||
|
|
|
@ -18,7 +18,6 @@ from homeassistant.components.weather import (
|
|||
ATTR_WEATHER_WIND_GUST_SPEED,
|
||||
ATTR_WEATHER_WIND_SPEED,
|
||||
DOMAIN as WEATHER_DOMAIN,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
SERVICE_GET_FORECASTS,
|
||||
)
|
||||
from homeassistant.const import ATTR_ATTRIBUTION
|
||||
|
@ -56,10 +55,7 @@ async def test_aemet_weather(
|
|||
|
||||
@pytest.mark.parametrize(
|
||||
("service"),
|
||||
[
|
||||
SERVICE_GET_FORECASTS,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
],
|
||||
[SERVICE_GET_FORECASTS],
|
||||
)
|
||||
async def test_forecast_service(
|
||||
hass: HomeAssistant,
|
||||
|
|
|
@ -15,7 +15,6 @@ from homeassistant.components.weather import (
|
|||
ATTR_WEATHER_WIND_BEARING,
|
||||
ATTR_WEATHER_WIND_SPEED,
|
||||
DOMAIN as WEATHER_DOMAIN,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
SERVICE_GET_FORECASTS,
|
||||
)
|
||||
from homeassistant.const import STATE_UNKNOWN
|
||||
|
@ -101,10 +100,7 @@ async def test_failed_get_observation_forecast(hass: HomeAssistant) -> None:
|
|||
|
||||
@pytest.mark.parametrize(
|
||||
("service"),
|
||||
[
|
||||
SERVICE_GET_FORECASTS,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
],
|
||||
[SERVICE_GET_FORECASTS],
|
||||
)
|
||||
async def test_forecast_service(
|
||||
hass: HomeAssistant,
|
||||
|
|
|
@ -10,7 +10,6 @@ from homeassistant.components.met_eireann import UPDATE_INTERVAL
|
|||
from homeassistant.components.met_eireann.const import DOMAIN
|
||||
from homeassistant.components.weather import (
|
||||
DOMAIN as WEATHER_DOMAIN,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
SERVICE_GET_FORECASTS,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
|
@ -65,10 +64,7 @@ async def test_weather(hass: HomeAssistant, mock_weather) -> None:
|
|||
|
||||
@pytest.mark.parametrize(
|
||||
("service"),
|
||||
[
|
||||
SERVICE_GET_FORECASTS,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
],
|
||||
[SERVICE_GET_FORECASTS],
|
||||
)
|
||||
async def test_forecast_service(
|
||||
hass: HomeAssistant,
|
||||
|
|
|
@ -14,7 +14,6 @@ from syrupy.assertion import SnapshotAssertion
|
|||
from homeassistant.components.metoffice.const import DEFAULT_SCAN_INTERVAL, DOMAIN
|
||||
from homeassistant.components.weather import (
|
||||
DOMAIN as WEATHER_DOMAIN,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
SERVICE_GET_FORECASTS,
|
||||
)
|
||||
from homeassistant.const import STATE_UNAVAILABLE
|
||||
|
@ -254,10 +253,7 @@ async def test_new_config_entry(
|
|||
@pytest.mark.freeze_time(datetime.datetime(2020, 4, 25, 12, tzinfo=datetime.UTC))
|
||||
@pytest.mark.parametrize(
|
||||
("service"),
|
||||
[
|
||||
SERVICE_GET_FORECASTS,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
],
|
||||
[SERVICE_GET_FORECASTS],
|
||||
)
|
||||
async def test_forecast_service(
|
||||
hass: HomeAssistant,
|
||||
|
|
|
@ -23,7 +23,6 @@ from homeassistant.components.weather import (
|
|||
ATTR_WEATHER_WIND_SPEED,
|
||||
ATTR_WEATHER_WIND_SPEED_UNIT,
|
||||
DOMAIN as WEATHER_DOMAIN,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
SERVICE_GET_FORECASTS,
|
||||
)
|
||||
from homeassistant.const import ATTR_ATTRIBUTION, STATE_UNKNOWN, UnitOfSpeed
|
||||
|
@ -489,10 +488,7 @@ async def test_forecast_services_lack_of_data(
|
|||
|
||||
@pytest.mark.parametrize(
|
||||
("service"),
|
||||
[
|
||||
SERVICE_GET_FORECASTS,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
],
|
||||
[SERVICE_GET_FORECASTS],
|
||||
)
|
||||
async def test_forecast_service(
|
||||
hass: HomeAssistant,
|
||||
|
|
|
@ -18,7 +18,6 @@ from homeassistant.components.weather import (
|
|||
ATTR_WEATHER_WIND_GUST_SPEED,
|
||||
ATTR_WEATHER_WIND_SPEED,
|
||||
DOMAIN as WEATHER_DOMAIN,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
SERVICE_GET_FORECASTS,
|
||||
Forecast,
|
||||
)
|
||||
|
@ -96,10 +95,7 @@ async def test_template_state_text(hass: HomeAssistant, start_ha) -> None:
|
|||
|
||||
@pytest.mark.parametrize(
|
||||
("service"),
|
||||
[
|
||||
SERVICE_GET_FORECASTS,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
],
|
||||
[SERVICE_GET_FORECASTS],
|
||||
)
|
||||
@pytest.mark.parametrize(("count", "domain"), [(1, WEATHER_DOMAIN)])
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -224,7 +220,6 @@ async def test_forecasts(
|
|||
("service", "expected"),
|
||||
[
|
||||
(SERVICE_GET_FORECASTS, {"weather.forecast": {"forecast": []}}),
|
||||
(LEGACY_SERVICE_GET_FORECAST, {"forecast": []}),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(("count", "domain"), [(1, WEATHER_DOMAIN)])
|
||||
|
@ -308,7 +303,6 @@ async def test_forecast_invalid(
|
|||
("service", "expected"),
|
||||
[
|
||||
(SERVICE_GET_FORECASTS, {"weather.forecast": {"forecast": []}}),
|
||||
(LEGACY_SERVICE_GET_FORECAST, {"forecast": []}),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(("count", "domain"), [(1, WEATHER_DOMAIN)])
|
||||
|
@ -377,7 +371,6 @@ async def test_forecast_invalid_is_daytime_missing_in_twice_daily(
|
|||
("service", "expected"),
|
||||
[
|
||||
(SERVICE_GET_FORECASTS, {"weather.forecast": {"forecast": []}}),
|
||||
(LEGACY_SERVICE_GET_FORECAST, {"forecast": []}),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(("count", "domain"), [(1, WEATHER_DOMAIN)])
|
||||
|
@ -444,10 +437,7 @@ async def test_forecast_invalid_datetime_missing(
|
|||
|
||||
@pytest.mark.parametrize(
|
||||
("service"),
|
||||
[
|
||||
SERVICE_GET_FORECASTS,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
],
|
||||
[SERVICE_GET_FORECASTS],
|
||||
)
|
||||
@pytest.mark.parametrize(("count", "domain"), [(1, WEATHER_DOMAIN)])
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -679,10 +669,7 @@ async def test_trigger_action(
|
|||
|
||||
@pytest.mark.parametrize(
|
||||
("service"),
|
||||
[
|
||||
SERVICE_GET_FORECASTS,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
],
|
||||
[SERVICE_GET_FORECASTS],
|
||||
)
|
||||
@pytest.mark.parametrize(("count", "domain"), [(1, "template")])
|
||||
@pytest.mark.parametrize(
|
||||
|
|
|
@ -36,7 +36,6 @@ from homeassistant.components.weather import (
|
|||
ATTR_WEATHER_WIND_SPEED,
|
||||
ATTR_WEATHER_WIND_SPEED_UNIT,
|
||||
DOMAIN as WEATHER_DOMAIN,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
SERVICE_GET_FORECASTS,
|
||||
)
|
||||
from homeassistant.config_entries import RELOAD_AFTER_UPDATE_DELAY, SOURCE_USER
|
||||
|
@ -243,10 +242,7 @@ async def test_v4_weather_legacy_entities(hass: HomeAssistant) -> None:
|
|||
|
||||
@pytest.mark.parametrize(
|
||||
("service"),
|
||||
[
|
||||
SERVICE_GET_FORECASTS,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
],
|
||||
[SERVICE_GET_FORECASTS],
|
||||
)
|
||||
@freeze_time(datetime(2021, 3, 6, 23, 59, 59, tzinfo=dt_util.UTC))
|
||||
async def test_v4_forecast_service(
|
||||
|
@ -272,37 +268,6 @@ async def test_v4_forecast_service(
|
|||
assert response == snapshot
|
||||
|
||||
|
||||
async def test_legacy_v4_bad_forecast(
|
||||
hass: HomeAssistant,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
tomorrowio_config_entry_update,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test bad forecast data."""
|
||||
freezer.move_to(datetime(2021, 3, 6, 23, 59, 59, tzinfo=dt_util.UTC))
|
||||
|
||||
weather_state = await _setup(hass, API_V4_ENTRY_DATA)
|
||||
entity_id = weather_state.entity_id
|
||||
hourly_forecast = tomorrowio_config_entry_update.return_value["forecasts"]["hourly"]
|
||||
hourly_forecast[0]["values"]["precipitationProbability"] = "blah"
|
||||
|
||||
# Trigger data refetch
|
||||
freezer.tick(timedelta(minutes=32) + timedelta(seconds=1))
|
||||
await hass.async_block_till_done()
|
||||
|
||||
response = await hass.services.async_call(
|
||||
WEATHER_DOMAIN,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
{
|
||||
"entity_id": entity_id,
|
||||
"type": "hourly",
|
||||
},
|
||||
blocking=True,
|
||||
return_response=True,
|
||||
)
|
||||
assert response["forecast"][0]["precipitation_probability"] is None
|
||||
|
||||
|
||||
async def test_v4_bad_forecast(
|
||||
hass: HomeAssistant,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
|
|
|
@ -22,7 +22,6 @@ from homeassistant.components.weather import (
|
|||
ATTR_WEATHER_WIND_SPEED,
|
||||
ATTR_WEATHER_WIND_SPEED_UNIT,
|
||||
DOMAIN,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
ROUNDING_PRECISION,
|
||||
SERVICE_GET_FORECASTS,
|
||||
Forecast,
|
||||
|
@ -47,7 +46,6 @@ from homeassistant.const import (
|
|||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
import homeassistant.helpers.issue_registry as ir
|
||||
from homeassistant.util import dt as dt_util
|
||||
from homeassistant.util.unit_conversion import (
|
||||
DistanceConverter,
|
||||
|
@ -608,7 +606,6 @@ async def test_forecast_twice_daily_missing_is_daytime(
|
|||
("service"),
|
||||
[
|
||||
SERVICE_GET_FORECASTS,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -681,12 +678,6 @@ async def test_get_forecast(
|
|||
}
|
||||
},
|
||||
),
|
||||
(
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
{
|
||||
"forecast": [],
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_get_forecast_no_forecast(
|
||||
|
@ -727,10 +718,7 @@ async def test_get_forecast_no_forecast(
|
|||
|
||||
@pytest.mark.parametrize(
|
||||
("service"),
|
||||
[
|
||||
SERVICE_GET_FORECASTS,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
],
|
||||
[SERVICE_GET_FORECASTS],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
("supported_features", "forecast_types"),
|
||||
|
@ -786,52 +774,3 @@ async def test_get_forecast_unsupported(
|
|||
|
||||
|
||||
ISSUE_TRACKER = "https://blablabla.com"
|
||||
|
||||
|
||||
async def test_issue_deprecated_service_weather_get_forecast(
|
||||
hass: HomeAssistant,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
config_flow_fixture: None,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test the issue is raised on deprecated service weather.get_forecast."""
|
||||
|
||||
class MockWeatherMock(MockWeatherTest):
|
||||
"""Mock weather class."""
|
||||
|
||||
async def async_forecast_daily(self) -> list[Forecast] | None:
|
||||
"""Return the forecast_daily."""
|
||||
return self.forecast_list
|
||||
|
||||
kwargs = {
|
||||
"native_temperature": 38,
|
||||
"native_temperature_unit": UnitOfTemperature.CELSIUS,
|
||||
"supported_features": WeatherEntityFeature.FORECAST_DAILY,
|
||||
}
|
||||
|
||||
entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs)
|
||||
|
||||
_ = await hass.services.async_call(
|
||||
DOMAIN,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
{
|
||||
"entity_id": entity0.entity_id,
|
||||
"type": "daily",
|
||||
},
|
||||
blocking=True,
|
||||
return_response=True,
|
||||
)
|
||||
|
||||
issue = issue_registry.async_get_issue(
|
||||
"weather", "deprecated_service_weather_get_forecast"
|
||||
)
|
||||
assert issue
|
||||
assert issue.issue_domain == "test"
|
||||
assert issue.issue_id == "deprecated_service_weather_get_forecast"
|
||||
assert issue.translation_key == "deprecated_service_weather_get_forecast"
|
||||
|
||||
assert (
|
||||
"Detected use of service 'weather.get_forecast'. "
|
||||
"This is deprecated and will stop working in Home Assistant 2024.6. "
|
||||
"Use 'weather.get_forecasts' instead which supports multiple entities"
|
||||
) in caplog.text
|
||||
|
|
|
@ -16,7 +16,6 @@ from homeassistant.components.weather import (
|
|||
ATTR_WEATHER_WIND_GUST_SPEED,
|
||||
ATTR_WEATHER_WIND_SPEED,
|
||||
DOMAIN as WEATHER_DOMAIN,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
SERVICE_GET_FORECASTS,
|
||||
WeatherEntityFeature,
|
||||
)
|
||||
|
@ -81,10 +80,7 @@ async def test_hourly_forecast_missing(hass: HomeAssistant) -> None:
|
|||
|
||||
@pytest.mark.parametrize(
|
||||
("service"),
|
||||
[
|
||||
SERVICE_GET_FORECASTS,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
],
|
||||
[SERVICE_GET_FORECASTS],
|
||||
)
|
||||
async def test_hourly_forecast(
|
||||
hass: HomeAssistant, snapshot: SnapshotAssertion, service: str
|
||||
|
@ -107,10 +103,7 @@ async def test_hourly_forecast(
|
|||
|
||||
@pytest.mark.parametrize(
|
||||
("service"),
|
||||
[
|
||||
SERVICE_GET_FORECASTS,
|
||||
LEGACY_SERVICE_GET_FORECAST,
|
||||
],
|
||||
[SERVICE_GET_FORECASTS],
|
||||
)
|
||||
async def test_daily_forecast(
|
||||
hass: HomeAssistant, snapshot: SnapshotAssertion, service: str
|
||||
|
|
Loading…
Reference in New Issue