Home Assistant Unofficial Reference 2024.12.1
services.py
Go to the documentation of this file.
1 """Services for the Fully Kiosk Browser integration."""
2 
3 from __future__ import annotations
4 
5 import voluptuous as vol
6 
7 from homeassistant.config_entries import ConfigEntry, ConfigEntryState
8 from homeassistant.const import ATTR_DEVICE_ID
9 from homeassistant.core import HomeAssistant, ServiceCall
10 from homeassistant.exceptions import HomeAssistantError
13 
14 from .const import (
15  ATTR_APPLICATION,
16  ATTR_KEY,
17  ATTR_URL,
18  ATTR_VALUE,
19  DOMAIN,
20  SERVICE_LOAD_URL,
21  SERVICE_SET_CONFIG,
22  SERVICE_START_APPLICATION,
23 )
24 from .coordinator import FullyKioskDataUpdateCoordinator
25 
26 
27 async def async_setup_services(hass: HomeAssistant) -> None:
28  """Set up the services for the Fully Kiosk Browser integration."""
29 
30  async def collect_coordinators(
31  device_ids: list[str],
32  ) -> list[FullyKioskDataUpdateCoordinator]:
33  config_entries = list[ConfigEntry]()
34  registry = dr.async_get(hass)
35  for target in device_ids:
36  device = registry.async_get(target)
37  if device:
38  device_entries = list[ConfigEntry]()
39  for entry_id in device.config_entries:
40  entry = hass.config_entries.async_get_entry(entry_id)
41  if entry and entry.domain == DOMAIN:
42  device_entries.append(entry)
43  if not device_entries:
44  raise HomeAssistantError(
45  f"Device '{target}' is not a {DOMAIN} device"
46  )
47  config_entries.extend(device_entries)
48  else:
49  raise HomeAssistantError(
50  f"Device '{target}' not found in device registry"
51  )
52  coordinators = list[FullyKioskDataUpdateCoordinator]()
53  for config_entry in config_entries:
54  if config_entry.state != ConfigEntryState.LOADED:
55  raise HomeAssistantError(f"{config_entry.title} is not loaded")
56  coordinators.append(config_entry.runtime_data)
57  return coordinators
58 
59  async def async_load_url(call: ServiceCall) -> None:
60  """Load a URL on the Fully Kiosk Browser."""
61  for coordinator in await collect_coordinators(call.data[ATTR_DEVICE_ID]):
62  await coordinator.fully.loadUrl(call.data[ATTR_URL])
63 
64  async def async_start_app(call: ServiceCall) -> None:
65  """Start an app on the device."""
66  for coordinator in await collect_coordinators(call.data[ATTR_DEVICE_ID]):
67  await coordinator.fully.startApplication(call.data[ATTR_APPLICATION])
68 
69  async def async_set_config(call: ServiceCall) -> None:
70  """Set a Fully Kiosk Browser config value on the device."""
71  for coordinator in await collect_coordinators(call.data[ATTR_DEVICE_ID]):
72  key = call.data[ATTR_KEY]
73  value = call.data[ATTR_VALUE]
74 
75  # Fully API has different methods for setting string and bool values.
76  # check if call.data[ATTR_VALUE] is a bool
77  if isinstance(value, bool) or (
78  isinstance(value, str) and value.lower() in ("true", "false")
79  ):
80  await coordinator.fully.setConfigurationBool(key, value)
81  else:
82  # Convert any int values to string
83  if isinstance(value, int):
84  value = str(value)
85 
86  await coordinator.fully.setConfigurationString(key, value)
87 
88  # Register all the above services
89  service_mapping = [
90  (async_load_url, SERVICE_LOAD_URL, ATTR_URL),
91  (async_start_app, SERVICE_START_APPLICATION, ATTR_APPLICATION),
92  ]
93  for service_handler, service_name, attrib in service_mapping:
94  hass.services.async_register(
95  DOMAIN,
96  service_name,
97  service_handler,
98  schema=vol.Schema(
99  vol.All(
100  {
101  vol.Required(ATTR_DEVICE_ID): cv.ensure_list,
102  vol.Required(attrib): cv.string,
103  }
104  )
105  ),
106  )
107 
108  hass.services.async_register(
109  DOMAIN,
110  SERVICE_SET_CONFIG,
111  async_set_config,
112  schema=vol.Schema(
113  vol.All(
114  {
115  vol.Required(ATTR_DEVICE_ID): cv.ensure_list,
116  vol.Required(ATTR_KEY): cv.string,
117  vol.Required(ATTR_VALUE): vol.Any(str, bool, int),
118  }
119  )
120  ),
121  )
None async_setup_services(HomeAssistant hass)
Definition: services.py:27