Home Assistant Unofficial Reference 2024.12.1
services.py
Go to the documentation of this file.
1 """Services for Fritz integration."""
2 
3 from __future__ import annotations
4 
5 import logging
6 
7 import voluptuous as vol
8 
9 from homeassistant.config_entries import ConfigEntryState
10 from homeassistant.core import HomeAssistant, ServiceCall
11 from homeassistant.exceptions import HomeAssistantError
12 from homeassistant.helpers.service import async_extract_config_entry_ids
13 
14 from .const import DOMAIN, FRITZ_SERVICES, SERVICE_SET_GUEST_WIFI_PW
15 from .coordinator import AvmWrapper
16 
17 _LOGGER = logging.getLogger(__name__)
18 
19 SERVICE_SCHEMA_SET_GUEST_WIFI_PW = vol.Schema(
20  {
21  vol.Required("device_id"): str,
22  vol.Optional("password"): vol.Length(min=8, max=63),
23  vol.Optional("length"): vol.Range(min=8, max=63),
24  }
25 )
26 
27 SERVICE_LIST: list[tuple[str, vol.Schema | None]] = [
28  (SERVICE_SET_GUEST_WIFI_PW, SERVICE_SCHEMA_SET_GUEST_WIFI_PW),
29 ]
30 
31 
32 async def async_setup_services(hass: HomeAssistant) -> None:
33  """Set up services for Fritz integration."""
34 
35  for service, _ in SERVICE_LIST:
36  if hass.services.has_service(DOMAIN, service):
37  return
38 
39  async def async_call_fritz_service(service_call: ServiceCall) -> None:
40  """Call correct Fritz service."""
41 
42  if not (
43  fritzbox_entry_ids := await _async_get_configured_avm_device(
44  hass, service_call
45  )
46  ):
47  raise HomeAssistantError(
48  translation_domain=DOMAIN,
49  translation_key="config_entry_not_found",
50  translation_placeholders={"service": service_call.service},
51  )
52 
53  for entry_id in fritzbox_entry_ids:
54  _LOGGER.debug("Executing service %s", service_call.service)
55  avm_wrapper: AvmWrapper = hass.data[DOMAIN][entry_id]
56  if config_entry := hass.config_entries.async_get_entry(entry_id):
57  await avm_wrapper.service_fritzbox(service_call, config_entry)
58  else:
59  _LOGGER.error(
60  "Executing service %s failed, no config entry found",
61  service_call.service,
62  )
63 
64  for service, schema in SERVICE_LIST:
65  hass.services.async_register(DOMAIN, service, async_call_fritz_service, schema)
66 
67 
69  hass: HomeAssistant, service_call: ServiceCall
70 ) -> list:
71  """Get FritzBoxTools class from config entry."""
72 
73  list_entry_id: list = []
74  for entry_id in await async_extract_config_entry_ids(hass, service_call):
75  config_entry = hass.config_entries.async_get_entry(entry_id)
76  if (
77  config_entry
78  and config_entry.domain == DOMAIN
79  and config_entry.state == ConfigEntryState.LOADED
80  ):
81  list_entry_id.append(entry_id)
82  return list_entry_id
83 
84 
85 async def async_unload_services(hass: HomeAssistant) -> None:
86  """Unload services for Fritz integration."""
87 
88  if not hass.data.get(FRITZ_SERVICES):
89  return
90 
91  hass.data[FRITZ_SERVICES] = False
92 
93  for service, _ in SERVICE_LIST:
94  hass.services.async_remove(DOMAIN, service)
None async_setup_services(HomeAssistant hass)
Definition: services.py:32
list _async_get_configured_avm_device(HomeAssistant hass, ServiceCall service_call)
Definition: services.py:70
None async_unload_services(HomeAssistant hass)
Definition: services.py:85
set[str] async_extract_config_entry_ids(HomeAssistant hass, ServiceCall service_call, bool expand_group=True)
Definition: service.py:635