From cbd884d54a04bd73563de4501295e262c2ec287c Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Sat, 7 Sep 2024 07:55:08 +0200 Subject: [PATCH] Add discovery schemas for Matter 1.3 power/energy sensors (#125403) * Add missing discovery schemas for (Matter 1.3) Power/Energy measurements * Prevent discovery of custom cluster if 1.3 cluster present * add tests * Use f-strings --------- Co-authored-by: Martin Hjelmare --- homeassistant/components/matter/sensor.py | 83 ++++ .../nodes/eve-energy-plug-patched.json | 382 ++++++++++++++++++ tests/components/matter/test_sensor.py | 81 +++- 3 files changed, 540 insertions(+), 6 deletions(-) create mode 100644 tests/components/matter/fixtures/nodes/eve-energy-plug-patched.json diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 5d4ad900d8ece..dd8467e24c9e2 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -175,6 +175,7 @@ def _update_from_device(self) -> None: ), entity_class=MatterSensor, required_attributes=(EveCluster.Attributes.Watt,), + absent_attributes=(clusters.ElectricalPowerMeasurement.Attributes.ActivePower,), ), MatterDiscoverySchema( platform=Platform.SENSOR, @@ -188,6 +189,7 @@ def _update_from_device(self) -> None: ), entity_class=MatterSensor, required_attributes=(EveCluster.Attributes.Voltage,), + absent_attributes=(clusters.ElectricalPowerMeasurement.Attributes.Voltage,), ), MatterDiscoverySchema( platform=Platform.SENSOR, @@ -201,6 +203,9 @@ def _update_from_device(self) -> None: ), entity_class=MatterSensor, required_attributes=(EveCluster.Attributes.WattAccumulated,), + absent_attributes=( + clusters.ElectricalEnergyMeasurement.Attributes.CumulativeEnergyImported, + ), ), MatterDiscoverySchema( platform=Platform.SENSOR, @@ -214,6 +219,9 @@ def _update_from_device(self) -> None: ), entity_class=MatterSensor, required_attributes=(EveCluster.Attributes.Current,), + absent_attributes=( + clusters.ElectricalPowerMeasurement.Attributes.ActiveCurrent, + ), ), MatterDiscoverySchema( platform=Platform.SENSOR, @@ -377,6 +385,7 @@ def _update_from_device(self) -> None: required_attributes=( ThirdRealityMeteringCluster.Attributes.InstantaneousDemand, ), + absent_attributes=(clusters.ElectricalPowerMeasurement.Attributes.ActivePower,), ), MatterDiscoverySchema( platform=Platform.SENSOR, @@ -393,6 +402,9 @@ def _update_from_device(self) -> None: required_attributes=( ThirdRealityMeteringCluster.Attributes.CurrentSummationDelivered, ), + absent_attributes=( + clusters.ElectricalEnergyMeasurement.Attributes.CumulativeEnergyImported, + ), ), MatterDiscoverySchema( platform=Platform.SENSOR, @@ -407,6 +419,7 @@ def _update_from_device(self) -> None: ), entity_class=MatterSensor, required_attributes=(NeoCluster.Attributes.Watt,), + absent_attributes=(clusters.ElectricalPowerMeasurement.Attributes.ActivePower,), ), MatterDiscoverySchema( platform=Platform.SENSOR, @@ -420,6 +433,9 @@ def _update_from_device(self) -> None: ), entity_class=MatterSensor, required_attributes=(NeoCluster.Attributes.WattAccumulated,), + absent_attributes=( + clusters.ElectricalEnergyMeasurement.Attributes.CumulativeEnergyImported, + ), ), MatterDiscoverySchema( platform=Platform.SENSOR, @@ -434,6 +450,7 @@ def _update_from_device(self) -> None: ), entity_class=MatterSensor, required_attributes=(NeoCluster.Attributes.Voltage,), + absent_attributes=(clusters.ElectricalPowerMeasurement.Attributes.Voltage,), ), MatterDiscoverySchema( platform=Platform.SENSOR, @@ -447,6 +464,9 @@ def _update_from_device(self) -> None: ), entity_class=MatterSensor, required_attributes=(NeoCluster.Attributes.Current,), + absent_attributes=( + clusters.ElectricalPowerMeasurement.Attributes.ActiveCurrent, + ), ), MatterDiscoverySchema( platform=Platform.SENSOR, @@ -462,4 +482,67 @@ def _update_from_device(self) -> None: required_attributes=(clusters.Switch.Attributes.CurrentPosition,), allow_multi=True, # also used for event entity ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="ElectricalPowerMeasurementWatt", + device_class=SensorDeviceClass.POWER, + entity_category=EntityCategory.DIAGNOSTIC, + native_unit_of_measurement=UnitOfPower.WATT, + suggested_display_precision=2, + state_class=SensorStateClass.MEASUREMENT, + measurement_to_ha=lambda x: x / 1000, + ), + entity_class=MatterSensor, + required_attributes=( + clusters.ElectricalPowerMeasurement.Attributes.ActivePower, + ), + ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="ElectricalPowerMeasurementVoltage", + device_class=SensorDeviceClass.VOLTAGE, + entity_category=EntityCategory.DIAGNOSTIC, + native_unit_of_measurement=UnitOfElectricPotential.VOLT, + suggested_display_precision=0, + state_class=SensorStateClass.MEASUREMENT, + measurement_to_ha=lambda x: x / 1000, + ), + entity_class=MatterSensor, + required_attributes=(clusters.ElectricalPowerMeasurement.Attributes.Voltage,), + ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="ElectricalPowerMeasurementActiveCurrent", + device_class=SensorDeviceClass.CURRENT, + entity_category=EntityCategory.DIAGNOSTIC, + native_unit_of_measurement=UnitOfElectricCurrent.AMPERE, + suggested_display_precision=2, + state_class=SensorStateClass.MEASUREMENT, + measurement_to_ha=lambda x: x / 1000, + ), + entity_class=MatterSensor, + required_attributes=( + clusters.ElectricalPowerMeasurement.Attributes.ActiveCurrent, + ), + ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="ElectricalEnergyMeasurementCumulativeEnergyImported", + 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, + # id 0 of the EnergyMeasurementStruct is the cumulative energy (in mWh) + measurement_to_ha=lambda x: x.energy / 1000000, + ), + entity_class=MatterSensor, + required_attributes=( + clusters.ElectricalEnergyMeasurement.Attributes.CumulativeEnergyImported, + ), + ), ] diff --git a/tests/components/matter/fixtures/nodes/eve-energy-plug-patched.json b/tests/components/matter/fixtures/nodes/eve-energy-plug-patched.json new file mode 100644 index 0000000000000..6b449643e8e95 --- /dev/null +++ b/tests/components/matter/fixtures/nodes/eve-energy-plug-patched.json @@ -0,0 +1,382 @@ +{ + "node_id": 183, + "date_commissioned": "2023-11-30T14:39:37.020026", + "last_interview": "2023-11-30T14:39:37.020029", + "interview_version": 5, + "available": true, + "is_bridge": false, + "attributes": { + "0/29/0": [ + { + "0": 22, + "1": 1 + } + ], + "0/29/1": [29, 31, 40, 42, 48, 49, 51, 53, 60, 62, 63], + "0/29/2": [41], + "0/29/3": [1], + "0/29/65532": 0, + "0/29/65533": 1, + "0/29/65528": [], + "0/29/65529": [], + "0/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533], + "0/31/0": [ + { + "254": 1 + }, + { + "254": 2 + }, + { + "1": 5, + "2": 2, + "3": [112233], + "4": null, + "254": 5 + } + ], + "0/31/1": [], + "0/31/2": 4, + "0/31/3": 3, + "0/31/4": 3, + "0/31/65532": 0, + "0/31/65533": 1, + "0/31/65528": [], + "0/31/65529": [], + "0/31/65531": [0, 1, 2, 3, 4, 65528, 65529, 65531, 65532, 65533], + "0/40/0": 1, + "0/40/1": "Eve Systems", + "0/40/2": 4874, + "0/40/3": "Eve Energy Plug Patched", + "0/40/4": 80, + "0/40/5": "", + "0/40/6": "XX", + "0/40/7": 1, + "0/40/8": "1.3", + "0/40/9": 6650, + "0/40/10": "3.2.1", + "0/40/15": "RV44L221A00081", + "0/40/18": "26E822F90561D17C42", + "0/40/19": { + "0": 3, + "1": 3 + }, + "0/40/65532": 0, + "0/40/65533": 1, + "0/40/65528": [], + "0/40/65529": [], + "0/40/65531": [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 18, 19, 65528, 65529, 65531, 65532, + 65533 + ], + "0/42/0": [ + { + "1": 2312386028615903905, + "2": 0, + "254": 1 + } + ], + "0/42/1": true, + "0/42/2": 1, + "0/42/3": null, + "0/42/65532": 0, + "0/42/65533": 1, + "0/42/65528": [], + "0/42/65529": [0], + "0/42/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533], + "0/48/0": 0, + "0/48/1": { + "0": 60, + "1": 900 + }, + "0/48/2": 0, + "0/48/3": 0, + "0/48/4": true, + "0/48/65532": 0, + "0/48/65533": 1, + "0/48/65528": [1, 3, 5], + "0/48/65529": [0, 2, 4], + "0/48/65531": [0, 1, 2, 3, 4, 65528, 65529, 65531, 65532, 65533], + "0/49/0": 1, + "0/49/1": [ + { + "0": "cfUKbvsdfsBjT+0=", + "1": true + } + ], + "0/49/2": 10, + "0/49/3": 20, + "0/49/4": true, + "0/49/5": 0, + "0/49/6": "cfUKbvBjdsffwT+0=", + "0/49/7": null, + "0/49/65532": 2, + "0/49/65533": 1, + "0/49/65528": [1, 5, 7], + "0/49/65529": [0, 3, 4, 6, 8], + "0/49/65531": [0, 1, 2, 3, 4, 5, 6, 7, 65528, 65529, 65531, 65532, 65533], + "0/51/0": [], + "0/51/1": 95, + "0/51/2": 268574, + "0/51/3": 4406, + "0/51/5": [], + "0/51/6": [], + "0/51/7": [], + "0/51/8": false, + "0/51/65532": 0, + "0/51/65533": 1, + "0/51/65528": [], + "0/51/65529": [0], + "0/51/65531": [0, 1, 2, 3, 5, 6, 7, 8, 65528, 65529, 65531, 65532, 65533], + "0/53/0": 25, + "0/53/1": 5, + "0/53/2": "MyHome23", + "0/53/3": 14707, + "0/53/4": 8211480967175688173, + "0/53/5": "aabbccdd", + "0/53/6": 0, + "0/53/7": [], + "0/53/8": [], + "0/53/9": 1828774034, + "0/53/10": 68, + "0/53/11": 237, + "0/53/12": 170, + "0/53/13": 23, + "0/53/14": 2, + "0/53/15": 1, + "0/53/16": 2, + "0/53/17": 0, + "0/53/18": 0, + "0/53/19": 2, + "0/53/20": 0, + "0/53/21": 0, + "0/53/22": 293884, + "0/53/23": 278934, + "0/53/24": 14950, + "0/53/25": 278894, + "0/53/26": 278468, + "0/53/27": 14990, + "0/53/28": 293844, + "0/53/29": 0, + "0/53/30": 40, + "0/53/31": 0, + "0/53/32": 0, + "0/53/33": 65244, + "0/53/34": 426, + "0/53/35": 0, + "0/53/36": 87, + "0/53/37": 0, + "0/53/38": 0, + "0/53/39": 6687540, + "0/53/40": 142626, + "0/53/41": 106835, + "0/53/42": 246171, + "0/53/43": 0, + "0/53/44": 541, + "0/53/45": 40, + "0/53/46": 0, + "0/53/47": 0, + "0/53/48": 6360718, + "0/53/49": 2141, + "0/53/50": 35259, + "0/53/51": 4374, + "0/53/52": 0, + "0/53/53": 568, + "0/53/54": 18599, + "0/53/55": 19143, + "0/53/59": { + "0": 672, + "1": 8335 + }, + "0/53/60": "AB//wA==", + "0/53/61": { + "0": true, + "1": false, + "2": true, + "3": true, + "4": true, + "5": true, + "6": false, + "7": true, + "8": true, + "9": true, + "10": true, + "11": true + }, + "0/53/62": [0, 0, 0, 0], + "0/53/65532": 15, + "0/53/65533": 1, + "0/53/65528": [], + "0/53/65529": [0], + "0/53/65531": [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 59, + 60, 61, 62, 65528, 65529, 65531, 65532, 65533 + ], + "0/60/0": 0, + "0/60/1": null, + "0/60/2": null, + "0/60/65532": 0, + "0/60/65533": 1, + "0/60/65528": [], + "0/60/65529": [0, 1, 2], + "0/60/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533], + "0/62/0": [], + "0/62/1": [], + "0/62/2": 5, + "0/62/3": 3, + "0/62/4": [ + "FTABAQAkAgE3AycUxofpv3kE1HwkFQEYJgS2Ty8rJgU2gxAtNwYnFMaH6b95BNR8JBUBGCQHASQIATAJQQSG0eCLvAjSHcSkZEo029SymN58wmxVcA645EXuFg6KwojGRyZsqWVtuMAYAB8TaPA9NEFsNvZZbvBR9XjrZhyKNwo1ASkBGCQCYDAEFNnFRJ+9qQIJtsM+LRdMdmCY3bQ4MAUU2cVEn72pAgm2wz4tF0x2YJjdtDgYMAtAFDv6Ouh7ugAGLiCjBQaEXCIAe0AkaaN8dBPskCZXOODjuZ1DCr4/f5IYg0rN2zFDUDTvG3GCxoI1+A7BvSjiNRg=", + "FTABAQAkAgE3AycUjuqR8vTQCmEkFQIYJgTFTy8rJgVFgxAtNwYnFI7qkfL00AphJBUCGCQHASQIATAJQQS5ZOLouMEkPsc/PYweZwUUFFWHWPR9nQVGsBl1VMWtm7CodpPAh4o79bZM9XU4T1wPVCvIzgGfuzIvsuwT7gHINwo1ASkBGCQCYDAEFKEEplpzAvCzsc5ga6CFmqmsv5onMAUUoQSmWnMC8LOxzmBroIWaqay/micYMAtAYkkA8OZFIGpxBEYYT+3A7Okba4WOq4NtwctIIZvCM48VU8pxQNjVvHMcJWPOP1Wh2Bw1VH7/Sg9lt9DL4DAwjBg=", + "FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQUARgkBwEkCAEwCUEECDlp5HtG4UpmG6QLEwaCUJ3TR0qWHEarwFuN7JkKUrPmQ3Zi3Nq/TFayJYQRvez268whgWhBhQudIm84xNwPXjcKNQEpARgkAmAwBBTJ3+WZAQkWgZboUpiyZL3FV8R8UzAFFMnf5ZkBCRaBluhSmLJkvcVXxHxTGDALQO9QSAdvJkM6b/wIc07MCw1ma46lTyGYG8nvpn0ICI73nuD3QeaWwGIQTkVGEpzF+TuDK7gtTz7YUrR+PSnvMk8Y" + ], + "0/62/5": 5, + "0/62/65532": 0, + "0/62/65533": 1, + "0/62/65528": [1, 3, 5, 8], + "0/62/65529": [0, 2, 4, 6, 7, 9, 10, 11], + "0/62/65531": [0, 1, 2, 3, 4, 5, 65528, 65529, 65531, 65532, 65533], + "0/63/0": [], + "0/63/1": [], + "0/63/2": 3, + "0/63/3": 3, + "0/63/65532": 0, + "0/63/65533": 1, + "0/63/65528": [2, 5], + "0/63/65529": [0, 1, 3, 4], + "0/63/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533], + "1/3/0": 0, + "1/3/1": 2, + "1/3/65532": 0, + "1/3/65533": 4, + "1/3/65528": [], + "1/3/65529": [0], + "1/3/65531": [0, 1, 65528, 65529, 65531, 65532, 65533], + "1/4/0": 128, + "1/4/65532": 1, + "1/4/65533": 4, + "1/4/65528": [0, 1, 2, 3], + "1/4/65529": [0, 1, 2, 3, 4, 5], + "1/4/65531": [0, 65528, 65529, 65531, 65532, 65533], + "1/6/0": false, + "1/6/16384": true, + "1/6/16385": 0, + "1/6/16386": 0, + "1/6/16387": null, + "1/6/65532": 1, + "1/6/65533": 4, + "1/6/65528": [], + "1/6/65529": [0, 1, 2, 64, 65, 66], + "1/6/65531": [ + 0, 16384, 16385, 16386, 16387, 65528, 65529, 65531, 65532, 65533 + ], + "1/29/0": [ + { + "0": 266, + "1": 1 + } + ], + "1/29/1": [3, 4, 6, 29, 319486977], + "1/29/2": [], + "1/29/3": [], + "1/29/65532": 0, + "1/29/65533": 1, + "1/29/65528": [], + "1/29/65529": [], + "1/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533], + "1/319486977/319422464": "AAFQCwIAAAMC+xkEDFJWNDRMMUEwMDA4MZwBAP8EAQIA1PkBAWABZNAEAAAAAEUFBQAAAABGCQUAAAAOAABCBkkGBQwIEIABRBEFFAAFAzwAAAAAAAAAAAAAAEcRBSoh/CGWImgjeAAAADwAAABIBgUAAAAAAEoGBQAAAAAA", + "1/319486977/319422466": "BEZiAQAAAAAAAAAABgsCDAINAgcCDgEBAn4PABAAWgAAs8c+AQEA", + "1/319486977/319422467": "EgtaAAB74T4BDwAANwkAAAAA", + "1/319486977/319422471": 0, + "1/319486977/319422472": 238.8000030517578, + "1/319486977/319422473": 0.0, + "1/319486977/319422474": 0.0, + "1/319486977/319422475": 0.2200000286102295, + "1/319486977/319422476": 0, + "1/319486977/319422478": 0, + "1/319486977/319422481": false, + "1/319486977/319422482": 54272, + "1/319486977/65533": 1, + "1/319486977/65528": [], + "1/319486977/65529": [], + "1/319486977/65531": [ + 65528, 65529, 65531, 319422464, 319422465, 319422466, 319422467, + 319422468, 319422469, 319422471, 319422472, 319422473, 319422474, + 319422475, 319422476, 319422478, 319422481, 319422482, 65533 + ], + "1/144/0": 2, + "1/144/1": 3, + "1/144/2": [ + { + "0": 1, + "1": true, + "2": 0, + "3": 100, + "4": [ + { + "0": 0, + "1": 4611686018427387904 + } + ] + }, + { + "0": 2, + "1": true, + "2": 0, + "3": 100, + "4": [ + { + "0": 0, + "1": 4611686018427387904 + } + ] + }, + { + "0": 5, + "1": true, + "2": 0, + "3": 100, + "4": [ + { + "0": 0, + "1": 4611686018427387904 + } + ] + } + ], + "1/144/4": 220000, + "1/144/5": 2000, + "1/144/8": 550000, + "1/144/65533": 1, + "1/144/65532": 2, + "1/144/65531": [0, 1, 2, 4, 5, 8, 65528, 65529, 65530, 65531, 65532, 65533], + "1/144/65530": [], + "1/144/65529": [], + "1/144/65528": [], + "1/145/0": { + "0": 14, + "1": true, + "2": 0, + "3": 0, + "4": [ + { + "0": 0, + "1": 4611686018427387904 + } + ] + }, + "1/145/65533": 1, + "1/145/65532": 7, + "1/145/65531": [0, 1, 2, 65528, 65529, 65530, 65531, 65532, 65533], + "1/145/65530": [0], + "1/145/65529": [], + "1/145/65528": [], + "1/145/1": { + "0": 2500 + }, + "1/145/2": null + }, + "attribute_subscriptions": [], + "last_subscription_attempt": 0 +} diff --git a/tests/components/matter/test_sensor.py b/tests/components/matter/test_sensor.py index 2c9bfae94ce4d..17cff38787c1d 100644 --- a/tests/components/matter/test_sensor.py +++ b/tests/components/matter/test_sensor.py @@ -74,6 +74,16 @@ async def eve_energy_plug_node_fixture( ) +@pytest.fixture(name="eve_energy_plug_patched_node") +async def eve_energy_plug_patched_node_fixture( + hass: HomeAssistant, matter_client: MagicMock +) -> MatterNode: + """Fixture for a Eve Energy Plug node (patched to include Matter 1.3 energy clusters).""" + return await setup_integration_with_node_fixture( + hass, "eve-energy-plug-patched", matter_client + ) + + @pytest.fixture(name="air_quality_sensor_node") async def air_quality_sensor_node_fixture( hass: HomeAssistant, matter_client: MagicMock @@ -243,14 +253,14 @@ async def test_battery_sensor( # This tests needs to be adjusted to remove lingering tasks @pytest.mark.parametrize("expected_lingering_tasks", [True]) -async def test_eve_energy_sensors( +async def test_energy_sensors_custom_cluster( hass: HomeAssistant, entity_registry: er.EntityRegistry, matter_client: MagicMock, eve_energy_plug_node: MatterNode, ) -> None: - """Test Energy sensors created from Eve Energy custom cluster.""" - # power sensor + """Test Energy sensors created from (Eve) custom cluster (Matter 1.3 energy clusters absent).""" + # power sensor on Eve custom cluster entity_id = "sensor.eve_energy_plug_power" state = hass.states.get(entity_id) assert state @@ -259,7 +269,7 @@ async def test_eve_energy_sensors( assert state.attributes["device_class"] == "power" assert state.attributes["friendly_name"] == "Eve Energy Plug Power" - # voltage sensor + # voltage sensor on Eve custom cluster entity_id = "sensor.eve_energy_plug_voltage" state = hass.states.get(entity_id) assert state @@ -268,7 +278,7 @@ async def test_eve_energy_sensors( assert state.attributes["device_class"] == "voltage" assert state.attributes["friendly_name"] == "Eve Energy Plug Voltage" - # energy sensor + # energy sensor on Eve custom cluster entity_id = "sensor.eve_energy_plug_energy" state = hass.states.get(entity_id) assert state @@ -278,7 +288,7 @@ async def test_eve_energy_sensors( assert state.attributes["friendly_name"] == "Eve Energy Plug Energy" assert state.attributes["state_class"] == "total_increasing" - # current sensor + # current sensor on Eve custom cluster entity_id = "sensor.eve_energy_plug_current" state = hass.states.get(entity_id) assert state @@ -288,6 +298,65 @@ async def test_eve_energy_sensors( assert state.attributes["friendly_name"] == "Eve Energy Plug Current" +# This tests needs to be adjusted to remove lingering tasks +@pytest.mark.parametrize("expected_lingering_tasks", [True]) +async def test_energy_sensors( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, + matter_client: MagicMock, + eve_energy_plug_patched_node: MatterNode, +) -> None: + """Test Energy sensors created from official Matter 1.3 energy clusters.""" + # power sensor on Matter 1.3 ElectricalPowermeasurement cluster + entity_id = "sensor.eve_energy_plug_patched_power" + state = hass.states.get(entity_id) + assert state + assert state.state == "550.0" + assert state.attributes["unit_of_measurement"] == "W" + assert state.attributes["device_class"] == "power" + assert state.attributes["friendly_name"] == "Eve Energy Plug Patched Power" + # ensure we do not have a duplicated entity from the custom cluster + state = hass.states.get(f"{entity_id}_1") + assert state is None + + # voltage sensor on Matter 1.3 ElectricalPowermeasurement cluster + entity_id = "sensor.eve_energy_plug_patched_voltage" + state = hass.states.get(entity_id) + assert state + assert state.state == "220.0" + assert state.attributes["unit_of_measurement"] == "V" + assert state.attributes["device_class"] == "voltage" + assert state.attributes["friendly_name"] == "Eve Energy Plug Patched Voltage" + # ensure we do not have a duplicated entity from the custom cluster + state = hass.states.get(f"{entity_id}_1") + assert state is None + + # energy sensor on Matter 1.3 ElectricalEnergymeasurement cluster + entity_id = "sensor.eve_energy_plug_patched_energy" + state = hass.states.get(entity_id) + assert state + assert state.state == "0.0025" + assert state.attributes["unit_of_measurement"] == "kWh" + assert state.attributes["device_class"] == "energy" + assert state.attributes["friendly_name"] == "Eve Energy Plug Patched Energy" + assert state.attributes["state_class"] == "total_increasing" + # ensure we do not have a duplicated entity from the custom cluster + state = hass.states.get(f"{entity_id}_1") + assert state is None + + # current sensor on Matter 1.3 ElectricalPowermeasurement cluster + entity_id = "sensor.eve_energy_plug_patched_current" + state = hass.states.get(entity_id) + assert state + assert state.state == "2.0" + assert state.attributes["unit_of_measurement"] == "A" + assert state.attributes["device_class"] == "current" + assert state.attributes["friendly_name"] == "Eve Energy Plug Patched Current" + # ensure we do not have a duplicated entity from the custom cluster + state = hass.states.get(f"{entity_id}_1") + assert state is None + + # This tests needs to be adjusted to remove lingering tasks @pytest.mark.parametrize("expected_lingering_tasks", [True]) async def test_air_quality_sensor(