Home Assistant Unofficial Reference 2024.12.1
hue_event.py
Go to the documentation of this file.
1 """Representation of a Hue remote firing events for button presses."""
2 
3 import logging
4 
5 from aiohue.v1.sensors import (
6  EVENT_BUTTON,
7  TYPE_ZGP_SWITCH,
8  TYPE_ZLL_ROTARY,
9  TYPE_ZLL_SWITCH,
10 )
11 
12 from homeassistant.const import CONF_DEVICE_ID, CONF_EVENT, CONF_ID, CONF_UNIQUE_ID
13 from homeassistant.core import callback
14 from homeassistant.helpers import device_registry as dr
15 from homeassistant.util import dt as dt_util, slugify
16 
17 from ..const import ATTR_HUE_EVENT
18 from .sensor_device import GenericHueDevice
19 
20 LOGGER = logging.getLogger(__name__)
21 
22 CONF_LAST_UPDATED = "last_updated"
23 
24 EVENT_NAME_FORMAT = "{}"
25 
26 
28  """When you want signals instead of entities.
29 
30  Stateless sensors such as remotes are expected to generate an event
31  instead of a sensor entity in hass.
32  """
33 
34  def __init__(self, sensor, name, bridge, primary_sensor=None):
35  """Register callback that will be used for signals."""
36  super().__init__(sensor, name, bridge, primary_sensor)
37  self.device_registry_iddevice_registry_id = None
38 
39  self.event_idevent_id = slugify(self.sensorsensor.name)
40  # Use the aiohue sensor 'state' dict to detect new remote presses
41  self._last_state_last_state = dict(self.sensorsensor.state)
42 
43  # Register callback in coordinator and add job to remove it on bridge reset.
44  self.bridgebridge.reset_jobs.append(
45  self.bridgebridge.sensor_manager.coordinator.async_add_listener(
46  self.async_update_callbackasync_update_callback
47  )
48  )
49 
50  @callback
52  """Fire the event if reason is that state is updated."""
53  if (
54  self.sensorsensor.state == self._last_state_last_state
55  # Filter out non-button events if last event type is available
56  or (
57  self.sensorsensor.last_event is not None
58  and self.sensorsensor.last_event["type"] != EVENT_BUTTON
59  )
60  ):
61  return
62 
63  # Filter out old states. Can happen when events fire while refreshing
64  now_updated = dt_util.parse_datetime(self.sensorsensor.state["lastupdated"])
65  last_updated = dt_util.parse_datetime(self._last_state_last_state["lastupdated"])
66 
67  if (
68  now_updated is not None
69  and last_updated is not None
70  and now_updated <= last_updated
71  ):
72  return
73 
74  # Extract the press code as state
75  if hasattr(self.sensorsensor, "rotaryevent"):
76  state = self.sensorsensor.rotaryevent
77  else:
78  state = self.sensorsensor.buttonevent
79 
80  self._last_state_last_state = dict(self.sensorsensor.state)
81 
82  # Fire event
83  data = {
84  CONF_ID: self.event_idevent_id,
85  CONF_DEVICE_ID: self.device_registry_iddevice_registry_id,
86  CONF_UNIQUE_ID: self.unique_idunique_id,
87  CONF_EVENT: state,
88  CONF_LAST_UPDATED: self.sensorsensor.lastupdated,
89  }
90  self.bridgebridge.hass.bus.async_fire(ATTR_HUE_EVENT, data)
91 
93  """Update device registry."""
94  device_registry = dr.async_get(self.bridgebridge.hass)
95 
96  entry = device_registry.async_get_or_create(
97  config_entry_id=self.bridgebridge.config_entry.entry_id, **self.device_infodevice_info
98  )
99  self.device_registry_iddevice_registry_id = entry.id
100  LOGGER.debug(
101  "Event registry with entry_id: %s and device_id: %s",
102  self.device_registry_iddevice_registry_id,
103  self.device_iddevice_id,
104  )
105 
106 
107 EVENT_CONFIG_MAP = {
108  TYPE_ZGP_SWITCH: {"name_format": EVENT_NAME_FORMAT, "class": HueEvent},
109  TYPE_ZLL_SWITCH: {"name_format": EVENT_NAME_FORMAT, "class": HueEvent},
110  TYPE_ZLL_ROTARY: {"name_format": EVENT_NAME_FORMAT, "class": HueEvent},
111 }
def __init__(self, sensor, name, bridge, primary_sensor=None)
Definition: hue_event.py:34