Add service to retrieve schedule configuration (#121904)

This commit is contained in:
Richard Kroegel 2025-02-03 15:41:25 +01:00 committed by GitHub
parent dba4637aa9
commit 71e28a4af3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 166 additions and 1 deletions

View File

@ -18,7 +18,13 @@ from homeassistant.const import (
STATE_OFF,
STATE_ON,
)
from homeassistant.core import HomeAssistant, ServiceCall, callback
from homeassistant.core import (
HomeAssistant,
ServiceCall,
ServiceResponse,
SupportsResponse,
callback,
)
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.collection import (
CollectionEntity,
@ -44,6 +50,7 @@ from .const import (
CONF_TO,
DOMAIN,
LOGGER,
SERVICE_GET,
WEEKDAY_TO_CONF,
)
@ -205,6 +212,14 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
reload_service_handler,
)
component.async_register_entity_service(
SERVICE_GET,
{},
async_get_schedule_service,
supports_response=SupportsResponse.ONLY,
)
await component.async_setup(config)
return True
@ -296,6 +311,10 @@ class Schedule(CollectionEntity):
self.async_on_remove(self._clean_up_listener)
self._update()
def get_schedule(self) -> ConfigType:
"""Return the schedule."""
return {d: self._config[d] for d in WEEKDAY_TO_CONF.values()}
@callback
def _update(self, _: datetime | None = None) -> None:
"""Update the states of the schedule."""
@ -390,3 +409,10 @@ class Schedule(CollectionEntity):
data_keys.update(time_range_custom_data.keys())
return frozenset(data_keys)
async def async_get_schedule_service(
schedule: Schedule, service_call: ServiceCall
) -> ServiceResponse:
"""Return the schedule configuration."""
return schedule.get_schedule()

View File

@ -37,3 +37,5 @@ WEEKDAY_TO_CONF: Final = {
5: CONF_SATURDAY,
6: CONF_SUNDAY,
}
SERVICE_GET: Final = "get_schedule"

View File

@ -2,6 +2,9 @@
"services": {
"reload": {
"service": "mdi:reload"
},
"get_schedule": {
"service": "mdi:calendar-export"
}
}
}

View File

@ -1 +1,5 @@
reload:
get_schedule:
target:
entity:
domain: schedule

View File

@ -25,6 +25,10 @@
"reload": {
"name": "[%key:common::action::reload%]",
"description": "Reloads schedules from the YAML-configuration."
},
"get_schedule": {
"name": "Get schedule",
"description": "Retrieve one or multiple schedules."
}
}
}

View File

@ -0,0 +1,59 @@
# serializer version: 1
# name: test_service_get[schedule.from_storage-get-after-update]
dict({
'friday': list([
]),
'monday': list([
]),
'saturday': list([
]),
'sunday': list([
]),
'thursday': list([
]),
'tuesday': list([
]),
'wednesday': list([
dict({
'from': datetime.time(17, 0),
'to': datetime.time(19, 0),
}),
]),
})
# ---
# name: test_service_get[schedule.from_storage-get]
dict({
'friday': list([
dict({
'data': dict({
'party_level': 'epic',
}),
'from': datetime.time(17, 0),
'to': datetime.time(23, 59, 59),
}),
]),
'monday': list([
]),
'saturday': list([
dict({
'from': datetime.time(0, 0),
'to': datetime.time(23, 59, 59),
}),
]),
'sunday': list([
dict({
'data': dict({
'entry': 'VIPs only',
}),
'from': datetime.time(0, 0),
'to': datetime.time(23, 59, 59, 999999),
}),
]),
'thursday': list([
]),
'tuesday': list([
]),
'wednesday': list([
]),
})
# ---

View File

@ -8,10 +8,12 @@ from unittest.mock import patch
from freezegun.api import FrozenDateTimeFactory
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.schedule import STORAGE_VERSION, STORAGE_VERSION_MINOR
from homeassistant.components.schedule.const import (
ATTR_NEXT_EVENT,
CONF_ALL_DAYS,
CONF_DATA,
CONF_FRIDAY,
CONF_FROM,
@ -23,12 +25,14 @@ from homeassistant.components.schedule.const import (
CONF_TUESDAY,
CONF_WEDNESDAY,
DOMAIN,
SERVICE_GET,
)
from homeassistant.const import (
ATTR_EDITABLE,
ATTR_FRIENDLY_NAME,
ATTR_ICON,
ATTR_NAME,
CONF_ENTITY_ID,
CONF_ICON,
CONF_ID,
CONF_NAME,
@ -754,3 +758,66 @@ async def test_ws_create(
assert result["party_mode"][CONF_MONDAY] == [
{CONF_FROM: "12:00:00", CONF_TO: saved_to}
]
async def test_service_get(
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,
snapshot: SnapshotAssertion,
schedule_setup: Callable[..., Coroutine[Any, Any, bool]],
) -> None:
"""Test getting a single schedule via service."""
assert await schedule_setup()
entity_id = "schedule.from_storage"
# Test retrieving a single schedule via service call
service_result = await hass.services.async_call(
DOMAIN,
SERVICE_GET,
{
CONF_ENTITY_ID: entity_id,
},
blocking=True,
return_response=True,
)
result = service_result.get(entity_id)
assert set(result) == CONF_ALL_DAYS
assert result == snapshot(name=f"{entity_id}-get")
# Now we update the schedule via WS
client = await hass_ws_client(hass)
await client.send_json(
{
"id": 1,
"type": f"{DOMAIN}/update",
f"{DOMAIN}_id": entity_id.rsplit(".", maxsplit=1)[-1],
CONF_NAME: "Party pooper",
CONF_ICON: "mdi:party-pooper",
CONF_MONDAY: [],
CONF_TUESDAY: [],
CONF_WEDNESDAY: [{CONF_FROM: "17:00:00", CONF_TO: "19:00:00"}],
CONF_THURSDAY: [],
CONF_FRIDAY: [],
CONF_SATURDAY: [],
CONF_SUNDAY: [],
}
)
resp = await client.receive_json()
assert resp["success"]
# Test retrieving the schedule via service call after WS update
service_result = await hass.services.async_call(
DOMAIN,
SERVICE_GET,
{
CONF_ENTITY_ID: entity_id,
},
blocking=True,
return_response=True,
)
result = service_result.get(entity_id)
assert set(result) == CONF_ALL_DAYS
assert result == snapshot(name=f"{entity_id}-get-after-update")