Home Assistant Unofficial Reference 2024.12.1
binary_sensor.py
Go to the documentation of this file.
1 """Binary sensors for myUplink."""
2 
3 from myuplink import DeviceConnectionState, DevicePoint
4 
6  BinarySensorDeviceClass,
7  BinarySensorEntity,
8  BinarySensorEntityDescription,
9 )
10 from homeassistant.const import Platform
11 from homeassistant.core import HomeAssistant
12 from homeassistant.helpers.entity_platform import AddEntitiesCallback
13 
14 from . import MyUplinkConfigEntry, MyUplinkDataCoordinator
15 from .const import F_SERIES
16 from .entity import MyUplinkEntity, MyUplinkSystemEntity
17 from .helpers import find_matching_platform, transform_model_series
18 
19 CATEGORY_BASED_DESCRIPTIONS: dict[str, dict[str, BinarySensorEntityDescription]] = {
20  F_SERIES: {
22  key="elect_add",
23  translation_key="elect_add",
24  ),
25  },
26  "NIBEF": {
28  key="elect_add",
29  translation_key="elect_add",
30  ),
31  },
32 }
33 
34 CONNECTED_BINARY_SENSOR_DESCRIPTION = BinarySensorEntityDescription(
35  key="connected_state",
36  device_class=BinarySensorDeviceClass.CONNECTIVITY,
37 )
38 
39 ALARM_BINARY_SENSOR_DESCRIPTION = BinarySensorEntityDescription(
40  key="has_alarm",
41  device_class=BinarySensorDeviceClass.PROBLEM,
42  translation_key="alarm",
43 )
44 
45 
46 def get_description(device_point: DevicePoint) -> BinarySensorEntityDescription | None:
47  """Get description for a device point.
48 
49  Priorities:
50  1. Category specific prefix e.g "NIBEF"
51  2. Default to None
52  """
53  prefix, _, _ = device_point.category.partition(" ")
54  prefix = transform_model_series(prefix)
55  return CATEGORY_BASED_DESCRIPTIONS.get(prefix, {}).get(device_point.parameter_id)
56 
57 
59  hass: HomeAssistant,
60  config_entry: MyUplinkConfigEntry,
61  async_add_entities: AddEntitiesCallback,
62 ) -> None:
63  """Set up myUplink binary_sensor."""
64  entities: list[BinarySensorEntity] = []
65  coordinator = config_entry.runtime_data
66 
67  # Setup device point bound sensors
68  for device_id, point_data in coordinator.data.points.items():
69  for point_id, device_point in point_data.items():
70  if find_matching_platform(device_point) == Platform.BINARY_SENSOR:
71  description = get_description(device_point)
72 
73  entities.append(
75  coordinator=coordinator,
76  device_id=device_id,
77  device_point=device_point,
78  entity_description=description,
79  unique_id_suffix=point_id,
80  )
81  )
82 
83  # Setup device bound sensors
84  entities.extend(
86  coordinator=coordinator,
87  device_id=device.id,
88  entity_description=CONNECTED_BINARY_SENSOR_DESCRIPTION,
89  unique_id_suffix="connection_state",
90  )
91  for system in coordinator.data.systems
92  for device in system.devices
93  )
94 
95  # Setup system bound sensors
96  for system in coordinator.data.systems:
97  device_id = system.devices[0].id
98  entities.append(
100  coordinator=coordinator,
101  device_id=device_id,
102  system_id=system.id,
103  entity_description=ALARM_BINARY_SENSOR_DESCRIPTION,
104  unique_id_suffix="has_alarm",
105  )
106  )
107 
108  async_add_entities(entities)
109 
110 
112  """Representation of a myUplink device point bound binary sensor."""
113 
114  def __init__(
115  self,
116  coordinator: MyUplinkDataCoordinator,
117  device_id: str,
118  device_point: DevicePoint,
119  entity_description: BinarySensorEntityDescription | None,
120  unique_id_suffix: str,
121  ) -> None:
122  """Initialize the binary_sensor."""
123  super().__init__(
124  coordinator=coordinator,
125  device_id=device_id,
126  unique_id_suffix=unique_id_suffix,
127  )
128 
129  # Internal properties
130  self.point_idpoint_id = device_point.parameter_id
131  self._attr_name_attr_name = device_point.parameter_name
132 
133  if entity_description is not None:
134  self.entity_descriptionentity_description = entity_description
135 
136  @property
137  def is_on(self) -> bool:
138  """Binary sensor state value."""
139  device_point = self.coordinator.data.points[self.device_iddevice_id][self.point_idpoint_id]
140  return int(device_point.value) != 0
141 
142  @property
143  def available(self) -> bool:
144  """Return device data availability."""
145  return super().available and (
146  self.coordinator.data.devices[self.device_iddevice_id].connectionState
147  == DeviceConnectionState.Connected
148  )
149 
150 
152  """Representation of a myUplink device bound binary sensor."""
153 
154  def __init__(
155  self,
156  coordinator: MyUplinkDataCoordinator,
157  device_id: str,
158  entity_description: BinarySensorEntityDescription | None,
159  unique_id_suffix: str,
160  ) -> None:
161  """Initialize the binary_sensor."""
162  super().__init__(
163  coordinator=coordinator,
164  device_id=device_id,
165  unique_id_suffix=unique_id_suffix,
166  )
167 
168  if entity_description is not None:
169  self.entity_descriptionentity_description = entity_description
170 
171  @property
172  def is_on(self) -> bool:
173  """Binary sensor state value."""
174  return (
175  self.coordinator.data.devices[self.device_iddevice_id].connectionState
176  == DeviceConnectionState.Connected
177  )
178 
179 
181  """Representation of a myUplink system bound binary sensor."""
182 
183  def __init__(
184  self,
185  coordinator: MyUplinkDataCoordinator,
186  system_id: str,
187  device_id: str,
188  entity_description: BinarySensorEntityDescription | None,
189  unique_id_suffix: str,
190  ) -> None:
191  """Initialize the binary_sensor."""
192  super().__init__(
193  coordinator=coordinator,
194  system_id=system_id,
195  device_id=device_id,
196  unique_id_suffix=unique_id_suffix,
197  )
198 
199  if entity_description is not None:
200  self.entity_descriptionentity_description = entity_description
201 
202  @property
203  def is_on(self) -> bool | None:
204  """Binary sensor state value."""
205  retval = None
206  for system in self.coordinator.data.systems:
207  if system.id == self.system_idsystem_id:
208  retval = system.has_alarm
209  break
210  return retval
web.Response get(self, web.Request request, str config_key)
Definition: view.py:88