Home Assistant Unofficial Reference 2024.12.1
device_trigger.py
Go to the documentation of this file.
1 """Provides device automations for Philips Hue events."""
2 
3 from __future__ import annotations
4 
5 from typing import TYPE_CHECKING, Any
6 
7 from aiohue.v2.models.resource import ResourceTypes
8 import voluptuous as vol
9 
10 from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
11 from homeassistant.components.homeassistant.triggers import event as event_trigger
12 from homeassistant.const import (
13  CONF_DEVICE_ID,
14  CONF_DOMAIN,
15  CONF_PLATFORM,
16  CONF_TYPE,
17  CONF_UNIQUE_ID,
18 )
19 from homeassistant.core import CALLBACK_TYPE, callback
20 from homeassistant.helpers.device_registry import DeviceEntry
21 from homeassistant.helpers.typing import ConfigType
22 
23 from ..const import (
24  ATTR_HUE_EVENT,
25  CONF_SUBTYPE,
26  DEFAULT_BUTTON_EVENT_TYPES,
27  DEFAULT_ROTARY_EVENT_SUBTYPES,
28  DEFAULT_ROTARY_EVENT_TYPES,
29  DEVICE_SPECIFIC_EVENT_TYPES,
30  DOMAIN,
31 )
32 
33 if TYPE_CHECKING:
34  from aiohue.v2 import HueBridgeV2
35 
36  from homeassistant.helpers.trigger import TriggerActionType, TriggerInfo
37 
38  from ..bridge import HueBridge
39 
40 TRIGGER_SCHEMA = DEVICE_TRIGGER_BASE_SCHEMA.extend(
41  {
42  vol.Required(CONF_TYPE): str,
43  vol.Required(CONF_SUBTYPE): vol.Union(int, str),
44  vol.Optional(CONF_UNIQUE_ID): str,
45  }
46 )
47 
48 
50  bridge: HueBridge,
51  device_entry: DeviceEntry,
52  config: ConfigType,
53 ) -> ConfigType:
54  """Validate config."""
55  return TRIGGER_SCHEMA(config)
56 
57 
59  bridge: HueBridge,
60  device_entry: DeviceEntry,
61  config: ConfigType,
62  action: TriggerActionType,
63  trigger_info: TriggerInfo,
64 ) -> CALLBACK_TYPE:
65  """Listen for state changes based on configuration."""
66  hass = bridge.hass
67  event_config = event_trigger.TRIGGER_SCHEMA(
68  {
69  event_trigger.CONF_PLATFORM: "event",
70  event_trigger.CONF_EVENT_TYPE: ATTR_HUE_EVENT,
71  event_trigger.CONF_EVENT_DATA: {
72  CONF_DEVICE_ID: config[CONF_DEVICE_ID],
73  CONF_TYPE: config[CONF_TYPE],
74  CONF_SUBTYPE: config[CONF_SUBTYPE],
75  },
76  }
77  )
78  return await event_trigger.async_attach_trigger(
79  hass, event_config, action, trigger_info, platform_type="device"
80  )
81 
82 
83 @callback
85  bridge: HueBridge, device_entry: DeviceEntry
86 ) -> list[dict[str, Any]]:
87  """Return device triggers for device on `v2` bridge."""
88  api: HueBridgeV2 = bridge.api
89 
90  # Get Hue device id from device identifier
91  hue_dev_id = get_hue_device_id(device_entry)
92  # extract triggers from all button resources of this Hue device
93  triggers: list[dict[str, Any]] = []
94  model_id = api.devices[hue_dev_id].product_data.product_name
95 
96  for resource in api.devices.get_sensors(hue_dev_id):
97  # button triggers
98  if resource.type == ResourceTypes.BUTTON:
99  triggers.extend(
100  {
101  CONF_DEVICE_ID: device_entry.id,
102  CONF_DOMAIN: DOMAIN,
103  CONF_PLATFORM: "device",
104  CONF_TYPE: event_type.value,
105  CONF_SUBTYPE: resource.metadata.control_id,
106  CONF_UNIQUE_ID: resource.id,
107  }
108  for event_type in DEVICE_SPECIFIC_EVENT_TYPES.get(
109  model_id, DEFAULT_BUTTON_EVENT_TYPES
110  )
111  )
112  # relative_rotary triggers
113  elif resource.type == ResourceTypes.RELATIVE_ROTARY:
114  triggers.extend(
115  {
116  CONF_DEVICE_ID: device_entry.id,
117  CONF_DOMAIN: DOMAIN,
118  CONF_PLATFORM: "device",
119  CONF_TYPE: event_type.value,
120  CONF_SUBTYPE: sub_type.value,
121  CONF_UNIQUE_ID: resource.id,
122  }
123  for event_type in DEFAULT_ROTARY_EVENT_TYPES
124  for sub_type in DEFAULT_ROTARY_EVENT_SUBTYPES
125  )
126  return triggers
127 
128 
129 @callback
130 def get_hue_device_id(device_entry: DeviceEntry) -> str | None:
131  """Get Hue device id from device entry."""
132  return next(
133  (
134  identifier[1]
135  for identifier in device_entry.identifiers
136  if identifier[0] == DOMAIN
137  and ":" not in identifier[1] # filter out v1 mac id
138  ),
139  None,
140  )
list[dict[str, Any]] async_get_triggers(HueBridge bridge, DeviceEntry device_entry)
CALLBACK_TYPE async_attach_trigger(HueBridge bridge, DeviceEntry device_entry, ConfigType config, TriggerActionType action, TriggerInfo trigger_info)
str|None get_hue_device_id(DeviceEntry device_entry)
ConfigType async_validate_trigger_config(HueBridge bridge, DeviceEntry device_entry, ConfigType config)