mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 04:07:08 +00:00
Add service to retrieve schedule configuration (#121904)
This commit is contained in:
parent
dba4637aa9
commit
71e28a4af3
@ -18,7 +18,13 @@ from homeassistant.const import (
|
|||||||
STATE_OFF,
|
STATE_OFF,
|
||||||
STATE_ON,
|
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 import config_validation as cv
|
||||||
from homeassistant.helpers.collection import (
|
from homeassistant.helpers.collection import (
|
||||||
CollectionEntity,
|
CollectionEntity,
|
||||||
@ -44,6 +50,7 @@ from .const import (
|
|||||||
CONF_TO,
|
CONF_TO,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
LOGGER,
|
LOGGER,
|
||||||
|
SERVICE_GET,
|
||||||
WEEKDAY_TO_CONF,
|
WEEKDAY_TO_CONF,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -205,6 +212,14 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||||||
reload_service_handler,
|
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
|
return True
|
||||||
|
|
||||||
|
|
||||||
@ -296,6 +311,10 @@ class Schedule(CollectionEntity):
|
|||||||
self.async_on_remove(self._clean_up_listener)
|
self.async_on_remove(self._clean_up_listener)
|
||||||
self._update()
|
self._update()
|
||||||
|
|
||||||
|
def get_schedule(self) -> ConfigType:
|
||||||
|
"""Return the schedule."""
|
||||||
|
return {d: self._config[d] for d in WEEKDAY_TO_CONF.values()}
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def _update(self, _: datetime | None = None) -> None:
|
def _update(self, _: datetime | None = None) -> None:
|
||||||
"""Update the states of the schedule."""
|
"""Update the states of the schedule."""
|
||||||
@ -390,3 +409,10 @@ class Schedule(CollectionEntity):
|
|||||||
data_keys.update(time_range_custom_data.keys())
|
data_keys.update(time_range_custom_data.keys())
|
||||||
|
|
||||||
return frozenset(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()
|
||||||
|
@ -37,3 +37,5 @@ WEEKDAY_TO_CONF: Final = {
|
|||||||
5: CONF_SATURDAY,
|
5: CONF_SATURDAY,
|
||||||
6: CONF_SUNDAY,
|
6: CONF_SUNDAY,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SERVICE_GET: Final = "get_schedule"
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
"services": {
|
"services": {
|
||||||
"reload": {
|
"reload": {
|
||||||
"service": "mdi:reload"
|
"service": "mdi:reload"
|
||||||
|
},
|
||||||
|
"get_schedule": {
|
||||||
|
"service": "mdi:calendar-export"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1,5 @@
|
|||||||
reload:
|
reload:
|
||||||
|
get_schedule:
|
||||||
|
target:
|
||||||
|
entity:
|
||||||
|
domain: schedule
|
||||||
|
@ -25,6 +25,10 @@
|
|||||||
"reload": {
|
"reload": {
|
||||||
"name": "[%key:common::action::reload%]",
|
"name": "[%key:common::action::reload%]",
|
||||||
"description": "Reloads schedules from the YAML-configuration."
|
"description": "Reloads schedules from the YAML-configuration."
|
||||||
|
},
|
||||||
|
"get_schedule": {
|
||||||
|
"name": "Get schedule",
|
||||||
|
"description": "Retrieve one or multiple schedules."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
59
tests/components/schedule/snapshots/test_init.ambr
Normal file
59
tests/components/schedule/snapshots/test_init.ambr
Normal 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([
|
||||||
|
]),
|
||||||
|
})
|
||||||
|
# ---
|
@ -8,10 +8,12 @@ from unittest.mock import patch
|
|||||||
|
|
||||||
from freezegun.api import FrozenDateTimeFactory
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
import pytest
|
import pytest
|
||||||
|
from syrupy.assertion import SnapshotAssertion
|
||||||
|
|
||||||
from homeassistant.components.schedule import STORAGE_VERSION, STORAGE_VERSION_MINOR
|
from homeassistant.components.schedule import STORAGE_VERSION, STORAGE_VERSION_MINOR
|
||||||
from homeassistant.components.schedule.const import (
|
from homeassistant.components.schedule.const import (
|
||||||
ATTR_NEXT_EVENT,
|
ATTR_NEXT_EVENT,
|
||||||
|
CONF_ALL_DAYS,
|
||||||
CONF_DATA,
|
CONF_DATA,
|
||||||
CONF_FRIDAY,
|
CONF_FRIDAY,
|
||||||
CONF_FROM,
|
CONF_FROM,
|
||||||
@ -23,12 +25,14 @@ from homeassistant.components.schedule.const import (
|
|||||||
CONF_TUESDAY,
|
CONF_TUESDAY,
|
||||||
CONF_WEDNESDAY,
|
CONF_WEDNESDAY,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
|
SERVICE_GET,
|
||||||
)
|
)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_EDITABLE,
|
ATTR_EDITABLE,
|
||||||
ATTR_FRIENDLY_NAME,
|
ATTR_FRIENDLY_NAME,
|
||||||
ATTR_ICON,
|
ATTR_ICON,
|
||||||
ATTR_NAME,
|
ATTR_NAME,
|
||||||
|
CONF_ENTITY_ID,
|
||||||
CONF_ICON,
|
CONF_ICON,
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
@ -754,3 +758,66 @@ async def test_ws_create(
|
|||||||
assert result["party_mode"][CONF_MONDAY] == [
|
assert result["party_mode"][CONF_MONDAY] == [
|
||||||
{CONF_FROM: "12:00:00", CONF_TO: saved_to}
|
{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")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user