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:
parent
02ef7d445d
commit
6d8eaa0bee
11 changed files with 37 additions and 1 deletions
|
@ -42,6 +42,7 @@ from .const import (
|
||||||
EVENT_IN,
|
EVENT_IN,
|
||||||
EVENT_IN_DAYS,
|
EVENT_IN_DAYS,
|
||||||
EVENT_IN_WEEKS,
|
EVENT_IN_WEEKS,
|
||||||
|
EVENT_LOCATION,
|
||||||
EVENT_RECURRENCE_ID,
|
EVENT_RECURRENCE_ID,
|
||||||
EVENT_RECURRENCE_RANGE,
|
EVENT_RECURRENCE_RANGE,
|
||||||
EVENT_RRULE,
|
EVENT_RRULE,
|
||||||
|
@ -176,6 +177,7 @@ CREATE_EVENT_SCHEMA = vol.All(
|
||||||
{
|
{
|
||||||
vol.Required(EVENT_SUMMARY): cv.string,
|
vol.Required(EVENT_SUMMARY): cv.string,
|
||||||
vol.Optional(EVENT_DESCRIPTION, default=""): cv.string,
|
vol.Optional(EVENT_DESCRIPTION, default=""): cv.string,
|
||||||
|
vol.Optional(EVENT_LOCATION): cv.string,
|
||||||
vol.Inclusive(
|
vol.Inclusive(
|
||||||
EVENT_START_DATE, "dates", "Start and end dates must both be specified"
|
EVENT_START_DATE, "dates", "Start and end dates must both be specified"
|
||||||
): cv.date,
|
): cv.date,
|
||||||
|
@ -213,6 +215,7 @@ WEBSOCKET_EVENT_SCHEMA = vol.Schema(
|
||||||
vol.Required(EVENT_END): vol.Any(cv.date, cv.datetime),
|
vol.Required(EVENT_END): vol.Any(cv.date, cv.datetime),
|
||||||
vol.Required(EVENT_SUMMARY): cv.string,
|
vol.Required(EVENT_SUMMARY): cv.string,
|
||||||
vol.Optional(EVENT_DESCRIPTION): cv.string,
|
vol.Optional(EVENT_DESCRIPTION): cv.string,
|
||||||
|
vol.Optional(EVENT_LOCATION): cv.string,
|
||||||
vol.Optional(EVENT_RRULE): _validate_rrule,
|
vol.Optional(EVENT_RRULE): _validate_rrule,
|
||||||
},
|
},
|
||||||
_has_same_type(EVENT_START, EVENT_END),
|
_has_same_type(EVENT_START, EVENT_END),
|
||||||
|
|
|
@ -46,3 +46,9 @@ create_event:
|
||||||
name: In
|
name: In
|
||||||
description: Days or weeks that you want to create the event in.
|
description: Days or weeks that you want to create the event in.
|
||||||
example: '{"days": 2} or {"weeks": 2}'
|
example: '{"days": 2} or {"weeks": 2}'
|
||||||
|
location:
|
||||||
|
name: Location
|
||||||
|
description: The location of the event.
|
||||||
|
example: "Conference Room - F123, Bldg. 002"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
|
@ -43,6 +43,7 @@ from .const import (
|
||||||
EVENT_IN,
|
EVENT_IN,
|
||||||
EVENT_IN_DAYS,
|
EVENT_IN_DAYS,
|
||||||
EVENT_IN_WEEKS,
|
EVENT_IN_WEEKS,
|
||||||
|
EVENT_LOCATION,
|
||||||
EVENT_START_DATE,
|
EVENT_START_DATE,
|
||||||
EVENT_START_DATETIME,
|
EVENT_START_DATETIME,
|
||||||
EVENT_SUMMARY,
|
EVENT_SUMMARY,
|
||||||
|
@ -116,6 +117,7 @@ ADD_EVENT_SERVICE_SCHEMA = vol.All(
|
||||||
vol.Required(EVENT_CALENDAR_ID): cv.string,
|
vol.Required(EVENT_CALENDAR_ID): cv.string,
|
||||||
vol.Required(EVENT_SUMMARY): cv.string,
|
vol.Required(EVENT_SUMMARY): cv.string,
|
||||||
vol.Optional(EVENT_DESCRIPTION, default=""): cv.string,
|
vol.Optional(EVENT_DESCRIPTION, default=""): cv.string,
|
||||||
|
vol.Optional(EVENT_LOCATION, default=""): cv.string,
|
||||||
vol.Inclusive(
|
vol.Inclusive(
|
||||||
EVENT_START_DATE, "dates", "Start and end dates must both be specified"
|
EVENT_START_DATE, "dates", "Start and end dates must both be specified"
|
||||||
): cv.date,
|
): cv.date,
|
||||||
|
@ -290,6 +292,7 @@ async def async_setup_add_event_service(
|
||||||
Event(
|
Event(
|
||||||
summary=call.data[EVENT_SUMMARY],
|
summary=call.data[EVENT_SUMMARY],
|
||||||
description=call.data[EVENT_DESCRIPTION],
|
description=call.data[EVENT_DESCRIPTION],
|
||||||
|
location=call.data[EVENT_LOCATION],
|
||||||
start=start,
|
start=start,
|
||||||
end=end,
|
end=end,
|
||||||
),
|
),
|
||||||
|
|
|
@ -24,6 +24,7 @@ from homeassistant.components.calendar import (
|
||||||
ENTITY_ID_FORMAT,
|
ENTITY_ID_FORMAT,
|
||||||
EVENT_DESCRIPTION,
|
EVENT_DESCRIPTION,
|
||||||
EVENT_END,
|
EVENT_END,
|
||||||
|
EVENT_LOCATION,
|
||||||
EVENT_RRULE,
|
EVENT_RRULE,
|
||||||
EVENT_START,
|
EVENT_START,
|
||||||
EVENT_SUMMARY,
|
EVENT_SUMMARY,
|
||||||
|
@ -507,6 +508,7 @@ class GoogleCalendarEntity(
|
||||||
"start": start,
|
"start": start,
|
||||||
"end": end,
|
"end": end,
|
||||||
EVENT_DESCRIPTION: kwargs.get(EVENT_DESCRIPTION),
|
EVENT_DESCRIPTION: kwargs.get(EVENT_DESCRIPTION),
|
||||||
|
EVENT_LOCATION: kwargs.get(EVENT_LOCATION),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if rrule := kwargs.get(EVENT_RRULE):
|
if rrule := kwargs.get(EVENT_RRULE):
|
||||||
|
@ -603,6 +605,7 @@ async def async_create_event(entity: GoogleCalendarEntity, call: ServiceCall) ->
|
||||||
Event(
|
Event(
|
||||||
summary=call.data[EVENT_SUMMARY],
|
summary=call.data[EVENT_SUMMARY],
|
||||||
description=call.data[EVENT_DESCRIPTION],
|
description=call.data[EVENT_DESCRIPTION],
|
||||||
|
location=call.data[EVENT_LOCATION],
|
||||||
start=start,
|
start=start,
|
||||||
end=end,
|
end=end,
|
||||||
),
|
),
|
||||||
|
|
|
@ -38,6 +38,7 @@ EVENT_END_DATETIME = "end_date_time"
|
||||||
EVENT_IN = "in"
|
EVENT_IN = "in"
|
||||||
EVENT_IN_DAYS = "days"
|
EVENT_IN_DAYS = "days"
|
||||||
EVENT_IN_WEEKS = "weeks"
|
EVENT_IN_WEEKS = "weeks"
|
||||||
|
EVENT_LOCATION = "location"
|
||||||
EVENT_START_DATE = "start_date"
|
EVENT_START_DATE = "start_date"
|
||||||
EVENT_START_DATETIME = "start_date_time"
|
EVENT_START_DATETIME = "start_date_time"
|
||||||
EVENT_SUMMARY = "summary"
|
EVENT_SUMMARY = "summary"
|
||||||
|
|
|
@ -103,3 +103,9 @@ create_event:
|
||||||
example: '"days": 2 or "weeks": 2'
|
example: '"days": 2 or "weeks": 2'
|
||||||
selector:
|
selector:
|
||||||
object:
|
object:
|
||||||
|
location:
|
||||||
|
name: Location
|
||||||
|
description: The location of the event. Optional.
|
||||||
|
example: "Conference Room - F123, Bldg. 002"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
|
@ -196,4 +196,5 @@ def _get_calendar_event(event: Event) -> CalendarEvent:
|
||||||
uid=event.uid,
|
uid=event.uid,
|
||||||
rrule=event.rrule.as_rrule_str() if event.rrule else None,
|
rrule=event.rrule.as_rrule_str() if event.rrule else None,
|
||||||
recurrence_id=event.recurrence_id,
|
recurrence_id=event.recurrence_id,
|
||||||
|
location=event.location,
|
||||||
)
|
)
|
||||||
|
|
|
@ -888,6 +888,7 @@ async def test_websocket_create(
|
||||||
assert aioclient_mock.mock_calls[0][2] == {
|
assert aioclient_mock.mock_calls[0][2] == {
|
||||||
"summary": "Bastille Day Party",
|
"summary": "Bastille Day Party",
|
||||||
"description": None,
|
"description": None,
|
||||||
|
"location": None,
|
||||||
"start": {
|
"start": {
|
||||||
"dateTime": "1997-07-14T11:00:00-06:00",
|
"dateTime": "1997-07-14T11:00:00-06:00",
|
||||||
"timeZone": "America/Regina",
|
"timeZone": "America/Regina",
|
||||||
|
@ -931,6 +932,7 @@ async def test_websocket_create_all_day(
|
||||||
assert aioclient_mock.mock_calls[0][2] == {
|
assert aioclient_mock.mock_calls[0][2] == {
|
||||||
"summary": "Bastille Day Party",
|
"summary": "Bastille Day Party",
|
||||||
"description": None,
|
"description": None,
|
||||||
|
"location": None,
|
||||||
"start": {
|
"start": {
|
||||||
"date": "1997-07-14",
|
"date": "1997-07-14",
|
||||||
},
|
},
|
||||||
|
|
|
@ -42,6 +42,7 @@ HassApi = Callable[[], Awaitable[dict[str, Any]]]
|
||||||
|
|
||||||
TEST_EVENT_SUMMARY = "Test Summary"
|
TEST_EVENT_SUMMARY = "Test Summary"
|
||||||
TEST_EVENT_DESCRIPTION = "Test Description"
|
TEST_EVENT_DESCRIPTION = "Test Description"
|
||||||
|
TEST_EVENT_LOCATION = "Test Location"
|
||||||
|
|
||||||
|
|
||||||
def assert_state(actual: State | None, expected: State | None) -> None:
|
def assert_state(actual: State | None, expected: State | None) -> None:
|
||||||
|
@ -93,6 +94,7 @@ def add_event_call_service(
|
||||||
**params,
|
**params,
|
||||||
"summary": TEST_EVENT_SUMMARY,
|
"summary": TEST_EVENT_SUMMARY,
|
||||||
"description": TEST_EVENT_DESCRIPTION,
|
"description": TEST_EVENT_DESCRIPTION,
|
||||||
|
"location": TEST_EVENT_LOCATION,
|
||||||
},
|
},
|
||||||
target=target,
|
target=target,
|
||||||
blocking=True,
|
blocking=True,
|
||||||
|
@ -484,6 +486,7 @@ async def test_add_event_date_in_x(
|
||||||
assert aioclient_mock.mock_calls[0][2] == {
|
assert aioclient_mock.mock_calls[0][2] == {
|
||||||
"summary": TEST_EVENT_SUMMARY,
|
"summary": TEST_EVENT_SUMMARY,
|
||||||
"description": TEST_EVENT_DESCRIPTION,
|
"description": TEST_EVENT_DESCRIPTION,
|
||||||
|
"location": TEST_EVENT_LOCATION,
|
||||||
"start": {"date": start_date.date().isoformat()},
|
"start": {"date": start_date.date().isoformat()},
|
||||||
"end": {"date": end_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] == {
|
assert aioclient_mock.mock_calls[0][2] == {
|
||||||
"summary": TEST_EVENT_SUMMARY,
|
"summary": TEST_EVENT_SUMMARY,
|
||||||
"description": TEST_EVENT_DESCRIPTION,
|
"description": TEST_EVENT_DESCRIPTION,
|
||||||
|
"location": TEST_EVENT_LOCATION,
|
||||||
"start": {"date": today.isoformat()},
|
"start": {"date": today.isoformat()},
|
||||||
"end": {"date": end_date.isoformat()},
|
"end": {"date": end_date.isoformat()},
|
||||||
}
|
}
|
||||||
|
@ -564,6 +568,7 @@ async def test_add_event_date_time(
|
||||||
assert aioclient_mock.mock_calls[0][2] == {
|
assert aioclient_mock.mock_calls[0][2] == {
|
||||||
"summary": TEST_EVENT_SUMMARY,
|
"summary": TEST_EVENT_SUMMARY,
|
||||||
"description": TEST_EVENT_DESCRIPTION,
|
"description": TEST_EVENT_DESCRIPTION,
|
||||||
|
"location": TEST_EVENT_LOCATION,
|
||||||
"start": {
|
"start": {
|
||||||
"dateTime": start_datetime.isoformat(timespec="seconds"),
|
"dateTime": start_datetime.isoformat(timespec="seconds"),
|
||||||
"timeZone": "America/Regina",
|
"timeZone": "America/Regina",
|
||||||
|
|
|
@ -108,7 +108,9 @@ def get_events_fixture(hass_client: ClientSessionGenerator) -> GetEventsFn:
|
||||||
def event_fields(data: dict[str, str]) -> dict[str, str]:
|
def event_fields(data: dict[str, str]) -> dict[str, str]:
|
||||||
"""Filter event API response to minimum fields."""
|
"""Filter event API response to minimum fields."""
|
||||||
return {
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -873,6 +873,7 @@ async def test_create_event_service(
|
||||||
"start_date_time": start_date_time,
|
"start_date_time": start_date_time,
|
||||||
"end_date_time": end_date_time,
|
"end_date_time": end_date_time,
|
||||||
"summary": "Bastille Day Party",
|
"summary": "Bastille Day Party",
|
||||||
|
"location": "Test Location",
|
||||||
},
|
},
|
||||||
target={"entity_id": TEST_ENTITY},
|
target={"entity_id": TEST_ENTITY},
|
||||||
blocking=True,
|
blocking=True,
|
||||||
|
@ -886,6 +887,7 @@ async def test_create_event_service(
|
||||||
"summary": "Bastille Day Party",
|
"summary": "Bastille Day Party",
|
||||||
"start": {"dateTime": "1997-07-14T11:00:00-06:00"},
|
"start": {"dateTime": "1997-07-14T11:00:00-06:00"},
|
||||||
"end": {"dateTime": "1997-07-14T22: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",
|
"summary": "Bastille Day Party",
|
||||||
"start": {"dateTime": "1997-07-14T11:00:00-06:00"},
|
"start": {"dateTime": "1997-07-14T11:00:00-06:00"},
|
||||||
"end": {"dateTime": "1997-07-14T22: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",
|
"summary": "Bastille Day Party",
|
||||||
"start": {"dateTime": "1997-07-14T11:00:00-06:00"},
|
"start": {"dateTime": "1997-07-14T11:00:00-06:00"},
|
||||||
"end": {"dateTime": "1997-07-14T22:00:00-06:00"},
|
"end": {"dateTime": "1997-07-14T22:00:00-06:00"},
|
||||||
|
"location": "Test Location",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue