Home Assistant Unofficial Reference 2024.12.1
services.py
Go to the documentation of this file.
1 """YoLink services."""
2 
3 import voluptuous as vol
4 from yolink.client_request import ClientRequest
5 
6 from homeassistant.config_entries import ConfigEntryState
7 from homeassistant.core import HomeAssistant, ServiceCall
8 from homeassistant.exceptions import ServiceValidationError
9 from homeassistant.helpers import config_validation as cv, device_registry as dr
10 
11 from .const import (
12  ATTR_REPEAT,
13  ATTR_TARGET_DEVICE,
14  ATTR_TEXT_MESSAGE,
15  ATTR_TONE,
16  ATTR_VOLUME,
17  DOMAIN,
18 )
19 
20 SERVICE_PLAY_ON_SPEAKER_HUB = "play_on_speaker_hub"
21 
22 
23 def async_register_services(hass: HomeAssistant) -> None:
24  """Register services for YoLink integration."""
25 
26  async def handle_speaker_hub_play_call(service_call: ServiceCall) -> None:
27  """Handle Speaker Hub audio play call."""
28  service_data = service_call.data
29  device_registry = dr.async_get(hass)
30  device_entry = device_registry.async_get(service_data[ATTR_TARGET_DEVICE])
31  if device_entry is not None:
32  for entry_id in device_entry.config_entries:
33  if (entry := hass.config_entries.async_get_entry(entry_id)) is None:
34  continue
35  if entry.domain == DOMAIN:
36  break
37  if entry is None or entry.state == ConfigEntryState.NOT_LOADED:
39  translation_domain=DOMAIN,
40  translation_key="invalid_config_entry",
41  )
42  home_store = hass.data[DOMAIN][entry.entry_id]
43  for identifier in device_entry.identifiers:
44  if (
45  device_coordinator := home_store.device_coordinators.get(
46  identifier[1]
47  )
48  ) is not None:
49  tone_param = service_data[ATTR_TONE].capitalize()
50  play_request = ClientRequest(
51  "playAudio",
52  {
53  ATTR_TONE: tone_param,
54  ATTR_TEXT_MESSAGE: service_data[ATTR_TEXT_MESSAGE],
55  ATTR_VOLUME: service_data[ATTR_VOLUME],
56  ATTR_REPEAT: service_data[ATTR_REPEAT],
57  },
58  )
59  await device_coordinator.device.call_device(play_request)
60 
61  hass.services.async_register(
62  domain=DOMAIN,
63  service=SERVICE_PLAY_ON_SPEAKER_HUB,
64  schema=vol.Schema(
65  {
66  vol.Required(ATTR_TARGET_DEVICE): cv.string,
67  vol.Required(ATTR_TONE): cv.string,
68  vol.Required(ATTR_TEXT_MESSAGE): cv.string,
69  vol.Required(ATTR_VOLUME): vol.All(
70  vol.Coerce(int), vol.Range(min=0, max=15)
71  ),
72  vol.Optional(ATTR_REPEAT, default=0): vol.All(
73  vol.Coerce(int), vol.Range(min=0, max=10)
74  ),
75  },
76  ),
77  service_func=handle_speaker_hub_play_call,
78  )