Home Assistant Unofficial Reference 2024.12.1
binary_sensor.py
Go to the documentation of this file.
1 """Matter binary sensors."""
2 
3 from __future__ import annotations
4 
5 from dataclasses import dataclass
6 
7 from chip.clusters import Objects as clusters
8 from chip.clusters.Objects import uint
9 from chip.clusters.Types import Nullable, NullValue
10 from matter_server.client.models import device_types
11 
13  BinarySensorDeviceClass,
14  BinarySensorEntity,
15  BinarySensorEntityDescription,
16 )
17 from homeassistant.config_entries import ConfigEntry
18 from homeassistant.const import EntityCategory, Platform
19 from homeassistant.core import HomeAssistant, callback
20 from homeassistant.helpers.entity_platform import AddEntitiesCallback
21 
22 from .entity import MatterEntity, MatterEntityDescription
23 from .helpers import get_matter
24 from .models import MatterDiscoverySchema
25 
26 
28  hass: HomeAssistant,
29  config_entry: ConfigEntry,
30  async_add_entities: AddEntitiesCallback,
31 ) -> None:
32  """Set up Matter binary sensor from Config Entry."""
33  matter = get_matter(hass)
34  matter.register_platform_handler(Platform.BINARY_SENSOR, async_add_entities)
35 
36 
37 @dataclass(frozen=True)
39  BinarySensorEntityDescription, MatterEntityDescription
40 ):
41  """Describe Matter binary sensor entities."""
42 
43 
45  """Representation of a Matter binary sensor."""
46 
47  entity_description: MatterBinarySensorEntityDescription
48 
49  @callback
50  def _update_from_device(self) -> None:
51  """Update from device."""
52  value: bool | uint | int | Nullable | None
53  value = self.get_matter_attribute_valueget_matter_attribute_value(self._entity_info_entity_info.primary_attribute)
54  if value in (None, NullValue):
55  value = None
56  elif value_convert := self.entity_descriptionentity_description.measurement_to_ha:
57  value = value_convert(value)
58  self._attr_is_on_attr_is_on = value
59 
60 
61 # Discovery schema(s) to map Matter Attributes to HA entities
62 DISCOVERY_SCHEMAS = [
63  # device specific: translate Hue motion to sensor to HA Motion sensor
64  # instead of generic occupancy sensor
66  platform=Platform.BINARY_SENSOR,
67  entity_description=MatterBinarySensorEntityDescription(
68  key="HueMotionSensor",
69  device_class=BinarySensorDeviceClass.MOTION,
70  measurement_to_ha=lambda x: (x & 1 == 1) if x is not None else None,
71  ),
72  entity_class=MatterBinarySensor,
73  required_attributes=(clusters.OccupancySensing.Attributes.Occupancy,),
74  vendor_id=(4107,),
75  product_name=("Hue motion sensor",),
76  ),
78  platform=Platform.BINARY_SENSOR,
79  entity_description=MatterBinarySensorEntityDescription(
80  key="OccupancySensor",
81  device_class=BinarySensorDeviceClass.OCCUPANCY,
82  # The first bit = if occupied
83  measurement_to_ha=lambda x: (x & 1 == 1) if x is not None else None,
84  ),
85  entity_class=MatterBinarySensor,
86  required_attributes=(clusters.OccupancySensing.Attributes.Occupancy,),
87  ),
89  platform=Platform.BINARY_SENSOR,
90  entity_description=MatterBinarySensorEntityDescription(
91  key="BatteryChargeLevel",
92  device_class=BinarySensorDeviceClass.BATTERY,
93  entity_category=EntityCategory.DIAGNOSTIC,
94  measurement_to_ha=lambda x: x
95  != clusters.PowerSource.Enums.BatChargeLevelEnum.kOk,
96  ),
97  entity_class=MatterBinarySensor,
98  required_attributes=(clusters.PowerSource.Attributes.BatChargeLevel,),
99  # only add binary battery sensor if a regular percentage based is not available
100  absent_attributes=(clusters.PowerSource.Attributes.BatPercentRemaining,),
101  ),
102  # BooleanState sensors (tied to device type)
104  platform=Platform.BINARY_SENSOR,
105  entity_description=MatterBinarySensorEntityDescription(
106  key="ContactSensor",
107  device_class=BinarySensorDeviceClass.DOOR,
108  # value is inverted on matter to what we expect
109  measurement_to_ha=lambda x: not x,
110  ),
111  entity_class=MatterBinarySensor,
112  required_attributes=(clusters.BooleanState.Attributes.StateValue,),
113  device_type=(device_types.ContactSensor,),
114  ),
116  platform=Platform.BINARY_SENSOR,
117  entity_description=MatterBinarySensorEntityDescription(
118  key="WaterLeakDetector",
119  translation_key="water_leak",
120  device_class=BinarySensorDeviceClass.MOISTURE,
121  ),
122  entity_class=MatterBinarySensor,
123  required_attributes=(clusters.BooleanState.Attributes.StateValue,),
124  device_type=(device_types.WaterLeakDetector,),
125  ),
127  platform=Platform.BINARY_SENSOR,
128  entity_description=MatterBinarySensorEntityDescription(
129  key="WaterFreezeDetector",
130  translation_key="water_freeze",
131  device_class=BinarySensorDeviceClass.COLD,
132  ),
133  entity_class=MatterBinarySensor,
134  required_attributes=(clusters.BooleanState.Attributes.StateValue,),
135  device_type=(device_types.WaterFreezeDetector,),
136  ),
138  platform=Platform.BINARY_SENSOR,
139  entity_description=MatterBinarySensorEntityDescription(
140  key="RainSensor",
141  translation_key="rain",
142  device_class=BinarySensorDeviceClass.MOISTURE,
143  ),
144  entity_class=MatterBinarySensor,
145  required_attributes=(clusters.BooleanState.Attributes.StateValue,),
146  device_type=(device_types.RainSensor,),
147  ),
149  platform=Platform.BINARY_SENSOR,
150  entity_description=MatterBinarySensorEntityDescription(
151  key="LockDoorStateSensor",
152  device_class=BinarySensorDeviceClass.DOOR,
153  measurement_to_ha={
154  clusters.DoorLock.Enums.DoorStateEnum.kDoorOpen: True,
155  clusters.DoorLock.Enums.DoorStateEnum.kDoorJammed: True,
156  clusters.DoorLock.Enums.DoorStateEnum.kDoorForcedOpen: True,
157  clusters.DoorLock.Enums.DoorStateEnum.kDoorClosed: False,
158  }.get,
159  ),
160  entity_class=MatterBinarySensor,
161  required_attributes=(clusters.DoorLock.Attributes.DoorState,),
162  featuremap_contains=clusters.DoorLock.Bitmaps.Feature.kDoorPositionSensor,
163  ),
165  platform=Platform.BINARY_SENSOR,
166  entity_description=MatterBinarySensorEntityDescription(
167  key="SmokeCoAlarmDeviceMutedSensor",
168  measurement_to_ha=lambda x: (
169  x == clusters.SmokeCoAlarm.Enums.MuteStateEnum.kMuted
170  ),
171  translation_key="muted",
172  entity_category=EntityCategory.DIAGNOSTIC,
173  ),
174  entity_class=MatterBinarySensor,
175  required_attributes=(clusters.SmokeCoAlarm.Attributes.DeviceMuted,),
176  ),
178  platform=Platform.BINARY_SENSOR,
179  entity_description=MatterBinarySensorEntityDescription(
180  key="SmokeCoAlarmEndfOfServiceSensor",
181  measurement_to_ha=lambda x: (
182  x == clusters.SmokeCoAlarm.Enums.EndOfServiceEnum.kExpired
183  ),
184  translation_key="end_of_service",
185  device_class=BinarySensorDeviceClass.PROBLEM,
186  entity_category=EntityCategory.DIAGNOSTIC,
187  ),
188  entity_class=MatterBinarySensor,
189  required_attributes=(clusters.SmokeCoAlarm.Attributes.EndOfServiceAlert,),
190  ),
192  platform=Platform.BINARY_SENSOR,
193  entity_description=MatterBinarySensorEntityDescription(
194  key="SmokeCoAlarmBatteryAlertSensor",
195  measurement_to_ha=lambda x: (
196  x != clusters.SmokeCoAlarm.Enums.AlarmStateEnum.kNormal
197  ),
198  translation_key="battery_alert",
199  device_class=BinarySensorDeviceClass.BATTERY,
200  entity_category=EntityCategory.DIAGNOSTIC,
201  ),
202  entity_class=MatterBinarySensor,
203  required_attributes=(clusters.SmokeCoAlarm.Attributes.BatteryAlert,),
204  ),
206  platform=Platform.BINARY_SENSOR,
207  entity_description=MatterBinarySensorEntityDescription(
208  key="SmokeCoAlarmTestInProgressSensor",
209  translation_key="test_in_progress",
210  device_class=BinarySensorDeviceClass.RUNNING,
211  entity_category=EntityCategory.DIAGNOSTIC,
212  ),
213  entity_class=MatterBinarySensor,
214  required_attributes=(clusters.SmokeCoAlarm.Attributes.TestInProgress,),
215  ),
217  platform=Platform.BINARY_SENSOR,
218  entity_description=MatterBinarySensorEntityDescription(
219  key="SmokeCoAlarmHardwareFaultAlertSensor",
220  translation_key="hardware_fault",
221  device_class=BinarySensorDeviceClass.PROBLEM,
222  entity_category=EntityCategory.DIAGNOSTIC,
223  ),
224  entity_class=MatterBinarySensor,
225  required_attributes=(clusters.SmokeCoAlarm.Attributes.HardwareFaultAlert,),
226  ),
228  platform=Platform.BINARY_SENSOR,
229  entity_description=MatterBinarySensorEntityDescription(
230  key="SmokeCoAlarmSmokeStateSensor",
231  device_class=BinarySensorDeviceClass.SMOKE,
232  measurement_to_ha=lambda x: (
233  x != clusters.SmokeCoAlarm.Enums.AlarmStateEnum.kNormal
234  ),
235  ),
236  entity_class=MatterBinarySensor,
237  required_attributes=(clusters.SmokeCoAlarm.Attributes.SmokeState,),
238  ),
240  platform=Platform.BINARY_SENSOR,
241  entity_description=MatterBinarySensorEntityDescription(
242  key="SmokeCoAlarmInterconnectSmokeAlarmSensor",
243  device_class=BinarySensorDeviceClass.SMOKE,
244  measurement_to_ha=lambda x: (
245  x != clusters.SmokeCoAlarm.Enums.AlarmStateEnum.kNormal
246  ),
247  translation_key="interconnected_smoke_alarm",
248  ),
249  entity_class=MatterBinarySensor,
250  required_attributes=(clusters.SmokeCoAlarm.Attributes.InterconnectSmokeAlarm,),
251  ),
253  platform=Platform.BINARY_SENSOR,
254  entity_description=MatterBinarySensorEntityDescription(
255  key="SmokeCoAlarmInterconnectCOAlarmSensor",
256  device_class=BinarySensorDeviceClass.CO,
257  measurement_to_ha=lambda x: (
258  x != clusters.SmokeCoAlarm.Enums.AlarmStateEnum.kNormal
259  ),
260  translation_key="interconnected_co_alarm",
261  ),
262  entity_class=MatterBinarySensor,
263  required_attributes=(clusters.SmokeCoAlarm.Attributes.InterconnectCOAlarm,),
264  ),
265 ]
Any get_matter_attribute_value(self, type[ClusterAttributeDescriptor] attribute, bool null_as_none=True)
Definition: entity.py:206
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
MatterAdapter get_matter(HomeAssistant hass)
Definition: helpers.py:35