Home Assistant Unofficial Reference 2024.12.1
device_trigger.py
Go to the documentation of this file.
1 """Provides device automations for ZHA devices that emit events."""
2 
3 import voluptuous as vol
4 from zha.application.const import ZHA_EVENT
5 
7  DEVICE_TRIGGER_BASE_SCHEMA,
8  InvalidDeviceAutomationConfig,
9 )
10 from homeassistant.components.homeassistant.triggers import event as event_trigger
11 from homeassistant.const import CONF_DEVICE_ID, CONF_DOMAIN, CONF_PLATFORM, CONF_TYPE
12 from homeassistant.core import CALLBACK_TYPE, HomeAssistant
13 from homeassistant.exceptions import HomeAssistantError
14 from homeassistant.helpers.trigger import TriggerActionType, TriggerInfo
15 from homeassistant.helpers.typing import ConfigType
16 
17 from .const import DOMAIN as ZHA_DOMAIN
18 from .helpers import async_get_zha_device_proxy, get_zha_data
19 
20 CONF_SUBTYPE = "subtype"
21 DEVICE = "device"
22 DEVICE_IEEE = "device_ieee"
23 
24 TRIGGER_SCHEMA = DEVICE_TRIGGER_BASE_SCHEMA.extend(
25  {vol.Required(CONF_TYPE): str, vol.Required(CONF_SUBTYPE): str}
26 )
27 
28 
29 def _get_device_trigger_data(hass: HomeAssistant, device_id: str) -> tuple[str, dict]:
30  """Get device trigger data for a device, falling back to the cache if possible."""
31 
32  # First, try checking to see if the device itself is accessible
33  try:
34  zha_device = async_get_zha_device_proxy(hass, device_id).device
35  except ValueError:
36  pass
37  else:
38  return str(zha_device.ieee), zha_device.device_automation_triggers
39 
40  # If not, check the trigger cache but allow any `KeyError`s to propagate
41  return get_zha_data(hass).device_trigger_cache[device_id]
42 
43 
45  hass: HomeAssistant, config: ConfigType
46 ) -> ConfigType:
47  """Validate config."""
48  config = TRIGGER_SCHEMA(config)
49 
50  # Trigger validation will not occur if the config entry is not loaded
51  _, triggers = _get_device_trigger_data(hass, config[CONF_DEVICE_ID])
52 
53  trigger = (config[CONF_TYPE], config[CONF_SUBTYPE])
54  if trigger not in triggers:
55  raise InvalidDeviceAutomationConfig(f"device does not have trigger {trigger}")
56 
57  return config
58 
59 
61  hass: HomeAssistant,
62  config: ConfigType,
63  action: TriggerActionType,
64  trigger_info: TriggerInfo,
65 ) -> CALLBACK_TYPE:
66  """Listen for state changes based on configuration."""
67 
68  try:
69  ieee, triggers = _get_device_trigger_data(hass, config[CONF_DEVICE_ID])
70  except KeyError as err:
71  raise HomeAssistantError(
72  f"Unable to get zha device {config[CONF_DEVICE_ID]}"
73  ) from err
74 
75  trigger_key: tuple[str, str] = (config[CONF_TYPE], config[CONF_SUBTYPE])
76 
77  if trigger_key not in triggers:
78  raise HomeAssistantError(f"Unable to find trigger {trigger_key}")
79 
80  event_config = event_trigger.TRIGGER_SCHEMA(
81  {
82  event_trigger.CONF_PLATFORM: "event",
83  event_trigger.CONF_EVENT_TYPE: ZHA_EVENT,
84  event_trigger.CONF_EVENT_DATA: {DEVICE_IEEE: ieee, **triggers[trigger_key]},
85  }
86  )
87  return await event_trigger.async_attach_trigger(
88  hass, event_config, action, trigger_info, platform_type="device"
89  )
90 
91 
93  hass: HomeAssistant, device_id: str
94 ) -> list[dict[str, str]]:
95  """List device triggers.
96 
97  Make sure the device supports device automations and return the trigger list.
98  """
99  try:
100  _, triggers = _get_device_trigger_data(hass, device_id)
101  except KeyError as err:
102  raise InvalidDeviceAutomationConfig from err
103 
104  return [
105  {
106  CONF_DEVICE_ID: device_id,
107  CONF_DOMAIN: ZHA_DOMAIN,
108  CONF_PLATFORM: DEVICE,
109  CONF_TYPE: trigger,
110  CONF_SUBTYPE: subtype,
111  }
112  for trigger, subtype in triggers
113  ]
list[dict[str, str]] async_get_triggers(HomeAssistant hass, str device_id)
CALLBACK_TYPE async_attach_trigger(HomeAssistant hass, ConfigType config, TriggerActionType action, TriggerInfo trigger_info)
ConfigType async_validate_trigger_config(HomeAssistant hass, ConfigType config)
tuple[str, dict] _get_device_trigger_data(HomeAssistant hass, str device_id)
ZHADeviceProxy async_get_zha_device_proxy(HomeAssistant hass, str device_id)
Definition: helpers.py:1053
HAZHAData get_zha_data(HomeAssistant hass)
Definition: helpers.py:1020