Home Assistant Unofficial Reference 2024.12.1
entity.py
Go to the documentation of this file.
1 """Insteon base entity."""
2 
3 import functools
4 import logging
5 
6 from pyinsteon import devices
7 
8 from homeassistant.core import callback
9 from homeassistant.helpers.device_registry import DeviceInfo
11  async_dispatcher_connect,
12  async_dispatcher_send,
13 )
14 from homeassistant.helpers.entity import Entity
15 
16 from .const import (
17  DOMAIN,
18  SIGNAL_ADD_DEFAULT_LINKS,
19  SIGNAL_LOAD_ALDB,
20  SIGNAL_PRINT_ALDB,
21  SIGNAL_REMOVE_ENTITY,
22  SIGNAL_SAVE_DEVICES,
23  STATE_NAME_LABEL_MAP,
24 )
25 from .utils import print_aldb_to_log
26 
27 _LOGGER = logging.getLogger(__name__)
28 
29 
31  """INSTEON abstract base entity."""
32 
33  _attr_should_poll = False
34 
35  def __init__(self, device, group):
36  """Initialize the INSTEON binary sensor."""
37  self._insteon_device_group_insteon_device_group = device.groups[group]
38  self._insteon_device_insteon_device = device
39 
40  def __hash__(self):
41  """Return the hash of the Insteon Entity."""
42  return hash(self._insteon_device_insteon_device)
43 
44  @property
45  def address(self):
46  """Return the address of the node."""
47  return str(self._insteon_device_insteon_device.address)
48 
49  @property
50  def group(self):
51  """Return the INSTEON group that the entity responds to."""
52  return self._insteon_device_group_insteon_device_group.group
53 
54  @property
55  def unique_id(self) -> str:
56  """Return a unique ID."""
57  if self._insteon_device_group_insteon_device_group.group == 0x01:
58  uid = self._insteon_device_insteon_device.id
59  else:
60  uid = f"{self._insteon_device.id}_{self._insteon_device_group.group}"
61  return uid
62 
63  @property
64  def name(self):
65  """Return the name of the node (used for Entity_ID)."""
66  # Set a base description
67  if (description := self._insteon_device_insteon_device.description) is None:
68  description = "Unknown Device"
69  # Get an extension label if there is one
70  if extension := self._get_label_get_label():
71  extension = f" {extension}"
72  return f"{description} {self._insteon_device.address}{extension}"
73 
74  @property
76  """Provide attributes for display on device card."""
77  return {
78  "insteon_address": self.addressaddress,
79  "insteon_group": self.groupgroup,
80  }
81 
82  @property
83  def device_info(self) -> DeviceInfo:
84  """Return device information."""
85  return DeviceInfo(
86  identifiers={(DOMAIN, str(self._insteon_device_insteon_device.address))},
87  manufacturer="SmartLabs, Inc",
88  model=(
89  f"{self._insteon_device.model} ({self._insteon_device.cat!r},"
90  f" 0x{self._insteon_device.subcat:02x})"
91  ),
92  name=f"{self._insteon_device.description} {self._insteon_device.address}",
93  sw_version=(
94  f"{self._insteon_device.firmware:02x} Engine Version:"
95  f" {self._insteon_device.engine_version}"
96  ),
97  via_device=(DOMAIN, str(devices.modem.address)),
98  configuration_url=f"homeassistant://insteon/device/config/{self._insteon_device.id}",
99  )
100 
101  @callback
102  def async_entity_update(self, name, address, value, group):
103  """Receive notification from transport that new data exists."""
104  _LOGGER.debug(
105  "Received update for device %s group %d value %s",
106  address,
107  group,
108  value,
109  )
110  self.async_write_ha_stateasync_write_ha_state()
111 
112  async def async_added_to_hass(self):
113  """Register INSTEON update events."""
114  _LOGGER.debug(
115  "Tracking updates for device %s group %d name %s",
116  self.addressaddress,
117  self.groupgroup,
118  self._insteon_device_group_insteon_device_group.name,
119  )
120  self._insteon_device_group_insteon_device_group.subscribe(self.async_entity_updateasync_entity_update)
121  load_signal = f"{self.entity_id}_{SIGNAL_LOAD_ALDB}"
122  self.async_on_removeasync_on_remove(
123  async_dispatcher_connect(self.hasshass, load_signal, self._async_read_aldb_async_read_aldb)
124  )
125  print_signal = f"{self.entity_id}_{SIGNAL_PRINT_ALDB}"
126  async_dispatcher_connect(self.hasshass, print_signal, self._print_aldb_print_aldb)
127  default_links_signal = f"{self.entity_id}_{SIGNAL_ADD_DEFAULT_LINKS}"
129  self.hasshass, default_links_signal, self._async_add_default_links_async_add_default_links
130  )
131  remove_signal = f"{self._insteon_device.address.id}_{SIGNAL_REMOVE_ENTITY}"
132  self.async_on_removeasync_on_remove(
134  self.hasshass,
135  remove_signal,
136  functools.partial(self.async_removeasync_remove, force_remove=True),
137  )
138  )
139 
141  """Unsubscribe to INSTEON update events."""
142  _LOGGER.debug(
143  "Remove tracking updates for device %s group %d name %s",
144  self.addressaddress,
145  self.groupgroup,
146  self._insteon_device_group_insteon_device_group.name,
147  )
148  self._insteon_device_group_insteon_device_group.unsubscribe(self.async_entity_updateasync_entity_update)
149 
150  async def _async_read_aldb(self, reload):
151  """Call device load process and print to log."""
152  await self._insteon_device_insteon_device.aldb.async_load(refresh=reload)
153  self._print_aldb_print_aldb()
154  async_dispatcher_send(self.hasshass, SIGNAL_SAVE_DEVICES)
155 
156  def _print_aldb(self):
157  """Print the device ALDB to the log file."""
158  print_aldb_to_log(self._insteon_device_insteon_device.aldb)
159 
160  def get_device_property(self, name: str):
161  """Get a single Insteon device property value (raw)."""
162  if (prop := self._insteon_device_insteon_device.properties.get(name)) is not None:
163  return prop.value
164  return None
165 
166  def _get_label(self):
167  """Get the device label for grouped devices."""
168  label = ""
169  if len(self._insteon_device_insteon_device.groups) > 1:
170  if self._insteon_device_group_insteon_device_group.name in STATE_NAME_LABEL_MAP:
171  label = STATE_NAME_LABEL_MAP[self._insteon_device_group_insteon_device_group.name]
172  else:
173  label = f"Group {self.group:d}"
174  return label
175 
176  async def _async_add_default_links(self):
177  """Add default links between the device and the modem."""
178  await self._insteon_device_insteon_device.async_add_default_links()
def async_entity_update(self, name, address, value, group)
Definition: entity.py:102
None async_on_remove(self, CALLBACK_TYPE func)
Definition: entity.py:1331
None async_remove(self, *bool force_remove=False)
Definition: entity.py:1387
Callable[[], None] subscribe(HomeAssistant hass, str topic, MessageCallbackType msg_callback, int qos=DEFAULT_QOS, str encoding="utf-8")
Definition: client.py:247
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
Definition: dispatcher.py:103
None async_dispatcher_send(HomeAssistant hass, str signal, *Any args)
Definition: dispatcher.py:193