Files
homeassistant-core/homeassistant/components/matter/binary_sensor.py
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

149 lines
5.6 KiB
Python
Raw Normal View History

2022-12-06 20:28:06 +01:00
"""Matter binary sensors."""
2022-12-06 20:28:06 +01:00
from __future__ import annotations
from dataclasses import dataclass
2022-12-06 20:28:06 +01:00
from chip.clusters import Objects as clusters
from chip.clusters.Objects import uint
from chip.clusters.Types import Nullable, NullValue
from matter_server.client.models import device_types
2022-12-06 20:28:06 +01:00
from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
BinarySensorEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory, Platform
2022-12-06 20:28:06 +01:00
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .entity import MatterEntity, MatterEntityDescription
2022-12-20 13:06:24 +01:00
from .helpers import get_matter
from .models import MatterDiscoverySchema
2022-12-06 20:28:06 +01:00
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up Matter binary sensor from Config Entry."""
2022-12-20 13:06:24 +01:00
matter = get_matter(hass)
2022-12-06 20:28:06 +01:00
matter.register_platform_handler(Platform.BINARY_SENSOR, async_add_entities)
@dataclass(frozen=True)
class MatterBinarySensorEntityDescription(
BinarySensorEntityDescription, MatterEntityDescription
):
"""Describe Matter binary sensor entities."""
2022-12-06 20:28:06 +01:00
class MatterBinarySensor(MatterEntity, BinarySensorEntity):
"""Representation of a Matter binary sensor."""
entity_description: MatterBinarySensorEntityDescription
2022-12-06 20:28:06 +01:00
@callback
def _update_from_device(self) -> None:
"""Update from device."""
value: bool | uint | int | Nullable | None
value = self.get_matter_attribute_value(self._entity_info.primary_attribute)
if value in (None, NullValue):
value = None
elif value_convert := self.entity_description.measurement_to_ha:
value = value_convert(value)
self._attr_is_on = value
2022-12-06 20:28:06 +01:00
# Discovery schema(s) to map Matter Attributes to HA entities
DISCOVERY_SCHEMAS = [
# device specific: translate Hue motion to sensor to HA Motion sensor
# instead of generic occupancy sensor
MatterDiscoverySchema(
platform=Platform.BINARY_SENSOR,
entity_description=MatterBinarySensorEntityDescription(
key="HueMotionSensor",
device_class=BinarySensorDeviceClass.MOTION,
measurement_to_ha=lambda x: (x & 1 == 1) if x is not None else None,
),
entity_class=MatterBinarySensor,
required_attributes=(clusters.OccupancySensing.Attributes.Occupancy,),
vendor_id=(4107,),
product_name=("Hue motion sensor",),
),
MatterDiscoverySchema(
platform=Platform.BINARY_SENSOR,
entity_description=MatterBinarySensorEntityDescription(
key="OccupancySensor",
device_class=BinarySensorDeviceClass.OCCUPANCY,
# The first bit = if occupied
measurement_to_ha=lambda x: (x & 1 == 1) if x is not None else None,
),
entity_class=MatterBinarySensor,
required_attributes=(clusters.OccupancySensing.Attributes.Occupancy,),
2022-12-06 20:28:06 +01:00
),
MatterDiscoverySchema(
platform=Platform.BINARY_SENSOR,
entity_description=MatterBinarySensorEntityDescription(
key="BatteryChargeLevel",
device_class=BinarySensorDeviceClass.BATTERY,
entity_category=EntityCategory.DIAGNOSTIC,
measurement_to_ha=lambda x: x
!= clusters.PowerSource.Enums.BatChargeLevelEnum.kOk,
),
entity_class=MatterBinarySensor,
required_attributes=(clusters.PowerSource.Attributes.BatChargeLevel,),
# only add binary battery sensor if a regular percentage based is not available
absent_attributes=(clusters.PowerSource.Attributes.BatPercentRemaining,),
2022-12-06 20:28:06 +01:00
),
# BooleanState sensors (tied to device type)
MatterDiscoverySchema(
platform=Platform.BINARY_SENSOR,
entity_description=MatterBinarySensorEntityDescription(
key="ContactSensor",
device_class=BinarySensorDeviceClass.DOOR,
# value is inverted on matter to what we expect
measurement_to_ha=lambda x: not x,
),
entity_class=MatterBinarySensor,
required_attributes=(clusters.BooleanState.Attributes.StateValue,),
device_type=(device_types.ContactSensor,),
),
MatterDiscoverySchema(
platform=Platform.BINARY_SENSOR,
entity_description=MatterBinarySensorEntityDescription(
key="WaterLeakDetector",
translation_key="water_leak",
device_class=BinarySensorDeviceClass.MOISTURE,
),
entity_class=MatterBinarySensor,
required_attributes=(clusters.BooleanState.Attributes.StateValue,),
device_type=(device_types.WaterLeakDetector,),
),
MatterDiscoverySchema(
platform=Platform.BINARY_SENSOR,
entity_description=MatterBinarySensorEntityDescription(
key="WaterFreezeDetector",
translation_key="water_freeze",
device_class=BinarySensorDeviceClass.COLD,
),
entity_class=MatterBinarySensor,
required_attributes=(clusters.BooleanState.Attributes.StateValue,),
device_type=(device_types.WaterFreezeDetector,),
),
MatterDiscoverySchema(
platform=Platform.BINARY_SENSOR,
entity_description=MatterBinarySensorEntityDescription(
key="RainSensor",
translation_key="rain",
device_class=BinarySensorDeviceClass.MOISTURE,
),
entity_class=MatterBinarySensor,
required_attributes=(clusters.BooleanState.Attributes.StateValue,),
device_type=(device_types.RainSensor,),
),
]