From 23eea49da2101fe08e93b169f86b91f07f9c1f2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Tue, 17 Dec 2024 20:53:33 +0100 Subject: [PATCH 01/58] EnergyEvse.Attributes.MinimumChargeCurrent --- homeassistant/components/matter/sensor.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index d71cd52a0c641c..d4f29d0b82e66a 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -675,4 +675,20 @@ def _update_from_device(self) -> None: clusters.OperationalState.Attributes.OperationalStateList, ), ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="EnergyEvseMinimumChargeCurrent", + 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.EnergyEvse.Attributes.MinimumChargeCurrent, + ), + ), ] From 69881035c27e1a1a7921a619af7bfa36cc8ef05d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Tue, 17 Dec 2024 21:01:35 +0100 Subject: [PATCH 02/58] EnergyEvse.Attributes.MaximumChargeCurrent --- homeassistant/components/matter/sensor.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index d4f29d0b82e66a..9fc260b0a25b70 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -691,4 +691,20 @@ def _update_from_device(self) -> None: clusters.EnergyEvse.Attributes.MinimumChargeCurrent, ), ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="EnergyEvseMaximumChargeCurrent", + 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.EnergyEvse.Attributes.MaximumChargeCurrent, + ), + ), ] From 493d486e67d14d31e75ab0d65563ca6c8eb68ffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Tue, 17 Dec 2024 21:02:27 +0100 Subject: [PATCH 03/58] EnergyEvse.Attributes.UserMaximumChargeCurrent --- homeassistant/components/matter/sensor.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 9fc260b0a25b70..af8f21d1984de2 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -707,4 +707,21 @@ def _update_from_device(self) -> None: clusters.EnergyEvse.Attributes.MaximumChargeCurrent, ), ), + + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="EnergyEvseUserMaximumChargeCurrent", + 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.EnergyEvse.Attributes.UserMaximumChargeCurrent, + ), + ), ] From e367ff636b436e44a0a27ce86d315eff639131c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Tue, 17 Dec 2024 21:37:29 +0100 Subject: [PATCH 04/58] EnergyEvse.Enums.StateEnum --- homeassistant/components/matter/sensor.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index af8f21d1984de2..218eb41a1e0fcc 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -72,6 +72,17 @@ } +EVSE_STATE_MAP = { + clusters.EnergyEvse.Enums.StateEnum.kNotPluggedIn: "NotPluggedIn", + clusters.EnergyEvse.Enums.StateEnum.kPluggedInNoDemand: "PluggedIn, NoDemand", + clusters.EnergyEvse.Enums.StateEnum.kPluggedInDemand: "PluggedIn, Demand", + clusters.EnergyEvse.Enums.StateEnum.kPluggedInCharging: "PluggedIn, Charging", + clusters.EnergyEvse.Enums.StateEnum.kPluggedInDischarging: "PluggedIn, Discharging", + clusters.EnergyEvse.Enums.StateEnum.kSessionEnding: "SessionEnding", + clusters.EnergyEvse.Enums.StateEnum.kFault: "Fault", +} + + async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, From 0ecdeb0b41271ccdd3714f37c66dbf72a7acb533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Tue, 17 Dec 2024 21:38:16 +0100 Subject: [PATCH 05/58] Update sensor.py --- homeassistant/components/matter/sensor.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 218eb41a1e0fcc..1d25b553da6367 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -718,7 +718,6 @@ def _update_from_device(self) -> None: clusters.EnergyEvse.Attributes.MaximumChargeCurrent, ), ), - MatterDiscoverySchema( platform=Platform.SENSOR, entity_description=MatterSensorEntityDescription( @@ -735,4 +734,18 @@ def _update_from_device(self) -> None: clusters.EnergyEvse.Attributes.UserMaximumChargeCurrent, ), ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="EnergyEvseState", + translation_key="evse_state", + device_class=SensorDeviceClass.ENUM, + options=list(EVSE_STATE_MAP.values()), + measurement_to_ha=EVSE_STATE_MAP.get, + ), + entity_class=MatterSensor, + required_attributes=( + clusters.EnergyEvse.Attributes.State, + ), + ), ] From 297e6e69b89f26a7b742b1a928c17e19b690599a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Tue, 17 Dec 2024 22:05:27 +0100 Subject: [PATCH 06/58] EnergyEvse.Attributes.CircuitCapacity --- homeassistant/components/matter/sensor.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 1d25b553da6367..82d5919f044ea3 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -686,6 +686,22 @@ def _update_from_device(self) -> None: clusters.OperationalState.Attributes.OperationalStateList, ), ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="EnergyEvseCircuitCapacity", + 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.EnergyEvse.Attributes.CircuitCapacity, + ), + ), MatterDiscoverySchema( platform=Platform.SENSOR, entity_description=MatterSensorEntityDescription( From 8780ed90c571c108c89025eb394bd48736de7144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Tue, 17 Dec 2024 23:32:11 +0100 Subject: [PATCH 07/58] ruff-format --- homeassistant/components/matter/sensor.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 82d5919f044ea3..7bc9ea75498111 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -698,9 +698,7 @@ def _update_from_device(self) -> None: measurement_to_ha=lambda x: x / 1000, ), entity_class=MatterSensor, - required_attributes=( - clusters.EnergyEvse.Attributes.CircuitCapacity, - ), + required_attributes=(clusters.EnergyEvse.Attributes.CircuitCapacity), ), MatterDiscoverySchema( platform=Platform.SENSOR, @@ -714,9 +712,7 @@ def _update_from_device(self) -> None: measurement_to_ha=lambda x: x / 1000, ), entity_class=MatterSensor, - required_attributes=( - clusters.EnergyEvse.Attributes.MinimumChargeCurrent, - ), + required_attributes=(clusters.EnergyEvse.Attributes.MinimumChargeCurrent,), ), MatterDiscoverySchema( platform=Platform.SENSOR, @@ -730,9 +726,7 @@ def _update_from_device(self) -> None: measurement_to_ha=lambda x: x / 1000, ), entity_class=MatterSensor, - required_attributes=( - clusters.EnergyEvse.Attributes.MaximumChargeCurrent, - ), + required_attributes=(clusters.EnergyEvse.Attributes.MaximumChargeCurrent,), ), MatterDiscoverySchema( platform=Platform.SENSOR, @@ -746,9 +740,7 @@ def _update_from_device(self) -> None: measurement_to_ha=lambda x: x / 1000, ), entity_class=MatterSensor, - required_attributes=( - clusters.EnergyEvse.Attributes.UserMaximumChargeCurrent, - ), + required_attributes=(required_attributes=(clusters.EnergyEvse.Attributes.UserMaximumChargeCurrent,), ), MatterDiscoverySchema( platform=Platform.SENSOR, From 43ab4e3b37805c74c46d728b40096d709cf7682f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Tue, 17 Dec 2024 23:34:58 +0100 Subject: [PATCH 08/58] ruff-format --- homeassistant/components/matter/sensor.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 7bc9ea75498111..e2f63fce393f4c 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -740,7 +740,7 @@ def _update_from_device(self) -> None: measurement_to_ha=lambda x: x / 1000, ), entity_class=MatterSensor, - required_attributes=(required_attributes=(clusters.EnergyEvse.Attributes.UserMaximumChargeCurrent,), + required_attributes=(clusters.EnergyEvse.Attributes.UserMaximumChargeCurrent,), ), MatterDiscoverySchema( platform=Platform.SENSOR, @@ -752,8 +752,6 @@ def _update_from_device(self) -> None: measurement_to_ha=EVSE_STATE_MAP.get, ), entity_class=MatterSensor, - required_attributes=( - clusters.EnergyEvse.Attributes.State, - ), + required_attributes=(clusters.EnergyEvse.Attributes.State,), ), ] From 5c782a1281a12ee94ae952218b4678fdd2f5d018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Tue, 17 Dec 2024 23:50:58 +0100 Subject: [PATCH 09/58] EnergyEvse.Attributes.SupplyState --- homeassistant/components/matter/sensor.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index e2f63fce393f4c..1d502df16bfa95 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -754,4 +754,16 @@ def _update_from_device(self) -> None: entity_class=MatterSensor, required_attributes=(clusters.EnergyEvse.Attributes.State,), ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="EnergyEvseSupplyState", + translation_key="evse_supply_state", + device_class=SensorDeviceClass.ENUM, + options=list(EVSE_SUPPLY_STATE_MAP.values()), + measurement_to_ha=EVSE_SUPPLY_STATE_MAP.get, + ), + entity_class=MatterSensor, + required_attributes=(clusters.EnergyEvse.Attributes.SupplyState,), + ), ] From ad881d224dd2dcbaa8770a950bf2665f3c04dbac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Tue, 17 Dec 2024 23:53:59 +0100 Subject: [PATCH 10/58] EnergyEvse.Enums.SupplyStateEnum --- homeassistant/components/matter/sensor.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 1d502df16bfa95..10af62d970dc29 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -83,6 +83,15 @@ } +EVSE_SUPPLY_STATE_MAP = { + clusters.EnergyEvse.Enums.SupplyStateEnum.kDisabled: "Disabled", + clusters.EnergyEvse.Enums.SupplyStateEnum.kChargingEnabled: "Charging Enabled", + clusters.EnergyEvse.Enums.SupplyStateEnum.kDischargingEnabled: "Discharging Enabled", + clusters.EnergyEvse.Enums.SupplyStateEnum.kDisabledDiagnostics: "Disabled Diagnostics", + clusters.EnergyEvse.Enums.SupplyStateEnum.kEnabled: "Enabled", +} + + async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, From d440e13a28a6f01ca2641ff0af1ef41b3d144eb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Wed, 18 Dec 2024 00:56:15 +0100 Subject: [PATCH 11/58] EnergyEvse.Commands.EnableCharging --- homeassistant/components/matter/button.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/homeassistant/components/matter/button.py b/homeassistant/components/matter/button.py index 153124a4f7ec71..b8ab72a3c97cdd 100644 --- a/homeassistant/components/matter/button.py +++ b/homeassistant/components/matter/button.py @@ -147,4 +147,15 @@ async def async_press(self) -> None: value_contains=clusters.ActivatedCarbonFilterMonitoring.Commands.ResetCondition.command_id, allow_multi=True, ), + MatterDiscoverySchema( + platform=Platform.BUTTON, + entity_description=MatterButtonEntityDescription( + key="EnergyEvseEnableChargingButton", + translation_key="enable_charging", + command=clusters.EnergyEvse.Commands.EnableCharging, + ), + entity_class=MatterCommandButton, + required_attributes=(clusters.EnergyEvse.Attributes.AcceptedCommandList,), + allow_multi=True, + ), ] From f5c5a822d38dba71bdec54d400f661bb67717a78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Wed, 18 Dec 2024 00:56:41 +0100 Subject: [PATCH 12/58] EnergyEvse.Commands.Disable --- homeassistant/components/matter/button.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/homeassistant/components/matter/button.py b/homeassistant/components/matter/button.py index b8ab72a3c97cdd..68f202e29f7b40 100644 --- a/homeassistant/components/matter/button.py +++ b/homeassistant/components/matter/button.py @@ -158,4 +158,15 @@ async def async_press(self) -> None: required_attributes=(clusters.EnergyEvse.Attributes.AcceptedCommandList,), allow_multi=True, ), + MatterDiscoverySchema( + platform=Platform.BUTTON, + entity_description=MatterButtonEntityDescription( + key="EnergyEvseDisableChargingButton", + translation_key="disable_charging", + command=clusters.EnergyEvse.Commands.Disable, + ), + entity_class=MatterCommandButton, + required_attributes=(clusters.EnergyEvse.Attributes.AcceptedCommandList,), + allow_multi=True, + ), ] From afee080e9daaf6132a31a3e27e73259db4ebbbfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Wed, 18 Dec 2024 07:55:51 +0100 Subject: [PATCH 13/58] Create evse_charging.json --- .../matter/fixtures/nodes/evse_charging.json | 584 ++++++++++++++++++ 1 file changed, 584 insertions(+) create mode 100644 tests/components/matter/fixtures/nodes/evse_charging.json diff --git a/tests/components/matter/fixtures/nodes/evse_charging.json b/tests/components/matter/fixtures/nodes/evse_charging.json new file mode 100644 index 00000000000000..3eac832a6c52fb --- /dev/null +++ b/tests/components/matter/fixtures/nodes/evse_charging.json @@ -0,0 +1,584 @@ +{ + "node": { + "node_id": 23, + "date_commissioned": "2024-12-17T18:14:53.210190", + "last_interview": "2024-12-17T18:14:53.211611", + "interview_version": 6, + "available": true, + "is_bridge": false, + "attributes": { + "0/29/0": [ + { + "0": 22, + "1": 1 + } + ], + "0/29/1": [29, 31, 40, 43, 44, 45, 48, 49, 51, 60, 62, 63], + "0/29/2": [], + "0/29/3": [1], + "0/29/65532": 0, + "0/29/65533": 2, + "0/29/65528": [], + "0/29/65529": [], + "0/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533], + "0/31/0": [ + { + "1": 5, + "2": 2, + "3": [112233], + "4": null, + "254": 1 + } + ], + "0/31/2": 4, + "0/31/3": 3, + "0/31/4": 4, + "0/31/65532": 0, + "0/31/65533": 2, + "0/31/65528": [], + "0/31/65529": [], + "0/31/65531": [0, 2, 3, 4, 65528, 65529, 65531, 65532, 65533], + "0/40/0": 18, + "0/40/1": "TEST_VENDOR", + "0/40/2": 65521, + "0/40/3": "Mock EVSE", + "0/40/4": 32769, + "0/40/5": "Mock EVSE", + "0/40/6": "**REDACTED**", + "0/40/7": 0, + "0/40/8": "TEST_VERSION", + "0/40/9": 1, + "0/40/10": "1.0", + "0/40/15": "TEST_SN", + "0/40/18": "mock-evse-charging", + "0/40/19": { + "0": 3, + "1": 65535 + }, + "0/40/21": 17039360, + "0/40/22": 1, + "0/40/65532": 0, + "0/40/65533": 4, + "0/40/65528": [], + "0/40/65529": [], + "0/40/65531": [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 18, 19, 21, 22, 65528, 65529, + 65531, 65532, 65533 + ], + "0/43/0": "en-US", + "0/43/1": [ + "en-US", + "de-DE", + "fr-FR", + "en-GB", + "es-ES", + "zh-CN", + "it-IT", + "ja-JP" + ], + "0/43/65532": 0, + "0/43/65533": 1, + "0/43/65528": [], + "0/43/65529": [], + "0/43/65531": [0, 1, 65528, 65529, 65531, 65532, 65533], + "0/44/0": 0, + "0/44/65532": 0, + "0/44/65533": 1, + "0/44/65528": [], + "0/44/65529": [], + "0/44/65531": [0, 65528, 65529, 65531, 65532, 65533], + "0/45/65532": 0, + "0/45/65533": 1, + "0/45/65528": [], + "0/45/65529": [], + "0/45/65531": [65528, 65529, 65531, 65532, 65533], + "0/48/0": 0, + "0/48/1": { + "0": 60, + "1": 900 + }, + "0/48/2": 0, + "0/48/3": 2, + "0/48/4": true, + "0/48/65532": 0, + "0/48/65533": 2, + "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": "ZW5zMzM=", + "1": true + } + ], + "0/49/4": true, + "0/49/5": null, + "0/49/6": null, + "0/49/7": null, + "0/49/8": [0], + "0/49/65532": 4, + "0/49/65533": 2, + "0/49/65528": [], + "0/49/65529": [], + "0/49/65531": [0, 1, 4, 5, 6, 7, 8, 65528, 65529, 65531, 65532, 65533], + "0/51/0": [ + { + "0": "docker0", + "1": false, + "2": null, + "3": null, + "4": "AkI9NTnB", + "5": ["rBEAAQ=="], + "6": [""], + "7": 0 + }, + { + "0": "ens33", + "1": true, + "2": null, + "3": null, + "4": "AAwp/F0T", + "5": ["wKgBpw=="], + "6": [ + "KgEOCgKzOZCNB+q+Uz0I9w==", + "KgEOCgKzOZC/O1Ew1WvS4A==", + "/oAAAAAAAADml3Ozl7GZug==" + ], + "7": 2 + }, + { + "0": "lo", + "1": true, + "2": null, + "3": null, + "4": "AAAAAAAA", + "5": ["fwAAAQ=="], + "6": ["AAAAAAAAAAAAAAAAAAAAAQ=="], + "7": 0 + } + ], + "0/51/1": 1, + "0/51/2": 10129, + "0/51/8": true, + "0/51/65532": 0, + "0/51/65533": 2, + "0/51/65528": [2], + "0/51/65529": [0, 1], + "0/51/65531": [0, 1, 2, 8, 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, 2], + "0/60/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533], + "0/62/0": [ + { + "1": "FTABAQEkAgE3AyQTAhgmBIAigScmBYAlTTo3BiQVASQRFxgkBwEkCAEwCUEECp4PASYUFk/DwQqGNBikYdiBRDJZbrfF4AYK8Y9jOeIpx7Xy+giJhmTpAVZ662hwszsFDGULGY/owXtMrqTxEDcKNQEoARgkAgE2AwQCBAEYMAQUqBmxO16fPQhbf33Gb2XwQ+NkXpswBRTx8+4bdkuqlxInfB5LXkhRBBvS2hgwC0A8aefsLm663Vuy+TkSvn/oLhRqt2phrG+i5aM5o15xiWDjnNVdUYpT09+K0mgVoMdFuFsmoWQxQh6jahaFJzUgGA==", + "2": "FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQTAhgkBwEkCAEwCUEEGp55xGRB0FBQ3Yw7ayQSzVtYA0BtCJFm9vRRcdr+nk0cuGX6zrUowSYOO/qiRBEACcCNNSqKh+DpRm2uVLOtaDcKNQEpARgkAmAwBBTx8+4bdkuqlxInfB5LXkhRBBvS2jAFFIxTG68U5WQVsk8AtvSQyeK3KLqPGDALQIw/6q5ILMNdOMcSif8HNbEgpjBeaBMfUpzOJFCRPM16sv1xiq3mALZj0u+iG8lUJEvDJOFKPoBvsOubwIwRgAQY", + "254": 1 + } + ], + "0/62/1": [ + { + "1": "BMeyHMXjJpVWF9saehBu7pZLTwdopKZTl5JdhU0/ozZ/sk1paVFE1U8OtuZqM/S/4W/fnkCnUrQ/Xcs7Ddy0hPE=", + "2": 65521, + "3": 1, + "4": 23, + "5": "HA_test", + "254": 1 + }, + { + "1": "BBF47gm4BEBA6LXQluAHjn6P3+MZKrhuMcJligg1xcBM7X++F7GsZFh4hYAhdmD9HHwhtZxH2c85aAzbpikViwI=", + "2": 65521, + "3": 1, + "4": 100, + "5": "", + "254": 2 + } + ], + "0/62/2": 16, + "0/62/3": 2, + "0/62/4": [ + "FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQUARgkBwEkCAEwCUEEx7IcxeMmlVYX2xp6EG7ulktPB2ikplOXkl2FTT+jNn+yTWlpUUTVTw625moz9L/hb9+eQKdStD9dyzsN3LSE8TcKNQEpARgkAmAwBBSMUxuvFOVkFbJPALb0kMnityi6jzAFFIxTG68U5WQVsk8AtvSQyeK3KLqPGDALQPBVUg+OBUWl1pe/k55ZigAZl3lfBP1Qd5zQP4AUB45mNTzdli8DRCj+h7cIs3JHQQPlUaRvG5xUoBZ+C7Gg2sQY", + "FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQUARgkBwEkCAEwCUEEEXjuCbgEQEDotdCW4AeOfo/f4xkquG4xwmWKCDXFwEztf74XsaxkWHiFgCF2YP0cfCG1nEfZzzloDNumKRWLAjcKNQEpARgkAmAwBBQD3rx0jOdkiCPt06hxW7Z2jJBPXTAFFAPevHSM52SII+3TqHFbtnaMkE9dGDALQL+L3Zc6En6Ionk6WIz+lM50iwOEzTi9VwyYQRUdtO99T8jRX52+Olh6zcUtWQuYO2XYiH2OZ8lM4guqqnS8U4UY" + ], + "0/62/5": 1, + "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": 4, + "0/63/3": 3, + "0/63/65532": 0, + "0/63/65533": 2, + "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": 0, + "1/3/65532": 0, + "1/3/65533": 5, + "1/3/65528": [], + "1/3/65529": [0, 64], + "1/3/65531": [0, 1, 65528, 65529, 65531, 65532, 65533], + "1/29/0": [ + { + "0": 1293, + "1": 1 + }, + { + "0": 1292, + "1": 1 + }, + { + "0": 1296, + "1": 1 + }, + { + "0": 17, + "1": 1 + } + ], + "1/29/1": [3, 29, 47, 144, 145, 152, 153, 156, 157, 159], + "1/29/2": [], + "1/29/3": [], + "1/29/65532": 0, + "1/29/65533": 2, + "1/29/65528": [], + "1/29/65529": [], + "1/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533], + "1/47/0": 1, + "1/47/1": 0, + "1/47/2": "Primary Mains Power", + "1/47/5": 0, + "1/47/7": 230000, + "1/47/8": 32000, + "1/47/31": [1], + "1/47/65532": 1, + "1/47/65533": 3, + "1/47/65528": [], + "1/47/65529": [], + "1/47/65531": [0, 1, 2, 5, 7, 8, 31, 65528, 65529, 65531, 65532, 65533], + "1/144/0": 2, + "1/144/1": 3, + "1/144/2": [ + { + "0": 5, + "1": true, + "2": -50000000, + "3": 50000000, + "4": [ + { + "0": -50000000, + "1": -10000000, + "2": 5000, + "3": 2000, + "4": 3000 + }, + { + "0": -9999999, + "1": 9999999, + "2": 1000, + "3": 100, + "4": 500 + }, + { + "0": 10000000, + "1": 50000000, + "2": 5000, + "3": 2000, + "4": 3000 + } + ] + }, + { + "0": 2, + "1": true, + "2": -100000, + "3": 100000, + "4": [ + { + "0": -100000, + "1": -5000, + "2": 5000, + "3": 2000, + "4": 3000 + }, + { + "0": -4999, + "1": 4999, + "2": 1000, + "3": 100, + "4": 500 + }, + { + "0": 5000, + "1": 100000, + "2": 5000, + "3": 2000, + "4": 3000 + } + ] + }, + { + "0": 1, + "1": true, + "2": -500000, + "3": 500000, + "4": [ + { + "0": -500000, + "1": -100000, + "2": 5000, + "3": 2000, + "4": 3000 + }, + { + "0": -99999, + "1": 99999, + "2": 1000, + "3": 100, + "4": 500 + }, + { + "0": 100000, + "1": 500000, + "2": 5000, + "3": 2000, + "4": 3000 + } + ] + } + ], + "1/144/3": [], + "1/144/4": null, + "1/144/5": null, + "1/144/6": null, + "1/144/7": null, + "1/144/8": null, + "1/144/9": null, + "1/144/10": null, + "1/144/11": null, + "1/144/12": null, + "1/144/13": null, + "1/144/14": null, + "1/144/15": [ + { + "0": 1, + "1": 100000 + } + ], + "1/144/16": [ + { + "0": 1, + "1": 100000 + } + ], + "1/144/17": null, + "1/144/18": null, + "1/144/65532": 31, + "1/144/65533": 1, + "1/144/65528": [], + "1/144/65529": [], + "1/144/65531": [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 65528, + 65529, 65531, 65532, 65533 + ], + "1/145/0": { + "0": 14, + "1": true, + "2": 0, + "3": 1000000000000000, + "4": [ + { + "0": 98440650424323, + "1": 98442759724168, + "2": 0, + "3": 0, + "5": 140728898420739, + "6": 98440650424355 + } + ] + }, + "1/145/1": null, + "1/145/2": null, + "1/145/3": null, + "1/145/4": null, + "1/145/5": { + "0": 0, + "1": 0, + "2": 0, + "3": 0 + }, + "1/145/65532": 15, + "1/145/65533": 1, + "1/145/65528": [], + "1/145/65529": [], + "1/145/65531": [0, 1, 2, 3, 4, 5, 65528, 65529, 65531, 65532, 65533], + "1/152/0": 0, + "1/152/1": false, + "1/152/2": 1, + "1/152/3": 1200000, + "1/152/4": 7600000, + "1/152/5": null, + "1/152/6": null, + "1/152/7": 0, + "1/152/65532": 123, + "1/152/65533": 4, + "1/152/65528": [], + "1/152/65529": [0, 1, 2, 3, 4, 5, 6, 7], + "1/152/65531": [ + 0, 1, 2, 3, 4, 5, 6, 7, 65528, 65529, 65531, 65532, 65533 + ], + "1/153/0": 3, + "1/153/1": 1, + "1/153/2": 0, + "1/153/3": null, + "1/153/5": 32000, + "1/153/6": 2000, + "1/153/7": 30000, + "1/153/9": 32000, + "1/153/10": 600, + "1/153/35": null, + "1/153/36": null, + "1/153/37": null, + "1/153/38": null, + "1/153/39": null, + "1/153/64": 2, + "1/153/65": 0, + "1/153/66": 0, + "1/153/65532": 9, + "1/153/65533": 3, + "1/153/65528": [0], + "1/153/65529": [1, 2, 5, 6, 7, 4], + "1/153/65531": [ + 0, 1, 2, 3, 5, 6, 7, 9, 10, 35, 36, 37, 38, 39, 64, 65, 66, 65528, + 65529, 65531, 65532, 65533 + ], + "1/156/65532": 1, + "1/156/65533": 1, + "1/156/65528": [], + "1/156/65529": [], + "1/156/65531": [65528, 65529, 65531, 65532, 65533], + "1/157/0": [ + { + "0": "Manual", + "1": 0, + "2": [ + { + "1": 16384 + } + ] + }, + { + "0": "Auto-scheduled", + "1": 1, + "2": [ + { + "1": 16385 + } + ] + }, + { + "0": "Solar", + "1": 2, + "2": [ + { + "1": 16386 + } + ] + }, + { + "0": "Auto-scheduled with Solar charging", + "1": 3, + "2": [ + { + "1": 16385 + }, + { + "1": 16386 + } + ] + } + ], + "1/157/1": 1, + "1/157/65532": 0, + "1/157/65533": 2, + "1/157/65528": [1], + "1/157/65529": [0], + "1/157/65531": [0, 1, 65528, 65529, 65531, 65532, 65533], + "1/159/0": [ + { + "0": "No energy management (forecast only)", + "1": 0, + "2": [ + { + "1": 16384 + } + ] + }, + { + "0": "Device optimizes (no local or grid control)", + "1": 1, + "2": [ + { + "1": 16385 + } + ] + }, + { + "0": "Optimized within building", + "1": 2, + "2": [ + { + "1": 16386 + }, + { + "1": 16385 + } + ] + }, + { + "0": "Optimized for grid", + "1": 3, + "2": [ + { + "1": 16385 + }, + { + "1": 16387 + } + ] + }, + { + "0": "Optimized for grid and building", + "1": 4, + "2": [ + { + "1": 16386 + }, + { + "1": 16385 + }, + { + "1": 16387 + } + ] + } + ], + "1/159/1": 3, + "1/159/65532": 0, + "1/159/65533": 2, + "1/159/65528": [1], + "1/159/65529": [0], + "1/159/65531": [0, 1, 65528, 65529, 65531, 65532, 65533] + }, + "attribute_subscriptions": [] + } +} From 80a20da2e12d5f01af1d6c3827a2f7edb68d1bcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Wed, 18 Dec 2024 08:13:17 +0100 Subject: [PATCH 14/58] EnergyEvse.Enums.FaultStateEnum --- homeassistant/components/matter/sensor.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 10af62d970dc29..0e0354e8f6ae6c 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -92,6 +92,26 @@ } +EVSE_FAULT_STATE_MAP = { + clusters.EnergyEvse.Enums.FaultStateEnum.kNoError: "No Error", + clusters.EnergyEvse.Enums.FaultStateEnum.kMeterFailure: "Meter Failure", + clusters.EnergyEvse.Enums.FaultStateEnum.kOverVoltage: "Over Voltage", + clusters.EnergyEvse.Enums.FaultStateEnum.kUnderVoltage: "Under Voltage", + clusters.EnergyEvse.Enums.FaultStateEnum.kOverCurrent: "Over Current", + clusters.EnergyEvse.Enums.FaultStateEnum.kContactWetFailure: "Contact Wet Failure", + clusters.EnergyEvse.Enums.FaultStateEnum.kContactDryFailure: "Contact Dry Failure", + clusters.EnergyEvse.Enums.FaultStateEnum.kPowerLoss: "Power Loss", + clusters.EnergyEvse.Enums.FaultStateEnum.kPowerQuality: "Power Quality", + clusters.EnergyEvse.Enums.FaultStateEnum.kPilotShortCircuit: "Pilot Short Circuit", + clusters.EnergyEvse.Enums.FaultStateEnum.kEmergencyStop: "Emergency Stop", + clusters.EnergyEvse.Enums.FaultStateEnum.kEVDisconnected: "EV Disconnected", + clusters.EnergyEvse.Enums.FaultStateEnum.kWrongPowerSupply: "Wrong Power Supply", + clusters.EnergyEvse.Enums.FaultStateEnum.kLiveNeutralSwap: "Live Neutral Swap", + clusters.EnergyEvse.Enums.FaultStateEnum.kOverTemperature: "Over Temperature", + clusters.EnergyEvse.Enums.FaultStateEnum.kOther: "Unknown", +} + + async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, From d03959af82ee4db0a9390f2f0aa3752a37684286 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Wed, 18 Dec 2024 08:14:26 +0100 Subject: [PATCH 15/58] EnergyEvse.Attributes.FaultState --- homeassistant/components/matter/sensor.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 0e0354e8f6ae6c..9e9983bbd5a26c 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -795,4 +795,18 @@ def _update_from_device(self) -> None: entity_class=MatterSensor, required_attributes=(clusters.EnergyEvse.Attributes.SupplyState,), ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="EnergyEvseFaultState", + translation_key="evse_fault_state", + device_class=SensorDeviceClass.ENUM, + options=list(EVSE_FAULT_STATE_MAP.values()), + measurement_to_ha=EVSE_FAULT_STATE_MAP.get, + ), + entity_class=MatterSensor, + required_attributes=( + clusters.EnergyEvse.Attributes.FaultState, + ), + ), ] From 8c409fe4cd2c18f4d5c47dbccb6bd46518695029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Wed, 18 Dec 2024 08:22:57 +0100 Subject: [PATCH 16/58] ruff-format --- homeassistant/components/matter/sensor.py | 74 +++++++++++------------ 1 file changed, 36 insertions(+), 38 deletions(-) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 9e9983bbd5a26c..aa709b484aa151 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -715,6 +715,42 @@ def _update_from_device(self) -> None: clusters.OperationalState.Attributes.OperationalStateList, ), ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="EnergyEvseState", + translation_key="evse_state", + device_class=SensorDeviceClass.ENUM, + options=list(EVSE_STATE_MAP.values()), + measurement_to_ha=EVSE_STATE_MAP.get, + ), + entity_class=MatterSensor, + required_attributes=(clusters.EnergyEvse.Attributes.State,), + ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="EnergyEvseSupplyState", + translation_key="evse_supply_state", + device_class=SensorDeviceClass.ENUM, + options=list(EVSE_SUPPLY_STATE_MAP.values()), + measurement_to_ha=EVSE_SUPPLY_STATE_MAP.get, + ), + entity_class=MatterSensor, + required_attributes=(clusters.EnergyEvse.Attributes.SupplyState,), + ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="EnergyEvseFaultState", + translation_key="evse_fault_state", + device_class=SensorDeviceClass.ENUM, + options=list(EVSE_FAULT_STATE_MAP.values()), + measurement_to_ha=EVSE_FAULT_STATE_MAP.get, + ), + entity_class=MatterSensor, + required_attributes=(clusters.EnergyEvse.Attributes.FaultState,), + ), MatterDiscoverySchema( platform=Platform.SENSOR, entity_description=MatterSensorEntityDescription( @@ -771,42 +807,4 @@ def _update_from_device(self) -> None: entity_class=MatterSensor, required_attributes=(clusters.EnergyEvse.Attributes.UserMaximumChargeCurrent,), ), - MatterDiscoverySchema( - platform=Platform.SENSOR, - entity_description=MatterSensorEntityDescription( - key="EnergyEvseState", - translation_key="evse_state", - device_class=SensorDeviceClass.ENUM, - options=list(EVSE_STATE_MAP.values()), - measurement_to_ha=EVSE_STATE_MAP.get, - ), - entity_class=MatterSensor, - required_attributes=(clusters.EnergyEvse.Attributes.State,), - ), - MatterDiscoverySchema( - platform=Platform.SENSOR, - entity_description=MatterSensorEntityDescription( - key="EnergyEvseSupplyState", - translation_key="evse_supply_state", - device_class=SensorDeviceClass.ENUM, - options=list(EVSE_SUPPLY_STATE_MAP.values()), - measurement_to_ha=EVSE_SUPPLY_STATE_MAP.get, - ), - entity_class=MatterSensor, - required_attributes=(clusters.EnergyEvse.Attributes.SupplyState,), - ), - MatterDiscoverySchema( - platform=Platform.SENSOR, - entity_description=MatterSensorEntityDescription( - key="EnergyEvseFaultState", - translation_key="evse_fault_state", - device_class=SensorDeviceClass.ENUM, - options=list(EVSE_FAULT_STATE_MAP.values()), - measurement_to_ha=EVSE_FAULT_STATE_MAP.get, - ), - entity_class=MatterSensor, - required_attributes=( - clusters.EnergyEvse.Attributes.FaultState, - ), - ), ] From f1eaa063cfdf3ea8c25ea72a5d2a664da18794f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Wed, 18 Dec 2024 10:20:23 +0100 Subject: [PATCH 17/58] EnergyEvse.Enums.SupplyStateEnum.kEnabled Only with Matter 1.4 --- homeassistant/components/matter/sensor.py | 1 - 1 file changed, 1 deletion(-) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index aa709b484aa151..47458fabad3b31 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -88,7 +88,6 @@ clusters.EnergyEvse.Enums.SupplyStateEnum.kChargingEnabled: "Charging Enabled", clusters.EnergyEvse.Enums.SupplyStateEnum.kDischargingEnabled: "Discharging Enabled", clusters.EnergyEvse.Enums.SupplyStateEnum.kDisabledDiagnostics: "Disabled Diagnostics", - clusters.EnergyEvse.Enums.SupplyStateEnum.kEnabled: "Enabled", } From b91fb0cde2dabcd2697305383b7576f1b035c716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Wed, 18 Dec 2024 12:12:57 +0100 Subject: [PATCH 18/58] Custom class for requests with `timed_request_timeout_ms` --- homeassistant/components/matter/button.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/matter/button.py b/homeassistant/components/matter/button.py index 68f202e29f7b40..db5631d3c99d0e 100644 --- a/homeassistant/components/matter/button.py +++ b/homeassistant/components/matter/button.py @@ -56,6 +56,23 @@ async def async_press(self) -> None: ) +class MatterCommandButtonCustom(MatterEntity, ButtonEntity): + """Representation of a Matter Button entity with request timeout.""" + + entity_description: MatterButtonEntityDescription + + async def async_press(self) -> None: + """Handle the button press leveraging a Matter command.""" + if TYPE_CHECKING: + assert self.entity_description.command is not None + await self.matter_client.send_device_command( + node_id=self._endpoint.node.node_id, + endpoint_id=self._endpoint.endpoint_id, + command=self.entity_description.command(), + timed_request_timeout_ms=3000, + ) + + # Discovery schema(s) to map Matter Attributes to HA entities DISCOVERY_SCHEMAS = [ MatterDiscoverySchema( @@ -154,7 +171,7 @@ async def async_press(self) -> None: translation_key="enable_charging", command=clusters.EnergyEvse.Commands.EnableCharging, ), - entity_class=MatterCommandButton, + entity_class=MatterCommandButtonCustom, required_attributes=(clusters.EnergyEvse.Attributes.AcceptedCommandList,), allow_multi=True, ), @@ -165,7 +182,7 @@ async def async_press(self) -> None: translation_key="disable_charging", command=clusters.EnergyEvse.Commands.Disable, ), - entity_class=MatterCommandButton, + entity_class=MatterCommandButtonCustom, required_attributes=(clusters.EnergyEvse.Attributes.AcceptedCommandList,), allow_multi=True, ), From 8e78a212fe62bd23480827e4b6f689a8a83cdb93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Wed, 18 Dec 2024 14:18:52 +0100 Subject: [PATCH 19/58] Generic `MatterCommandButton` class --- homeassistant/components/matter/button.py | 25 ++++++----------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/homeassistant/components/matter/button.py b/homeassistant/components/matter/button.py index db5631d3c99d0e..afe286a90d71a8 100644 --- a/homeassistant/components/matter/button.py +++ b/homeassistant/components/matter/button.py @@ -38,6 +38,7 @@ class MatterButtonEntityDescription(ButtonEntityDescription, MatterEntityDescrip """Describe Matter Button entities.""" command: Callable[[], Any] | None = None + command_timeout: int | None = None class MatterCommandButton(MatterEntity, ButtonEntity): @@ -53,23 +54,7 @@ async def async_press(self) -> None: node_id=self._endpoint.node.node_id, endpoint_id=self._endpoint.endpoint_id, command=self.entity_description.command(), - ) - - -class MatterCommandButtonCustom(MatterEntity, ButtonEntity): - """Representation of a Matter Button entity with request timeout.""" - - entity_description: MatterButtonEntityDescription - - async def async_press(self) -> None: - """Handle the button press leveraging a Matter command.""" - if TYPE_CHECKING: - assert self.entity_description.command is not None - await self.matter_client.send_device_command( - node_id=self._endpoint.node.node_id, - endpoint_id=self._endpoint.endpoint_id, - command=self.entity_description.command(), - timed_request_timeout_ms=3000, + timed_request_timeout_ms=self.entity_description.command_timeout, ) @@ -170,8 +155,9 @@ async def async_press(self) -> None: key="EnergyEvseEnableChargingButton", translation_key="enable_charging", command=clusters.EnergyEvse.Commands.EnableCharging, + command_timeout=3000, ), - entity_class=MatterCommandButtonCustom, + entity_class=MatterCommandButton, required_attributes=(clusters.EnergyEvse.Attributes.AcceptedCommandList,), allow_multi=True, ), @@ -181,8 +167,9 @@ async def async_press(self) -> None: key="EnergyEvseDisableChargingButton", translation_key="disable_charging", command=clusters.EnergyEvse.Commands.Disable, + command_timeout=3000, ), - entity_class=MatterCommandButtonCustom, + entity_class=MatterCommandButton, required_attributes=(clusters.EnergyEvse.Attributes.AcceptedCommandList,), allow_multi=True, ), From 8027a8e4abd85249a09fc3c3c8d5ef2753c8dc74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Wed, 18 Dec 2024 14:34:42 +0100 Subject: [PATCH 20/58] Update icons.json --- homeassistant/components/matter/icons.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/homeassistant/components/matter/icons.json b/homeassistant/components/matter/icons.json index adcdcd051376d8..206f35edb8d88c 100644 --- a/homeassistant/components/matter/icons.json +++ b/homeassistant/components/matter/icons.json @@ -17,6 +17,12 @@ }, "stop": { "default": "mdi:stop" + }, + "enable_charging": { + "default": "mdi:play" + }, + "disable_charging": { + "default": "mdi:stop" } }, "fan": { From 5525f00b4c4158d6af473d22500b65fc9918bed8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Wed, 18 Dec 2024 14:35:47 +0100 Subject: [PATCH 21/58] Update strings.json --- homeassistant/components/matter/strings.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/homeassistant/components/matter/strings.json b/homeassistant/components/matter/strings.json index ca15538997e2b9..0e67a8c3b7fecc 100644 --- a/homeassistant/components/matter/strings.json +++ b/homeassistant/components/matter/strings.json @@ -93,6 +93,12 @@ }, "reset_filter_condition": { "name": "Reset filter condition" + }, + "enable_charging": { + "name": "[%key:common::action::start%]" + }, + "disable_charging": { + "name": "[%key:common::action::stop%]" } }, "climate": { From ba9a4f55739ae019e092395b0272a64071519793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Wed, 18 Dec 2024 15:16:02 +0100 Subject: [PATCH 22/58] Update icons.json --- homeassistant/components/matter/icons.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/homeassistant/components/matter/icons.json b/homeassistant/components/matter/icons.json index 206f35edb8d88c..7a7023ea77debb 100644 --- a/homeassistant/components/matter/icons.json +++ b/homeassistant/components/matter/icons.json @@ -63,6 +63,15 @@ }, "valve_position": { "default": "mdi:valve" + }, + "evse_state": { + "default": "mdi:ev-station" + }, + "evse_supply_state": { + "default": "mdi:ev-station" + }, + "evse_fault_state": { + "default": "mdi:ev-station" } } } From d39bc5eba05dadab53d9d97b0c9ce44850953dd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Wed, 18 Dec 2024 15:16:57 +0100 Subject: [PATCH 23/58] Update strings.json --- homeassistant/components/matter/strings.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/homeassistant/components/matter/strings.json b/homeassistant/components/matter/strings.json index 0e67a8c3b7fecc..d86edadc47f0d1 100644 --- a/homeassistant/components/matter/strings.json +++ b/homeassistant/components/matter/strings.json @@ -254,6 +254,15 @@ }, "battery_replacement_description": { "name": "Battery type" + }, + "evse_state": { + "name": "State" + }, + "evse_supply_state": { + "name": "Supply state" + }, + "evse_fault_state": { + "name": "Fault state" } }, "switch": { From bf7cdd8a8342fdd5bc263e43ad5d81c160a3a5c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Wed, 18 Dec 2024 15:32:29 +0100 Subject: [PATCH 24/58] Update strings.json --- homeassistant/components/matter/strings.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/homeassistant/components/matter/strings.json b/homeassistant/components/matter/strings.json index d86edadc47f0d1..b8a2f141542767 100644 --- a/homeassistant/components/matter/strings.json +++ b/homeassistant/components/matter/strings.json @@ -263,6 +263,18 @@ }, "evse_fault_state": { "name": "Fault state" + }, + "evse_circuit_capacity": { + "name": "Circuit capacity" + }, + "evse_charge_current": { + "name": "Charge current" + }, + "evse_max_charge_current": { + "name": "Max charge current" + }, + "evse_user_max_charge_current": { + "name": "User max charge current" } }, "switch": { From cd1afcf120fb20e6224b68472654df6907525f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Wed, 18 Dec 2024 14:55:22 +0000 Subject: [PATCH 25/58] Test evse sensor --- tests/components/matter/test_sensor.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/components/matter/test_sensor.py b/tests/components/matter/test_sensor.py index 3215ec581161f0..c91f98360b02bf 100644 --- a/tests/components/matter/test_sensor.py +++ b/tests/components/matter/test_sensor.py @@ -333,3 +333,23 @@ async def test_operational_state_sensor( state = hass.states.get("sensor.dishwasher_operational_state") assert state assert state.state == "extra_state" + + +@pytest.mark.parametrize("node_fixture", ["evse_charging"]) +async def test_evse_sensor( + hass: HomeAssistant, + matter_client: MagicMock, + matter_node: MatterNode, +) -> None: + """Test evse sensor.""" + # State + state = hass.states.get("sensor.mock_evse_evse_state") + assert state + assert state.state == "3" + + set_node_attribute(matter_node, 1, 153, 0, 1) + await trigger_subscription_callback(hass, matter_client) + + state = hass.states.get("sensor.mock_evse_evse_state") + assert state + assert state.state == "1" From 90b0118839af8a3e05241c9c337085d5424e1072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Thu, 19 Dec 2024 16:24:15 +0100 Subject: [PATCH 26/58] Update test_sensor.py --- tests/components/matter/test_sensor.py | 27 +++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/tests/components/matter/test_sensor.py b/tests/components/matter/test_sensor.py index c91f98360b02bf..10d67faaf9aa6a 100644 --- a/tests/components/matter/test_sensor.py +++ b/tests/components/matter/test_sensor.py @@ -342,7 +342,7 @@ async def test_evse_sensor( matter_node: MatterNode, ) -> None: """Test evse sensor.""" - # State + # EnergyEvseState state = hass.states.get("sensor.mock_evse_evse_state") assert state assert state.state == "3" @@ -353,3 +353,28 @@ async def test_evse_sensor( state = hass.states.get("sensor.mock_evse_evse_state") assert state assert state.state == "1" + + # EnergyEvseSupplyState + state = hass.states.get("sensor.mock_evse_evse_supply_state") + assert state + assert state.state == "1" + + set_node_attribute(matter_node, 1, 153, 1, 0) + await trigger_subscription_callback(hass, matter_client) + + state = hass.states.get("sensor.mock_evse_evse_supply_state") + assert state + assert state.state == "0" + + # EnergyEvseFaultState + state = hass.states.get("sensor.mock_evse_evse_fault_state") + assert state + assert state.state == "0" + + set_node_attribute(matter_node, 1, 153, 1, 2) + await trigger_subscription_callback(hass, matter_client) + + state = hass.states.get("sensor.mock_evse_evse_fault_state") + assert state + assert state.state == "2" + From cf0d4337196dfe9d72e639de0b7c90c1c2760db0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Thu, 19 Dec 2024 16:27:24 +0100 Subject: [PATCH 27/58] Update test_sensor.py --- tests/components/matter/test_sensor.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/components/matter/test_sensor.py b/tests/components/matter/test_sensor.py index 10d67faaf9aa6a..f016394e3d28ac 100644 --- a/tests/components/matter/test_sensor.py +++ b/tests/components/matter/test_sensor.py @@ -377,4 +377,3 @@ async def test_evse_sensor( state = hass.states.get("sensor.mock_evse_evse_fault_state") assert state assert state.state == "2" - From 113bcc71c061de826eb98e5185bb9a7752022bdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Thu, 19 Dec 2024 21:22:09 +0100 Subject: [PATCH 28/58] Update evse_charging.json Remove `node` object --- .../matter/fixtures/nodes/evse_charging.json | 1136 ++++++++--------- 1 file changed, 566 insertions(+), 570 deletions(-) diff --git a/tests/components/matter/fixtures/nodes/evse_charging.json b/tests/components/matter/fixtures/nodes/evse_charging.json index 3eac832a6c52fb..d1664a203e2bab 100644 --- a/tests/components/matter/fixtures/nodes/evse_charging.json +++ b/tests/components/matter/fixtures/nodes/evse_charging.json @@ -1,584 +1,580 @@ { - "node": { - "node_id": 23, - "date_commissioned": "2024-12-17T18:14:53.210190", - "last_interview": "2024-12-17T18:14:53.211611", - "interview_version": 6, - "available": true, - "is_bridge": false, - "attributes": { - "0/29/0": [ - { - "0": 22, - "1": 1 - } - ], - "0/29/1": [29, 31, 40, 43, 44, 45, 48, 49, 51, 60, 62, 63], - "0/29/2": [], - "0/29/3": [1], - "0/29/65532": 0, - "0/29/65533": 2, - "0/29/65528": [], - "0/29/65529": [], - "0/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533], - "0/31/0": [ - { - "1": 5, - "2": 2, - "3": [112233], - "4": null, - "254": 1 - } - ], - "0/31/2": 4, - "0/31/3": 3, - "0/31/4": 4, - "0/31/65532": 0, - "0/31/65533": 2, - "0/31/65528": [], - "0/31/65529": [], - "0/31/65531": [0, 2, 3, 4, 65528, 65529, 65531, 65532, 65533], - "0/40/0": 18, - "0/40/1": "TEST_VENDOR", - "0/40/2": 65521, - "0/40/3": "Mock EVSE", - "0/40/4": 32769, - "0/40/5": "Mock EVSE", - "0/40/6": "**REDACTED**", - "0/40/7": 0, - "0/40/8": "TEST_VERSION", - "0/40/9": 1, - "0/40/10": "1.0", - "0/40/15": "TEST_SN", - "0/40/18": "mock-evse-charging", - "0/40/19": { - "0": 3, - "1": 65535 + "node_id": 23, + "date_commissioned": "2024-12-17T18:14:53.210190", + "last_interview": "2024-12-17T18:14:53.211611", + "interview_version": 6, + "available": true, + "is_bridge": false, + "attributes": { + "0/29/0": [ + { + "0": 22, + "1": 1 + } + ], + "0/29/1": [29, 31, 40, 43, 44, 45, 48, 49, 51, 60, 62, 63], + "0/29/2": [], + "0/29/3": [1], + "0/29/65532": 0, + "0/29/65533": 2, + "0/29/65528": [], + "0/29/65529": [], + "0/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533], + "0/31/0": [ + { + "1": 5, + "2": 2, + "3": [112233], + "4": null, + "254": 1 + } + ], + "0/31/2": 4, + "0/31/3": 3, + "0/31/4": 4, + "0/31/65532": 0, + "0/31/65533": 2, + "0/31/65528": [], + "0/31/65529": [], + "0/31/65531": [0, 2, 3, 4, 65528, 65529, 65531, 65532, 65533], + "0/40/0": 18, + "0/40/1": "TEST_VENDOR", + "0/40/2": 65521, + "0/40/3": "Mock EVSE", + "0/40/4": 32769, + "0/40/5": "Mock EVSE", + "0/40/6": "**REDACTED**", + "0/40/7": 0, + "0/40/8": "TEST_VERSION", + "0/40/9": 1, + "0/40/10": "1.0", + "0/40/15": "TEST_SN", + "0/40/18": "mock-evse-charging", + "0/40/19": { + "0": 3, + "1": 65535 + }, + "0/40/21": 17039360, + "0/40/22": 1, + "0/40/65532": 0, + "0/40/65533": 4, + "0/40/65528": [], + "0/40/65529": [], + "0/40/65531": [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 18, 19, 21, 22, 65528, 65529, 65531, + 65532, 65533 + ], + "0/43/0": "en-US", + "0/43/1": [ + "en-US", + "de-DE", + "fr-FR", + "en-GB", + "es-ES", + "zh-CN", + "it-IT", + "ja-JP" + ], + "0/43/65532": 0, + "0/43/65533": 1, + "0/43/65528": [], + "0/43/65529": [], + "0/43/65531": [0, 1, 65528, 65529, 65531, 65532, 65533], + "0/44/0": 0, + "0/44/65532": 0, + "0/44/65533": 1, + "0/44/65528": [], + "0/44/65529": [], + "0/44/65531": [0, 65528, 65529, 65531, 65532, 65533], + "0/45/65532": 0, + "0/45/65533": 1, + "0/45/65528": [], + "0/45/65529": [], + "0/45/65531": [65528, 65529, 65531, 65532, 65533], + "0/48/0": 0, + "0/48/1": { + "0": 60, + "1": 900 + }, + "0/48/2": 0, + "0/48/3": 2, + "0/48/4": true, + "0/48/65532": 0, + "0/48/65533": 2, + "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": "ZW5zMzM=", + "1": true + } + ], + "0/49/4": true, + "0/49/5": null, + "0/49/6": null, + "0/49/7": null, + "0/49/8": [0], + "0/49/65532": 4, + "0/49/65533": 2, + "0/49/65528": [], + "0/49/65529": [], + "0/49/65531": [0, 1, 4, 5, 6, 7, 8, 65528, 65529, 65531, 65532, 65533], + "0/51/0": [ + { + "0": "docker0", + "1": false, + "2": null, + "3": null, + "4": "AkI9NTnB", + "5": ["rBEAAQ=="], + "6": [""], + "7": 0 }, - "0/40/21": 17039360, - "0/40/22": 1, - "0/40/65532": 0, - "0/40/65533": 4, - "0/40/65528": [], - "0/40/65529": [], - "0/40/65531": [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 18, 19, 21, 22, 65528, 65529, - 65531, 65532, 65533 - ], - "0/43/0": "en-US", - "0/43/1": [ - "en-US", - "de-DE", - "fr-FR", - "en-GB", - "es-ES", - "zh-CN", - "it-IT", - "ja-JP" - ], - "0/43/65532": 0, - "0/43/65533": 1, - "0/43/65528": [], - "0/43/65529": [], - "0/43/65531": [0, 1, 65528, 65529, 65531, 65532, 65533], - "0/44/0": 0, - "0/44/65532": 0, - "0/44/65533": 1, - "0/44/65528": [], - "0/44/65529": [], - "0/44/65531": [0, 65528, 65529, 65531, 65532, 65533], - "0/45/65532": 0, - "0/45/65533": 1, - "0/45/65528": [], - "0/45/65529": [], - "0/45/65531": [65528, 65529, 65531, 65532, 65533], - "0/48/0": 0, - "0/48/1": { - "0": 60, - "1": 900 + { + "0": "ens33", + "1": true, + "2": null, + "3": null, + "4": "AAwp/F0T", + "5": ["wKgBpw=="], + "6": [ + "KgEOCgKzOZCNB+q+Uz0I9w==", + "KgEOCgKzOZC/O1Ew1WvS4A==", + "/oAAAAAAAADml3Ozl7GZug==" + ], + "7": 2 }, - "0/48/2": 0, - "0/48/3": 2, - "0/48/4": true, - "0/48/65532": 0, - "0/48/65533": 2, - "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": "ZW5zMzM=", - "1": true - } - ], - "0/49/4": true, - "0/49/5": null, - "0/49/6": null, - "0/49/7": null, - "0/49/8": [0], - "0/49/65532": 4, - "0/49/65533": 2, - "0/49/65528": [], - "0/49/65529": [], - "0/49/65531": [0, 1, 4, 5, 6, 7, 8, 65528, 65529, 65531, 65532, 65533], - "0/51/0": [ - { - "0": "docker0", - "1": false, - "2": null, - "3": null, - "4": "AkI9NTnB", - "5": ["rBEAAQ=="], - "6": [""], - "7": 0 - }, - { - "0": "ens33", - "1": true, - "2": null, - "3": null, - "4": "AAwp/F0T", - "5": ["wKgBpw=="], - "6": [ - "KgEOCgKzOZCNB+q+Uz0I9w==", - "KgEOCgKzOZC/O1Ew1WvS4A==", - "/oAAAAAAAADml3Ozl7GZug==" - ], - "7": 2 - }, - { - "0": "lo", - "1": true, - "2": null, - "3": null, - "4": "AAAAAAAA", - "5": ["fwAAAQ=="], - "6": ["AAAAAAAAAAAAAAAAAAAAAQ=="], - "7": 0 - } - ], - "0/51/1": 1, - "0/51/2": 10129, - "0/51/8": true, - "0/51/65532": 0, - "0/51/65533": 2, - "0/51/65528": [2], - "0/51/65529": [0, 1], - "0/51/65531": [0, 1, 2, 8, 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, 2], - "0/60/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533], - "0/62/0": [ - { - "1": "FTABAQEkAgE3AyQTAhgmBIAigScmBYAlTTo3BiQVASQRFxgkBwEkCAEwCUEECp4PASYUFk/DwQqGNBikYdiBRDJZbrfF4AYK8Y9jOeIpx7Xy+giJhmTpAVZ662hwszsFDGULGY/owXtMrqTxEDcKNQEoARgkAgE2AwQCBAEYMAQUqBmxO16fPQhbf33Gb2XwQ+NkXpswBRTx8+4bdkuqlxInfB5LXkhRBBvS2hgwC0A8aefsLm663Vuy+TkSvn/oLhRqt2phrG+i5aM5o15xiWDjnNVdUYpT09+K0mgVoMdFuFsmoWQxQh6jahaFJzUgGA==", - "2": "FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQTAhgkBwEkCAEwCUEEGp55xGRB0FBQ3Yw7ayQSzVtYA0BtCJFm9vRRcdr+nk0cuGX6zrUowSYOO/qiRBEACcCNNSqKh+DpRm2uVLOtaDcKNQEpARgkAmAwBBTx8+4bdkuqlxInfB5LXkhRBBvS2jAFFIxTG68U5WQVsk8AtvSQyeK3KLqPGDALQIw/6q5ILMNdOMcSif8HNbEgpjBeaBMfUpzOJFCRPM16sv1xiq3mALZj0u+iG8lUJEvDJOFKPoBvsOubwIwRgAQY", - "254": 1 - } - ], - "0/62/1": [ - { - "1": "BMeyHMXjJpVWF9saehBu7pZLTwdopKZTl5JdhU0/ozZ/sk1paVFE1U8OtuZqM/S/4W/fnkCnUrQ/Xcs7Ddy0hPE=", - "2": 65521, - "3": 1, - "4": 23, - "5": "HA_test", - "254": 1 - }, - { - "1": "BBF47gm4BEBA6LXQluAHjn6P3+MZKrhuMcJligg1xcBM7X++F7GsZFh4hYAhdmD9HHwhtZxH2c85aAzbpikViwI=", - "2": 65521, - "3": 1, - "4": 100, - "5": "", - "254": 2 - } - ], - "0/62/2": 16, - "0/62/3": 2, - "0/62/4": [ - "FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQUARgkBwEkCAEwCUEEx7IcxeMmlVYX2xp6EG7ulktPB2ikplOXkl2FTT+jNn+yTWlpUUTVTw625moz9L/hb9+eQKdStD9dyzsN3LSE8TcKNQEpARgkAmAwBBSMUxuvFOVkFbJPALb0kMnityi6jzAFFIxTG68U5WQVsk8AtvSQyeK3KLqPGDALQPBVUg+OBUWl1pe/k55ZigAZl3lfBP1Qd5zQP4AUB45mNTzdli8DRCj+h7cIs3JHQQPlUaRvG5xUoBZ+C7Gg2sQY", - "FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQUARgkBwEkCAEwCUEEEXjuCbgEQEDotdCW4AeOfo/f4xkquG4xwmWKCDXFwEztf74XsaxkWHiFgCF2YP0cfCG1nEfZzzloDNumKRWLAjcKNQEpARgkAmAwBBQD3rx0jOdkiCPt06hxW7Z2jJBPXTAFFAPevHSM52SII+3TqHFbtnaMkE9dGDALQL+L3Zc6En6Ionk6WIz+lM50iwOEzTi9VwyYQRUdtO99T8jRX52+Olh6zcUtWQuYO2XYiH2OZ8lM4guqqnS8U4UY" - ], - "0/62/5": 1, - "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": 4, - "0/63/3": 3, - "0/63/65532": 0, - "0/63/65533": 2, - "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": 0, - "1/3/65532": 0, - "1/3/65533": 5, - "1/3/65528": [], - "1/3/65529": [0, 64], - "1/3/65531": [0, 1, 65528, 65529, 65531, 65532, 65533], - "1/29/0": [ - { - "0": 1293, - "1": 1 - }, - { - "0": 1292, - "1": 1 - }, - { - "0": 1296, - "1": 1 - }, - { - "0": 17, - "1": 1 - } - ], - "1/29/1": [3, 29, 47, 144, 145, 152, 153, 156, 157, 159], - "1/29/2": [], - "1/29/3": [], - "1/29/65532": 0, - "1/29/65533": 2, - "1/29/65528": [], - "1/29/65529": [], - "1/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533], - "1/47/0": 1, - "1/47/1": 0, - "1/47/2": "Primary Mains Power", - "1/47/5": 0, - "1/47/7": 230000, - "1/47/8": 32000, - "1/47/31": [1], - "1/47/65532": 1, - "1/47/65533": 3, - "1/47/65528": [], - "1/47/65529": [], - "1/47/65531": [0, 1, 2, 5, 7, 8, 31, 65528, 65529, 65531, 65532, 65533], - "1/144/0": 2, - "1/144/1": 3, - "1/144/2": [ - { - "0": 5, - "1": true, - "2": -50000000, - "3": 50000000, - "4": [ - { - "0": -50000000, - "1": -10000000, - "2": 5000, - "3": 2000, - "4": 3000 - }, - { - "0": -9999999, - "1": 9999999, - "2": 1000, - "3": 100, - "4": 500 - }, - { - "0": 10000000, - "1": 50000000, - "2": 5000, - "3": 2000, - "4": 3000 - } - ] - }, - { - "0": 2, - "1": true, - "2": -100000, - "3": 100000, - "4": [ - { - "0": -100000, - "1": -5000, - "2": 5000, - "3": 2000, - "4": 3000 - }, - { - "0": -4999, - "1": 4999, - "2": 1000, - "3": 100, - "4": 500 - }, - { - "0": 5000, - "1": 100000, - "2": 5000, - "3": 2000, - "4": 3000 - } - ] - }, - { - "0": 1, - "1": true, - "2": -500000, - "3": 500000, - "4": [ - { - "0": -500000, - "1": -100000, - "2": 5000, - "3": 2000, - "4": 3000 - }, - { - "0": -99999, - "1": 99999, - "2": 1000, - "3": 100, - "4": 500 - }, - { - "0": 100000, - "1": 500000, - "2": 5000, - "3": 2000, - "4": 3000 - } - ] - } - ], - "1/144/3": [], - "1/144/4": null, - "1/144/5": null, - "1/144/6": null, - "1/144/7": null, - "1/144/8": null, - "1/144/9": null, - "1/144/10": null, - "1/144/11": null, - "1/144/12": null, - "1/144/13": null, - "1/144/14": null, - "1/144/15": [ - { - "0": 1, - "1": 100000 - } - ], - "1/144/16": [ - { - "0": 1, - "1": 100000 - } - ], - "1/144/17": null, - "1/144/18": null, - "1/144/65532": 31, - "1/144/65533": 1, - "1/144/65528": [], - "1/144/65529": [], - "1/144/65531": [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 65528, - 65529, 65531, 65532, 65533 - ], - "1/145/0": { - "0": 14, + { + "0": "lo", "1": true, - "2": 0, - "3": 1000000000000000, + "2": null, + "3": null, + "4": "AAAAAAAA", + "5": ["fwAAAQ=="], + "6": ["AAAAAAAAAAAAAAAAAAAAAQ=="], + "7": 0 + } + ], + "0/51/1": 1, + "0/51/2": 10129, + "0/51/8": true, + "0/51/65532": 0, + "0/51/65533": 2, + "0/51/65528": [2], + "0/51/65529": [0, 1], + "0/51/65531": [0, 1, 2, 8, 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, 2], + "0/60/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533], + "0/62/0": [ + { + "1": "FTABAQEkAgE3AyQTAhgmBIAigScmBYAlTTo3BiQVASQRFxgkBwEkCAEwCUEECp4PASYUFk/DwQqGNBikYdiBRDJZbrfF4AYK8Y9jOeIpx7Xy+giJhmTpAVZ662hwszsFDGULGY/owXtMrqTxEDcKNQEoARgkAgE2AwQCBAEYMAQUqBmxO16fPQhbf33Gb2XwQ+NkXpswBRTx8+4bdkuqlxInfB5LXkhRBBvS2hgwC0A8aefsLm663Vuy+TkSvn/oLhRqt2phrG+i5aM5o15xiWDjnNVdUYpT09+K0mgVoMdFuFsmoWQxQh6jahaFJzUgGA==", + "2": "FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQTAhgkBwEkCAEwCUEEGp55xGRB0FBQ3Yw7ayQSzVtYA0BtCJFm9vRRcdr+nk0cuGX6zrUowSYOO/qiRBEACcCNNSqKh+DpRm2uVLOtaDcKNQEpARgkAmAwBBTx8+4bdkuqlxInfB5LXkhRBBvS2jAFFIxTG68U5WQVsk8AtvSQyeK3KLqPGDALQIw/6q5ILMNdOMcSif8HNbEgpjBeaBMfUpzOJFCRPM16sv1xiq3mALZj0u+iG8lUJEvDJOFKPoBvsOubwIwRgAQY", + "254": 1 + } + ], + "0/62/1": [ + { + "1": "BMeyHMXjJpVWF9saehBu7pZLTwdopKZTl5JdhU0/ozZ/sk1paVFE1U8OtuZqM/S/4W/fnkCnUrQ/Xcs7Ddy0hPE=", + "2": 65521, + "3": 1, + "4": 23, + "5": "HA_test", + "254": 1 + }, + { + "1": "BBF47gm4BEBA6LXQluAHjn6P3+MZKrhuMcJligg1xcBM7X++F7GsZFh4hYAhdmD9HHwhtZxH2c85aAzbpikViwI=", + "2": 65521, + "3": 1, + "4": 100, + "5": "", + "254": 2 + } + ], + "0/62/2": 16, + "0/62/3": 2, + "0/62/4": [ + "FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQUARgkBwEkCAEwCUEEx7IcxeMmlVYX2xp6EG7ulktPB2ikplOXkl2FTT+jNn+yTWlpUUTVTw625moz9L/hb9+eQKdStD9dyzsN3LSE8TcKNQEpARgkAmAwBBSMUxuvFOVkFbJPALb0kMnityi6jzAFFIxTG68U5WQVsk8AtvSQyeK3KLqPGDALQPBVUg+OBUWl1pe/k55ZigAZl3lfBP1Qd5zQP4AUB45mNTzdli8DRCj+h7cIs3JHQQPlUaRvG5xUoBZ+C7Gg2sQY", + "FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQUARgkBwEkCAEwCUEEEXjuCbgEQEDotdCW4AeOfo/f4xkquG4xwmWKCDXFwEztf74XsaxkWHiFgCF2YP0cfCG1nEfZzzloDNumKRWLAjcKNQEpARgkAmAwBBQD3rx0jOdkiCPt06hxW7Z2jJBPXTAFFAPevHSM52SII+3TqHFbtnaMkE9dGDALQL+L3Zc6En6Ionk6WIz+lM50iwOEzTi9VwyYQRUdtO99T8jRX52+Olh6zcUtWQuYO2XYiH2OZ8lM4guqqnS8U4UY" + ], + "0/62/5": 1, + "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": 4, + "0/63/3": 3, + "0/63/65532": 0, + "0/63/65533": 2, + "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": 0, + "1/3/65532": 0, + "1/3/65533": 5, + "1/3/65528": [], + "1/3/65529": [0, 64], + "1/3/65531": [0, 1, 65528, 65529, 65531, 65532, 65533], + "1/29/0": [ + { + "0": 1293, + "1": 1 + }, + { + "0": 1292, + "1": 1 + }, + { + "0": 1296, + "1": 1 + }, + { + "0": 17, + "1": 1 + } + ], + "1/29/1": [3, 29, 47, 144, 145, 152, 153, 156, 157, 159], + "1/29/2": [], + "1/29/3": [], + "1/29/65532": 0, + "1/29/65533": 2, + "1/29/65528": [], + "1/29/65529": [], + "1/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533], + "1/47/0": 1, + "1/47/1": 0, + "1/47/2": "Primary Mains Power", + "1/47/5": 0, + "1/47/7": 230000, + "1/47/8": 32000, + "1/47/31": [1], + "1/47/65532": 1, + "1/47/65533": 3, + "1/47/65528": [], + "1/47/65529": [], + "1/47/65531": [0, 1, 2, 5, 7, 8, 31, 65528, 65529, 65531, 65532, 65533], + "1/144/0": 2, + "1/144/1": 3, + "1/144/2": [ + { + "0": 5, + "1": true, + "2": -50000000, + "3": 50000000, "4": [ { - "0": 98440650424323, - "1": 98442759724168, - "2": 0, - "3": 0, - "5": 140728898420739, - "6": 98440650424355 + "0": -50000000, + "1": -10000000, + "2": 5000, + "3": 2000, + "4": 3000 + }, + { + "0": -9999999, + "1": 9999999, + "2": 1000, + "3": 100, + "4": 500 + }, + { + "0": 10000000, + "1": 50000000, + "2": 5000, + "3": 2000, + "4": 3000 } ] }, - "1/145/1": null, - "1/145/2": null, - "1/145/3": null, - "1/145/4": null, - "1/145/5": { - "0": 0, - "1": 0, - "2": 0, - "3": 0 + { + "0": 2, + "1": true, + "2": -100000, + "3": 100000, + "4": [ + { + "0": -100000, + "1": -5000, + "2": 5000, + "3": 2000, + "4": 3000 + }, + { + "0": -4999, + "1": 4999, + "2": 1000, + "3": 100, + "4": 500 + }, + { + "0": 5000, + "1": 100000, + "2": 5000, + "3": 2000, + "4": 3000 + } + ] }, - "1/145/65532": 15, - "1/145/65533": 1, - "1/145/65528": [], - "1/145/65529": [], - "1/145/65531": [0, 1, 2, 3, 4, 5, 65528, 65529, 65531, 65532, 65533], - "1/152/0": 0, - "1/152/1": false, - "1/152/2": 1, - "1/152/3": 1200000, - "1/152/4": 7600000, - "1/152/5": null, - "1/152/6": null, - "1/152/7": 0, - "1/152/65532": 123, - "1/152/65533": 4, - "1/152/65528": [], - "1/152/65529": [0, 1, 2, 3, 4, 5, 6, 7], - "1/152/65531": [ - 0, 1, 2, 3, 4, 5, 6, 7, 65528, 65529, 65531, 65532, 65533 - ], - "1/153/0": 3, - "1/153/1": 1, - "1/153/2": 0, - "1/153/3": null, - "1/153/5": 32000, - "1/153/6": 2000, - "1/153/7": 30000, - "1/153/9": 32000, - "1/153/10": 600, - "1/153/35": null, - "1/153/36": null, - "1/153/37": null, - "1/153/38": null, - "1/153/39": null, - "1/153/64": 2, - "1/153/65": 0, - "1/153/66": 0, - "1/153/65532": 9, - "1/153/65533": 3, - "1/153/65528": [0], - "1/153/65529": [1, 2, 5, 6, 7, 4], - "1/153/65531": [ - 0, 1, 2, 3, 5, 6, 7, 9, 10, 35, 36, 37, 38, 39, 64, 65, 66, 65528, - 65529, 65531, 65532, 65533 - ], - "1/156/65532": 1, - "1/156/65533": 1, - "1/156/65528": [], - "1/156/65529": [], - "1/156/65531": [65528, 65529, 65531, 65532, 65533], - "1/157/0": [ - { - "0": "Manual", - "1": 0, - "2": [ - { - "1": 16384 - } - ] - }, - { - "0": "Auto-scheduled", - "1": 1, - "2": [ - { - "1": 16385 - } - ] - }, - { - "0": "Solar", - "1": 2, - "2": [ - { - "1": 16386 - } - ] - }, - { - "0": "Auto-scheduled with Solar charging", - "1": 3, - "2": [ - { - "1": 16385 - }, - { - "1": 16386 - } - ] - } - ], - "1/157/1": 1, - "1/157/65532": 0, - "1/157/65533": 2, - "1/157/65528": [1], - "1/157/65529": [0], - "1/157/65531": [0, 1, 65528, 65529, 65531, 65532, 65533], - "1/159/0": [ - { - "0": "No energy management (forecast only)", - "1": 0, - "2": [ - { - "1": 16384 - } - ] - }, - { - "0": "Device optimizes (no local or grid control)", - "1": 1, - "2": [ - { - "1": 16385 - } - ] - }, - { - "0": "Optimized within building", - "1": 2, - "2": [ - { - "1": 16386 - }, - { - "1": 16385 - } - ] - }, - { - "0": "Optimized for grid", - "1": 3, - "2": [ - { - "1": 16385 - }, - { - "1": 16387 - } - ] - }, + { + "0": 1, + "1": true, + "2": -500000, + "3": 500000, + "4": [ + { + "0": -500000, + "1": -100000, + "2": 5000, + "3": 2000, + "4": 3000 + }, + { + "0": -99999, + "1": 99999, + "2": 1000, + "3": 100, + "4": 500 + }, + { + "0": 100000, + "1": 500000, + "2": 5000, + "3": 2000, + "4": 3000 + } + ] + } + ], + "1/144/3": [], + "1/144/4": null, + "1/144/5": null, + "1/144/6": null, + "1/144/7": null, + "1/144/8": null, + "1/144/9": null, + "1/144/10": null, + "1/144/11": null, + "1/144/12": null, + "1/144/13": null, + "1/144/14": null, + "1/144/15": [ + { + "0": 1, + "1": 100000 + } + ], + "1/144/16": [ + { + "0": 1, + "1": 100000 + } + ], + "1/144/17": null, + "1/144/18": null, + "1/144/65532": 31, + "1/144/65533": 1, + "1/144/65528": [], + "1/144/65529": [], + "1/144/65531": [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 65528, + 65529, 65531, 65532, 65533 + ], + "1/145/0": { + "0": 14, + "1": true, + "2": 0, + "3": 1000000000000000, + "4": [ { - "0": "Optimized for grid and building", - "1": 4, - "2": [ - { - "1": 16386 - }, - { - "1": 16385 - }, - { - "1": 16387 - } - ] + "0": 98440650424323, + "1": 98442759724168, + "2": 0, + "3": 0, + "5": 140728898420739, + "6": 98440650424355 } - ], - "1/159/1": 3, - "1/159/65532": 0, - "1/159/65533": 2, - "1/159/65528": [1], - "1/159/65529": [0], - "1/159/65531": [0, 1, 65528, 65529, 65531, 65532, 65533] + ] }, - "attribute_subscriptions": [] - } + "1/145/1": null, + "1/145/2": null, + "1/145/3": null, + "1/145/4": null, + "1/145/5": { + "0": 0, + "1": 0, + "2": 0, + "3": 0 + }, + "1/145/65532": 15, + "1/145/65533": 1, + "1/145/65528": [], + "1/145/65529": [], + "1/145/65531": [0, 1, 2, 3, 4, 5, 65528, 65529, 65531, 65532, 65533], + "1/152/0": 0, + "1/152/1": false, + "1/152/2": 1, + "1/152/3": 1200000, + "1/152/4": 7600000, + "1/152/5": null, + "1/152/6": null, + "1/152/7": 0, + "1/152/65532": 123, + "1/152/65533": 4, + "1/152/65528": [], + "1/152/65529": [0, 1, 2, 3, 4, 5, 6, 7], + "1/152/65531": [0, 1, 2, 3, 4, 5, 6, 7, 65528, 65529, 65531, 65532, 65533], + "1/153/0": 3, + "1/153/1": 1, + "1/153/2": 0, + "1/153/3": null, + "1/153/5": 32000, + "1/153/6": 2000, + "1/153/7": 30000, + "1/153/9": 32000, + "1/153/10": 600, + "1/153/35": null, + "1/153/36": null, + "1/153/37": null, + "1/153/38": null, + "1/153/39": null, + "1/153/64": 2, + "1/153/65": 0, + "1/153/66": 0, + "1/153/65532": 9, + "1/153/65533": 3, + "1/153/65528": [0], + "1/153/65529": [1, 2, 5, 6, 7, 4], + "1/153/65531": [ + 0, 1, 2, 3, 5, 6, 7, 9, 10, 35, 36, 37, 38, 39, 64, 65, 66, 65528, 65529, + 65531, 65532, 65533 + ], + "1/156/65532": 1, + "1/156/65533": 1, + "1/156/65528": [], + "1/156/65529": [], + "1/156/65531": [65528, 65529, 65531, 65532, 65533], + "1/157/0": [ + { + "0": "Manual", + "1": 0, + "2": [ + { + "1": 16384 + } + ] + }, + { + "0": "Auto-scheduled", + "1": 1, + "2": [ + { + "1": 16385 + } + ] + }, + { + "0": "Solar", + "1": 2, + "2": [ + { + "1": 16386 + } + ] + }, + { + "0": "Auto-scheduled with Solar charging", + "1": 3, + "2": [ + { + "1": 16385 + }, + { + "1": 16386 + } + ] + } + ], + "1/157/1": 1, + "1/157/65532": 0, + "1/157/65533": 2, + "1/157/65528": [1], + "1/157/65529": [0], + "1/157/65531": [0, 1, 65528, 65529, 65531, 65532, 65533], + "1/159/0": [ + { + "0": "No energy management (forecast only)", + "1": 0, + "2": [ + { + "1": 16384 + } + ] + }, + { + "0": "Device optimizes (no local or grid control)", + "1": 1, + "2": [ + { + "1": 16385 + } + ] + }, + { + "0": "Optimized within building", + "1": 2, + "2": [ + { + "1": 16386 + }, + { + "1": 16385 + } + ] + }, + { + "0": "Optimized for grid", + "1": 3, + "2": [ + { + "1": 16385 + }, + { + "1": 16387 + } + ] + }, + { + "0": "Optimized for grid and building", + "1": 4, + "2": [ + { + "1": 16386 + }, + { + "1": 16385 + }, + { + "1": 16387 + } + ] + } + ], + "1/159/1": 3, + "1/159/65532": 0, + "1/159/65533": 2, + "1/159/65528": [1], + "1/159/65529": [0], + "1/159/65531": [0, 1, 65528, 65529, 65531, 65532, 65533] + }, + "attribute_subscriptions": [] } From bd8776994387ba7f8de290762d728ad824c54cd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Fri, 20 Dec 2024 09:01:17 +0100 Subject: [PATCH 29/58] Update test_sensor.py --- tests/components/matter/test_sensor.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/components/matter/test_sensor.py b/tests/components/matter/test_sensor.py index f016394e3d28ac..feaba9d6c1b3a7 100644 --- a/tests/components/matter/test_sensor.py +++ b/tests/components/matter/test_sensor.py @@ -343,37 +343,37 @@ async def test_evse_sensor( ) -> None: """Test evse sensor.""" # EnergyEvseState - state = hass.states.get("sensor.mock_evse_evse_state") + state = hass.states.get("sensor.evse_state") assert state assert state.state == "3" set_node_attribute(matter_node, 1, 153, 0, 1) await trigger_subscription_callback(hass, matter_client) - state = hass.states.get("sensor.mock_evse_evse_state") + state = hass.states.get("sensor.evse_state") assert state assert state.state == "1" # EnergyEvseSupplyState - state = hass.states.get("sensor.mock_evse_evse_supply_state") + state = hass.states.get("sensor.evse_supply_state") assert state assert state.state == "1" set_node_attribute(matter_node, 1, 153, 1, 0) await trigger_subscription_callback(hass, matter_client) - state = hass.states.get("sensor.mock_evse_evse_supply_state") + state = hass.states.get("sensor.evse_supply_state") assert state assert state.state == "0" # EnergyEvseFaultState - state = hass.states.get("sensor.mock_evse_evse_fault_state") + state = hass.states.get("sensor.evse_fault_state") assert state assert state.state == "0" set_node_attribute(matter_node, 1, 153, 1, 2) await trigger_subscription_callback(hass, matter_client) - state = hass.states.get("sensor.mock_evse_evse_fault_state") + state = hass.states.get("sensor.evse_fault_state") assert state assert state.state == "2" From 7cc67655752e285f4cfdf906ebd2961c329f66cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Fri, 20 Dec 2024 09:01:57 +0100 Subject: [PATCH 30/58] Update evse_charging.json --- tests/components/matter/fixtures/nodes/evse_charging.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/components/matter/fixtures/nodes/evse_charging.json b/tests/components/matter/fixtures/nodes/evse_charging.json index d1664a203e2bab..d45f0d419b956f 100644 --- a/tests/components/matter/fixtures/nodes/evse_charging.json +++ b/tests/components/matter/fixtures/nodes/evse_charging.json @@ -40,16 +40,16 @@ "0/40/0": 18, "0/40/1": "TEST_VENDOR", "0/40/2": 65521, - "0/40/3": "Mock EVSE", + "0/40/3": "evse", "0/40/4": 32769, - "0/40/5": "Mock EVSE", + "0/40/5": "evse", "0/40/6": "**REDACTED**", "0/40/7": 0, "0/40/8": "TEST_VERSION", "0/40/9": 1, "0/40/10": "1.0", "0/40/15": "TEST_SN", - "0/40/18": "mock-evse-charging", + "0/40/18": "evse", "0/40/19": { "0": 3, "1": 65535 From aebaa3e9e1e5c0710c10bad1530a40225e950889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Fri, 20 Dec 2024 11:24:08 +0100 Subject: [PATCH 31/58] Update sensor.py --- homeassistant/components/matter/sensor.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 47458fabad3b31..a9e54b5a2ea120 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -726,6 +726,7 @@ def _update_from_device(self) -> None: entity_class=MatterSensor, required_attributes=(clusters.EnergyEvse.Attributes.State,), ), + ''' MatterDiscoverySchema( platform=Platform.SENSOR, entity_description=MatterSensorEntityDescription( @@ -806,4 +807,5 @@ def _update_from_device(self) -> None: entity_class=MatterSensor, required_attributes=(clusters.EnergyEvse.Attributes.UserMaximumChargeCurrent,), ), + ''' ] From 2fdbba954eea0aafc46d5d06f60e972ec3055702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Fri, 20 Dec 2024 12:47:46 +0100 Subject: [PATCH 32/58] Update test_sensor.py --- tests/components/matter/test_sensor.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/components/matter/test_sensor.py b/tests/components/matter/test_sensor.py index feaba9d6c1b3a7..2eb24b1cd2d195 100644 --- a/tests/components/matter/test_sensor.py +++ b/tests/components/matter/test_sensor.py @@ -343,37 +343,37 @@ async def test_evse_sensor( ) -> None: """Test evse sensor.""" # EnergyEvseState - state = hass.states.get("sensor.evse_state") + state = hass.states.get("sensor.evse_none") assert state - assert state.state == "3" + assert state.state == "PluggedIn, Charging" set_node_attribute(matter_node, 1, 153, 0, 1) await trigger_subscription_callback(hass, matter_client) - state = hass.states.get("sensor.evse_state") + state = hass.states.get("sensor.evse_none") assert state - assert state.state == "1" + assert state.state == "PluggedIn, NoDemand" # EnergyEvseSupplyState - state = hass.states.get("sensor.evse_supply_state") + state = hass.states.get("sensor.evse_none_2") assert state - assert state.state == "1" + assert state.state == "Charging Enabled" set_node_attribute(matter_node, 1, 153, 1, 0) await trigger_subscription_callback(hass, matter_client) - state = hass.states.get("sensor.evse_supply_state") + state = hass.states.get("sensor.evse_none_2") assert state - assert state.state == "0" + assert state.state == "Disabled" # EnergyEvseFaultState - state = hass.states.get("sensor.evse_fault_state") + state = hass.states.get("sensor.evse_none_3") assert state - assert state.state == "0" + assert state.state == "No Error" - set_node_attribute(matter_node, 1, 153, 1, 2) + set_node_attribute(matter_node, 1, 153, 2, 4) await trigger_subscription_callback(hass, matter_client) - state = hass.states.get("sensor.evse_fault_state") + state = hass.states.get("sensor.evse_none_3") assert state - assert state.state == "2" + assert state.state == "Over Current" From 26e9363fbf25212cf7a0a101ab2223012b7371da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Fri, 20 Dec 2024 12:49:45 +0100 Subject: [PATCH 33/58] Update strings.json --- homeassistant/components/matter/strings.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/matter/strings.json b/homeassistant/components/matter/strings.json index b8a2f141542767..37de52c89c70ec 100644 --- a/homeassistant/components/matter/strings.json +++ b/homeassistant/components/matter/strings.json @@ -95,10 +95,10 @@ "name": "Reset filter condition" }, "enable_charging": { - "name": "[%key:common::action::start%]" + "name": "Enable charging" }, "disable_charging": { - "name": "[%key:common::action::stop%]" + "name": "Disable charging" } }, "climate": { From 5128238d08b9ccd47299c346cdab749dcbdb0a46 Mon Sep 17 00:00:00 2001 From: Ludovic BOUE Date: Fri, 20 Dec 2024 16:05:15 +0100 Subject: [PATCH 34/58] EnergyEvse.Attributes.State --- homeassistant/components/matter/sensor.py | 23 + .../matter/fixtures/nodes/evse_charging.json | 580 ++++++++++++++++++ tests/components/matter/test_sensor.py | 20 + 3 files changed, 623 insertions(+) create mode 100644 tests/components/matter/fixtures/nodes/evse_charging.json diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 847c9439b81c73..eb48532dbdfa40 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -72,6 +72,17 @@ } +EVSE_STATE_MAP = { + clusters.EnergyEvse.Enums.StateEnum.kNotPluggedIn: "NotPluggedIn", + clusters.EnergyEvse.Enums.StateEnum.kPluggedInNoDemand: "PluggedIn, NoDemand", + clusters.EnergyEvse.Enums.StateEnum.kPluggedInDemand: "PluggedIn, Demand", + clusters.EnergyEvse.Enums.StateEnum.kPluggedInCharging: "PluggedIn, Charging", + clusters.EnergyEvse.Enums.StateEnum.kPluggedInDischarging: "PluggedIn, Discharging", + clusters.EnergyEvse.Enums.StateEnum.kSessionEnding: "SessionEnding", + clusters.EnergyEvse.Enums.StateEnum.kFault: "Fault", +} + + async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, @@ -675,4 +686,16 @@ def _update_from_device(self) -> None: clusters.OperationalState.Attributes.OperationalStateList, ), ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="EnergyEvseState", + translation_key="evse_state", + device_class=SensorDeviceClass.ENUM, + options=list(EVSE_STATE_MAP.values()), + measurement_to_ha=EVSE_STATE_MAP.get, + ), + entity_class=MatterSensor, + required_attributes=(clusters.EnergyEvse.Attributes.State,), + ), ] diff --git a/tests/components/matter/fixtures/nodes/evse_charging.json b/tests/components/matter/fixtures/nodes/evse_charging.json new file mode 100644 index 00000000000000..d45f0d419b956f --- /dev/null +++ b/tests/components/matter/fixtures/nodes/evse_charging.json @@ -0,0 +1,580 @@ +{ + "node_id": 23, + "date_commissioned": "2024-12-17T18:14:53.210190", + "last_interview": "2024-12-17T18:14:53.211611", + "interview_version": 6, + "available": true, + "is_bridge": false, + "attributes": { + "0/29/0": [ + { + "0": 22, + "1": 1 + } + ], + "0/29/1": [29, 31, 40, 43, 44, 45, 48, 49, 51, 60, 62, 63], + "0/29/2": [], + "0/29/3": [1], + "0/29/65532": 0, + "0/29/65533": 2, + "0/29/65528": [], + "0/29/65529": [], + "0/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533], + "0/31/0": [ + { + "1": 5, + "2": 2, + "3": [112233], + "4": null, + "254": 1 + } + ], + "0/31/2": 4, + "0/31/3": 3, + "0/31/4": 4, + "0/31/65532": 0, + "0/31/65533": 2, + "0/31/65528": [], + "0/31/65529": [], + "0/31/65531": [0, 2, 3, 4, 65528, 65529, 65531, 65532, 65533], + "0/40/0": 18, + "0/40/1": "TEST_VENDOR", + "0/40/2": 65521, + "0/40/3": "evse", + "0/40/4": 32769, + "0/40/5": "evse", + "0/40/6": "**REDACTED**", + "0/40/7": 0, + "0/40/8": "TEST_VERSION", + "0/40/9": 1, + "0/40/10": "1.0", + "0/40/15": "TEST_SN", + "0/40/18": "evse", + "0/40/19": { + "0": 3, + "1": 65535 + }, + "0/40/21": 17039360, + "0/40/22": 1, + "0/40/65532": 0, + "0/40/65533": 4, + "0/40/65528": [], + "0/40/65529": [], + "0/40/65531": [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 18, 19, 21, 22, 65528, 65529, 65531, + 65532, 65533 + ], + "0/43/0": "en-US", + "0/43/1": [ + "en-US", + "de-DE", + "fr-FR", + "en-GB", + "es-ES", + "zh-CN", + "it-IT", + "ja-JP" + ], + "0/43/65532": 0, + "0/43/65533": 1, + "0/43/65528": [], + "0/43/65529": [], + "0/43/65531": [0, 1, 65528, 65529, 65531, 65532, 65533], + "0/44/0": 0, + "0/44/65532": 0, + "0/44/65533": 1, + "0/44/65528": [], + "0/44/65529": [], + "0/44/65531": [0, 65528, 65529, 65531, 65532, 65533], + "0/45/65532": 0, + "0/45/65533": 1, + "0/45/65528": [], + "0/45/65529": [], + "0/45/65531": [65528, 65529, 65531, 65532, 65533], + "0/48/0": 0, + "0/48/1": { + "0": 60, + "1": 900 + }, + "0/48/2": 0, + "0/48/3": 2, + "0/48/4": true, + "0/48/65532": 0, + "0/48/65533": 2, + "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": "ZW5zMzM=", + "1": true + } + ], + "0/49/4": true, + "0/49/5": null, + "0/49/6": null, + "0/49/7": null, + "0/49/8": [0], + "0/49/65532": 4, + "0/49/65533": 2, + "0/49/65528": [], + "0/49/65529": [], + "0/49/65531": [0, 1, 4, 5, 6, 7, 8, 65528, 65529, 65531, 65532, 65533], + "0/51/0": [ + { + "0": "docker0", + "1": false, + "2": null, + "3": null, + "4": "AkI9NTnB", + "5": ["rBEAAQ=="], + "6": [""], + "7": 0 + }, + { + "0": "ens33", + "1": true, + "2": null, + "3": null, + "4": "AAwp/F0T", + "5": ["wKgBpw=="], + "6": [ + "KgEOCgKzOZCNB+q+Uz0I9w==", + "KgEOCgKzOZC/O1Ew1WvS4A==", + "/oAAAAAAAADml3Ozl7GZug==" + ], + "7": 2 + }, + { + "0": "lo", + "1": true, + "2": null, + "3": null, + "4": "AAAAAAAA", + "5": ["fwAAAQ=="], + "6": ["AAAAAAAAAAAAAAAAAAAAAQ=="], + "7": 0 + } + ], + "0/51/1": 1, + "0/51/2": 10129, + "0/51/8": true, + "0/51/65532": 0, + "0/51/65533": 2, + "0/51/65528": [2], + "0/51/65529": [0, 1], + "0/51/65531": [0, 1, 2, 8, 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, 2], + "0/60/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533], + "0/62/0": [ + { + "1": "FTABAQEkAgE3AyQTAhgmBIAigScmBYAlTTo3BiQVASQRFxgkBwEkCAEwCUEECp4PASYUFk/DwQqGNBikYdiBRDJZbrfF4AYK8Y9jOeIpx7Xy+giJhmTpAVZ662hwszsFDGULGY/owXtMrqTxEDcKNQEoARgkAgE2AwQCBAEYMAQUqBmxO16fPQhbf33Gb2XwQ+NkXpswBRTx8+4bdkuqlxInfB5LXkhRBBvS2hgwC0A8aefsLm663Vuy+TkSvn/oLhRqt2phrG+i5aM5o15xiWDjnNVdUYpT09+K0mgVoMdFuFsmoWQxQh6jahaFJzUgGA==", + "2": "FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQTAhgkBwEkCAEwCUEEGp55xGRB0FBQ3Yw7ayQSzVtYA0BtCJFm9vRRcdr+nk0cuGX6zrUowSYOO/qiRBEACcCNNSqKh+DpRm2uVLOtaDcKNQEpARgkAmAwBBTx8+4bdkuqlxInfB5LXkhRBBvS2jAFFIxTG68U5WQVsk8AtvSQyeK3KLqPGDALQIw/6q5ILMNdOMcSif8HNbEgpjBeaBMfUpzOJFCRPM16sv1xiq3mALZj0u+iG8lUJEvDJOFKPoBvsOubwIwRgAQY", + "254": 1 + } + ], + "0/62/1": [ + { + "1": "BMeyHMXjJpVWF9saehBu7pZLTwdopKZTl5JdhU0/ozZ/sk1paVFE1U8OtuZqM/S/4W/fnkCnUrQ/Xcs7Ddy0hPE=", + "2": 65521, + "3": 1, + "4": 23, + "5": "HA_test", + "254": 1 + }, + { + "1": "BBF47gm4BEBA6LXQluAHjn6P3+MZKrhuMcJligg1xcBM7X++F7GsZFh4hYAhdmD9HHwhtZxH2c85aAzbpikViwI=", + "2": 65521, + "3": 1, + "4": 100, + "5": "", + "254": 2 + } + ], + "0/62/2": 16, + "0/62/3": 2, + "0/62/4": [ + "FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQUARgkBwEkCAEwCUEEx7IcxeMmlVYX2xp6EG7ulktPB2ikplOXkl2FTT+jNn+yTWlpUUTVTw625moz9L/hb9+eQKdStD9dyzsN3LSE8TcKNQEpARgkAmAwBBSMUxuvFOVkFbJPALb0kMnityi6jzAFFIxTG68U5WQVsk8AtvSQyeK3KLqPGDALQPBVUg+OBUWl1pe/k55ZigAZl3lfBP1Qd5zQP4AUB45mNTzdli8DRCj+h7cIs3JHQQPlUaRvG5xUoBZ+C7Gg2sQY", + "FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQUARgkBwEkCAEwCUEEEXjuCbgEQEDotdCW4AeOfo/f4xkquG4xwmWKCDXFwEztf74XsaxkWHiFgCF2YP0cfCG1nEfZzzloDNumKRWLAjcKNQEpARgkAmAwBBQD3rx0jOdkiCPt06hxW7Z2jJBPXTAFFAPevHSM52SII+3TqHFbtnaMkE9dGDALQL+L3Zc6En6Ionk6WIz+lM50iwOEzTi9VwyYQRUdtO99T8jRX52+Olh6zcUtWQuYO2XYiH2OZ8lM4guqqnS8U4UY" + ], + "0/62/5": 1, + "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": 4, + "0/63/3": 3, + "0/63/65532": 0, + "0/63/65533": 2, + "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": 0, + "1/3/65532": 0, + "1/3/65533": 5, + "1/3/65528": [], + "1/3/65529": [0, 64], + "1/3/65531": [0, 1, 65528, 65529, 65531, 65532, 65533], + "1/29/0": [ + { + "0": 1293, + "1": 1 + }, + { + "0": 1292, + "1": 1 + }, + { + "0": 1296, + "1": 1 + }, + { + "0": 17, + "1": 1 + } + ], + "1/29/1": [3, 29, 47, 144, 145, 152, 153, 156, 157, 159], + "1/29/2": [], + "1/29/3": [], + "1/29/65532": 0, + "1/29/65533": 2, + "1/29/65528": [], + "1/29/65529": [], + "1/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533], + "1/47/0": 1, + "1/47/1": 0, + "1/47/2": "Primary Mains Power", + "1/47/5": 0, + "1/47/7": 230000, + "1/47/8": 32000, + "1/47/31": [1], + "1/47/65532": 1, + "1/47/65533": 3, + "1/47/65528": [], + "1/47/65529": [], + "1/47/65531": [0, 1, 2, 5, 7, 8, 31, 65528, 65529, 65531, 65532, 65533], + "1/144/0": 2, + "1/144/1": 3, + "1/144/2": [ + { + "0": 5, + "1": true, + "2": -50000000, + "3": 50000000, + "4": [ + { + "0": -50000000, + "1": -10000000, + "2": 5000, + "3": 2000, + "4": 3000 + }, + { + "0": -9999999, + "1": 9999999, + "2": 1000, + "3": 100, + "4": 500 + }, + { + "0": 10000000, + "1": 50000000, + "2": 5000, + "3": 2000, + "4": 3000 + } + ] + }, + { + "0": 2, + "1": true, + "2": -100000, + "3": 100000, + "4": [ + { + "0": -100000, + "1": -5000, + "2": 5000, + "3": 2000, + "4": 3000 + }, + { + "0": -4999, + "1": 4999, + "2": 1000, + "3": 100, + "4": 500 + }, + { + "0": 5000, + "1": 100000, + "2": 5000, + "3": 2000, + "4": 3000 + } + ] + }, + { + "0": 1, + "1": true, + "2": -500000, + "3": 500000, + "4": [ + { + "0": -500000, + "1": -100000, + "2": 5000, + "3": 2000, + "4": 3000 + }, + { + "0": -99999, + "1": 99999, + "2": 1000, + "3": 100, + "4": 500 + }, + { + "0": 100000, + "1": 500000, + "2": 5000, + "3": 2000, + "4": 3000 + } + ] + } + ], + "1/144/3": [], + "1/144/4": null, + "1/144/5": null, + "1/144/6": null, + "1/144/7": null, + "1/144/8": null, + "1/144/9": null, + "1/144/10": null, + "1/144/11": null, + "1/144/12": null, + "1/144/13": null, + "1/144/14": null, + "1/144/15": [ + { + "0": 1, + "1": 100000 + } + ], + "1/144/16": [ + { + "0": 1, + "1": 100000 + } + ], + "1/144/17": null, + "1/144/18": null, + "1/144/65532": 31, + "1/144/65533": 1, + "1/144/65528": [], + "1/144/65529": [], + "1/144/65531": [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 65528, + 65529, 65531, 65532, 65533 + ], + "1/145/0": { + "0": 14, + "1": true, + "2": 0, + "3": 1000000000000000, + "4": [ + { + "0": 98440650424323, + "1": 98442759724168, + "2": 0, + "3": 0, + "5": 140728898420739, + "6": 98440650424355 + } + ] + }, + "1/145/1": null, + "1/145/2": null, + "1/145/3": null, + "1/145/4": null, + "1/145/5": { + "0": 0, + "1": 0, + "2": 0, + "3": 0 + }, + "1/145/65532": 15, + "1/145/65533": 1, + "1/145/65528": [], + "1/145/65529": [], + "1/145/65531": [0, 1, 2, 3, 4, 5, 65528, 65529, 65531, 65532, 65533], + "1/152/0": 0, + "1/152/1": false, + "1/152/2": 1, + "1/152/3": 1200000, + "1/152/4": 7600000, + "1/152/5": null, + "1/152/6": null, + "1/152/7": 0, + "1/152/65532": 123, + "1/152/65533": 4, + "1/152/65528": [], + "1/152/65529": [0, 1, 2, 3, 4, 5, 6, 7], + "1/152/65531": [0, 1, 2, 3, 4, 5, 6, 7, 65528, 65529, 65531, 65532, 65533], + "1/153/0": 3, + "1/153/1": 1, + "1/153/2": 0, + "1/153/3": null, + "1/153/5": 32000, + "1/153/6": 2000, + "1/153/7": 30000, + "1/153/9": 32000, + "1/153/10": 600, + "1/153/35": null, + "1/153/36": null, + "1/153/37": null, + "1/153/38": null, + "1/153/39": null, + "1/153/64": 2, + "1/153/65": 0, + "1/153/66": 0, + "1/153/65532": 9, + "1/153/65533": 3, + "1/153/65528": [0], + "1/153/65529": [1, 2, 5, 6, 7, 4], + "1/153/65531": [ + 0, 1, 2, 3, 5, 6, 7, 9, 10, 35, 36, 37, 38, 39, 64, 65, 66, 65528, 65529, + 65531, 65532, 65533 + ], + "1/156/65532": 1, + "1/156/65533": 1, + "1/156/65528": [], + "1/156/65529": [], + "1/156/65531": [65528, 65529, 65531, 65532, 65533], + "1/157/0": [ + { + "0": "Manual", + "1": 0, + "2": [ + { + "1": 16384 + } + ] + }, + { + "0": "Auto-scheduled", + "1": 1, + "2": [ + { + "1": 16385 + } + ] + }, + { + "0": "Solar", + "1": 2, + "2": [ + { + "1": 16386 + } + ] + }, + { + "0": "Auto-scheduled with Solar charging", + "1": 3, + "2": [ + { + "1": 16385 + }, + { + "1": 16386 + } + ] + } + ], + "1/157/1": 1, + "1/157/65532": 0, + "1/157/65533": 2, + "1/157/65528": [1], + "1/157/65529": [0], + "1/157/65531": [0, 1, 65528, 65529, 65531, 65532, 65533], + "1/159/0": [ + { + "0": "No energy management (forecast only)", + "1": 0, + "2": [ + { + "1": 16384 + } + ] + }, + { + "0": "Device optimizes (no local or grid control)", + "1": 1, + "2": [ + { + "1": 16385 + } + ] + }, + { + "0": "Optimized within building", + "1": 2, + "2": [ + { + "1": 16386 + }, + { + "1": 16385 + } + ] + }, + { + "0": "Optimized for grid", + "1": 3, + "2": [ + { + "1": 16385 + }, + { + "1": 16387 + } + ] + }, + { + "0": "Optimized for grid and building", + "1": 4, + "2": [ + { + "1": 16386 + }, + { + "1": 16385 + }, + { + "1": 16387 + } + ] + } + ], + "1/159/1": 3, + "1/159/65532": 0, + "1/159/65533": 2, + "1/159/65528": [1], + "1/159/65529": [0], + "1/159/65531": [0, 1, 65528, 65529, 65531, 65532, 65533] + }, + "attribute_subscriptions": [] +} diff --git a/tests/components/matter/test_sensor.py b/tests/components/matter/test_sensor.py index 3215ec581161f0..bb5eb0a86c8615 100644 --- a/tests/components/matter/test_sensor.py +++ b/tests/components/matter/test_sensor.py @@ -333,3 +333,23 @@ async def test_operational_state_sensor( state = hass.states.get("sensor.dishwasher_operational_state") assert state assert state.state == "extra_state" + + +@pytest.mark.parametrize("node_fixture", ["evse_charging"]) +async def test_evse_sensor( + hass: HomeAssistant, + matter_client: MagicMock, + matter_node: MatterNode, +) -> None: + """Test evse sensor.""" + # EnergyEvseState + state = hass.states.get("sensor.evse_none") + assert state + assert state.state == "PluggedIn, Charging" + + set_node_attribute(matter_node, 1, 153, 0, 1) + await trigger_subscription_callback(hass, matter_client) + + state = hass.states.get("sensor.evse_none") + assert state + assert state.state == "PluggedIn, NoDemand" From 03933cddfa3c0f5ab9dd1262d098d3f7b8e98a7d Mon Sep 17 00:00:00 2001 From: Ludovic BOUE Date: Fri, 20 Dec 2024 16:45:40 +0100 Subject: [PATCH 35/58] EnergyEvse.Attributes.SupplyState --- homeassistant/components/matter/sensor.py | 39 ++++++++++++++++++++++- tests/components/matter/test_sensor.py | 12 +++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index eb48532dbdfa40..3f213eac6a90af 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -71,7 +71,6 @@ clusters.OperationalState.Enums.OperationalStateEnum.kError: "error", } - EVSE_STATE_MAP = { clusters.EnergyEvse.Enums.StateEnum.kNotPluggedIn: "NotPluggedIn", clusters.EnergyEvse.Enums.StateEnum.kPluggedInNoDemand: "PluggedIn, NoDemand", @@ -82,6 +81,32 @@ clusters.EnergyEvse.Enums.StateEnum.kFault: "Fault", } +EVSE_SUPPLY_STATE_MAP = { + clusters.EnergyEvse.Enums.SupplyStateEnum.kDisabled: "Disabled", + clusters.EnergyEvse.Enums.SupplyStateEnum.kChargingEnabled: "Charging Enabled", + clusters.EnergyEvse.Enums.SupplyStateEnum.kDischargingEnabled: "Discharging Enabled", + clusters.EnergyEvse.Enums.SupplyStateEnum.kDisabledDiagnostics: "Disabled Diagnostics", +} + +EVSE_FAULT_STATE_MAP = { + clusters.EnergyEvse.Enums.FaultStateEnum.kNoError: "No Error", + clusters.EnergyEvse.Enums.FaultStateEnum.kMeterFailure: "Meter Failure", + clusters.EnergyEvse.Enums.FaultStateEnum.kOverVoltage: "Over Voltage", + clusters.EnergyEvse.Enums.FaultStateEnum.kUnderVoltage: "Under Voltage", + clusters.EnergyEvse.Enums.FaultStateEnum.kOverCurrent: "Over Current", + clusters.EnergyEvse.Enums.FaultStateEnum.kContactWetFailure: "Contact Wet Failure", + clusters.EnergyEvse.Enums.FaultStateEnum.kContactDryFailure: "Contact Dry Failure", + clusters.EnergyEvse.Enums.FaultStateEnum.kPowerLoss: "Power Loss", + clusters.EnergyEvse.Enums.FaultStateEnum.kPowerQuality: "Power Quality", + clusters.EnergyEvse.Enums.FaultStateEnum.kPilotShortCircuit: "Pilot Short Circuit", + clusters.EnergyEvse.Enums.FaultStateEnum.kEmergencyStop: "Emergency Stop", + clusters.EnergyEvse.Enums.FaultStateEnum.kEVDisconnected: "EV Disconnected", + clusters.EnergyEvse.Enums.FaultStateEnum.kWrongPowerSupply: "Wrong Power Supply", + clusters.EnergyEvse.Enums.FaultStateEnum.kLiveNeutralSwap: "Live Neutral Swap", + clusters.EnergyEvse.Enums.FaultStateEnum.kOverTemperature: "Over Temperature", + clusters.EnergyEvse.Enums.FaultStateEnum.kOther: "Unknown", +} + async def async_setup_entry( hass: HomeAssistant, @@ -698,4 +723,16 @@ def _update_from_device(self) -> None: entity_class=MatterSensor, required_attributes=(clusters.EnergyEvse.Attributes.State,), ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="EnergyEvseSupplyState", + translation_key="evse_supply_state", + device_class=SensorDeviceClass.ENUM, + options=list(EVSE_SUPPLY_STATE_MAP.values()), + measurement_to_ha=EVSE_SUPPLY_STATE_MAP.get, + ), + entity_class=MatterSensor, + required_attributes=(clusters.EnergyEvse.Attributes.SupplyState,), + ), ] diff --git a/tests/components/matter/test_sensor.py b/tests/components/matter/test_sensor.py index bb5eb0a86c8615..f29e3c45373ae0 100644 --- a/tests/components/matter/test_sensor.py +++ b/tests/components/matter/test_sensor.py @@ -353,3 +353,15 @@ async def test_evse_sensor( state = hass.states.get("sensor.evse_none") assert state assert state.state == "PluggedIn, NoDemand" + + # EnergyEvseSupplyState + state = hass.states.get("sensor.evse_none_2") + assert state + assert state.state == "Charging Enabled" + + set_node_attribute(matter_node, 1, 153, 1, 0) + await trigger_subscription_callback(hass, matter_client) + + state = hass.states.get("sensor.evse_none_2") + assert state + assert state.state == "Disabled" From 7b3905e5415fdb3a72b6ea7cd9697398299f8716 Mon Sep 17 00:00:00 2001 From: Ludovic BOUE Date: Fri, 20 Dec 2024 16:54:59 +0100 Subject: [PATCH 36/58] EnergyEvse.Attributes.FaultState --- homeassistant/components/matter/sensor.py | 12 ++++++++++++ tests/components/matter/test_sensor.py | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 3f213eac6a90af..6a79b8aa55b701 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -735,4 +735,16 @@ def _update_from_device(self) -> None: entity_class=MatterSensor, required_attributes=(clusters.EnergyEvse.Attributes.SupplyState,), ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="EnergyEvseFaultState", + translation_key="evse_fault_state", + device_class=SensorDeviceClass.ENUM, + options=list(EVSE_FAULT_STATE_MAP.values()), + measurement_to_ha=EVSE_FAULT_STATE_MAP.get, + ), + entity_class=MatterSensor, + required_attributes=(clusters.EnergyEvse.Attributes.FaultState,), + ), ] diff --git a/tests/components/matter/test_sensor.py b/tests/components/matter/test_sensor.py index f29e3c45373ae0..2eb24b1cd2d195 100644 --- a/tests/components/matter/test_sensor.py +++ b/tests/components/matter/test_sensor.py @@ -365,3 +365,15 @@ async def test_evse_sensor( state = hass.states.get("sensor.evse_none_2") assert state assert state.state == "Disabled" + + # EnergyEvseFaultState + state = hass.states.get("sensor.evse_none_3") + assert state + assert state.state == "No Error" + + set_node_attribute(matter_node, 1, 153, 2, 4) + await trigger_subscription_callback(hass, matter_client) + + state = hass.states.get("sensor.evse_none_3") + assert state + assert state.state == "Over Current" From 1108486cb91ceae13a417700f49ba835f8225938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Fri, 20 Dec 2024 17:17:09 +0100 Subject: [PATCH 37/58] Update sensor.py --- homeassistant/components/matter/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index a9e54b5a2ea120..809f8fa56d24b8 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -763,7 +763,7 @@ def _update_from_device(self) -> None: measurement_to_ha=lambda x: x / 1000, ), entity_class=MatterSensor, - required_attributes=(clusters.EnergyEvse.Attributes.CircuitCapacity), + required_attributes=(clusters.EnergyEvse.Attributes.CircuitCapacity,), ), MatterDiscoverySchema( platform=Platform.SENSOR, From c379aea30cbfb50e929b5cd91e495781eed330e8 Mon Sep 17 00:00:00 2001 From: Ludovic BOUE Date: Fri, 20 Dec 2024 17:45:43 +0100 Subject: [PATCH 38/58] EnergyEvse.Attributes.CircuitCapacity --- homeassistant/components/matter/sensor.py | 14 ++++++++++++++ tests/components/matter/test_sensor.py | 12 ++++++++++++ 2 files changed, 26 insertions(+) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 6a79b8aa55b701..2f2911c414f344 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -747,4 +747,18 @@ def _update_from_device(self) -> None: entity_class=MatterSensor, required_attributes=(clusters.EnergyEvse.Attributes.FaultState,), ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="EnergyEvseCircuitCapacity", + device_class=SensorDeviceClass.CURRENT, + entity_category=EntityCategory.DIAGNOSTIC, + native_unit_of_measurement=UnitOfElectricCurrent.MILLIAMPERE, + suggested_unit_of_measurement=UnitOfElectricCurrent.AMPERE, + suggested_display_precision=2, + state_class=SensorStateClass.MEASUREMENT, + ), + entity_class=MatterSensor, + required_attributes=(clusters.EnergyEvse.Attributes.CircuitCapacity,), + ), ] diff --git a/tests/components/matter/test_sensor.py b/tests/components/matter/test_sensor.py index 2eb24b1cd2d195..c3039f8ff6726c 100644 --- a/tests/components/matter/test_sensor.py +++ b/tests/components/matter/test_sensor.py @@ -377,3 +377,15 @@ async def test_evse_sensor( state = hass.states.get("sensor.evse_none_3") assert state assert state.state == "Over Current" + + # EnergyEvseCircuitCapacity + state = hass.states.get("sensor.evse_current_2") + assert state + assert state.state == "32.0" + + set_node_attribute(matter_node, 1, 153, 5, 63000) + await trigger_subscription_callback(hass, matter_client) + + state = hass.states.get("sensor.evse_current_2") + assert state + assert state.state == "63.0" From c118b1f4cea57332ec0464559085fd0aca342829 Mon Sep 17 00:00:00 2001 From: Ludovic BOUE Date: Fri, 20 Dec 2024 17:59:09 +0100 Subject: [PATCH 39/58] EnergyEvse.Attributes.MinimumChargeCurrent --- homeassistant/components/matter/sensor.py | 14 ++++++++++++++ tests/components/matter/test_sensor.py | 12 ++++++++++++ 2 files changed, 26 insertions(+) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 2f2911c414f344..754b25017fbb1a 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -761,4 +761,18 @@ def _update_from_device(self) -> None: entity_class=MatterSensor, required_attributes=(clusters.EnergyEvse.Attributes.CircuitCapacity,), ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="EnergyEvseMinimumChargeCurrent", + device_class=SensorDeviceClass.CURRENT, + entity_category=EntityCategory.DIAGNOSTIC, + native_unit_of_measurement=UnitOfElectricCurrent.MILLIAMPERE, + suggested_unit_of_measurement=UnitOfElectricCurrent.AMPERE, + suggested_display_precision=2, + state_class=SensorStateClass.MEASUREMENT, + ), + entity_class=MatterSensor, + required_attributes=(clusters.EnergyEvse.Attributes.MinimumChargeCurrent,), + ), ] diff --git a/tests/components/matter/test_sensor.py b/tests/components/matter/test_sensor.py index c3039f8ff6726c..259e805f690dff 100644 --- a/tests/components/matter/test_sensor.py +++ b/tests/components/matter/test_sensor.py @@ -389,3 +389,15 @@ async def test_evse_sensor( state = hass.states.get("sensor.evse_current_2") assert state assert state.state == "63.0" + + # EnergyEvseMinimumChargeCurrent + state = hass.states.get("sensor.evse_current_3") + assert state + assert state.state == "2.0" + + set_node_attribute(matter_node, 1, 153, 6, 5000) + await trigger_subscription_callback(hass, matter_client) + + state = hass.states.get("sensor.evse_current_3") + assert state + assert state.state == "5.0" From 45f0f4019d5b42548c1e095dc66c1112ee3a4a3b Mon Sep 17 00:00:00 2001 From: Ludovic BOUE Date: Fri, 20 Dec 2024 18:18:03 +0100 Subject: [PATCH 40/58] EnergyEvse.Attributes.MaximumChargeCurrent --- homeassistant/components/matter/sensor.py | 14 ++++++++++++++ tests/components/matter/test_sensor.py | 12 ++++++++++++ 2 files changed, 26 insertions(+) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 754b25017fbb1a..0bfbc87e61a76d 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -775,4 +775,18 @@ def _update_from_device(self) -> None: entity_class=MatterSensor, required_attributes=(clusters.EnergyEvse.Attributes.MinimumChargeCurrent,), ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="EnergyEvseMaximumChargeCurrent", + device_class=SensorDeviceClass.CURRENT, + entity_category=EntityCategory.DIAGNOSTIC, + native_unit_of_measurement=UnitOfElectricCurrent.MILLIAMPERE, + suggested_unit_of_measurement=UnitOfElectricCurrent.AMPERE, + suggested_display_precision=2, + state_class=SensorStateClass.MEASUREMENT, + ), + entity_class=MatterSensor, + required_attributes=(clusters.EnergyEvse.Attributes.MaximumChargeCurrent,), + ), ] diff --git a/tests/components/matter/test_sensor.py b/tests/components/matter/test_sensor.py index 259e805f690dff..87f42f69310315 100644 --- a/tests/components/matter/test_sensor.py +++ b/tests/components/matter/test_sensor.py @@ -401,3 +401,15 @@ async def test_evse_sensor( state = hass.states.get("sensor.evse_current_3") assert state assert state.state == "5.0" + + # EnergyEvseMaximumChargeCurrent + state = hass.states.get("sensor.evse_current_4") + assert state + assert state.state == "30.0" + + set_node_attribute(matter_node, 1, 153, 7, 20000) + await trigger_subscription_callback(hass, matter_client) + + state = hass.states.get("sensor.evse_current_4") + assert state + assert state.state == "20.0" From 4f3dc0a81c109e34aa7da1e1c2439d2052514514 Mon Sep 17 00:00:00 2001 From: Ludovic BOUE Date: Fri, 20 Dec 2024 18:52:17 +0100 Subject: [PATCH 41/58] EnergyEvse.Attributes.UserMaximumChargeCurrent --- homeassistant/components/matter/sensor.py | 14 ++++++++++++++ tests/components/matter/test_sensor.py | 12 ++++++++++++ 2 files changed, 26 insertions(+) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 0bfbc87e61a76d..4c0969cc775758 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -789,4 +789,18 @@ def _update_from_device(self) -> None: entity_class=MatterSensor, required_attributes=(clusters.EnergyEvse.Attributes.MaximumChargeCurrent,), ), + MatterDiscoverySchema( + platform=Platform.SENSOR, + entity_description=MatterSensorEntityDescription( + key="EnergyEvseUserMaximumChargeCurrent", + device_class=SensorDeviceClass.CURRENT, + entity_category=EntityCategory.DIAGNOSTIC, + native_unit_of_measurement=UnitOfElectricCurrent.MILLIAMPERE, + suggested_unit_of_measurement=UnitOfElectricCurrent.AMPERE, + suggested_display_precision=2, + state_class=SensorStateClass.MEASUREMENT, + ), + entity_class=MatterSensor, + required_attributes=(clusters.EnergyEvse.Attributes.UserMaximumChargeCurrent,), + ), ] diff --git a/tests/components/matter/test_sensor.py b/tests/components/matter/test_sensor.py index 87f42f69310315..36580ee776deea 100644 --- a/tests/components/matter/test_sensor.py +++ b/tests/components/matter/test_sensor.py @@ -413,3 +413,15 @@ async def test_evse_sensor( state = hass.states.get("sensor.evse_current_4") assert state assert state.state == "20.0" + + # EnergyEvseMaximumChargeCurrent + state = hass.states.get("sensor.evse_current_5") + assert state + assert state.state == "32.0" + + set_node_attribute(matter_node, 1, 153, 9, 63000) + await trigger_subscription_callback(hass, matter_client) + + state = hass.states.get("sensor.evse_current_5") + assert state + assert state.state == "63.0" From 257c12eea9768a3b2309cc3f34f330b39bf967f1 Mon Sep 17 00:00:00 2001 From: Ludovic BOUE Date: Fri, 20 Dec 2024 20:03:28 +0100 Subject: [PATCH 42/58] Buttons --- homeassistant/components/matter/button.py | 26 +++++++++++++++++++++++ tests/components/matter/test_button.py | 2 ++ 2 files changed, 28 insertions(+) diff --git a/homeassistant/components/matter/button.py b/homeassistant/components/matter/button.py index 153124a4f7ec71..afe286a90d71a8 100644 --- a/homeassistant/components/matter/button.py +++ b/homeassistant/components/matter/button.py @@ -38,6 +38,7 @@ class MatterButtonEntityDescription(ButtonEntityDescription, MatterEntityDescrip """Describe Matter Button entities.""" command: Callable[[], Any] | None = None + command_timeout: int | None = None class MatterCommandButton(MatterEntity, ButtonEntity): @@ -53,6 +54,7 @@ async def async_press(self) -> None: node_id=self._endpoint.node.node_id, endpoint_id=self._endpoint.endpoint_id, command=self.entity_description.command(), + timed_request_timeout_ms=self.entity_description.command_timeout, ) @@ -147,4 +149,28 @@ async def async_press(self) -> None: value_contains=clusters.ActivatedCarbonFilterMonitoring.Commands.ResetCondition.command_id, allow_multi=True, ), + MatterDiscoverySchema( + platform=Platform.BUTTON, + entity_description=MatterButtonEntityDescription( + key="EnergyEvseEnableChargingButton", + translation_key="enable_charging", + command=clusters.EnergyEvse.Commands.EnableCharging, + command_timeout=3000, + ), + entity_class=MatterCommandButton, + required_attributes=(clusters.EnergyEvse.Attributes.AcceptedCommandList,), + allow_multi=True, + ), + MatterDiscoverySchema( + platform=Platform.BUTTON, + entity_description=MatterButtonEntityDescription( + key="EnergyEvseDisableChargingButton", + translation_key="disable_charging", + command=clusters.EnergyEvse.Commands.Disable, + command_timeout=3000, + ), + entity_class=MatterCommandButton, + required_attributes=(clusters.EnergyEvse.Attributes.AcceptedCommandList,), + allow_multi=True, + ), ] diff --git a/tests/components/matter/test_button.py b/tests/components/matter/test_button.py index cbf62dd80c7b71..ab634f1e32d77c 100644 --- a/tests/components/matter/test_button.py +++ b/tests/components/matter/test_button.py @@ -48,6 +48,7 @@ async def test_identify_button( node_id=matter_node.node_id, endpoint_id=1, command=clusters.Identify.Commands.Identify(identifyTime=15), + timed_request_timeout_ms=None, ) @@ -79,4 +80,5 @@ async def test_operational_state_buttons( node_id=matter_node.node_id, endpoint_id=1, command=clusters.OperationalState.Commands.Pause(), + timed_request_timeout_ms=None, ) From c579194686bf9097b3d1d1a85609eeb3b1fa6ab7 Mon Sep 17 00:00:00 2001 From: Ludovic BOUE Date: Fri, 20 Dec 2024 20:08:32 +0100 Subject: [PATCH 43/58] Icons --- homeassistant/components/matter/icons.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/homeassistant/components/matter/icons.json b/homeassistant/components/matter/icons.json index adcdcd051376d8..7a7023ea77debb 100644 --- a/homeassistant/components/matter/icons.json +++ b/homeassistant/components/matter/icons.json @@ -17,6 +17,12 @@ }, "stop": { "default": "mdi:stop" + }, + "enable_charging": { + "default": "mdi:play" + }, + "disable_charging": { + "default": "mdi:stop" } }, "fan": { @@ -57,6 +63,15 @@ }, "valve_position": { "default": "mdi:valve" + }, + "evse_state": { + "default": "mdi:ev-station" + }, + "evse_supply_state": { + "default": "mdi:ev-station" + }, + "evse_fault_state": { + "default": "mdi:ev-station" } } } From f6a7cf8e7077421677ee4ebbadf7690497a0c8c9 Mon Sep 17 00:00:00 2001 From: Ludovic BOUE Date: Fri, 20 Dec 2024 20:15:25 +0100 Subject: [PATCH 44/58] Strings --- homeassistant/components/matter/strings.json | 27 ++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/homeassistant/components/matter/strings.json b/homeassistant/components/matter/strings.json index ca15538997e2b9..37de52c89c70ec 100644 --- a/homeassistant/components/matter/strings.json +++ b/homeassistant/components/matter/strings.json @@ -93,6 +93,12 @@ }, "reset_filter_condition": { "name": "Reset filter condition" + }, + "enable_charging": { + "name": "Enable charging" + }, + "disable_charging": { + "name": "Disable charging" } }, "climate": { @@ -248,6 +254,27 @@ }, "battery_replacement_description": { "name": "Battery type" + }, + "evse_state": { + "name": "State" + }, + "evse_supply_state": { + "name": "Supply state" + }, + "evse_fault_state": { + "name": "Fault state" + }, + "evse_circuit_capacity": { + "name": "Circuit capacity" + }, + "evse_charge_current": { + "name": "Charge current" + }, + "evse_max_charge_current": { + "name": "Max charge current" + }, + "evse_user_max_charge_current": { + "name": "User max charge current" } }, "switch": { From 21fcad3f06202ea93cb0cc9c92b0318f74ffe863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Fri, 20 Dec 2024 20:54:53 +0100 Subject: [PATCH 45/58] Update test_sensor.py --- tests/components/matter/test_sensor.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/components/matter/test_sensor.py b/tests/components/matter/test_sensor.py index 36580ee776deea..c6bf3777b938cc 100644 --- a/tests/components/matter/test_sensor.py +++ b/tests/components/matter/test_sensor.py @@ -343,38 +343,38 @@ async def test_evse_sensor( ) -> None: """Test evse sensor.""" # EnergyEvseState - state = hass.states.get("sensor.evse_none") + state = hass.states.get("sensor.evse_state") assert state assert state.state == "PluggedIn, Charging" set_node_attribute(matter_node, 1, 153, 0, 1) await trigger_subscription_callback(hass, matter_client) - state = hass.states.get("sensor.evse_none") + state = hass.states.get("sensor.evse_state") assert state assert state.state == "PluggedIn, NoDemand" # EnergyEvseSupplyState - state = hass.states.get("sensor.evse_none_2") + state = hass.states.get("sensor.evse_supply_state") assert state assert state.state == "Charging Enabled" set_node_attribute(matter_node, 1, 153, 1, 0) await trigger_subscription_callback(hass, matter_client) - state = hass.states.get("sensor.evse_none_2") + state = hass.states.get("sensor.evse_supply_state") assert state assert state.state == "Disabled" # EnergyEvseFaultState - state = hass.states.get("sensor.evse_none_3") + state = hass.states.get("sensor.evse_fault_state") assert state assert state.state == "No Error" set_node_attribute(matter_node, 1, 153, 2, 4) await trigger_subscription_callback(hass, matter_client) - state = hass.states.get("sensor.evse_none_3") + state = hass.states.get("sensor.evse_fault_state") assert state assert state.state == "Over Current" From a8179b27e31e692a38eddca7dd84a23c06064a72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Sun, 22 Dec 2024 21:00:16 +0100 Subject: [PATCH 46/58] Update sensor.py Move EnergyEvseFaultState to Diagnostic category --- homeassistant/components/matter/sensor.py | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index bef74e170bc57a..f4d58a31bed8a4 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -780,6 +780,7 @@ def _update_from_device(self) -> None: key="EnergyEvseFaultState", translation_key="evse_fault_state", device_class=SensorDeviceClass.ENUM, + entity_category=EntityCategory.DIAGNOSTIC, options=list(EVSE_FAULT_STATE_MAP.values()), measurement_to_ha=EVSE_FAULT_STATE_MAP.get, ), From 96f55c446e50e5941ff4536226999b59880f8847 Mon Sep 17 00:00:00 2001 From: Ludovic BOUE Date: Tue, 24 Dec 2024 15:17:02 +0100 Subject: [PATCH 47/58] Translate maps into camelcase strings --- homeassistant/components/matter/sensor.py | 54 +++++++++++------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 4c0969cc775758..4e7d6bd9c2123e 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -72,39 +72,39 @@ } EVSE_STATE_MAP = { - clusters.EnergyEvse.Enums.StateEnum.kNotPluggedIn: "NotPluggedIn", - clusters.EnergyEvse.Enums.StateEnum.kPluggedInNoDemand: "PluggedIn, NoDemand", - clusters.EnergyEvse.Enums.StateEnum.kPluggedInDemand: "PluggedIn, Demand", - clusters.EnergyEvse.Enums.StateEnum.kPluggedInCharging: "PluggedIn, Charging", - clusters.EnergyEvse.Enums.StateEnum.kPluggedInDischarging: "PluggedIn, Discharging", - clusters.EnergyEvse.Enums.StateEnum.kSessionEnding: "SessionEnding", - clusters.EnergyEvse.Enums.StateEnum.kFault: "Fault", + clusters.EnergyEvse.Enums.StateEnum.kNotPluggedIn: "not_plugged_in", + clusters.EnergyEvse.Enums.StateEnum.kPluggedInNoDemand: "plugged_in_no_demand", + clusters.EnergyEvse.Enums.StateEnum.kPluggedInDemand: "plugged_in_demand", + clusters.EnergyEvse.Enums.StateEnum.kPluggedInCharging: "plugged_in_charging", + clusters.EnergyEvse.Enums.StateEnum.kPluggedInDischarging: "plugged_in_discharging", + clusters.EnergyEvse.Enums.StateEnum.kSessionEnding: "session_ending", + clusters.EnergyEvse.Enums.StateEnum.kFault: "fault", } EVSE_SUPPLY_STATE_MAP = { - clusters.EnergyEvse.Enums.SupplyStateEnum.kDisabled: "Disabled", - clusters.EnergyEvse.Enums.SupplyStateEnum.kChargingEnabled: "Charging Enabled", - clusters.EnergyEvse.Enums.SupplyStateEnum.kDischargingEnabled: "Discharging Enabled", - clusters.EnergyEvse.Enums.SupplyStateEnum.kDisabledDiagnostics: "Disabled Diagnostics", + clusters.EnergyEvse.Enums.SupplyStateEnum.kDisabled: "disabled", + clusters.EnergyEvse.Enums.SupplyStateEnum.kChargingEnabled: "charging_enabled", + clusters.EnergyEvse.Enums.SupplyStateEnum.kDischargingEnabled: "discharging_enabled", + clusters.EnergyEvse.Enums.SupplyStateEnum.kDisabledDiagnostics: "disabled_diagnostics", } EVSE_FAULT_STATE_MAP = { - clusters.EnergyEvse.Enums.FaultStateEnum.kNoError: "No Error", - clusters.EnergyEvse.Enums.FaultStateEnum.kMeterFailure: "Meter Failure", - clusters.EnergyEvse.Enums.FaultStateEnum.kOverVoltage: "Over Voltage", - clusters.EnergyEvse.Enums.FaultStateEnum.kUnderVoltage: "Under Voltage", - clusters.EnergyEvse.Enums.FaultStateEnum.kOverCurrent: "Over Current", - clusters.EnergyEvse.Enums.FaultStateEnum.kContactWetFailure: "Contact Wet Failure", - clusters.EnergyEvse.Enums.FaultStateEnum.kContactDryFailure: "Contact Dry Failure", - clusters.EnergyEvse.Enums.FaultStateEnum.kPowerLoss: "Power Loss", - clusters.EnergyEvse.Enums.FaultStateEnum.kPowerQuality: "Power Quality", - clusters.EnergyEvse.Enums.FaultStateEnum.kPilotShortCircuit: "Pilot Short Circuit", - clusters.EnergyEvse.Enums.FaultStateEnum.kEmergencyStop: "Emergency Stop", - clusters.EnergyEvse.Enums.FaultStateEnum.kEVDisconnected: "EV Disconnected", - clusters.EnergyEvse.Enums.FaultStateEnum.kWrongPowerSupply: "Wrong Power Supply", - clusters.EnergyEvse.Enums.FaultStateEnum.kLiveNeutralSwap: "Live Neutral Swap", - clusters.EnergyEvse.Enums.FaultStateEnum.kOverTemperature: "Over Temperature", - clusters.EnergyEvse.Enums.FaultStateEnum.kOther: "Unknown", + clusters.EnergyEvse.Enums.FaultStateEnum.kNoError: "no_error", + clusters.EnergyEvse.Enums.FaultStateEnum.kMeterFailure: "meter_failure", + clusters.EnergyEvse.Enums.FaultStateEnum.kOverVoltage: "over_voltage", + clusters.EnergyEvse.Enums.FaultStateEnum.kUnderVoltage: "under_voltage", + clusters.EnergyEvse.Enums.FaultStateEnum.kOverCurrent: "over_current", + clusters.EnergyEvse.Enums.FaultStateEnum.kContactWetFailure: "contact_wet_failure", + clusters.EnergyEvse.Enums.FaultStateEnum.kContactDryFailure: "contact_dry_failure", + clusters.EnergyEvse.Enums.FaultStateEnum.kPowerLoss: "power_loss", + clusters.EnergyEvse.Enums.FaultStateEnum.kPowerQuality: "power_quality", + clusters.EnergyEvse.Enums.FaultStateEnum.kPilotShortCircuit: "pilot_short_circuit", + clusters.EnergyEvse.Enums.FaultStateEnum.kEmergencyStop: "emergency_stop", + clusters.EnergyEvse.Enums.FaultStateEnum.kEVDisconnected: "ev_disconnected", + clusters.EnergyEvse.Enums.FaultStateEnum.kWrongPowerSupply: "wrong_power_supply", + clusters.EnergyEvse.Enums.FaultStateEnum.kLiveNeutralSwap: "live_neutral_swap", + clusters.EnergyEvse.Enums.FaultStateEnum.kOverTemperature: "over_temperature", + clusters.EnergyEvse.Enums.FaultStateEnum.kOther: "other", } From 8b0e93b02466d643ce8bdbb70dfb0462ccc4dcf4 Mon Sep 17 00:00:00 2001 From: Ludovic BOUE Date: Tue, 24 Dec 2024 15:39:04 +0100 Subject: [PATCH 48/58] Add states strings for EVSE maps --- homeassistant/components/matter/strings.json | 39 ++++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/matter/strings.json b/homeassistant/components/matter/strings.json index 37de52c89c70ec..688bf7f099c16c 100644 --- a/homeassistant/components/matter/strings.json +++ b/homeassistant/components/matter/strings.json @@ -256,13 +256,46 @@ "name": "Battery type" }, "evse_state": { - "name": "State" + "name": "State", + "state": { + "not_plugged_in": "Not plugged in", + "plugged_in_no_demand": "Plugged in, no demand", + "plugged_in_demand": "Plugged in, demand", + "plugged_in_charging": "Plugged in, charging", + "plugged_in_discharging": "Plugged in, discharging", + "session_ending": "Session ending", + "fault": "Fault" + } }, "evse_supply_state": { - "name": "Supply state" + "name": "Supply state", + "state": { + "disabled": "Disabled", + "charging_enabled": "Charging enabled", + "discharging_enabled": "Discharging enabled", + "disabled_diagnostics": "Disabled diagnostics" + } }, "evse_fault_state": { - "name": "Fault state" + "name": "Fault state", + "state": { + "no_error": "OK", + "meter_failure": "Meter failure", + "over_voltage": "Over Voltage", + "under_voltage": "Under Voltage", + "over_current": "Over current", + "contact_wet_failure": "Contact wet failure", + "contact_dry_failure": "Contact dry failure", + "power_loss": "Power loss", + "power_quality": "Power quality", + "pilot_short_circuit": "Pilot short circuit", + "emergency_stop": "Emergency stop", + "ev_disconnected": "EV disconnected", + "wrong_power_supply": "Wrong power supply", + "live_neutral_swap": "Live neutral swap", + "over_temperature": "Over temperature", + "other": "Other fault" + } }, "evse_circuit_capacity": { "name": "Circuit capacity" From 6a9f74d1a71ae963e4deb35f1c03601f6b419c13 Mon Sep 17 00:00:00 2001 From: Ludovic BOUE Date: Tue, 24 Dec 2024 15:59:38 +0100 Subject: [PATCH 49/58] Update tests for state maps --- tests/components/matter/test_sensor.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/components/matter/test_sensor.py b/tests/components/matter/test_sensor.py index 36580ee776deea..1ff2d8f9dc2c8a 100644 --- a/tests/components/matter/test_sensor.py +++ b/tests/components/matter/test_sensor.py @@ -343,40 +343,40 @@ async def test_evse_sensor( ) -> None: """Test evse sensor.""" # EnergyEvseState - state = hass.states.get("sensor.evse_none") + state = hass.states.get("sensor.evse_state") assert state - assert state.state == "PluggedIn, Charging" + assert state.state == "plugged_in_charging" set_node_attribute(matter_node, 1, 153, 0, 1) await trigger_subscription_callback(hass, matter_client) - state = hass.states.get("sensor.evse_none") + state = hass.states.get("sensor.evse_state") assert state - assert state.state == "PluggedIn, NoDemand" + assert state.state == "plugged_in_no_demand" # EnergyEvseSupplyState - state = hass.states.get("sensor.evse_none_2") + state = hass.states.get("sensor.evse_supply_state") assert state - assert state.state == "Charging Enabled" + assert state.state == "charging_enabled" set_node_attribute(matter_node, 1, 153, 1, 0) await trigger_subscription_callback(hass, matter_client) - state = hass.states.get("sensor.evse_none_2") + state = hass.states.get("sensor.evse_supply_state") assert state - assert state.state == "Disabled" + assert state.state == "disabled" # EnergyEvseFaultState - state = hass.states.get("sensor.evse_none_3") + state = hass.states.get("sensor.evse_fault_state") assert state - assert state.state == "No Error" + assert state.state == "no_error" set_node_attribute(matter_node, 1, 153, 2, 4) await trigger_subscription_callback(hass, matter_client) - state = hass.states.get("sensor.evse_none_3") + state = hass.states.get("sensor.evse_fault_state") assert state - assert state.state == "Over Current" + assert state.state == "over_current" # EnergyEvseCircuitCapacity state = hass.states.get("sensor.evse_current_2") From a6e77347dd55404f2b6a116bece96e61292e497b Mon Sep 17 00:00:00 2001 From: Ludovic BOUE Date: Tue, 24 Dec 2024 16:47:11 +0100 Subject: [PATCH 50/58] Fix tests --- homeassistant/components/matter/sensor.py | 43 ++------------------ homeassistant/components/matter/strings.json | 3 ++ tests/components/matter/test_sensor.py | 18 ++++---- 3 files changed, 16 insertions(+), 48 deletions(-) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index f6e788fa1ef803..74f96cacb12e90 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -108,45 +108,6 @@ } -EVSE_STATE_MAP = { - clusters.EnergyEvse.Enums.StateEnum.kNotPluggedIn: "NotPluggedIn", - clusters.EnergyEvse.Enums.StateEnum.kPluggedInNoDemand: "PluggedIn, NoDemand", - clusters.EnergyEvse.Enums.StateEnum.kPluggedInDemand: "PluggedIn, Demand", - clusters.EnergyEvse.Enums.StateEnum.kPluggedInCharging: "PluggedIn, Charging", - clusters.EnergyEvse.Enums.StateEnum.kPluggedInDischarging: "PluggedIn, Discharging", - clusters.EnergyEvse.Enums.StateEnum.kSessionEnding: "SessionEnding", - clusters.EnergyEvse.Enums.StateEnum.kFault: "Fault", -} - - -EVSE_SUPPLY_STATE_MAP = { - clusters.EnergyEvse.Enums.SupplyStateEnum.kDisabled: "Disabled", - clusters.EnergyEvse.Enums.SupplyStateEnum.kChargingEnabled: "Charging Enabled", - clusters.EnergyEvse.Enums.SupplyStateEnum.kDischargingEnabled: "Discharging Enabled", - clusters.EnergyEvse.Enums.SupplyStateEnum.kDisabledDiagnostics: "Disabled Diagnostics", -} - - -EVSE_FAULT_STATE_MAP = { - clusters.EnergyEvse.Enums.FaultStateEnum.kNoError: "No Error", - clusters.EnergyEvse.Enums.FaultStateEnum.kMeterFailure: "Meter Failure", - clusters.EnergyEvse.Enums.FaultStateEnum.kOverVoltage: "Over Voltage", - clusters.EnergyEvse.Enums.FaultStateEnum.kUnderVoltage: "Under Voltage", - clusters.EnergyEvse.Enums.FaultStateEnum.kOverCurrent: "Over Current", - clusters.EnergyEvse.Enums.FaultStateEnum.kContactWetFailure: "Contact Wet Failure", - clusters.EnergyEvse.Enums.FaultStateEnum.kContactDryFailure: "Contact Dry Failure", - clusters.EnergyEvse.Enums.FaultStateEnum.kPowerLoss: "Power Loss", - clusters.EnergyEvse.Enums.FaultStateEnum.kPowerQuality: "Power Quality", - clusters.EnergyEvse.Enums.FaultStateEnum.kPilotShortCircuit: "Pilot Short Circuit", - clusters.EnergyEvse.Enums.FaultStateEnum.kEmergencyStop: "Emergency Stop", - clusters.EnergyEvse.Enums.FaultStateEnum.kEVDisconnected: "EV Disconnected", - clusters.EnergyEvse.Enums.FaultStateEnum.kWrongPowerSupply: "Wrong Power Supply", - clusters.EnergyEvse.Enums.FaultStateEnum.kLiveNeutralSwap: "Live Neutral Swap", - clusters.EnergyEvse.Enums.FaultStateEnum.kOverTemperature: "Over Temperature", - clusters.EnergyEvse.Enums.FaultStateEnum.kOther: "Unknown", -} - - async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, @@ -791,6 +752,7 @@ def _update_from_device(self) -> None: platform=Platform.SENSOR, entity_description=MatterSensorEntityDescription( key="EnergyEvseCircuitCapacity", + translation_key="evse_circuit_capacity", device_class=SensorDeviceClass.CURRENT, entity_category=EntityCategory.DIAGNOSTIC, native_unit_of_measurement=UnitOfElectricCurrent.MILLIAMPERE, @@ -805,6 +767,7 @@ def _update_from_device(self) -> None: platform=Platform.SENSOR, entity_description=MatterSensorEntityDescription( key="EnergyEvseMinimumChargeCurrent", + translation_key="evse_min_charge_current", device_class=SensorDeviceClass.CURRENT, entity_category=EntityCategory.DIAGNOSTIC, native_unit_of_measurement=UnitOfElectricCurrent.MILLIAMPERE, @@ -819,6 +782,7 @@ def _update_from_device(self) -> None: platform=Platform.SENSOR, entity_description=MatterSensorEntityDescription( key="EnergyEvseMaximumChargeCurrent", + translation_key="evse_max_charge_current", device_class=SensorDeviceClass.CURRENT, entity_category=EntityCategory.DIAGNOSTIC, native_unit_of_measurement=UnitOfElectricCurrent.MILLIAMPERE, @@ -833,6 +797,7 @@ def _update_from_device(self) -> None: platform=Platform.SENSOR, entity_description=MatterSensorEntityDescription( key="EnergyEvseUserMaximumChargeCurrent", + translation_key="evse_user_max_charge_current", device_class=SensorDeviceClass.CURRENT, entity_category=EntityCategory.DIAGNOSTIC, native_unit_of_measurement=UnitOfElectricCurrent.MILLIAMPERE, diff --git a/homeassistant/components/matter/strings.json b/homeassistant/components/matter/strings.json index 688bf7f099c16c..ade755fa9fd0f1 100644 --- a/homeassistant/components/matter/strings.json +++ b/homeassistant/components/matter/strings.json @@ -303,6 +303,9 @@ "evse_charge_current": { "name": "Charge current" }, + "evse_min_charge_current": { + "name": "Min charge current" + }, "evse_max_charge_current": { "name": "Max charge current" }, diff --git a/tests/components/matter/test_sensor.py b/tests/components/matter/test_sensor.py index 1ff2d8f9dc2c8a..ebeee942787821 100644 --- a/tests/components/matter/test_sensor.py +++ b/tests/components/matter/test_sensor.py @@ -379,49 +379,49 @@ async def test_evse_sensor( assert state.state == "over_current" # EnergyEvseCircuitCapacity - state = hass.states.get("sensor.evse_current_2") + state = hass.states.get("sensor.evse_circuit_capacity") assert state assert state.state == "32.0" set_node_attribute(matter_node, 1, 153, 5, 63000) await trigger_subscription_callback(hass, matter_client) - state = hass.states.get("sensor.evse_current_2") + state = hass.states.get("sensor.evse_circuit_capacity") assert state assert state.state == "63.0" # EnergyEvseMinimumChargeCurrent - state = hass.states.get("sensor.evse_current_3") + state = hass.states.get("sensor.evse_min_charge_current") assert state assert state.state == "2.0" set_node_attribute(matter_node, 1, 153, 6, 5000) await trigger_subscription_callback(hass, matter_client) - state = hass.states.get("sensor.evse_current_3") + state = hass.states.get("sensor.evse_min_charge_current") assert state assert state.state == "5.0" # EnergyEvseMaximumChargeCurrent - state = hass.states.get("sensor.evse_current_4") + state = hass.states.get("sensor.evse_max_charge_current") assert state assert state.state == "30.0" set_node_attribute(matter_node, 1, 153, 7, 20000) await trigger_subscription_callback(hass, matter_client) - state = hass.states.get("sensor.evse_current_4") + state = hass.states.get("sensor.evse_max_charge_current") assert state assert state.state == "20.0" - # EnergyEvseMaximumChargeCurrent - state = hass.states.get("sensor.evse_current_5") + # EnergyEvseUserMaximumChargeCurrent + state = hass.states.get("sensor.evse_user_max_charge_current") assert state assert state.state == "32.0" set_node_attribute(matter_node, 1, 153, 9, 63000) await trigger_subscription_callback(hass, matter_client) - state = hass.states.get("sensor.evse_current_5") + state = hass.states.get("sensor.evse_user_max_charge_current") assert state assert state.state == "63.0" From 71e411060c91ec296d75153d07e907d4cda26c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Thu, 16 Jan 2025 13:58:37 +0100 Subject: [PATCH 51/58] Add the evse_charging fixture to the list of fixtures --- tests/components/matter/conftest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/components/matter/conftest.py b/tests/components/matter/conftest.py index bbafec48e10faf..073cd65966aa58 100644 --- a/tests/components/matter/conftest.py +++ b/tests/components/matter/conftest.py @@ -85,6 +85,7 @@ async def integration_fixture( "eve_energy_plug_patched", "eve_thermo", "eve_weather_sensor", + "evse_charging", "extended_color_light", "fan", "flow_sensor", From 826038928b592d9bb48894a85e1e9e3135f13d18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Thu, 16 Jan 2025 14:04:14 +0100 Subject: [PATCH 52/58] Update icons.json --- homeassistant/components/matter/icons.json | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/matter/icons.json b/homeassistant/components/matter/icons.json index c4290b64648981..436dafddc1480f 100644 --- a/homeassistant/components/matter/icons.json +++ b/homeassistant/components/matter/icons.json @@ -72,6 +72,7 @@ }, "evse_fault_state": { "default": "mdi:ev-station" + }, "battery_replacement_description": { "default": "mdi:battery-sync-outline" } From f00a1cfbc2ec5da88725dddf9500341c81beec82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Thu, 16 Jan 2025 15:31:05 +0000 Subject: [PATCH 53/58] Update snapshots for EVSE --- .../matter/snapshots/test_button.ambr | 139 ++++ .../matter/snapshots/test_select.ambr | 120 ++++ .../matter/snapshots/test_sensor.ambr | 666 ++++++++++++++++++ 3 files changed, 925 insertions(+) diff --git a/tests/components/matter/snapshots/test_button.ambr b/tests/components/matter/snapshots/test_button.ambr index 10792b58d28e0f..b1baae30aee297 100644 --- a/tests/components/matter/snapshots/test_button.ambr +++ b/tests/components/matter/snapshots/test_button.ambr @@ -843,6 +843,145 @@ 'state': 'unknown', }) # --- +# name: test_buttons[evse_charging][button.evse_disable_charging-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.evse_disable_charging', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Disable charging', + 'platform': 'matter', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'disable_charging', + 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-EnergyEvseDisableChargingButton-153-65529', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[evse_charging][button.evse_disable_charging-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'evse Disable charging', + }), + 'context': , + 'entity_id': 'button.evse_disable_charging', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[evse_charging][button.evse_enable_charging-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.evse_enable_charging', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Enable charging', + 'platform': 'matter', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'enable_charging', + 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-EnergyEvseEnableChargingButton-153-65529', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[evse_charging][button.evse_enable_charging-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'evse Enable charging', + }), + 'context': , + 'entity_id': 'button.evse_enable_charging', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[evse_charging][button.evse_identify-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.evse_identify', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Identify', + 'platform': 'matter', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-IdentifyButton-3-65529', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[evse_charging][button.evse_identify-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'identify', + 'friendly_name': 'evse Identify', + }), + 'context': , + 'entity_id': 'button.evse_identify', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- # name: test_buttons[extended_color_light][button.mock_extended_color_light_identify-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ diff --git a/tests/components/matter/snapshots/test_select.ambr b/tests/components/matter/snapshots/test_select.ambr index 663b0cdaf51828..60d9133592e705 100644 --- a/tests/components/matter/snapshots/test_select.ambr +++ b/tests/components/matter/snapshots/test_select.ambr @@ -546,6 +546,126 @@ 'state': 'previous', }) # --- +# name: test_selects[evse_charging][select.evse_mode-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': list([ + 'Manual', + 'Auto-scheduled', + 'Solar', + 'Auto-scheduled with Solar charging', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'select', + 'entity_category': None, + 'entity_id': 'select.evse_mode', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Mode', + 'platform': 'matter', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'mode', + 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-MatterEnergyEvseMode-157-1', + 'unit_of_measurement': None, + }) +# --- +# name: test_selects[evse_charging][select.evse_mode-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'evse Mode', + 'options': list([ + 'Manual', + 'Auto-scheduled', + 'Solar', + 'Auto-scheduled with Solar charging', + ]), + }), + 'context': , + 'entity_id': 'select.evse_mode', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'Auto-scheduled', + }) +# --- +# name: test_selects[evse_charging][select.evse_mode_2-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': list([ + 'No energy management (forecast only)', + 'Device optimizes (no local or grid control)', + 'Optimized within building', + 'Optimized for grid', + 'Optimized for grid and building', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'select', + 'entity_category': None, + 'entity_id': 'select.evse_mode_2', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Mode', + 'platform': 'matter', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'mode', + 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-MatterDeviceEnergyManagementMode-159-1', + 'unit_of_measurement': None, + }) +# --- +# name: test_selects[evse_charging][select.evse_mode_2-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'evse Mode', + 'options': list([ + 'No energy management (forecast only)', + 'Device optimizes (no local or grid control)', + 'Optimized within building', + 'Optimized for grid', + 'Optimized for grid and building', + ]), + }), + 'context': , + 'entity_id': 'select.evse_mode_2', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'Optimized for grid', + }) +# --- # name: test_selects[extended_color_light][select.mock_extended_color_light_lighting-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ diff --git a/tests/components/matter/snapshots/test_sensor.ambr b/tests/components/matter/snapshots/test_sensor.ambr index f88604e7d46b1b..ede1bbaf7b6426 100644 --- a/tests/components/matter/snapshots/test_sensor.ambr +++ b/tests/components/matter/snapshots/test_sensor.ambr @@ -2337,6 +2337,672 @@ 'state': '2.956', }) # --- +# name: test_sensors[evse_charging][sensor.evse_circuit_capacity-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.evse_circuit_capacity', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + 'sensor': dict({ + 'suggested_display_precision': 2, + }), + 'sensor.private': dict({ + 'suggested_unit_of_measurement': , + }), + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Circuit capacity', + 'platform': 'matter', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'evse_circuit_capacity', + 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-EnergyEvseCircuitCapacity-153-5', + 'unit_of_measurement': , + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_circuit_capacity-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'current', + 'friendly_name': 'evse Circuit capacity', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.evse_circuit_capacity', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '32.0', + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_current-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.evse_current', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + 'sensor': dict({ + 'suggested_display_precision': 2, + }), + 'sensor.private': dict({ + 'suggested_unit_of_measurement': , + }), + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Current', + 'platform': 'matter', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-ElectricalPowerMeasurementActiveCurrent-144-5', + 'unit_of_measurement': , + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_current-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'current', + 'friendly_name': 'evse Current', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.evse_current', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_energy-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.evse_energy', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + 'sensor': dict({ + 'suggested_display_precision': 3, + }), + 'sensor.private': dict({ + 'suggested_unit_of_measurement': , + }), + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Energy', + 'platform': 'matter', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-ElectricalEnergyMeasurementCumulativeEnergyImported-145-1', + 'unit_of_measurement': , + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_energy-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'energy', + 'friendly_name': 'evse Energy', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.evse_energy', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_fault_state-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': list([ + 'no_error', + 'meter_failure', + 'over_voltage', + 'under_voltage', + 'over_current', + 'contact_wet_failure', + 'contact_dry_failure', + 'power_loss', + 'power_quality', + 'pilot_short_circuit', + 'emergency_stop', + 'ev_disconnected', + 'wrong_power_supply', + 'live_neutral_swap', + 'over_temperature', + 'other', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.evse_fault_state', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Fault state', + 'platform': 'matter', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'evse_fault_state', + 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-EnergyEvseFaultState-153-2', + 'unit_of_measurement': None, + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_fault_state-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'enum', + 'friendly_name': 'evse Fault state', + 'options': list([ + 'no_error', + 'meter_failure', + 'over_voltage', + 'under_voltage', + 'over_current', + 'contact_wet_failure', + 'contact_dry_failure', + 'power_loss', + 'power_quality', + 'pilot_short_circuit', + 'emergency_stop', + 'ev_disconnected', + 'wrong_power_supply', + 'live_neutral_swap', + 'over_temperature', + 'other', + ]), + }), + 'context': , + 'entity_id': 'sensor.evse_fault_state', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'no_error', + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_max_charge_current-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.evse_max_charge_current', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + 'sensor': dict({ + 'suggested_display_precision': 2, + }), + 'sensor.private': dict({ + 'suggested_unit_of_measurement': , + }), + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Max charge current', + 'platform': 'matter', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'evse_max_charge_current', + 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-EnergyEvseMaximumChargeCurrent-153-7', + 'unit_of_measurement': , + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_max_charge_current-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'current', + 'friendly_name': 'evse Max charge current', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.evse_max_charge_current', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '30.0', + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_min_charge_current-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.evse_min_charge_current', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + 'sensor': dict({ + 'suggested_display_precision': 2, + }), + 'sensor.private': dict({ + 'suggested_unit_of_measurement': , + }), + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Min charge current', + 'platform': 'matter', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'evse_min_charge_current', + 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-EnergyEvseMinimumChargeCurrent-153-6', + 'unit_of_measurement': , + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_min_charge_current-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'current', + 'friendly_name': 'evse Min charge current', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.evse_min_charge_current', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '2.0', + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_power-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.evse_power', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + 'sensor': dict({ + 'suggested_display_precision': 2, + }), + 'sensor.private': dict({ + 'suggested_unit_of_measurement': , + }), + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Power', + 'platform': 'matter', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-ElectricalPowerMeasurementWatt-144-8', + 'unit_of_measurement': , + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_power-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'power', + 'friendly_name': 'evse Power', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.evse_power', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_state-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': list([ + 'not_plugged_in', + 'plugged_in_no_demand', + 'plugged_in_demand', + 'plugged_in_charging', + 'plugged_in_discharging', + 'session_ending', + 'fault', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.evse_state', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'State', + 'platform': 'matter', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'evse_state', + 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-EnergyEvseState-153-0', + 'unit_of_measurement': None, + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_state-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'enum', + 'friendly_name': 'evse State', + 'options': list([ + 'not_plugged_in', + 'plugged_in_no_demand', + 'plugged_in_demand', + 'plugged_in_charging', + 'plugged_in_discharging', + 'session_ending', + 'fault', + ]), + }), + 'context': , + 'entity_id': 'sensor.evse_state', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'plugged_in_charging', + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_supply_state-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': list([ + 'disabled', + 'charging_enabled', + 'discharging_enabled', + 'disabled_diagnostics', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.evse_supply_state', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Supply state', + 'platform': 'matter', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'evse_supply_state', + 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-EnergyEvseSupplyState-153-1', + 'unit_of_measurement': None, + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_supply_state-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'enum', + 'friendly_name': 'evse Supply state', + 'options': list([ + 'disabled', + 'charging_enabled', + 'discharging_enabled', + 'disabled_diagnostics', + ]), + }), + 'context': , + 'entity_id': 'sensor.evse_supply_state', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'charging_enabled', + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_user_max_charge_current-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.evse_user_max_charge_current', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + 'sensor': dict({ + 'suggested_display_precision': 2, + }), + 'sensor.private': dict({ + 'suggested_unit_of_measurement': , + }), + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'User max charge current', + 'platform': 'matter', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'evse_user_max_charge_current', + 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-EnergyEvseUserMaximumChargeCurrent-153-9', + 'unit_of_measurement': , + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_user_max_charge_current-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'current', + 'friendly_name': 'evse User max charge current', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.evse_user_max_charge_current', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '32.0', + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_voltage-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.evse_voltage', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + 'sensor': dict({ + 'suggested_display_precision': 0, + }), + 'sensor.private': dict({ + 'suggested_unit_of_measurement': , + }), + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Voltage', + 'platform': 'matter', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-ElectricalPowerMeasurementVoltage-144-4', + 'unit_of_measurement': , + }) +# --- +# name: test_sensors[evse_charging][sensor.evse_voltage-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'voltage', + 'friendly_name': 'evse Voltage', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.evse_voltage', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- # name: test_sensors[flow_sensor][sensor.mock_flow_sensor_flow-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ From f1ba30e7b29360fe7cef4c27d2a3bbac835c70dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Fri, 17 Jan 2025 07:55:15 +0000 Subject: [PATCH 54/58] EnableCharging has arguments --- homeassistant/components/matter/button.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/matter/button.py b/homeassistant/components/matter/button.py index afe286a90d71a8..4301284fdcf86e 100644 --- a/homeassistant/components/matter/button.py +++ b/homeassistant/components/matter/button.py @@ -7,6 +7,7 @@ from typing import TYPE_CHECKING, Any from chip.clusters import Objects as clusters +from chip.clusters.Objects import NullValue from homeassistant.components.button import ( ButtonDeviceClass, @@ -154,7 +155,11 @@ async def async_press(self) -> None: entity_description=MatterButtonEntityDescription( key="EnergyEvseEnableChargingButton", translation_key="enable_charging", - command=clusters.EnergyEvse.Commands.EnableCharging, + command=clusters.EnergyEvse.Commands.EnableCharging( + chargingEnabledUntil=NullValue, + minimumChargeCurrent=0, + maximumChargeCurrent=0, + ), command_timeout=3000, ), entity_class=MatterCommandButton, From b4a213b07f88505c44f669553965f529e01555e8 Mon Sep 17 00:00:00 2001 From: Ludovic BOUE Date: Fri, 17 Jan 2025 11:57:43 +0100 Subject: [PATCH 55/58] Test EVSE buttons --- tests/components/matter/test_button.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/components/matter/test_button.py b/tests/components/matter/test_button.py index ab634f1e32d77c..f5fb911f624638 100644 --- a/tests/components/matter/test_button.py +++ b/tests/components/matter/test_button.py @@ -82,3 +82,14 @@ async def test_operational_state_buttons( command=clusters.OperationalState.Commands.Pause(), timed_request_timeout_ms=None, ) + + +@pytest.mark.parametrize("node_fixture", ["evse_charging"]) +async def test_evse_buttons( + hass: HomeAssistant, + matter_client: MagicMock, + matter_node: MatterNode, +) -> None: + """Test if button entities are created for EVSE commands.""" + assert hass.states.get("button.evse_enable_charging") + assert hass.states.get("button.evse_disable_charging") From 6fcbf0fe3c7a66f4265c7af41acef4586a702e80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Fri, 17 Jan 2025 16:15:41 +0000 Subject: [PATCH 56/58] Test EnableCharging command --- homeassistant/components/matter/button.py | 4 +++- tests/components/matter/test_button.py | 24 ++++++++++++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/matter/button.py b/homeassistant/components/matter/button.py index 4301284fdcf86e..6b4cfd301da4fe 100644 --- a/homeassistant/components/matter/button.py +++ b/homeassistant/components/matter/button.py @@ -155,7 +155,7 @@ async def async_press(self) -> None: entity_description=MatterButtonEntityDescription( key="EnergyEvseEnableChargingButton", translation_key="enable_charging", - command=clusters.EnergyEvse.Commands.EnableCharging( + command=lambda: clusters.EnergyEvse.Commands.EnableCharging( chargingEnabledUntil=NullValue, minimumChargeCurrent=0, maximumChargeCurrent=0, @@ -164,6 +164,7 @@ async def async_press(self) -> None: ), entity_class=MatterCommandButton, required_attributes=(clusters.EnergyEvse.Attributes.AcceptedCommandList,), + value_contains=clusters.EnergyEvse.Commands.EnableCharging.command_id, allow_multi=True, ), MatterDiscoverySchema( @@ -176,6 +177,7 @@ async def async_press(self) -> None: ), entity_class=MatterCommandButton, required_attributes=(clusters.EnergyEvse.Attributes.AcceptedCommandList,), + value_contains=clusters.EnergyEvse.Commands.Disable.command_id, allow_multi=True, ), ] diff --git a/tests/components/matter/test_button.py b/tests/components/matter/test_button.py index f5fb911f624638..1c3b12abead0bf 100644 --- a/tests/components/matter/test_button.py +++ b/tests/components/matter/test_button.py @@ -3,6 +3,7 @@ from unittest.mock import MagicMock, call from chip.clusters import Objects as clusters +from chip.clusters.Objects import NullValue from matter_server.client.models.node import MatterNode import pytest from syrupy import SnapshotAssertion @@ -90,6 +91,23 @@ async def test_evse_buttons( matter_client: MagicMock, matter_node: MatterNode, ) -> None: - """Test if button entities are created for EVSE commands.""" - assert hass.states.get("button.evse_enable_charging") - assert hass.states.get("button.evse_disable_charging") + """Test button for EVSE commands.""" + await hass.services.async_call( + "button", + "press", + { + "entity_id": "button.evse_enable_charging", + }, + blocking=True, + ) + assert matter_client.send_device_command.call_count == 1 + assert matter_client.send_device_command.call_args == call( + node_id=matter_node.node_id, + endpoint_id=1, + command=clusters.EnergyEvse.Commands.EnableCharging( + chargingEnabledUntil=NullValue, + minimumChargeCurrent=0, + maximumChargeCurrent=0, + ), + timed_request_timeout_ms=3000, + ) From e6147c6bb9303f517962f6a80d49d01a9f04e58f Mon Sep 17 00:00:00 2001 From: Ludovic BOUE Date: Fri, 24 Jan 2025 10:43:22 +0100 Subject: [PATCH 57/58] Resolv conflicts --- .../matter/snapshots/test_select.ambr | 150 ++++++++---------- 1 file changed, 70 insertions(+), 80 deletions(-) diff --git a/tests/components/matter/snapshots/test_select.ambr b/tests/components/matter/snapshots/test_select.ambr index 60d9133592e705..ce83ebf1bb60ef 100644 --- a/tests/components/matter/snapshots/test_select.ambr +++ b/tests/components/matter/snapshots/test_select.ambr @@ -546,17 +546,15 @@ 'state': 'previous', }) # --- -# name: test_selects[evse_charging][select.evse_mode-entry] +# name: test_selects[eve_thermo][select.eve_thermo_temperature_display_mode-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), 'area_id': None, 'capabilities': dict({ 'options': list([ - 'Manual', - 'Auto-scheduled', - 'Solar', - 'Auto-scheduled with Solar charging', + 'Celsius', + 'Fahrenheit', ]), }), 'config_entry_id': , @@ -564,8 +562,8 @@ 'device_id': , 'disabled_by': None, 'domain': 'select', - 'entity_category': None, - 'entity_id': 'select.evse_mode', + 'entity_category': , + 'entity_id': 'select.eve_thermo_temperature_display_mode', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -577,93 +575,30 @@ }), 'original_device_class': None, 'original_icon': None, - 'original_name': 'Mode', + 'original_name': 'Temperature display mode', 'platform': 'matter', 'previous_unique_id': None, 'supported_features': 0, - 'translation_key': 'mode', - 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-MatterEnergyEvseMode-157-1', + 'translation_key': 'temperature_display_mode', + 'unique_id': '00000000000004D2-0000000000000021-MatterNodeDevice-1-TrvTemperatureDisplayMode-516-0', 'unit_of_measurement': None, }) # --- -# name: test_selects[evse_charging][select.evse_mode-state] +# name: test_selects[eve_thermo][select.eve_thermo_temperature_display_mode-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'friendly_name': 'evse Mode', + 'friendly_name': 'Eve Thermo Temperature display mode', 'options': list([ - 'Manual', - 'Auto-scheduled', - 'Solar', - 'Auto-scheduled with Solar charging', + 'Celsius', + 'Fahrenheit', ]), }), 'context': , - 'entity_id': 'select.evse_mode', + 'entity_id': 'select.eve_thermo_temperature_display_mode', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'Auto-scheduled', - }) -# --- -# name: test_selects[evse_charging][select.evse_mode_2-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': dict({ - 'options': list([ - 'No energy management (forecast only)', - 'Device optimizes (no local or grid control)', - 'Optimized within building', - 'Optimized for grid', - 'Optimized for grid and building', - ]), - }), - 'config_entry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'select', - 'entity_category': None, - 'entity_id': 'select.evse_mode_2', - 'has_entity_name': True, - 'hidden_by': None, - 'icon': None, - 'id': , - 'labels': set({ - }), - 'name': None, - 'options': dict({ - }), - 'original_device_class': None, - 'original_icon': None, - 'original_name': 'Mode', - 'platform': 'matter', - 'previous_unique_id': None, - 'supported_features': 0, - 'translation_key': 'mode', - 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-MatterDeviceEnergyManagementMode-159-1', - 'unit_of_measurement': None, - }) -# --- -# name: test_selects[evse_charging][select.evse_mode_2-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'friendly_name': 'evse Mode', - 'options': list([ - 'No energy management (forecast only)', - 'Device optimizes (no local or grid control)', - 'Optimized within building', - 'Optimized for grid', - 'Optimized for grid and building', - ]), - }), - 'context': , - 'entity_id': 'select.evse_mode_2', - 'last_changed': , - 'last_reported': , - 'last_updated': , - 'state': 'Optimized for grid', + 'state': 'Celsius', }) # --- # name: test_selects[extended_color_light][select.mock_extended_color_light_lighting-entry] @@ -1693,6 +1628,61 @@ 'state': 'previous', }) # --- +# name: test_selects[thermostat][select.longan_link_hvac_temperature_display_mode-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': list([ + 'Celsius', + 'Fahrenheit', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'select', + 'entity_category': , + 'entity_id': 'select.longan_link_hvac_temperature_display_mode', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Temperature display mode', + 'platform': 'matter', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'temperature_display_mode', + 'unique_id': '00000000000004D2-0000000000000004-MatterNodeDevice-1-TrvTemperatureDisplayMode-516-0', + 'unit_of_measurement': None, + }) +# --- +# name: test_selects[thermostat][select.longan_link_hvac_temperature_display_mode-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Longan link HVAC Temperature display mode', + 'options': list([ + 'Celsius', + 'Fahrenheit', + ]), + }), + 'context': , + 'entity_id': 'select.longan_link_hvac_temperature_display_mode', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'Celsius', + }) +# --- # name: test_selects[vacuum_cleaner][select.mock_vacuum_clean_mode-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -1753,4 +1743,4 @@ 'last_updated': , 'state': 'Quick', }) -# --- +# --- \ No newline at end of file From 5e4e9a359f553580b420aa74b5b8f484e39c5f8b Mon Sep 17 00:00:00 2001 From: Ludovic BOUE Date: Fri, 24 Jan 2025 10:50:05 +0100 Subject: [PATCH 58/58] Update snapshots --- .../matter/snapshots/test_select.ambr | 122 +++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) diff --git a/tests/components/matter/snapshots/test_select.ambr b/tests/components/matter/snapshots/test_select.ambr index ce83ebf1bb60ef..fafab2669d718e 100644 --- a/tests/components/matter/snapshots/test_select.ambr +++ b/tests/components/matter/snapshots/test_select.ambr @@ -601,6 +601,126 @@ 'state': 'Celsius', }) # --- +# name: test_selects[evse_charging][select.evse_mode-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': list([ + 'Manual', + 'Auto-scheduled', + 'Solar', + 'Auto-scheduled with Solar charging', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'select', + 'entity_category': None, + 'entity_id': 'select.evse_mode', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Mode', + 'platform': 'matter', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'mode', + 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-MatterEnergyEvseMode-157-1', + 'unit_of_measurement': None, + }) +# --- +# name: test_selects[evse_charging][select.evse_mode-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'evse Mode', + 'options': list([ + 'Manual', + 'Auto-scheduled', + 'Solar', + 'Auto-scheduled with Solar charging', + ]), + }), + 'context': , + 'entity_id': 'select.evse_mode', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'Auto-scheduled', + }) +# --- +# name: test_selects[evse_charging][select.evse_mode_2-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': list([ + 'No energy management (forecast only)', + 'Device optimizes (no local or grid control)', + 'Optimized within building', + 'Optimized for grid', + 'Optimized for grid and building', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'select', + 'entity_category': None, + 'entity_id': 'select.evse_mode_2', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Mode', + 'platform': 'matter', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'mode', + 'unique_id': '00000000000004D2-0000000000000017-MatterNodeDevice-1-MatterDeviceEnergyManagementMode-159-1', + 'unit_of_measurement': None, + }) +# --- +# name: test_selects[evse_charging][select.evse_mode_2-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'evse Mode', + 'options': list([ + 'No energy management (forecast only)', + 'Device optimizes (no local or grid control)', + 'Optimized within building', + 'Optimized for grid', + 'Optimized for grid and building', + ]), + }), + 'context': , + 'entity_id': 'select.evse_mode_2', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'Optimized for grid', + }) +# --- # name: test_selects[extended_color_light][select.mock_extended_color_light_lighting-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -1743,4 +1863,4 @@ 'last_updated': , 'state': 'Quick', }) -# --- \ No newline at end of file +# ---