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/yamlpull/104226/head
parent
41224f1674
commit
173f4760bc
|
@ -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"]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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
|
@ -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",
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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
|
@ -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(
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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([
|
||||
|
|
|
@ -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
|
@ -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"])
|
||||
|
|
|
@ -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,
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue