Home Assistant Unofficial Reference 2024.12.1
entity.py
Go to the documentation of this file.
1 """Support for Notion."""
2 
3 from __future__ import annotations
4 
5 from dataclasses import dataclass
6 
7 from aionotion.bridge.models import Bridge
8 from aionotion.listener.models import Listener, ListenerKind
9 
10 from homeassistant.core import callback
11 from homeassistant.helpers import device_registry as dr
12 from homeassistant.helpers.device_registry import DeviceInfo
13 from homeassistant.helpers.entity import EntityDescription
14 from homeassistant.helpers.update_coordinator import CoordinatorEntity
15 
16 from .const import DOMAIN, LOGGER
17 from .coordinator import NotionDataUpdateCoordinator
18 
19 
20 @dataclass(frozen=True, kw_only=True)
22  """Define an description for Notion entities."""
23 
24  listener_kind: ListenerKind
25 
26 
27 class NotionEntity(CoordinatorEntity[NotionDataUpdateCoordinator]):
28  """Define a base Notion entity."""
29 
30  _attr_has_entity_name = True
31 
32  def __init__(
33  self,
34  coordinator: NotionDataUpdateCoordinator,
35  listener_id: str,
36  sensor_id: str,
37  bridge_id: int,
38  description: EntityDescription,
39  ) -> None:
40  """Initialize the entity."""
41  super().__init__(coordinator)
42 
43  sensor = self.coordinator.data.sensors[sensor_id]
44 
45  self._attr_device_info_attr_device_info = DeviceInfo(
46  identifiers={(DOMAIN, sensor.hardware_id)},
47  manufacturer="Silicon Labs",
48  model=str(sensor.hardware_revision),
49  name=str(sensor.name).capitalize(),
50  sw_version=sensor.firmware_version,
51  )
52 
53  if bridge := self._async_get_bridge_async_get_bridge(bridge_id):
54  self._attr_device_info_attr_device_info["via_device"] = (DOMAIN, bridge.hardware_id)
55 
56  self._attr_extra_state_attributes_attr_extra_state_attributes = {}
57  self._attr_unique_id_attr_unique_id = listener_id
58  self._bridge_id_bridge_id = bridge_id
59  self._listener_id_listener_id = listener_id
60  self._sensor_id_sensor_id = sensor_id
61  self.entity_descriptionentity_description = description
62 
63  @property
64  def available(self) -> bool:
65  """Return True if entity is available."""
66  return (
67  self.coordinator.last_update_success
68  and self._listener_id_listener_id in self.coordinator.data.listeners
69  )
70 
71  @property
72  def listener(self) -> Listener:
73  """Return the listener related to this entity."""
74  return self.coordinator.data.listeners[self._listener_id_listener_id]
75 
76  @callback
77  def _async_get_bridge(self, bridge_id: int) -> Bridge | None:
78  """Get a bridge by ID (if it exists)."""
79  if (bridge := self.coordinator.data.bridges.get(bridge_id)) is None:
80  LOGGER.debug("Entity references a non-existent bridge ID: %s", bridge_id)
81  return None
82  return bridge
83 
84  @callback
85  def _async_update_bridge_id(self) -> None:
86  """Update the entity's bridge ID if it has changed.
87 
88  Sensors can move to other bridges based on signal strength, etc.
89  """
90  sensor = self.coordinator.data.sensors[self._sensor_id_sensor_id]
91 
92  # If the bridge ID hasn't changed, return:
93  if self._bridge_id_bridge_id == sensor.bridge.id:
94  return
95 
96  # If the bridge doesn't exist, return:
97  if (bridge := self._async_get_bridge_async_get_bridge(sensor.bridge.id)) is None:
98  return
99 
100  self._bridge_id_bridge_id = sensor.bridge.id
101 
102  device_registry = dr.async_get(self.hasshass)
103  this_device = device_registry.async_get_device(
104  identifiers={(DOMAIN, sensor.hardware_id)}
105  )
106  bridge = self.coordinator.data.bridges[self._bridge_id_bridge_id]
107  bridge_device = device_registry.async_get_device(
108  identifiers={(DOMAIN, bridge.hardware_id)}
109  )
110 
111  if not bridge_device or not this_device:
112  return
113 
114  device_registry.async_update_device(
115  this_device.id, via_device_id=bridge_device.id
116  )
117 
118  @callback
119  def _handle_coordinator_update(self) -> None:
120  """Respond to a DataUpdateCoordinator update."""
121  if self._listener_id_listener_id in self.coordinator.data.listeners:
122  self._async_update_bridge_id_async_update_bridge_id()
None __init__(self, NotionDataUpdateCoordinator coordinator, str listener_id, str sensor_id, int bridge_id, EntityDescription description)
Definition: entity.py:39
Bridge|None _async_get_bridge(self, int bridge_id)
Definition: entity.py:77