Deprecate weather.get_forecast (#102534)

* Deprecate weather.get_forecast

* Rename forecast to get_forecasts

* raise issue for use of deprecated service

* Add fix_flow

* Add service translation/yaml
pull/104226/head
Kevin Stillhammer 2023-11-19 20:44:02 +01:00 committed by GitHub
parent 41224f1674
commit 173f4760bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 18726 additions and 76 deletions

View File

@ -135,7 +135,9 @@ SCAN_INTERVAL = timedelta(seconds=30)
ROUNDING_PRECISION = 2
SERVICE_GET_FORECAST: Final = "get_forecast"
LEGACY_SERVICE_GET_FORECAST: Final = "get_forecast"
"""Deprecated: please use SERVICE_GET_FORECASTS."""
SERVICE_GET_FORECASTS: Final = "get_forecasts"
_ObservationUpdateCoordinatorT = TypeVar(
"_ObservationUpdateCoordinatorT", bound="DataUpdateCoordinator[Any]"
@ -211,7 +213,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
_LOGGER, DOMAIN, hass, SCAN_INTERVAL
)
component.async_register_legacy_entity_service(
SERVICE_GET_FORECAST,
LEGACY_SERVICE_GET_FORECAST,
{vol.Required("type"): vol.In(("daily", "hourly", "twice_daily"))},
async_get_forecast_service,
required_features=[
@ -221,6 +223,17 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
],
supports_response=SupportsResponse.ONLY,
)
component.async_register_entity_service(
SERVICE_GET_FORECASTS,
{vol.Required("type"): vol.In(("daily", "hourly", "twice_daily"))},
async_get_forecasts_service,
required_features=[
WeatherEntityFeature.FORECAST_DAILY,
WeatherEntityFeature.FORECAST_HOURLY,
WeatherEntityFeature.FORECAST_TWICE_DAILY,
],
supports_response=SupportsResponse.ONLY,
)
async_setup_ws_api(hass)
await component.async_setup(config)
return True
@ -1086,6 +1099,32 @@ 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:
"""Get weather forecast."""
forecast_type = service_call.data["type"]

View File

@ -16,3 +16,21 @@ get_forecast:
- "hourly"
- "twice_daily"
translation_key: forecast_type
get_forecasts:
target:
entity:
domain: weather
supported_features:
- weather.WeatherEntityFeature.FORECAST_DAILY
- weather.WeatherEntityFeature.FORECAST_HOURLY
- weather.WeatherEntityFeature.FORECAST_TWICE_DAILY
fields:
type:
required: true
selector:
select:
options:
- "daily"
- "hourly"
- "twice_daily"
translation_key: forecast_type

View File

@ -88,13 +88,23 @@
}
},
"services": {
"get_forecasts": {
"name": "Get forecasts",
"description": "Get weather forecasts.",
"fields": {
"type": {
"name": "Forecast type",
"description": "Forecast type: daily, hourly or twice daily."
}
}
},
"get_forecast": {
"name": "Get forecast",
"description": "Get weather forecast.",
"fields": {
"type": {
"name": "Forecast type",
"description": "Forecast type: daily, hourly or twice daily."
"name": "[%key:component::weather::services::get_forecasts::fields::type::name%]",
"description": "[%key:component::weather::services::get_forecasts::fields::type::description%]"
}
}
}
@ -107,6 +117,17 @@
"deprecated_weather_forecast_no_url": {
"title": "[%key:component::weather::issues::deprecated_weather_forecast_url::title%]",
"description": "The custom integration `{platform}` implements the `forecast` property or sets `self._attr_forecast` in a subclass of WeatherEntity.\n\nPlease report it to the author of the {platform} integration.\n\nOnce an updated version of `{platform}` is available, install it and restart Home Assistant to fix this issue."
},
"deprecated_service_weather_get_forecast": {
"title": "Detected use of deprecated service `weather.get_forecast`",
"fix_flow": {
"step": {
"confirm": {
"title": "[%key:component::weather::issues::deprecated_service_weather_get_forecast::title%]",
"description": "Use `weather.get_forecasts` instead which supports multiple entities.\n\nPlease replace this service and adjust your automations and scripts and select **submit** to close this issue."
}
}
}
}
}
}

View File

