mirror of
https://github.com/home-assistant/core.git
synced 2025-07-13 16:27:08 +00:00
Deprecate calendar.list_events (#102481)
* deprecate calendar.list_events * rename events to get_events * raise issue for use of deprecated service * Make issue fixable * Add fix_flow * Add service translation/yaml
This commit is contained in:
parent
d3b4dd226b
commit
51385dcaab
@ -37,6 +37,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.helpers.entity_component import EntityComponent
|
||||
from homeassistant.helpers.event import async_track_point_in_time
|
||||
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
||||
from homeassistant.helpers.template import DATE_STR_FORMAT
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
from homeassistant.util import dt as dt_util
|
||||
@ -261,8 +262,10 @@ CALENDAR_EVENT_SCHEMA = vol.Schema(
|
||||
extra=vol.ALLOW_EXTRA,
|
||||
)
|
||||
|
||||
SERVICE_LIST_EVENTS: Final = "list_events"
|
||||
SERVICE_LIST_EVENTS_SCHEMA: Final = vol.All(
|
||||
LEGACY_SERVICE_LIST_EVENTS: Final = "list_events"
|
||||
"""Deprecated: please use SERVICE_LIST_EVENTS."""
|
||||
SERVICE_GET_EVENTS: Final = "get_events"
|
||||
SERVICE_GET_EVENTS_SCHEMA: Final = vol.All(
|
||||
cv.has_at_least_one_key(EVENT_END_DATETIME, EVENT_DURATION),
|
||||
cv.has_at_most_one_key(EVENT_END_DATETIME, EVENT_DURATION),
|
||||
cv.make_entity_service_schema(
|
||||
@ -301,11 +304,17 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
required_features=[CalendarEntityFeature.CREATE_EVENT],
|
||||
)
|
||||
component.async_register_legacy_entity_service(
|
||||
SERVICE_LIST_EVENTS,
|
||||
SERVICE_LIST_EVENTS_SCHEMA,
|
||||
LEGACY_SERVICE_LIST_EVENTS,
|
||||
SERVICE_GET_EVENTS_SCHEMA,
|
||||
async_list_events_service,
|
||||
supports_response=SupportsResponse.ONLY,
|
||||
)
|
||||
component.async_register_entity_service(
|
||||
SERVICE_GET_EVENTS,
|
||||
SERVICE_GET_EVENTS_SCHEMA,
|
||||
async_get_events_service,
|
||||
supports_response=SupportsResponse.ONLY,
|
||||
)
|
||||
await component.async_setup(config)
|
||||
return True
|
||||
|
||||
@ -850,6 +859,32 @@ async def async_create_event(entity: CalendarEntity, call: ServiceCall) -> None:
|
||||
|
||||
async def async_list_events_service(
|
||||
calendar: CalendarEntity, service_call: ServiceCall
|
||||
) -> ServiceResponse:
|
||||
"""List events on a calendar during a time range.
|
||||
|
||||
Deprecated: please use async_get_events_service.
|
||||
"""
|
||||
_LOGGER.warning(
|
||||
"Detected use of service 'calendar.list_events'. "
|
||||
"This is deprecated and will stop working in Home Assistant 2024.6. "
|
||||
"Use 'calendar.get_events' instead which supports multiple entities",
|
||||
)
|
||||
async_create_issue(
|
||||
calendar.hass,
|
||||
DOMAIN,
|
||||
"deprecated_service_calendar_list_events",
|
||||
breaks_in_ha_version="2024.6.0",
|
||||
is_fixable=True,
|
||||
is_persistent=False,
|
||||
issue_domain=calendar.platform.platform_name,
|
||||
severity=IssueSeverity.WARNING,
|
||||
translation_key="deprecated_service_calendar_list_events",
|
||||
)
|
||||
return await async_get_events_service(calendar, service_call)
|
||||
|
||||
|
||||
async def async_get_events_service(
|
||||
calendar: CalendarEntity, service_call: ServiceCall
|
||||
) -> ServiceResponse:
|
||||
"""List events on a calendar during a time range."""
|
||||
start = service_call.data.get(EVENT_START_DATETIME, dt_util.now())
|
||||
|
@ -52,3 +52,19 @@ list_events:
|
||||
duration:
|
||||
selector:
|
||||
duration:
|
||||
get_events:
|
||||
target:
|
||||
entity:
|
||||
domain: calendar
|
||||
fields:
|
||||
start_date_time:
|
||||
example: "2022-03-22 20:00:00"
|
||||
selector:
|
||||
datetime:
|
||||
end_date_time:
|
||||
example: "2022-03-22 22:00:00"
|
||||
selector:
|
||||
datetime:
|
||||
duration:
|
||||
selector:
|
||||
duration:
|
||||
|
@ -72,9 +72,9 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"list_events": {
|
||||
"name": "List event",
|
||||
"description": "Lists events on a calendar within a time range.",
|
||||
"get_events": {
|
||||
"name": "Get event",
|
||||
"description": "Get events on a calendar within a time range.",
|
||||
"fields": {
|
||||
"start_date_time": {
|
||||
"name": "Start time",
|
||||
@ -89,6 +89,37 @@
|
||||
"description": "Returns active events from start_date_time until the specified duration."
|
||||
}
|
||||
}
|
||||
},
|
||||
"list_events": {
|
||||
"name": "List event",
|
||||
"description": "Lists events on a calendar within a time range.",
|
||||
"fields": {
|
||||
"start_date_time": {
|
||||
"name": "[%key:component::calendar::services::get_events::fields::start_date_time::name%]",
|
||||
"description": "[%key:component::calendar::services::get_events::fields::start_date_time::description%]"
|
||||
},
|
||||
"end_date_time": {
|
||||
"name": "[%key:component::calendar::services::get_events::fields::end_date_time::name%]",
|
||||
"description": "[%key:component::calendar::services::get_events::fields::end_date_time::description%]"
|
||||
},
|
||||
"duration": {
|
||||
"name": "[%key:component::calendar::services::get_events::fields::duration::name%]",
|
||||
"description": "[%key:component::calendar::services::get_events::fields::duration::description%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"issues": {
|
||||
"deprecated_service_calendar_list_events": {
|
||||
"title": "Detected use of deprecated service `calendar.list_events`",
|
||||
"fix_flow": {
|
||||
"step": {
|
||||
"confirm": {
|
||||
"title": "[%key:component::calendar::issues::deprecated_service_calendar_list_events::title%]",
|
||||
"description": "Use `calendar.get_events` instead which supports multiple entities.\n\nPlease replace this service and adjust your automations and scripts and select **submit** to close this issue."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,34 @@
|
||||
# serializer version: 1
|
||||
# name: test_list_events_service_duration[calendar.calendar_1-00:15:00]
|
||||
# name: test_list_events_service_duration[calendar.calendar_1-00:15:00-get_events]
|
||||
dict({
|
||||
'calendar.calendar_1': dict({
|
||||
'events': list([
|
||||
]),
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
# name: test_list_events_service_duration[calendar.calendar_1-00:15:00-list_events]
|
||||
dict({
|
||||
'events': list([
|
||||
]),
|
||||
})
|
||||
# ---
|
||||
# name: test_list_events_service_duration[calendar.calendar_1-01:00:00]
|
||||
# name: test_list_events_service_duration[calendar.calendar_1-01:00:00-get_events]
|
||||
dict({
|
||||
'calendar.calendar_1': dict({
|
||||
'events': list([
|
||||
dict({
|
||||
'description': 'Future Description',
|
||||
'end': '2023-10-19T08:20:05-07:00',
|
||||
'location': 'Future Location',
|
||||
'start': '2023-10-19T07:20:05-07:00',
|
||||
'summary': 'Future Event',
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
# name: test_list_events_service_duration[calendar.calendar_1-01:00:00-list_events]
|
||||
dict({
|
||||
'events': list([
|
||||
dict({
|
||||
@ -18,7 +41,20 @@
|
||||
]),
|
||||
})
|
||||
# ---
|
||||
# name: test_list_events_service_duration[calendar.calendar_2-00:15:00]
|
||||
# name: test_list_events_service_duration[calendar.calendar_2-00:15:00-get_events]
|
||||
dict({
|
||||
'calendar.calendar_2': dict({
|
||||
'events': list([
|
||||
dict({
|
||||
'end': '2023-10-19T07:20:05-07:00',
|
||||
'start': '2023-10-19T06:20:05-07:00',
|
||||
'summary': 'Current Event',
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
# name: test_list_events_service_duration[calendar.calendar_2-00:15:00-list_events]
|
||||
dict({
|
||||
'events': list([
|
||||
dict({
|
||||
|
@ -12,9 +12,14 @@ from syrupy.assertion import SnapshotAssertion
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.bootstrap import async_setup_component
|
||||
from homeassistant.components.calendar import DOMAIN, SERVICE_LIST_EVENTS
|
||||
from homeassistant.components.calendar import (
|
||||
DOMAIN,
|
||||
LEGACY_SERVICE_LIST_EVENTS,
|
||||
SERVICE_GET_EVENTS,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.issue_registry import IssueRegistry
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from tests.typing import ClientSessionGenerator, WebSocketGenerator
|
||||
@ -389,6 +394,41 @@ async def test_create_event_service_invalid_params(
|
||||
|
||||
|
||||
@freeze_time("2023-06-22 10:30:00+00:00")
|
||||
@pytest.mark.parametrize(
|
||||
("service", "expected"),
|
||||
[
|
||||
(
|
||||
LEGACY_SERVICE_LIST_EVENTS,
|
||||
{
|
||||
"events": [
|
||||
{
|
||||
"start": "2023-06-22T05:00:00-06:00",
|
||||
"end": "2023-06-22T06:00:00-06:00",
|
||||
"summary": "Future Event",
|
||||
"description": "Future Description",
|
||||
"location": "Future Location",
|
||||
}
|
||||
]
|
||||
},
|
||||
),
|
||||
(
|
||||
SERVICE_GET_EVENTS,
|
||||
{
|
||||
"calendar.calendar_1": {
|
||||
"events": [
|
||||
{
|
||||
"start": "2023-06-22T05:00:00-06:00",
|
||||
"end": "2023-06-22T06:00:00-06:00",
|
||||
"summary": "Future Event",
|
||||
"description": "Future Description",
|
||||
"location": "Future Location",
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
("start_time", "end_time"),
|
||||
[
|
||||
@ -402,6 +442,8 @@ async def test_list_events_service(
|
||||
set_time_zone: None,
|
||||
start_time: str,
|
||||
end_time: str,
|
||||
service: str,
|
||||
expected: dict[str, Any],
|
||||
) -> None:
|
||||
"""Test listing events from the service call using exlplicit start and end time.
|
||||
|
||||
@ -414,8 +456,9 @@ async def test_list_events_service(
|
||||
|
||||
response = await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_LIST_EVENTS,
|
||||
{
|
||||
service,
|
||||
target={"entity_id": ["calendar.calendar_1"]},
|
||||
service_data={
|
||||
"entity_id": "calendar.calendar_1",
|
||||
"start_date_time": start_time,
|
||||
"end_date_time": end_time,
|
||||
@ -423,19 +466,16 @@ async def test_list_events_service(
|
||||
blocking=True,
|
||||
return_response=True,
|
||||
)
|
||||
assert response == {
|
||||
"events": [
|
||||
{
|
||||
"start": "2023-06-22T05:00:00-06:00",
|
||||
"end": "2023-06-22T06:00:00-06:00",
|
||||
"summary": "Future Event",
|
||||
"description": "Future Description",
|
||||
"location": "Future Location",
|
||||
}
|
||||
]
|
||||
}
|
||||
assert response == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("service"),
|
||||
[
|
||||
(LEGACY_SERVICE_LIST_EVENTS),
|
||||
SERVICE_GET_EVENTS,
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
("entity", "duration"),
|
||||
[
|
||||
@ -452,6 +492,7 @@ async def test_list_events_service_duration(
|
||||
hass: HomeAssistant,
|
||||
entity: str,
|
||||
duration: str,
|
||||
service: str,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test listing events using a time duration."""
|
||||
@ -460,7 +501,7 @@ async def test_list_events_service_duration(
|
||||
|
||||
response = await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_LIST_EVENTS,
|
||||
service,
|
||||
{
|
||||
"entity_id": entity,
|
||||
"duration": duration,
|
||||
@ -479,7 +520,7 @@ async def test_list_events_positive_duration(hass: HomeAssistant) -> None:
|
||||
with pytest.raises(vol.Invalid, match="should be positive"):
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_LIST_EVENTS,
|
||||
SERVICE_GET_EVENTS,
|
||||
{
|
||||
"entity_id": "calendar.calendar_1",
|
||||
"duration": "-01:00:00",
|
||||
@ -499,7 +540,7 @@ async def test_list_events_exclusive_fields(hass: HomeAssistant) -> None:
|
||||
with pytest.raises(vol.Invalid, match="at most one of"):
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_LIST_EVENTS,
|
||||
SERVICE_GET_EVENTS,
|
||||
{
|
||||
"entity_id": "calendar.calendar_1",
|
||||
"end_date_time": end,
|
||||
@ -518,10 +559,47 @@ async def test_list_events_missing_fields(hass: HomeAssistant) -> None:
|
||||
with pytest.raises(vol.Invalid, match="at least one of"):
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_LIST_EVENTS,
|
||||
SERVICE_GET_EVENTS,
|
||||
{
|
||||
"entity_id": "calendar.calendar_1",
|
||||
},
|
||||
blocking=True,
|
||||
return_response=True,
|
||||
)
|
||||
|
||||
|
||||
async def test_issue_deprecated_service_calendar_list_events(
|
||||
hass: HomeAssistant,
|
||||
issue_registry: IssueRegistry,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test the issue is raised on deprecated service weather.get_forecast."""
|
||||
|
||||
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
_ = await hass.services.async_call(
|
||||
DOMAIN,
|
||||
LEGACY_SERVICE_LIST_EVENTS,
|
||||
target={"entity_id": ["calendar.calendar_1"]},
|
||||
service_data={
|
||||
"entity_id": "calendar.calendar_1",
|
||||
"duration": "01:00:00",
|
||||
},
|
||||
blocking=True,
|
||||
return_response=True,
|
||||
)
|
||||
|
||||
issue = issue_registry.async_get_issue(
|
||||
"calendar", "deprecated_service_calendar_list_events"
|
||||
)
|
||||
assert issue
|
||||
assert issue.issue_domain == "demo"
|
||||
assert issue.issue_id == "deprecated_service_calendar_list_events"
|
||||
assert issue.translation_key == "deprecated_service_calendar_list_events"
|
||||
|
||||
assert (
|
||||
"Detected use of service 'calendar.list_events'. "
|
||||
"This is deprecated and will stop working in Home Assistant 2024.6. "
|
||||
"Use 'calendar.get_events' instead which supports multiple entities"
|
||||
) in caplog.text
|
||||
|
Loading…
x
Reference in New Issue
Block a user