Home Assistant Unofficial Reference 2024.12.1
services.py
Go to the documentation of this file.
1 """Support for recorder services."""
2 
3 from __future__ import annotations
4 
5 from datetime import timedelta
6 from typing import cast
7 
8 import voluptuous as vol
9 
10 from homeassistant.const import ATTR_ENTITY_ID
11 from homeassistant.core import HomeAssistant, ServiceCall, callback
13 from homeassistant.helpers.entityfilter import generate_filter
15  async_extract_entity_ids,
16  async_register_admin_service,
17 )
18 import homeassistant.util.dt as dt_util
19 
20 from .const import ATTR_APPLY_FILTER, ATTR_KEEP_DAYS, ATTR_REPACK, DOMAIN
21 from .core import Recorder
22 from .tasks import PurgeEntitiesTask, PurgeTask
23 
24 SERVICE_PURGE = "purge"
25 SERVICE_PURGE_ENTITIES = "purge_entities"
26 SERVICE_ENABLE = "enable"
27 SERVICE_DISABLE = "disable"
28 
29 SERVICE_PURGE_SCHEMA = vol.Schema(
30  {
31  vol.Optional(ATTR_KEEP_DAYS): cv.positive_int,
32  vol.Optional(ATTR_REPACK, default=False): cv.boolean,
33  vol.Optional(ATTR_APPLY_FILTER, default=False): cv.boolean,
34  }
35 )
36 
37 ATTR_DOMAINS = "domains"
38 ATTR_ENTITY_GLOBS = "entity_globs"
39 
40 SERVICE_PURGE_ENTITIES_SCHEMA = vol.All(
41  vol.Schema(
42  {
43  vol.Optional(ATTR_ENTITY_ID, default=[]): cv.entity_ids,
44  vol.Optional(ATTR_DOMAINS, default=[]): vol.All(
45  cv.ensure_list, [cv.string]
46  ),
47  vol.Optional(ATTR_ENTITY_GLOBS, default=[]): vol.All(
48  cv.ensure_list, [cv.string]
49  ),
50  vol.Optional(ATTR_KEEP_DAYS, default=0): cv.positive_int,
51  }
52  ),
53  vol.Any(
54  vol.Schema({vol.Required(ATTR_ENTITY_ID): vol.IsTrue()}, extra=vol.ALLOW_EXTRA),
55  vol.Schema({vol.Required(ATTR_DOMAINS): vol.IsTrue()}, extra=vol.ALLOW_EXTRA),
56  vol.Schema(
57  {vol.Required(ATTR_ENTITY_GLOBS): vol.IsTrue()}, extra=vol.ALLOW_EXTRA
58  ),
59  msg="At least one of entity_id, domains, or entity_globs must have a value",
60  ),
61 )
62 
63 SERVICE_ENABLE_SCHEMA = vol.Schema({})
64 SERVICE_DISABLE_SCHEMA = vol.Schema({})
65 
66 
67 @callback
68 def _async_register_purge_service(hass: HomeAssistant, instance: Recorder) -> None:
69  async def async_handle_purge_service(service: ServiceCall) -> None:
70  """Handle calls to the purge service."""
71  kwargs = service.data
72  keep_days = kwargs.get(ATTR_KEEP_DAYS, instance.keep_days)
73  repack = cast(bool, kwargs[ATTR_REPACK])
74  apply_filter = cast(bool, kwargs[ATTR_APPLY_FILTER])
75  purge_before = dt_util.utcnow() - timedelta(days=keep_days)
76  instance.queue_task(PurgeTask(purge_before, repack, apply_filter))
77 
79  hass,
80  DOMAIN,
81  SERVICE_PURGE,
82  async_handle_purge_service,
83  schema=SERVICE_PURGE_SCHEMA,
84  )
85 
86 
87 @callback
89  hass: HomeAssistant, instance: Recorder
90 ) -> None:
91  async def async_handle_purge_entities_service(service: ServiceCall) -> None:
92  """Handle calls to the purge entities service."""
93  entity_ids = await async_extract_entity_ids(hass, service)
94  domains = service.data.get(ATTR_DOMAINS, [])
95  keep_days = service.data.get(ATTR_KEEP_DAYS, 0)
96  entity_globs = service.data.get(ATTR_ENTITY_GLOBS, [])
97  entity_filter = generate_filter(domains, list(entity_ids), [], [], entity_globs)
98  purge_before = dt_util.utcnow() - timedelta(days=keep_days)
99  instance.queue_task(PurgeEntitiesTask(entity_filter, purge_before))
100 
102  hass,
103  DOMAIN,
104  SERVICE_PURGE_ENTITIES,
105  async_handle_purge_entities_service,
106  schema=SERVICE_PURGE_ENTITIES_SCHEMA,
107  )
108 
109 
110 @callback
111 def _async_register_enable_service(hass: HomeAssistant, instance: Recorder) -> None:
112  async def async_handle_enable_service(service: ServiceCall) -> None:
113  instance.set_enable(True)
114 
116  hass,
117  DOMAIN,
118  SERVICE_ENABLE,
119  async_handle_enable_service,
120  schema=SERVICE_ENABLE_SCHEMA,
121  )
122 
123 
124 @callback
125 def _async_register_disable_service(hass: HomeAssistant, instance: Recorder) -> None:
126  async def async_handle_disable_service(service: ServiceCall) -> None:
127  instance.set_enable(False)
128 
130  hass,
131  DOMAIN,
132  SERVICE_DISABLE,
133  async_handle_disable_service,
134  schema=SERVICE_DISABLE_SCHEMA,
135  )
136 
137 
138 @callback
139 def async_register_services(hass: HomeAssistant, instance: Recorder) -> None:
140  """Register recorder services."""
141  _async_register_purge_service(hass, instance)
143  _async_register_enable_service(hass, instance)
144  _async_register_disable_service(hass, instance)
None _async_register_disable_service(HomeAssistant hass, Recorder instance)
Definition: services.py:125
None async_register_services(HomeAssistant hass, Recorder instance)
Definition: services.py:139
None _async_register_purge_service(HomeAssistant hass, Recorder instance)
Definition: services.py:68
None _async_register_enable_service(HomeAssistant hass, Recorder instance)
Definition: services.py:111
None _async_register_purge_entities_service(HomeAssistant hass, Recorder instance)
Definition: services.py:90
Callable[[str], bool] generate_filter(list[str] include_domains, list[str] include_entities, list[str] exclude_domains, list[str] exclude_entities, list[str]|None include_entity_globs=None, list[str]|None exclude_entity_globs=None)
None async_register_admin_service(HomeAssistant hass, str domain, str service, Callable[[ServiceCall], Awaitable[None]|None] service_func, VolSchemaType schema=vol.Schema({}, extra=vol.PREVENT_EXTRA))
Definition: service.py:1121
set[str] async_extract_entity_ids(HomeAssistant hass, ServiceCall service_call, bool expand_group=True)
Definition: service.py:490