Add Matter custom cluster sensors (Eve Energy Plug energy measurements) (#104830)

* Support for sensors from custom clusters in Matter

* lint

* no need to write state twice

* Add test for eve energy plug

* Update homeassistant/components/matter/entity.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* adjust comment

* debounce extra poll timer

* use async_call_later helper

* Update homeassistant/components/matter/entity.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* wip extend test

* Update test_sensor.py

* fix state class for sensors

* trigger (fake) event callback on all subscribers

* Update eve-energy-plug.json

* add test for additionally polled value

* adjust delay to 3 seconds

* Adjust subscribe_events to always use kwargs

* Update tests/components/matter/common.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update test_sensor.py

* remove redundant code

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
Marcel van der Veldt 2023-12-04 17:21:41 +01:00 committed by GitHub
parent 7d21ed41a2
commit 516966db33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 867 additions and 15 deletions

View file

@ -5,6 +5,7 @@ from dataclasses import dataclass
from chip.clusters import Objects as clusters
from chip.clusters.Types import Nullable, NullValue
from matter_server.client.models.clusters import EveEnergyCluster
from homeassistant.components.sensor import (
SensorDeviceClass,
@ -18,6 +19,10 @@ from homeassistant.const import (
PERCENTAGE,
EntityCategory,
Platform,
UnitOfElectricCurrent,
UnitOfElectricPotential,
UnitOfEnergy,
UnitOfPower,
UnitOfPressure,
UnitOfTemperature,
UnitOfVolumeFlowRate,
@ -48,7 +53,6 @@ class MatterSensorEntityDescription(SensorEntityDescription, MatterEntityDescrip
class MatterSensor(MatterEntity, SensorEntity):
"""Representation of a Matter sensor."""
_attr_state_class = SensorStateClass.MEASUREMENT
entity_description: MatterSensorEntityDescription
@callback
@ -72,6 +76,7 @@ DISCOVERY_SCHEMAS = [
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE,
measurement_to_ha=lambda x: x / 100,
state_class=SensorStateClass.MEASUREMENT,
),
entity_class=MatterSensor,
required_attributes=(clusters.TemperatureMeasurement.Attributes.MeasuredValue,),
@ -83,6 +88,7 @@ DISCOVERY_SCHEMAS = [
native_unit_of_measurement=UnitOfPressure.KPA,
device_class=SensorDeviceClass.PRESSURE,
measurement_to_ha=lambda x: x / 10,
state_class=SensorStateClass.MEASUREMENT,
),
entity_class=MatterSensor,
required_attributes=(clusters.PressureMeasurement.Attributes.MeasuredValue,),
@ -94,6 +100,7 @@ DISCOVERY_SCHEMAS = [
native_unit_of_measurement=UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
translation_key="flow",
measurement_to_ha=lambda x: x / 10,
state_class=SensorStateClass.MEASUREMENT,
),
entity_class=MatterSensor,
required_attributes=(clusters.FlowMeasurement.Attributes.MeasuredValue,),
@ -105,6 +112,7 @@ DISCOVERY_SCHEMAS = [
native_unit_of_measurement=PERCENTAGE,
device_class=SensorDeviceClass.HUMIDITY,
measurement_to_ha=lambda x: x / 100,
state_class=SensorStateClass.MEASUREMENT,
),
entity_class=MatterSensor,
required_attributes=(
@ -118,6 +126,7 @@ DISCOVERY_SCHEMAS = [
native_unit_of_measurement=LIGHT_LUX,
device_class=SensorDeviceClass.ILLUMINANCE,
measurement_to_ha=lambda x: round(pow(10, ((x - 1) / 10000)), 1),
state_class=SensorStateClass.MEASUREMENT,
),
entity_class=MatterSensor,
required_attributes=(clusters.IlluminanceMeasurement.Attributes.MeasuredValue,),
@ -131,8 +140,71 @@ DISCOVERY_SCHEMAS = [
entity_category=EntityCategory.DIAGNOSTIC,
# value has double precision
measurement_to_ha=lambda x: int(x / 2),
state_class=SensorStateClass.MEASUREMENT,
),
entity_class=MatterSensor,
required_attributes=(clusters.PowerSource.Attributes.BatPercentRemaining,),
),
MatterDiscoverySchema(
platform=Platform.SENSOR,
entity_description=MatterSensorEntityDescription(
key="EveEnergySensorWatt",
device_class=SensorDeviceClass.POWER,
entity_category=EntityCategory.DIAGNOSTIC,
native_unit_of_measurement=UnitOfPower.WATT,
suggested_display_precision=2,
state_class=SensorStateClass.MEASUREMENT,
),
entity_class=MatterSensor,
required_attributes=(EveEnergyCluster.Attributes.Watt,),
# Add OnOff Attribute as optional attribute to poll
# the primary value when the relay is toggled
optional_attributes=(clusters.OnOff.Attributes.OnOff,),
should_poll=True,
),
MatterDiscoverySchema(
platform=Platform.SENSOR,
entity_description=MatterSensorEntityDescription(
key="EveEnergySensorVoltage",
device_class=SensorDeviceClass.VOLTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
suggested_display_precision=0,
state_class=SensorStateClass.MEASUREMENT,
),
entity_class=MatterSensor,
required_attributes=(EveEnergyCluster.Attributes.Voltage,),
should_poll=True,
),
MatterDiscoverySchema(
platform=Platform.SENSOR,
entity_description=MatterSensorEntityDescription(
key="EveEnergySensorWattAccumulated",
device_class=SensorDeviceClass.ENERGY,
entity_category=EntityCategory.DIAGNOSTIC,
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
suggested_display_precision=3,
state_class=SensorStateClass.TOTAL_INCREASING,
),
entity_class=MatterSensor,
required_attributes=(EveEnergyCluster.Attributes.WattAccumulated,),
should_poll=True,
),
MatterDiscoverySchema(
platform=Platform.SENSOR,
entity_description=MatterSensorEntityDescription(
key="EveEnergySensorWattCurrent",
device_class=SensorDeviceClass.CURRENT,
entity_category=EntityCategory.DIAGNOSTIC,
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
suggested_display_precision=2,
state_class=SensorStateClass.MEASUREMENT,
),
entity_class=MatterSensor,
required_attributes=(EveEnergyCluster.Attributes.Current,),
# Add OnOff Attribute as optional attribute to poll
# the primary value when the relay is toggled
optional_attributes=(clusters.OnOff.Attributes.OnOff,),
should_poll=True,
),
]