@ -75,6 +75,238 @@
]),
})
# ---
# name: test_forecast_service[forecast]
dict({
'weather.home': dict({
'forecast': list([
dict({
'apparent_temperature': 29.8,
'cloud_coverage': 58,
'condition': 'lightning-rainy',
'datetime': '2020-07-26T05:00:00+00:00',
'precipitation': 2.5,
'precipitation_probability': 60,
'temperature': 29.5,
'templow': 15.4,
'uv_index': 5,
'wind_bearing': 166,
'wind_gust_speed': 29.6,
'wind_speed': 13.0,
}),
dict({
'apparent_temperature': 28.9,
'cloud_coverage': 52,
'condition': 'partlycloudy',
'datetime': '2020-07-27T05:00:00+00:00',
'precipitation': 0.0,
'precipitation_probability': 25,
'temperature': 26.2,
'templow': 15.9,
'uv_index': 7,
'wind_bearing': 297,
'wind_gust_speed': 14.8,
'wind_speed': 9.3,
}),
dict({
'apparent_temperature': 31.6,
'cloud_coverage': 65,
'condition': 'partlycloudy',
'datetime': '2020-07-28T05:00:00+00:00',
'precipitation': 0.0,
'precipitation_probability': 10,
'temperature': 31.7,
'templow': 16.8,
'uv_index': 7,
'wind_bearing': 198,
'wind_gust_speed': 24.1,
'wind_speed': 16.7,
}),
dict({
'apparent_temperature': 26.5,
'cloud_coverage': 45,
'condition': 'partlycloudy',
'datetime': '2020-07-29T05:00:00+00:00',
'precipitation': 0.0,
'precipitation_probability': 9,
'temperature': 24.0,
'templow': 11.7,
'uv_index': 6,
'wind_bearing': 293,
'wind_gust_speed': 24.1,
'wind_speed': 13.0,
}),
dict({
'apparent_temperature': 22.2,
'cloud_coverage': 50,
'condition': 'partlycloudy',
'datetime': '2020-07-30T05:00:00+00:00',
'precipitation': 0.0,
'precipitation_probability': 1,
'temperature': 21.4,
'templow': 12.2,
'uv_index': 7,
'wind_bearing': 280,
'wind_gust_speed': 27.8,
'wind_speed': 18.5,
}),
]),
}),
})
# ---
# name: test_forecast_service[get_forecast]
dict({
'forecast': list([
dict({
'apparent_temperature': 29.8,
'cloud_coverage': 58,
'condition': 'lightning-rainy',
'datetime': '2020-07-26T05:00:00+00:00',
'precipitation': 2.5,
'precipitation_probability': 60,
'temperature': 29.5,
'templow': 15.4,
'uv_index': 5,
'wind_bearing': 166,
'wind_gust_speed': 29.6,
'wind_speed': 13.0,
}),
dict({
'apparent_temperature': 28.9,
'cloud_coverage': 52,
'condition': 'partlycloudy',
'datetime': '2020-07-27T05:00:00+00:00',
'precipitation': 0.0,
'precipitation_probability': 25,
'temperature': 26.2,
'templow': 15.9,
'uv_index': 7,
'wind_bearing': 297,
'wind_gust_speed': 14.8,
'wind_speed': 9.3,
}),
dict({
'apparent_temperature': 31.6,
'cloud_coverage': 65,
'condition': 'partlycloudy',
'datetime': '2020-07-28T05:00:00+00:00',
'precipitation': 0.0,
'precipitation_probability': 10,
'temperature': 31.7,
'templow': 16.8,
'uv_index': 7,
'wind_bearing': 198,
'wind_gust_speed': 24.1,
'wind_speed': 16.7,
}),
dict({
'apparent_temperature': 26.5,
'cloud_coverage': 45,
'condition': 'partlycloudy',
'datetime': '2020-07-29T05:00:00+00:00',
'precipitation': 0.0,
'precipitation_probability': 9,
'temperature': 24.0,
'templow': 11.7,
'uv_index': 6,
'wind_bearing': 293,
'wind_gust_speed': 24.1,
'wind_speed': 13.0,
}),
dict({
'apparent_temperature': 22.2,
'cloud_coverage': 50,
'condition': 'partlycloudy',
'datetime': '2020-07-30T05:00:00+00:00',
'precipitation': 0.0,
'precipitation_probability': 1,
'temperature': 21.4,
'templow': 12.2,
'uv_index': 7,
'wind_bearing': 280,
'wind_gust_speed': 27.8,
'wind_speed': 18.5,
}),
]),
})
# ---
# name: test_forecast_service[get_forecasts]
dict({
'weather.home': dict({
'forecast': list([
dict({
'apparent_temperature': 29.8,
'cloud_coverage': 58,
'condition': 'lightning-rainy',
'datetime': '2020-07-26T05:00:00+00:00',
'precipitation': 2.5,
'precipitation_probability': 60,
'temperature': 29.5,
'templow': 15.4,
'uv_index': 5,
'wind_bearing': 166,
'wind_gust_speed': 29.6,
'wind_speed': 13.0,
}),
dict({
'apparent_temperature': 28.9,
'cloud_coverage': 52,
'condition': 'partlycloudy',
'datetime': '2020-07-27T05:00:00+00:00',
'precipitation': 0.0,
'precipitation_probability': 25,
'temperature': 26.2,
'templow': 15.9,
'uv_index': 7,
'wind_bearing': 297,
'wind_gust_speed': 14.8,
'wind_speed': 9.3,
}),
dict({
'apparent_temperature': 31.6,
'cloud_coverage': 65,
'condition': 'partlycloudy',
'datetime': '2020-07-28T05:00:00+00:00',
'precipitation': 0.0,
'precipitation_probability': 10,
'temperature': 31.7,
'templow': 16.8,
'uv_index': 7,
'wind_bearing': 198,
'wind_gust_speed': 24.1,
'wind_speed': 16.7,
}),
dict({
'apparent_temperature': 26.5,
'cloud_coverage': 45,
'condition': 'partlycloudy',
'datetime': '2020-07-29T05:00:00+00:00',
'precipitation': 0.0,
'precipitation_probability': 9,
'temperature': 24.0,
'templow': 11.7,
'uv_index': 6,
'wind_bearing': 293,
'wind_gust_speed': 24.1,
'wind_speed': 13.0,
}),
dict({
'apparent_temperature': 22.2,
'cloud_coverage': 50,
'condition': 'partlycloudy',
'datetime': '2020-07-30T05:00:00+00:00',
'precipitation': 0.0,
'precipitation_probability': 1,
'temperature': 21.4,
'templow': 12.2,
'uv_index': 7,
'wind_bearing': 280,
'wind_gust_speed': 27.8,
'wind_speed': 18.5,
}),
]),
}),
})
# ---
# name: test_forecast_subscription
list([
dict({

View File

@ -3,6 +3,7 @@ from datetime import timedelta
from unittest.mock import PropertyMock, patch
from freezegun.api import FrozenDateTimeFactory
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.accuweather.const import ATTRIBUTION
@ -31,7 +32,8 @@ from homeassistant.components.weather import (
ATTR_WEATHER_WIND_GUST_SPEED,
ATTR_WEATHER_WIND_SPEED,
DOMAIN as WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
LEGACY_SERVICE_GET_FORECAST,
SERVICE_GET_FORECASTS,
WeatherEntityFeature,
)
from homeassistant.const import (
@ -206,16 +208,24 @@ async def test_unsupported_condition_icon_data(hass: HomeAssistant) -> None:
assert state.attributes.get(ATTR_FORECAST_CONDITION) is None
@pytest.mark.parametrize(
("service"),
[
SERVICE_GET_FORECASTS,
LEGACY_SERVICE_GET_FORECAST,
],
)
async def test_forecast_service(
hass: HomeAssistant,
snapshot: SnapshotAssertion,
service: str,
) -> None:
"""Test multiple forecast."""
await init_integration(hass, forecast=True)
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": "weather.home",
"type": "daily",
@ -223,7 +233,6 @@ async def test_forecast_service(
blocking=True,
return_response=True,
)
assert response["forecast"] != []
assert response == snapshot

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,8 @@ from homeassistant.components.weather import (
ATTR_WEATHER_WIND_GUST_SPEED,
ATTR_WEATHER_WIND_SPEED,
DOMAIN as WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
LEGACY_SERVICE_GET_FORECAST,
SERVICE_GET_FORECASTS,
)
from homeassistant.const import ATTR_ATTRIBUTION
from homeassistant.core import HomeAssistant
@ -122,10 +123,18 @@ async def test_aemet_weather_legacy(
assert state is None
@pytest.mark.parametrize(
("service"),
[
SERVICE_GET_FORECASTS,
LEGACY_SERVICE_GET_FORECAST,
],
)
async def test_forecast_service(
hass: HomeAssistant,
freezer: FrozenDateTimeFactory,
snapshot: SnapshotAssertion,
service: str,
) -> None:
"""Test multiple forecast."""
@ -135,7 +144,7 @@ async def test_forecast_service(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": "weather.aemet",
"type": "daily",
@ -147,7 +156,7 @@ async def test_forecast_service(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": "weather.aemet",
"type": "hourly",

View File

@ -36,6 +36,125 @@
]),
})
# ---
# name: test_forecast_service[forecast]
dict({
'weather.hometown': dict({
'forecast': list([
dict({
'condition': 'rainy',
'datetime': datetime.datetime(2020, 1, 16, 0, 0),
'precipitation_probability': '100.0',
'temperature': 16.2,
'templow': 10.6,
'wind_bearing': 'S',
'wind_speed': 10.0,
}),
]),
}),
})
# ---
# name: test_forecast_service[forecast].1
dict({
'weather.hometown': dict({
'forecast': list([
dict({
'condition': 'rainy',
'datetime': datetime.datetime(2020, 1, 15, 1, 0, tzinfo=datetime.timezone.utc),
'precipitation_probability': 80.0,
'temperature': 12.0,
'wind_bearing': 'S',
'wind_speed': 32.7,
}),
dict({
'condition': 'clear-night',
'datetime': datetime.datetime(2020, 1, 15, 2, 0, tzinfo=datetime.timezone.utc),
'precipitation_probability': 80.0,
'temperature': 12.0,
'wind_bearing': 'S',
'wind_speed': 32.7,
}),
]),
}),
})
# ---
# name: test_forecast_service[get_forecast]
dict({
'forecast': list([
dict({
'condition': 'rainy',
'datetime': datetime.datetime(2020, 1, 16, 0, 0),
'precipitation_probability': '100.0',
'temperature': 16.2,
'templow': 10.6,
'wind_bearing': 'S',
'wind_speed': 10.0,
}),
]),
})
# ---
# name: test_forecast_service[get_forecast].1
dict({
'forecast': list([
dict({
'condition': 'rainy',
'datetime': datetime.datetime(2020, 1, 15, 1, 0, tzinfo=datetime.timezone.utc),
'precipitation_probability': 80.0,
'temperature': 12.0,
'wind_bearing': 'S',
'wind_speed': 32.7,
}),
dict({
'condition': 'clear-night',
'datetime': datetime.datetime(2020, 1, 15, 2, 0, tzinfo=datetime.timezone.utc),
'precipitation_probability': 80.0,
'temperature': 12.0,
'wind_bearing': 'S',
'wind_speed': 32.7,
}),
]),
})
# ---
# name: test_forecast_service[get_forecasts]
dict({
'weather.hometown': dict({
'forecast': list([
dict({
'condition': 'rainy',
'datetime': datetime.datetime(2020, 1, 16, 0, 0),
'precipitation_probability': '100.0',
'temperature': 16.2,
'templow': 10.6,
'wind_bearing': 'S',
'wind_speed': 10.0,
}),
]),
}),
})
# ---
# name: test_forecast_service[get_forecasts].1
dict({
'weather.hometown': dict({
'forecast': list([
dict({
'condition': 'rainy',
'datetime': datetime.datetime(2020, 1, 15, 1, 0, tzinfo=datetime.timezone.utc),
'precipitation_probability': 80.0,
'temperature': 12.0,
'wind_bearing': 'S',
'wind_speed': 32.7,
}),
dict({
'condition': 'clear-night',
'datetime': datetime.datetime(2020, 1, 15, 2, 0, tzinfo=datetime.timezone.utc),
'precipitation_probability': 80.0,
'temperature': 12.0,
'wind_bearing': 'S',
'wind_speed': 32.7,
}),
]),
}),
})
# ---
# name: test_forecast_subscription[daily]
list([
dict({

View File

@ -22,7 +22,8 @@ from homeassistant.components.weather import (
ATTR_WEATHER_WIND_BEARING,
ATTR_WEATHER_WIND_SPEED,
DOMAIN as WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
LEGACY_SERVICE_GET_FORECAST,
SERVICE_GET_FORECASTS,
)
from homeassistant.const import STATE_UNKNOWN
from homeassistant.core import HomeAssistant
@ -152,9 +153,17 @@ async def test_failed_get_observation_forecast(hass: HomeAssistant) -> None:
assert state.attributes.get("friendly_name") == "HomeTown"
@pytest.mark.parametrize(
("service"),
[
SERVICE_GET_FORECASTS,
LEGACY_SERVICE_GET_FORECAST,
],
)
async def test_forecast_service(
hass: HomeAssistant,
snapshot: SnapshotAssertion,
service: str,
) -> None:
"""Test multiple forecast."""
@ -169,7 +178,7 @@ async def test_forecast_service(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": "weather.hometown",
"type": "daily",
@ -181,7 +190,7 @@ async def test_forecast_service(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": "weather.hometown",
"type": "hourly",

View File

@ -31,6 +31,110 @@
]),
})
# ---
# name: test_forecast_service[forecast]
dict({
'weather.somewhere': dict({
'forecast': list([
dict({
'condition': 'lightning-rainy',
'datetime': '2023-08-08T12:00:00+00:00',
'temperature': 10.0,
}),
dict({
'condition': 'lightning-rainy',
'datetime': '2023-08-09T12:00:00+00:00',
'temperature': 20.0,
}),
]),
}),
})
# ---
# name: test_forecast_service[forecast].1
dict({
'weather.somewhere': dict({
'forecast': list([
dict({
'condition': 'lightning-rainy',
'datetime': '2023-08-08T12:00:00+00:00',
'temperature': 10.0,
}),
dict({
'condition': 'lightning-rainy',
'datetime': '2023-08-09T12:00:00+00:00',
'temperature': 20.0,
}),
]),
}),
})
# ---
# name: test_forecast_service[get_forecast]
dict({
'forecast': list([
dict({
'condition': 'lightning-rainy',
'datetime': '2023-08-08T12:00:00+00:00',
'temperature': 10.0,
}),
dict({
'condition': 'lightning-rainy',
'datetime': '2023-08-09T12:00:00+00:00',
'temperature': 20.0,
}),
]),
})
# ---
# name: test_forecast_service[get_forecast].1
dict({
'forecast': list([
dict({
'condition': 'lightning-rainy',
'datetime': '2023-08-08T12:00:00+00:00',
'temperature': 10.0,
}),
dict({
'condition': 'lightning-rainy',
'datetime': '2023-08-09T12:00:00+00:00',
'temperature': 20.0,
}),
]),
})
# ---
# name: test_forecast_service[get_forecasts]
dict({
'weather.somewhere': dict({
'forecast': list([
dict({
'condition': 'lightning-rainy',
'datetime': '2023-08-08T12:00:00+00:00',
'temperature': 10.0,
}),
dict({
'condition': 'lightning-rainy',
'datetime': '2023-08-09T12:00:00+00:00',
'temperature': 20.0,
}),
]),
}),
})
# ---
# name: test_forecast_service[get_forecasts].1
dict({
'weather.somewhere': dict({
'forecast': list([
dict({
'condition': 'lightning-rainy',
'datetime': '2023-08-08T12:00:00+00:00',
'temperature': 10.0,
}),
dict({
'condition': 'lightning-rainy',
'datetime': '2023-08-09T12:00:00+00:00',
'temperature': 20.0,
}),
]),
}),
})
# ---
# name: test_forecast_subscription[daily]
list([
dict({

View File

@ -9,7 +9,8 @@ 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,
SERVICE_GET_FORECAST,
LEGACY_SERVICE_GET_FORECAST,
SERVICE_GET_FORECASTS,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
@ -77,10 +78,18 @@ async def test_weather(hass: HomeAssistant, mock_weather) -> None:
assert len(hass.states.async_entity_ids("weather")) == 0
@pytest.mark.parametrize(
("service"),
[
SERVICE_GET_FORECASTS,
LEGACY_SERVICE_GET_FORECAST,
],
)
async def test_forecast_service(
hass: HomeAssistant,
mock_weather,
snapshot: SnapshotAssertion,
service: str,
) -> None:
"""Test multiple forecast."""
mock_weather.get_forecast.return_value = [
@ -102,7 +111,7 @@ async def test_forecast_service(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": entity_id,
"type": "daily",
@ -114,7 +123,7 @@ async def test_forecast_service(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": entity_id,
"type": "hourly",

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,8 @@ from syrupy.assertion import SnapshotAssertion
from homeassistant.components.metoffice.const import DEFAULT_SCAN_INTERVAL, DOMAIN
from homeassistant.components.weather import (
DOMAIN as WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
LEGACY_SERVICE_GET_FORECAST,
SERVICE_GET_FORECASTS,
)
from homeassistant.const import STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
@ -421,6 +422,13 @@ async def test_legacy_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,
],
)
async def test_forecast_service(
hass: HomeAssistant,
freezer: FrozenDateTimeFactory,
@ -428,6 +436,7 @@ async def test_forecast_service(
snapshot: SnapshotAssertion,
no_sensor,
wavertree_data: dict[str, _Matcher],
service: str,
) -> None:
"""Test multiple forecast."""
entry = MockConfigEntry(
@ -444,7 +453,7 @@ async def test_forecast_service(
for forecast_type in ("daily", "hourly"):
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": "weather.met_office_wavertree_daily",
"type": forecast_type,
@ -452,7 +461,6 @@ async def test_forecast_service(
blocking=True,
return_response=True,
)
assert response["forecast"] != []
assert response == snapshot
# Calling the services should use cached data
@ -470,7 +478,7 @@ async def test_forecast_service(
for forecast_type in ("daily", "hourly"):
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": "weather.met_office_wavertree_daily",
"type": forecast_type,
@ -478,7 +486,6 @@ async def test_forecast_service(
blocking=True,
return_response=True,
)
assert response["forecast"] != []
assert response == snapshot
# Calling the services should update the hourly forecast
@ -494,7 +501,7 @@ async def test_forecast_service(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": "weather.met_office_wavertree_daily",
"type": "hourly",
@ -502,7 +509,7 @@ async def test_forecast_service(
blocking=True,
return_response=True,
)
assert response["forecast"] == []
assert response == snapshot
@pytest.mark.parametrize(

View File

@ -103,6 +103,309 @@
]),
})
# ---
# 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([
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[get_forecast].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[get_forecast].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[get_forecast].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[get_forecast].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[get_forecast].5
dict({
'forecast': list([
]),
})
# ---
# name: test_forecast_service[get_forecasts]
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[get_forecasts].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[get_forecasts].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[get_forecasts].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[get_forecasts].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[get_forecasts].5
dict({
'weather.abc_daynight': dict({
'forecast': list([
]),
}),
})
# ---
# name: test_forecast_subscription[hourly-weather.abc_daynight]
list([
dict({

View File

@ -13,7 +13,8 @@ from homeassistant.components.weather import (
ATTR_CONDITION_SUNNY,
ATTR_FORECAST,
DOMAIN as WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
LEGACY_SERVICE_GET_FORECAST,
SERVICE_GET_FORECASTS,
)
from homeassistant.const import STATE_UNAVAILABLE, STATE_UNKNOWN
from homeassistant.core import HomeAssistant
@ -400,12 +401,20 @@ async def test_legacy_config_entry(hass: HomeAssistant, no_sensor) -> None:
assert len(er.async_entries_for_config_entry(registry, entry.entry_id)) == 2
@pytest.mark.parametrize(
("service"),
[
SERVICE_GET_FORECASTS,
LEGACY_SERVICE_GET_FORECAST,
],
)
async def test_forecast_service(
hass: HomeAssistant,
freezer: FrozenDateTimeFactory,
snapshot: SnapshotAssertion,
mock_simple_nws,
no_sensor,
service: str,
) -> None:
"""Test multiple forecast."""
instance = mock_simple_nws.return_value
@ -425,7 +434,7 @@ async def test_forecast_service(
for forecast_type in ("twice_daily", "hourly"):
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": "weather.abc_daynight",
"type": forecast_type,
@ -433,7 +442,6 @@ async def test_forecast_service(
blocking=True,
return_response=True,
)
assert response["forecast"] != []
assert response == snapshot
# Calling the services should use cached data
@ -453,7 +461,7 @@ async def test_forecast_service(
for forecast_type in ("twice_daily", "hourly"):
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": "weather.abc_daynight",
"type": forecast_type,
@ -461,7 +469,6 @@ async def test_forecast_service(
blocking=True,
return_response=True,
)
assert response["forecast"] != []
assert response == snapshot
# Calling the services should update the hourly forecast
@ -477,7 +484,7 @@ async def test_forecast_service(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": "weather.abc_daynight",
"type": "hourly",
@ -485,7 +492,6 @@ async def test_forecast_service(
blocking=True,
return_response=True,
)
assert response["forecast"] != []
assert response == snapshot
# after additional 35 minutes data caching expires, data is no longer shown
@ -495,7 +501,7 @@ async def test_forecast_service(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": "weather.abc_daynight",
"type": "hourly",
@ -503,7 +509,7 @@ async def test_forecast_service(
blocking=True,
return_response=True,
)
assert response["forecast"] == []
assert response == snapshot
@pytest.mark.parametrize(

View File

@ -195,6 +195,418 @@
]),
})
# ---
# name: test_forecast_service[forecast]
dict({
'weather.smhi_test': dict({
'forecast': list([
dict({
'cloud_coverage': 100,
'condition': 'cloudy',
'datetime': '2023-08-07T12:00:00',
'humidity': 96,
'precipitation': 0.0,
'pressure': 991.0,
'temperature': 18.0,
'templow': 15.0,
'wind_bearing': 114,
'wind_gust_speed': 32.76,
'wind_speed': 10.08,
}),
dict({
'cloud_coverage': 100,
'condition': 'rainy',
'datetime': '2023-08-08T12:00:00',
'humidity': 97,
'precipitation': 10.6,
'pressure': 984.0,
'temperature': 15.0,
'templow': 11.0,
'wind_bearing': 183,
'wind_gust_speed': 27.36,
'wind_speed': 11.16,
}),
dict({
'cloud_coverage': 100,
'condition': 'rainy',
'datetime': '2023-08-09T12:00:00',
'humidity': 95,
'precipitation': 6.3,
'pressure': 1001.0,
'temperature': 12.0,
'templow': 11.0,
'wind_bearing': 166,
'wind_gust_speed': 48.24,
'wind_speed': 18.0,
}),
dict({
'cloud_coverage': 100,
'condition': 'cloudy',
'datetime': '2023-08-10T12:00:00',
'humidity': 75,
'precipitation': 4.8,
'pressure': 1011.0,
'temperature': 14.0,
'templow': 10.0,
'wind_bearing': 174,
'wind_gust_speed': 29.16,
'wind_speed': 11.16,
}),
dict({
'cloud_coverage': 100,
'condition': 'cloudy',
'datetime': '2023-08-11T12:00:00',
'humidity': 69,
'precipitation': 0.6,
'pressure': 1015.0,
'temperature': 18.0,
'templow': 12.0,
'wind_bearing': 197,
'wind_gust_speed': 27.36,
'wind_speed': 10.08,
}),
dict({
'cloud_coverage': 100,
'condition': 'cloudy',
'datetime': '2023-08-12T12:00:00',
'humidity': 82,
'precipitation': 0.0,
'pressure': 1014.0,
'temperature': 17.0,
'templow': 12.0,
'wind_bearing': 225,
'wind_gust_speed': 28.08,
'wind_speed': 8.64,
}),
dict({
'cloud_coverage': 75,
'condition': 'partlycloudy',
'datetime': '2023-08-13T12:00:00',
'humidity': 59,
'precipitation': 0.0,
'pressure': 1013.0,
'temperature': 20.0,
'templow': 14.0,
'wind_bearing': 234,
'wind_gust_speed': 35.64,
'wind_speed': 14.76,
}),
dict({
'cloud_coverage': 100,
'condition': 'partlycloudy',
'datetime': '2023-08-14T12:00:00',
'humidity': 56,
'precipitation': 0.0,
'pressure': 1015.0,
'temperature': 21.0,
'templow': 14.0,
'wind_bearing': 216,
'wind_gust_speed': 33.12,
'wind_speed': 13.68,
}),
dict({
'cloud_coverage': 88,
'condition': 'partlycloudy',
'datetime': '2023-08-15T12:00:00',
'humidity': 64,
'precipitation': 3.6,
'pressure': 1014.0,
'temperature': 20.0,
'templow': 14.0,
'wind_bearing': 226,
'wind_gust_speed': 33.12,
'wind_speed': 13.68,
}),
dict({
'cloud_coverage': 75,
'condition': 'partlycloudy',
'datetime': '2023-08-16T12:00:00',
'humidity': 61,
'precipitation': 2.4,
'pressure': 1014.0,
'temperature': 20.0,
'templow': 14.0,
'wind_bearing': 233,
'wind_gust_speed': 33.48,
'wind_speed': 14.04,
}),
]),
}),
})
# ---
# name: test_forecast_service[get_forecast]
dict({
'forecast': list([
dict({
'cloud_coverage': 100,
'condition': 'cloudy',
'datetime': '2023-08-07T12:00:00',
'humidity': 96,
'precipitation': 0.0,
'pressure': 991.0,
'temperature': 18.0,
'templow': 15.0,
'wind_bearing': 114,
'wind_gust_speed': 32.76,
'wind_speed': 10.08,
}),
dict({
'cloud_coverage': 100,
'condition': 'rainy',
'datetime': '2023-08-08T12:00:00',
'humidity': 97,
'precipitation': 10.6,
'pressure': 984.0,
'temperature': 15.0,
'templow': 11.0,
'wind_bearing': 183,
'wind_gust_speed': 27.36,
'wind_speed': 11.16,
}),
dict({
'cloud_coverage': 100,
'condition': 'rainy',
'datetime': '2023-08-09T12:00:00',
'humidity': 95,
'precipitation': 6.3,
'pressure': 1001.0,
'temperature': 12.0,
'templow': 11.0,
'wind_bearing': 166,
'wind_gust_speed': 48.24,
'wind_speed': 18.0,
}),
dict({
'cloud_coverage': 100,
'condition': 'cloudy',
'datetime': '2023-08-10T12:00:00',
'humidity': 75,
'precipitation': 4.8,
'pressure': 1011.0,
'temperature': 14.0,
'templow': 10.0,
'wind_bearing': 174,
'wind_gust_speed': 29.16,
'wind_speed': 11.16,
}),
dict({
'cloud_coverage': 100,
'condition': 'cloudy',
'datetime': '2023-08-11T12:00:00',
'humidity': 69,
'precipitation': 0.6,
'pressure': 1015.0,
'temperature': 18.0,
'templow': 12.0,
'wind_bearing': 197,
'wind_gust_speed': 27.36,
'wind_speed': 10.08,
}),
dict({
'cloud_coverage': 100,
'condition': 'cloudy',
'datetime': '2023-08-12T12:00:00',
'humidity': 82,
'precipitation': 0.0,
'pressure': 1014.0,
'temperature': 17.0,
'templow': 12.0,
'wind_bearing': 225,
'wind_gust_speed': 28.08,
'wind_speed': 8.64,
}),
dict({
'cloud_coverage': 75,
'condition': 'partlycloudy',
'datetime': '2023-08-13T12:00:00',
'humidity': 59,
'precipitation': 0.0,
'pressure': 1013.0,
'temperature': 20.0,
'templow': 14.0,
'wind_bearing': 234,
'wind_gust_speed': 35.64,
'wind_speed': 14.76,
}),
dict({
'cloud_coverage': 100,
'condition': 'partlycloudy',
'datetime': '2023-08-14T12:00:00',
'humidity': 56,
'precipitation': 0.0,
'pressure': 1015.0,
'temperature': 21.0,
'templow': 14.0,
'wind_bearing': 216,
'wind_gust_speed': 33.12,
'wind_speed': 13.68,
}),
dict({
'cloud_coverage': 88,
'condition': 'partlycloudy',
'datetime': '2023-08-15T12:00:00',
'humidity': 64,
'precipitation': 3.6,
'pressure': 1014.0,
'temperature': 20.0,
'templow': 14.0,
'wind_bearing': 226,
'wind_gust_speed': 33.12,
'wind_speed': 13.68,
}),
dict({
'cloud_coverage': 75,
'condition': 'partlycloudy',
'datetime': '2023-08-16T12:00:00',
'humidity': 61,
'precipitation': 2.4,
'pressure': 1014.0,
'temperature': 20.0,
'templow': 14.0,
'wind_bearing': 233,
'wind_gust_speed': 33.48,
'wind_speed': 14.04,
}),
]),
})
# ---
# name: test_forecast_service[get_forecasts]
dict({
'weather.smhi_test': dict({
'forecast': list([
dict({
'cloud_coverage': 100,
'condition': 'cloudy',
'datetime': '2023-08-07T12:00:00',
'humidity': 96,
'precipitation': 0.0,
'pressure': 991.0,
'temperature': 18.0,
'templow': 15.0,
'wind_bearing': 114,
'wind_gust_speed': 32.76,
'wind_speed': 10.08,
}),
dict({
'cloud_coverage': 100,
'condition': 'rainy',
'datetime': '2023-08-08T12:00:00',
'humidity': 97,
'precipitation': 10.6,
'pressure': 984.0,
'temperature': 15.0,
'templow': 11.0,
'wind_bearing': 183,
'wind_gust_speed': 27.36,
'wind_speed': 11.16,
}),
dict({
'cloud_coverage': 100,
'condition': 'rainy',
'datetime': '2023-08-09T12:00:00',
'humidity': 95,
'precipitation': 6.3,
'pressure': 1001.0,
'temperature': 12.0,
'templow': 11.0,
'wind_bearing': 166,
'wind_gust_speed': 48.24,
'wind_speed': 18.0,
}),
dict({
'cloud_coverage': 100,
'condition': 'cloudy',
'datetime': '2023-08-10T12:00:00',
'humidity': 75,
'precipitation': 4.8,
'pressure': 1011.0,
'temperature': 14.0,
'templow': 10.0,
'wind_bearing': 174,
'wind_gust_speed': 29.16,
'wind_speed': 11.16,
}),
dict({
'cloud_coverage': 100,
'condition': 'cloudy',
'datetime': '2023-08-11T12:00:00',
'humidity': 69,
'precipitation': 0.6,
'pressure': 1015.0,
'temperature': 18.0,
'templow': 12.0,
'wind_bearing': 197,
'wind_gust_speed': 27.36,
'wind_speed': 10.08,
}),
dict({
'cloud_coverage': 100,
'condition': 'cloudy',
'datetime': '2023-08-12T12:00:00',
'humidity': 82,
'precipitation': 0.0,
'pressure': 1014.0,
'temperature': 17.0,
'templow': 12.0,
'wind_bearing': 225,
'wind_gust_speed': 28.08,
'wind_speed': 8.64,
}),
dict({
'cloud_coverage': 75,
'condition': 'partlycloudy',
'datetime': '2023-08-13T12:00:00',
'humidity': 59,
'precipitation': 0.0,
'pressure': 1013.0,
'temperature': 20.0,
'templow': 14.0,
'wind_bearing': 234,
'wind_gust_speed': 35.64,
'wind_speed': 14.76,
}),
dict({
'cloud_coverage': 100,
'condition': 'partlycloudy',
'datetime': '2023-08-14T12:00:00',
'humidity': 56,
'precipitation': 0.0,
'pressure': 1015.0,
'temperature': 21.0,
'templow': 14.0,
'wind_bearing': 216,
'wind_gust_speed': 33.12,
'wind_speed': 13.68,
}),
dict({
'cloud_coverage': 88,
'condition': 'partlycloudy',
'datetime': '2023-08-15T12:00:00',
'humidity': 64,
'precipitation': 3.6,
'pressure': 1014.0,
'temperature': 20.0,
'templow': 14.0,
'wind_bearing': 226,
'wind_gust_speed': 33.12,
'wind_speed': 13.68,
}),
dict({
'cloud_coverage': 75,
'condition': 'partlycloudy',
'datetime': '2023-08-16T12:00:00',
'humidity': 61,
'precipitation': 2.4,
'pressure': 1014.0,
'temperature': 20.0,
'templow': 14.0,
'wind_bearing': 233,
'wind_gust_speed': 33.48,
'wind_speed': 14.04,
}),
]),
}),
})
# ---
# name: test_forecast_services
dict({
'cloud_coverage': 100,

View File

@ -20,7 +20,8 @@ from homeassistant.components.weather import (
ATTR_WEATHER_WIND_SPEED,
ATTR_WEATHER_WIND_SPEED_UNIT,
DOMAIN as WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
LEGACY_SERVICE_GET_FORECAST,
SERVICE_GET_FORECASTS,
)
from homeassistant.components.weather.const import (
ATTR_WEATHER_CLOUD_COVERAGE,
@ -443,11 +444,19 @@ async def test_forecast_services_lack_of_data(
assert forecast1 is None
@pytest.mark.parametrize(
("service"),
[
SERVICE_GET_FORECASTS,
LEGACY_SERVICE_GET_FORECAST,
],
)
async def test_forecast_service(
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
api_response: str,
snapshot: SnapshotAssertion,
service: str,
) -> None:
"""Test forecast service."""
uri = APIURL_TEMPLATE.format(
@ -463,7 +472,7 @@ async def test_forecast_service(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": ENTITY_ID, "type": "daily"},
blocking=True,
return_response=True,

View File

@ -1,4 +1,155 @@
# serializer version: 1
# name: test_forecasts[config0-1-weather-forecast]
dict({
'weather.forecast': dict({
'forecast': list([
dict({
'condition': 'cloudy',
'datetime': '2023-02-17T14:00:00+00:00',
'temperature': 14.2,
}),
]),
}),
})
# ---
# name: test_forecasts[config0-1-weather-forecast].1
dict({
'weather.forecast': dict({
'forecast': list([
dict({
'condition': 'cloudy',
'datetime': '2023-02-17T14:00:00+00:00',
'temperature': 14.2,
}),
]),
}),
})
# ---
# name: test_forecasts[config0-1-weather-forecast].2
dict({
'weather.forecast': dict({
'forecast': list([
dict({
'condition': 'fog',
'datetime': '2023-02-17T14:00:00+00:00',
'is_daytime': True,
'temperature': 14.2,
}),
]),
}),
})
# ---
# name: test_forecasts[config0-1-weather-forecast].3
dict({
'weather.forecast': dict({
'forecast': list([
dict({
'condition': 'cloudy',
'datetime': '2023-02-17T14:00:00+00:00',
'temperature': 16.9,
}),
]),
}),
})
# ---
# name: test_forecasts[config0-1-weather-get_forecast]
dict({
'forecast': list([
dict({
'condition': 'cloudy',
'datetime': '2023-02-17T14:00:00+00:00',
'temperature': 14.2,
}),
]),
})
# ---
# name: test_forecasts[config0-1-weather-get_forecast].1
dict({
'forecast': list([
dict({
'condition': 'cloudy',
'datetime': '2023-02-17T14:00:00+00:00',
'temperature': 14.2,
}),
]),
})
# ---
# name: test_forecasts[config0-1-weather-get_forecast].2
dict({
'forecast': list([
dict({
'condition': 'fog',
'datetime': '2023-02-17T14:00:00+00:00',
'is_daytime': True,
'temperature': 14.2,
}),
]),
})
# ---
# name: test_forecasts[config0-1-weather-get_forecast].3
dict({
'forecast': list([
dict({
'condition': 'cloudy',
'datetime': '2023-02-17T14:00:00+00:00',
'temperature': 16.9,
}),
]),
})
# ---
# name: test_forecasts[config0-1-weather-get_forecasts]
dict({
'weather.forecast': dict({
'forecast': list([
dict({
'condition': 'cloudy',
'datetime': '2023-02-17T14:00:00+00:00',
'temperature': 14.2,
}),
]),
}),
})
# ---
# name: test_forecasts[config0-1-weather-get_forecasts].1
dict({
'weather.forecast': dict({
'forecast': list([
dict({
'condition': 'cloudy',
'datetime': '2023-02-17T14:00:00+00:00',
'temperature': 14.2,
}),
]),
}),
})
# ---
# name: test_forecasts[config0-1-weather-get_forecasts].2
dict({
'weather.forecast': dict({
'forecast': list([
dict({
'condition': 'fog',
'datetime': '2023-02-17T14:00:00+00:00',
'is_daytime': True,
'temperature': 14.2,
}),
]),
}),
})
# ---
# name: test_forecasts[config0-1-weather-get_forecasts].3
dict({
'weather.forecast': dict({
'forecast': list([
dict({
'condition': 'cloudy',
'datetime': '2023-02-17T14:00:00+00:00',
'temperature': 16.9,
}),
]),
}),
})
# ---
# name: test_forecasts[config0-1-weather]
dict({
'forecast': list([
@ -59,6 +210,138 @@
'last_wind_speed': None,
})
# ---
# name: test_trigger_weather_services[config0-1-template-forecast]
dict({
'weather.test': dict({
'forecast': list([
dict({
'condition': 'sunny',
'datetime': '2023-10-19T06:50:05-07:00',
'precipitation': 20.0,
'temperature': 20.0,
'templow': 15.0,
}),
]),
}),
})
# ---
# name: test_trigger_weather_services[config0-1-template-forecast].1
dict({
'weather.test': dict({
'forecast': list([
dict({
'condition': 'sunny',
'datetime': '2023-10-19T06:50:05-07:00',
'precipitation': 20.0,
'temperature': 20.0,
'templow': 15.0,
}),
]),
}),
})
# ---
# name: test_trigger_weather_services[config0-1-template-forecast].2
dict({
'weather.test': dict({
'forecast': list([
dict({
'condition': 'sunny',
'datetime': '2023-10-19T06:50:05-07:00',
'is_daytime': True,
'precipitation': 20.0,
'temperature': 20.0,
'templow': 15.0,
}),
]),
}),
})
# ---
# name: test_trigger_weather_services[config0-1-template-get_forecast]
dict({
'forecast': list([
dict({
'condition': 'sunny',
'datetime': '2023-10-19T06:50:05-07:00',
'precipitation': 20.0,
'temperature': 20.0,
'templow': 15.0,
}),
]),
})
# ---
# name: test_trigger_weather_services[config0-1-template-get_forecast].1
dict({
'forecast': list([
dict({
'condition': 'sunny',
'datetime': '2023-10-19T06:50:05-07:00',
'precipitation': 20.0,
'temperature': 20.0,
'templow': 15.0,
}),
]),
})
# ---
# name: test_trigger_weather_services[config0-1-template-get_forecast].2
dict({
'forecast': list([
dict({
'condition': 'sunny',
'datetime': '2023-10-19T06:50:05-07:00',
'is_daytime': True,
'precipitation': 20.0,
'temperature': 20.0,
'templow': 15.0,
}),
]),
})
# ---
# name: test_trigger_weather_services[config0-1-template-get_forecasts]
dict({
'weather.test': dict({
'forecast': list([
dict({
'condition': 'sunny',
'datetime': '2023-10-19T06:50:05-07:00',
'precipitation': 20.0,
'temperature': 20.0,
'templow': 15.0,
}),
]),
}),
})
# ---
# name: test_trigger_weather_services[config0-1-template-get_forecasts].1
dict({
'weather.test': dict({
'forecast': list([
dict({
'condition': 'sunny',
'datetime': '2023-10-19T06:50:05-07:00',
'precipitation': 20.0,
'temperature': 20.0,
'templow': 15.0,
}),
]),
}),
})
# ---
# name: test_trigger_weather_services[config0-1-template-get_forecasts].2
dict({
'weather.test': dict({
'forecast': list([
dict({
'condition': 'sunny',
'datetime': '2023-10-19T06:50:05-07:00',
'is_daytime': True,
'precipitation': 20.0,
'temperature': 20.0,
'templow': 15.0,
}),
]),
}),
})
# ---
# name: test_trigger_weather_services[config0-1-template]
dict({
'forecast': list([

View File

@ -18,7 +18,8 @@ from homeassistant.components.weather import (
ATTR_WEATHER_WIND_GUST_SPEED,
ATTR_WEATHER_WIND_SPEED,
DOMAIN as WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
LEGACY_SERVICE_GET_FORECAST,
SERVICE_GET_FORECASTS,
Forecast,
)
from homeassistant.const import ATTR_ATTRIBUTION, STATE_UNAVAILABLE, STATE_UNKNOWN
@ -92,6 +93,13 @@ async def test_template_state_text(hass: HomeAssistant, start_ha) -> None:
assert state.attributes.get(v_attr) == value
@pytest.mark.parametrize(
("service"),
[
SERVICE_GET_FORECASTS,
LEGACY_SERVICE_GET_FORECAST,
],
)
@pytest.mark.parametrize(("count", "domain"), [(1, WEATHER_DOMAIN)])
@pytest.mark.parametrize(
"config",
@ -114,7 +122,7 @@ async def test_template_state_text(hass: HomeAssistant, start_ha) -> None:
],
)
async def test_forecasts(
hass: HomeAssistant, start_ha, snapshot: SnapshotAssertion
hass: HomeAssistant, start_ha, snapshot: SnapshotAssertion, service: str
) -> None:
"""Test forecast service."""
for attr, _v_attr, value in [
@ -161,7 +169,7 @@ async def test_forecasts(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "daily"},
blocking=True,
return_response=True,
@ -169,7 +177,7 @@ async def test_forecasts(
assert response == snapshot
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "hourly"},
blocking=True,
return_response=True,
@ -177,7 +185,7 @@ async def test_forecasts(
assert response == snapshot
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "twice_daily"},
blocking=True,
return_response=True,
@ -204,7 +212,7 @@ async def test_forecasts(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "daily"},
blocking=True,
return_response=True,
@ -212,6 +220,13 @@ async def test_forecasts(
assert response == snapshot
@pytest.mark.parametrize(
("service", "expected"),
[
(SERVICE_GET_FORECASTS, {"weather.forecast": {"forecast": []}}),
(LEGACY_SERVICE_GET_FORECAST, {"forecast": []}),
],
)
@pytest.mark.parametrize(("count", "domain"), [(1, WEATHER_DOMAIN)])
@pytest.mark.parametrize(
"config",
@ -236,6 +251,8 @@ async def test_forecast_invalid(
hass: HomeAssistant,
start_ha,
caplog: pytest.LogCaptureFixture,
service: str,
expected: dict[str, Any],
) -> None:
"""Test invalid forecasts."""
for attr, _v_attr, value in [
@ -271,23 +288,30 @@ async def test_forecast_invalid(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "daily"},
blocking=True,
return_response=True,
)
assert response == {"forecast": []}
assert response == expected
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "hourly"},
blocking=True,
return_response=True,
)
assert response == {"forecast": []}
assert response == expected
assert "Only valid keys in Forecast are allowed" in caplog.text
@pytest.mark.parametrize(
("service", "expected"),
[
(SERVICE_GET_FORECASTS, {"weather.forecast": {"forecast": []}}),
(LEGACY_SERVICE_GET_FORECAST, {"forecast": []}),
],
)
@pytest.mark.parametrize(("count", "domain"), [(1, WEATHER_DOMAIN)])
@pytest.mark.parametrize(
"config",
@ -311,6 +335,8 @@ async def test_forecast_invalid_is_daytime_missing_in_twice_daily(
hass: HomeAssistant,
start_ha,
caplog: pytest.LogCaptureFixture,
service: str,
expected: dict[str, Any],
) -> None:
"""Test forecast service invalid when is_daytime missing in twice_daily forecast."""
for attr, _v_attr, value in [
@ -340,15 +366,22 @@ async def test_forecast_invalid_is_daytime_missing_in_twice_daily(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "twice_daily"},
blocking=True,
return_response=True,
)
assert response == {"forecast": []}
assert response == expected
assert "`is_daytime` is missing in twice_daily forecast" in caplog.text
@pytest.mark.parametrize(
("service", "expected"),
[
(SERVICE_GET_FORECASTS, {"weather.forecast": {"forecast": []}}),
(LEGACY_SERVICE_GET_FORECAST, {"forecast": []}),
],
)
@pytest.mark.parametrize(("count", "domain"), [(1, WEATHER_DOMAIN)])
@pytest.mark.parametrize(
"config",
@ -372,6 +405,8 @@ async def test_forecast_invalid_datetime_missing(
hass: HomeAssistant,
start_ha,
caplog: pytest.LogCaptureFixture,
service: str,
expected: dict[str, Any],
) -> None:
"""Test forecast service invalid when datetime missing."""
for attr, _v_attr, value in [
@ -401,15 +436,22 @@ async def test_forecast_invalid_datetime_missing(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "twice_daily"},
blocking=True,
return_response=True,
)
assert response == {"forecast": []}
assert response == expected
assert "`datetime` is required in forecasts" in caplog.text
@pytest.mark.parametrize(
("service"),
[
SERVICE_GET_FORECASTS,
LEGACY_SERVICE_GET_FORECAST,
],
)
@pytest.mark.parametrize(("count", "domain"), [(1, WEATHER_DOMAIN)])
@pytest.mark.parametrize(
"config",
@ -431,7 +473,7 @@ async def test_forecast_invalid_datetime_missing(
],
)
async def test_forecast_format_error(
hass: HomeAssistant, start_ha, caplog: pytest.LogCaptureFixture
hass: HomeAssistant, start_ha, caplog: pytest.LogCaptureFixture, service: str
) -> None:
"""Test forecast service invalid on incorrect format."""
for attr, _v_attr, value in [
@ -467,7 +509,7 @@ async def test_forecast_format_error(
await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "daily"},
blocking=True,
return_response=True,
@ -475,7 +517,7 @@ async def test_forecast_format_error(
assert "Forecasts is not a list, see Weather documentation" in caplog.text
await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "hourly"},
blocking=True,
return_response=True,
@ -638,6 +680,13 @@ async def test_trigger_action(
assert state.context is context
@pytest.mark.parametrize(
("service"),
[
SERVICE_GET_FORECASTS,
LEGACY_SERVICE_GET_FORECAST,
],
)
@pytest.mark.parametrize(("count", "domain"), [(1, "template")])
@pytest.mark.parametrize(
"config",
@ -694,6 +743,7 @@ async def test_trigger_weather_services(
start_ha,
entity_registry: er.EntityRegistry,
snapshot: SnapshotAssertion,
service: str,
) -> None:
"""Test trigger weather entity with services."""
state = hass.states.get("weather.test")
@ -756,7 +806,7 @@ async def test_trigger_weather_services(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": state.entity_id,
"type": "daily",
@ -768,7 +818,7 @@ async def test_trigger_weather_services(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": state.entity_id,
"type": "hourly",
@ -780,7 +830,7 @@ async def test_trigger_weather_services(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": state.entity_id,
"type": "twice_daily",

File diff suppressed because it is too large Load Diff

View File

@ -46,7 +46,8 @@ from homeassistant.components.weather import (
ATTR_WEATHER_WIND_SPEED,
ATTR_WEATHER_WIND_SPEED_UNIT,
DOMAIN as WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
LEGACY_SERVICE_GET_FORECAST,
SERVICE_GET_FORECASTS,
)
from homeassistant.config_entries import RELOAD_AFTER_UPDATE_DELAY, SOURCE_USER
from homeassistant.const import ATTR_ATTRIBUTION, ATTR_FRIENDLY_NAME, CONF_NAME
@ -277,10 +278,18 @@ async def test_v4_weather_legacy_entities(hass: HomeAssistant) -> None:
assert weather_state.attributes[ATTR_WEATHER_WIND_SPEED_UNIT] == "km/h"
@pytest.mark.parametrize(
("service"),
[
SERVICE_GET_FORECASTS,
LEGACY_SERVICE_GET_FORECAST,
],
)
@freeze_time(datetime(2021, 3, 6, 23, 59, 59, tzinfo=dt_util.UTC))
async def test_v4_forecast_service(
hass: HomeAssistant,
snapshot: SnapshotAssertion,
service: str,
) -> None:
"""Test multiple forecast."""
weather_state = await _setup(hass, API_V4_ENTRY_DATA)
@ -289,7 +298,7 @@ async def test_v4_forecast_service(
for forecast_type in ("daily", "hourly"):
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": entity_id,
"type": forecast_type,
@ -297,10 +306,40 @@ async def test_v4_forecast_service(
blocking=True,
return_response=True,
)
assert response["forecast"] != []
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,
@ -321,7 +360,7 @@ async def test_v4_bad_forecast(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
SERVICE_GET_FORECASTS,
{
"entity_id": entity_id,
"type": "hourly",
@ -329,7 +368,12 @@ async def test_v4_bad_forecast(
blocking=True,
return_response=True,
)
assert response["forecast"][0]["precipitation_probability"] is None
assert (
response["weather.tomorrow_io_daily"]["forecast"][0][
"precipitation_probability"
]
is None
)
@pytest.mark.parametrize("forecast_type", ["daily", "hourly"])

View File

@ -1,5 +1,5 @@
# serializer version: 1
# name: test_get_forecast[daily-1]
# name: test_get_forecast[daily-1-get_forecast]
dict({
'forecast': list([
dict({
@ -12,7 +12,22 @@
]),
})
# ---
# name: test_get_forecast[hourly-2]
# name: test_get_forecast[daily-1-get_forecasts]
dict({
'weather.testing': dict({
'forecast': list([
dict({
'cloud_coverage': None,
'temperature': 38.0,
'templow': 38.0,
'uv_index': None,
'wind_bearing': None,
}),
]),
}),
})
# ---
# name: test_get_forecast[hourly-2-get_forecast]
dict({
'forecast': list([
dict({
@ -25,7 +40,22 @@
]),
})
# ---
# name: test_get_forecast[twice_daily-4]
# name: test_get_forecast[hourly-2-get_forecasts]
dict({
'weather.testing': dict({
'forecast': list([
dict({
'cloud_coverage': None,
'temperature': 38.0,
'templow': 38.0,
'uv_index': None,
'wind_bearing': None,
}),
]),
}),
})
# ---
# name: test_get_forecast[twice_daily-4-get_forecast]
dict({
'forecast': list([
dict({
@ -39,3 +69,19 @@
]),
})
# ---
# name: test_get_forecast[twice_daily-4-get_forecasts]
dict({
'weather.testing': dict({
'forecast': list([
dict({
'cloud_coverage': None,
'is_daytime': True,
'temperature': 38.0,
'templow': 38.0,
'uv_index': None,
'wind_bearing': None,
}),
]),
}),
})
# ---

View File

@ -32,8 +32,9 @@ from homeassistant.components.weather import (
ATTR_WEATHER_WIND_SPEED,
ATTR_WEATHER_WIND_SPEED_UNIT,
DOMAIN,
LEGACY_SERVICE_GET_FORECAST,
ROUNDING_PRECISION,
SERVICE_GET_FORECAST,
SERVICE_GET_FORECASTS,
Forecast,
WeatherEntity,
WeatherEntityFeature,
@ -959,6 +960,13 @@ async def test_forecast_twice_daily_missing_is_daytime(
assert msg["type"] == "result"
@pytest.mark.parametrize(
("service"),
[
SERVICE_GET_FORECASTS,
LEGACY_SERVICE_GET_FORECAST,
],
)
@pytest.mark.parametrize(
("forecast_type", "supported_features"),
[
@ -976,6 +984,7 @@ async def test_get_forecast(
forecast_type: str,
supported_features: int,
snapshot: SnapshotAssertion,
service: str,
) -> None:
"""Test get forecast service."""
@ -1006,7 +1015,7 @@ async def test_get_forecast(
response = await hass.services.async_call(
DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": entity0.entity_id,
"type": forecast_type,
@ -1017,9 +1026,30 @@ async def test_get_forecast(
assert response == snapshot
@pytest.mark.parametrize(
("service", "expected"),
[
(
SERVICE_GET_FORECASTS,
{
"weather.testing": {
"forecast": [],
}
},
),
(
LEGACY_SERVICE_GET_FORECAST,
{
"forecast": [],
},
),
],
)
async def test_get_forecast_no_forecast(
hass: HomeAssistant,
config_flow_fixture: None,
service: str,
expected: dict[str, list | dict[str, list]],
) -> None:
"""Test get forecast service."""
@ -1040,7 +1070,7 @@ async def test_get_forecast_no_forecast(
response = await hass.services.async_call(
DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": entity0.entity_id,
"type": "daily",
@ -1048,11 +1078,16 @@ async def test_get_forecast_no_forecast(
blocking=True,
return_response=True,
)
assert response == {
"forecast": [],
}
assert response == expected
@pytest.mark.parametrize(
("service"),
[
SERVICE_GET_FORECASTS,
LEGACY_SERVICE_GET_FORECAST,
],
)
@pytest.mark.parametrize(
("supported_features", "forecast_types"),
[
@ -1066,6 +1101,7 @@ async def test_get_forecast_unsupported(
config_flow_fixture: None,
forecast_types: list[str],
supported_features: int,
service: str,
) -> None:
"""Test get forecast service."""
@ -1095,7 +1131,7 @@ async def test_get_forecast_unsupported(
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": weather_entity.entity_id,
"type": forecast_type,
@ -1255,3 +1291,52 @@ async def test_issue_forecast_deprecated_no_logging(
"custom_components.test_weather.weather::weather.test is using a forecast attribute on an instance of WeatherEntity"
not in caplog.text
)
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

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
"""Weather entity tests for the WeatherKit integration."""
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.weather import (
@ -15,7 +16,8 @@ from homeassistant.components.weather import (
ATTR_WEATHER_WIND_GUST_SPEED,
ATTR_WEATHER_WIND_SPEED,
DOMAIN as WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
LEGACY_SERVICE_GET_FORECAST,
SERVICE_GET_FORECASTS,
)
from homeassistant.components.weather.const import WeatherEntityFeature
from homeassistant.components.weatherkit.const import ATTRIBUTION
@ -77,15 +79,22 @@ async def test_hourly_forecast_missing(hass: HomeAssistant) -> None:
) == 0
@pytest.mark.parametrize(
("service"),
[
SERVICE_GET_FORECASTS,
LEGACY_SERVICE_GET_FORECAST,
],
)
async def test_hourly_forecast(
hass: HomeAssistant, snapshot: SnapshotAssertion
hass: HomeAssistant, snapshot: SnapshotAssertion, service: str
) -> None:
"""Test states of the hourly forecast."""
await init_integration(hass)
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": "weather.home",
"type": "hourly",
@ -93,17 +102,25 @@ async def test_hourly_forecast(
blocking=True,
return_response=True,
)
assert response["forecast"] != []
assert response == snapshot
async def test_daily_forecast(hass: HomeAssistant, snapshot: SnapshotAssertion) -> None:
@pytest.mark.parametrize(
("service"),
[
SERVICE_GET_FORECASTS,
LEGACY_SERVICE_GET_FORECAST,
],
)
async def test_daily_forecast(
hass: HomeAssistant, snapshot: SnapshotAssertion, service: str
) -> None:
"""Test states of the daily forecast."""
await init_integration(hass)
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": "weather.home",
"type": "daily",
@ -111,5 +128,4 @@ async def test_daily_forecast(hass: HomeAssistant, snapshot: SnapshotAssertion)
blocking=True,
return_response=True,
)
assert response["forecast"] != []
assert response == snapshot