Home Assistant Unofficial Reference 2024.12.1
device_action.py
Go to the documentation of this file.
1 """Provides device actions for Mobile App."""
2 
3 from __future__ import annotations
4 
5 import voluptuous as vol
6 
7 from homeassistant.components import notify
8 from homeassistant.components.device_automation import InvalidDeviceAutomationConfig
9 from homeassistant.const import CONF_DEVICE_ID, CONF_DOMAIN, CONF_TYPE
10 from homeassistant.core import Context, HomeAssistant
11 from homeassistant.exceptions import TemplateError
12 from homeassistant.helpers import config_validation as cv, template
13 from homeassistant.helpers.typing import ConfigType, TemplateVarsType
14 
15 from .const import DOMAIN
16 from .util import get_notify_service, supports_push, webhook_id_from_device_id
17 
18 ACTION_SCHEMA = cv.DEVICE_ACTION_BASE_SCHEMA.extend(
19  {
20  vol.Required(CONF_TYPE): "notify",
21  vol.Required(notify.ATTR_MESSAGE): cv.template,
22  vol.Optional(notify.ATTR_TITLE): cv.template,
23  vol.Optional(notify.ATTR_DATA): cv.template_complex,
24  }
25 )
26 
27 
29  hass: HomeAssistant, device_id: str
30 ) -> list[dict[str, str]]:
31  """List device actions for Mobile App devices."""
32  webhook_id = webhook_id_from_device_id(hass, device_id)
33 
34  if webhook_id is None or not supports_push(hass, webhook_id):
35  return []
36 
37  return [{CONF_DEVICE_ID: device_id, CONF_DOMAIN: DOMAIN, CONF_TYPE: "notify"}]
38 
39 
41  hass: HomeAssistant,
42  config: ConfigType,
43  variables: TemplateVarsType,
44  context: Context | None,
45 ) -> None:
46  """Execute a device action."""
47  webhook_id = webhook_id_from_device_id(hass, config[CONF_DEVICE_ID])
48 
49  if webhook_id is None:
51  "Unable to resolve webhook ID from the device ID"
52  )
53 
54  if (service_name := get_notify_service(hass, webhook_id)) is None:
56  "Unable to find notify service for webhook ID"
57  )
58 
59  service_data = {notify.ATTR_TARGET: webhook_id}
60 
61  # Render it here because we have access to variables here.
62  for key in (notify.ATTR_MESSAGE, notify.ATTR_TITLE, notify.ATTR_DATA):
63  if key not in config:
64  continue
65 
66  value_template = config[key]
67 
68  try:
69  service_data[key] = template.render_complex(value_template, variables)
70  except TemplateError as err:
72  f"Error rendering {key}: {err}"
73  ) from err
74 
75  await hass.services.async_call(
76  notify.DOMAIN, service_name, service_data, blocking=True, context=context
77  )
78 
79 
81  hass: HomeAssistant, config: ConfigType
82 ) -> dict[str, vol.Schema]:
83  """List action capabilities."""
84  if config[CONF_TYPE] != "notify":
85  return {}
86 
87  return {
88  "extra_fields": vol.Schema(
89  {
90  vol.Required(notify.ATTR_MESSAGE): str,
91  vol.Optional(notify.ATTR_TITLE): str,
92  }
93  )
94  }
None async_call_action_from_config(HomeAssistant hass, ConfigType config, TemplateVarsType variables, Context|None context)
dict[str, vol.Schema] async_get_action_capabilities(HomeAssistant hass, ConfigType config)
list[dict[str, str]] async_get_actions(HomeAssistant hass, str device_id)
bool supports_push(HomeAssistant hass, str webhook_id)
Definition: util.py:42
str|None get_notify_service(HomeAssistant hass, str webhook_id)
Definition: util.py:52
str|None webhook_id_from_device_id(HomeAssistant hass, str device_id)
Definition: util.py:29