Add location field to calendar create_event service supported by Google Calendar and Local Calendar (#90098)

* Update __init__.py

* Update __init__.py

* Update __init__.py

* Update calendar.py

* Update calendar.py

* Update services.yaml

* Update services.yaml

* Update calendar.py

* Update calendar.py

* Update __init__.py

* Update services.yaml

* Update services.yaml

* Update test_calendar.py

* Update test_init.py

* Update test_init.py

* Update test_init.py

* Update test_init.py

* Update __init__.py

* Update const.py

* Address changes to service.yaml

* Address changes to service.yaml

* Update test_calendar.py

* Update test_calendar.py

* Update test_calendar.py

* Update conftest.py

* Update conftest.py

* Update calendar.py

* Update __init__.py
This commit is contained in:
Luca Angemi 2023-03-25 17:43:49 +01:00 committed by GitHub
parent 02ef7d445d
commit 6d8eaa0bee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 37 additions and 1 deletions

View File

@ -42,6 +42,7 @@ from .const import (
EVENT_IN,
EVENT_IN_DAYS,
EVENT_IN_WEEKS,
EVENT_LOCATION,
EVENT_RECURRENCE_ID,
EVENT_RECURRENCE_RANGE,
EVENT_RRULE,
@ -176,6 +177,7 @@ CREATE_EVENT_SCHEMA = vol.All(
{
vol.Required(EVENT_SUMMARY): cv.string,
vol.Optional(EVENT_DESCRIPTION, default=""): cv.string,
vol.Optional(EVENT_LOCATION): cv.string,
vol.Inclusive(
EVENT_START_DATE, "dates", "Start and end dates must both be specified"
): cv.date,
@ -213,6 +215,7 @@ WEBSOCKET_EVENT_SCHEMA = vol.Schema(
vol.Required(EVENT_END): vol.Any(cv.date, cv.datetime),
vol.Required(EVENT_SUMMARY): cv.string,
vol.Optional(EVENT_DESCRIPTION): cv.string,
vol.Optional(EVENT_LOCATION): cv.string,
vol.Optional(EVENT_RRULE): _validate_rrule,
},
_has_same_type(EVENT_START, EVENT_END),

View File

@ -46,3 +46,9 @@ create_event:
name: In
description: Days or weeks that you want to create the event in.
example: '{"days": 2} or {"weeks": 2}'
location:
name: Location
description: The location of the event.
example: "Conference Room - F123, Bldg. 002"
selector:
text:

View File

@ -43,6 +43,7 @@ from .const import (
EVENT_IN,
EVENT_IN_DAYS,
EVENT_IN_WEEKS,
EVENT_LOCATION,
EVENT_START_DATE,
EVENT_START_DATETIME,
EVENT_SUMMARY,
@ -116,6 +117,7 @@ ADD_EVENT_SERVICE_SCHEMA = vol.All(
vol.Required(EVENT_CALENDAR_ID): cv.string,
vol.Required(EVENT_SUMMARY): cv.string,
vol.Optional(EVENT_DESCRIPTION, default=""): cv.string,
vol.Optional(EVENT_LOCATION, default=""): cv.string,
vol.Inclusive(
EVENT_START_DATE, "dates", "Start and end dates must both be specified"
): cv.date,
@ -290,6 +292,7 @@ async def async_setup_add_event_service(
Event(
summary=call.data[EVENT_SUMMARY],
description=call.data[EVENT_DESCRIPTION],
location=call.data[EVENT_LOCATION],
start=start,
end=end,
),

View File

@ -24,6 +24,7 @@ from homeassistant.components.calendar import (
ENTITY_ID_FORMAT,
EVENT_DESCRIPTION,
EVENT_END,
EVENT_LOCATION,
EVENT_RRULE,
EVENT_START,
EVENT_SUMMARY,
@ -507,6 +508,7 @@ class GoogleCalendarEntity(
"start": start,
"end": end,
EVENT_DESCRIPTION: kwargs.get(EVENT_DESCRIPTION),
EVENT_LOCATION: kwargs.get(EVENT_LOCATION),
}
)
if rrule := kwargs.get(EVENT_RRULE):
@ -603,6 +605,7 @@ async def async_create_event(entity: GoogleCalendarEntity, call: ServiceCall) ->
Event(
summary=call.data[EVENT_SUMMARY],
description=call.data[EVENT_DESCRIPTION],
location=call.data[EVENT_LOCATION],
start=start,
end=end,
),

View File

@ -38,6 +38,7 @@ EVENT_END_DATETIME = "end_date_time"
EVENT_IN = "in"
EVENT_IN_DAYS = "days"
EVENT_IN_WEEKS = "weeks"
EVENT_LOCATION = "location"
EVENT_START_DATE = "start_date"
EVENT_START_DATETIME = "start_date_time"
EVENT_SUMMARY = "summary"

View File

@ -103,3 +103,9 @@ create_event:
example: '"days": 2 or "weeks": 2'
selector:
object:
location:
name: Location
description: The location of the event. Optional.
example: "Conference Room - F123, Bldg. 002"
selector:
text:

View File

@ -196,4 +196,5 @@ def _get_calendar_event(event: Event) -> CalendarEvent:
uid=event.uid,
rrule=event.rrule.as_rrule_str() if event.rrule else None,
recurrence_id=event.recurrence_id,
location=event.location,
)

View File

@ -888,6 +888,7 @@ async def test_websocket_create(
assert aioclient_mock.mock_calls[0][2] == {
"summary": "Bastille Day Party",
"description": None,
"location": None,
"start": {
"dateTime": "1997-07-14T11:00:00-06:00",
"timeZone": "America/Regina",
@ -931,6 +932,7 @@ async def test_websocket_create_all_day(
assert aioclient_mock.mock_calls[0][2] == {
"summary": "Bastille Day Party",
"description": None,
"location": None,
"start": {
"date": "1997-07-14",
},

View File

@ -42,6 +42,7 @@ HassApi = Callable[[], Awaitable[dict[str, Any]]]
TEST_EVENT_SUMMARY = "Test Summary"
TEST_EVENT_DESCRIPTION = "Test Description"
TEST_EVENT_LOCATION = "Test Location"
def assert_state(actual: State | None, expected: State | None) -> None:
@ -93,6 +94,7 @@ def add_event_call_service(
**params,
"summary": TEST_EVENT_SUMMARY,
"description": TEST_EVENT_DESCRIPTION,
"location": TEST_EVENT_LOCATION,
},
target=target,
blocking=True,
@ -484,6 +486,7 @@ async def test_add_event_date_in_x(
assert aioclient_mock.mock_calls[0][2] == {
"summary": TEST_EVENT_SUMMARY,
"description": TEST_EVENT_DESCRIPTION,
"location": TEST_EVENT_LOCATION,
"start": {"date": start_date.date().isoformat()},
"end": {"date": end_date.date().isoformat()},
}
@ -524,6 +527,7 @@ async def test_add_event_date(
assert aioclient_mock.mock_calls[0][2] == {
"summary": TEST_EVENT_SUMMARY,
"description": TEST_EVENT_DESCRIPTION,
"location": TEST_EVENT_LOCATION,
"start": {"date": today.isoformat()},
"end": {"date": end_date.isoformat()},
}
@ -564,6 +568,7 @@ async def test_add_event_date_time(
assert aioclient_mock.mock_calls[0][2] == {
"summary": TEST_EVENT_SUMMARY,
"description": TEST_EVENT_DESCRIPTION,
"location": TEST_EVENT_LOCATION,
"start": {
"dateTime": start_datetime.isoformat(timespec="seconds"),
"timeZone": "America/Regina",

View File

@ -108,7 +108,9 @@ def get_events_fixture(hass_client: ClientSessionGenerator) -> GetEventsFn:
def event_fields(data: dict[str, str]) -> dict[str, str]:
"""Filter event API response to minimum fields."""
return {
k: data[k] for k in ["summary", "start", "end", "recurrence_id"] if data.get(k)
k: data[k]
for k in ["summary", "start", "end", "recurrence_id", "location"]
if data.get(k)
}

View File

@ -873,6 +873,7 @@ async def test_create_event_service(
"start_date_time": start_date_time,
"end_date_time": end_date_time,
"summary": "Bastille Day Party",
"location": "Test Location",
},
target={"entity_id": TEST_ENTITY},
blocking=True,
@ -886,6 +887,7 @@ async def test_create_event_service(
"summary": "Bastille Day Party",
"start": {"dateTime": "1997-07-14T11:00:00-06:00"},
"end": {"dateTime": "1997-07-14T22:00:00-06:00"},
"location": "Test Location",
}
]
@ -895,6 +897,7 @@ async def test_create_event_service(
"summary": "Bastille Day Party",
"start": {"dateTime": "1997-07-14T11:00:00-06:00"},
"end": {"dateTime": "1997-07-14T22:00:00-06:00"},
"location": "Test Location",
}
]
@ -909,5 +912,6 @@ async def test_create_event_service(
"summary": "Bastille Day Party",
"start": {"dateTime": "1997-07-14T11:00:00-06:00"},
"end": {"dateTime": "1997-07-14T22:00:00-06:00"},
"location": "Test Location",
}
]