From 2da732f11b00fcd80759667f6be9514e1dcc2df6 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 15 Jul 2024 17:01:41 +0200 Subject: [PATCH 1/8] change translation keys for 2 entities --- zha/application/platforms/select.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zha/application/platforms/select.py b/zha/application/platforms/select.py index c769808b1..13e8427a4 100644 --- a/zha/application/platforms/select.py +++ b/zha/application/platforms/select.py @@ -485,7 +485,7 @@ class AqaraT2RelaySwitchType(ZCLEnumSelectEntity): _unique_id_suffix = "switch_type" _attribute_name = "switch_type" _enum = T2RelayOppleCluster.SwitchType - _attr_translation_key: str = "switch_type" + _attr_translation_key: str = "relay_switch_type" @CONFIG_DIAGNOSTIC_MATCH( @@ -549,7 +549,7 @@ class InovelliSwitchTypeEntity(ZCLEnumSelectEntity): _unique_id_suffix = "switch_type" _attribute_name = "switch_type" _enum = InovelliSwitchType - _attr_translation_key: str = "switch_type" + _attr_translation_key: str = "fan_switch_type" class InovelliFanSwitchType(types.enum1): From cffcda21f7dd8ed25ded3e6c6565d832a21cc035 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 15 Jul 2024 17:30:34 +0200 Subject: [PATCH 2/8] change state format to snake_case, instead of 'titles with spaces starting with a capital letter' --- zha/application/platforms/select.py | 15 +++++++++++---- zha/application/platforms/sensor/__init__.py | 4 ++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/zha/application/platforms/select.py b/zha/application/platforms/select.py index 13e8427a4..fff153ddc 100644 --- a/zha/application/platforms/select.py +++ b/zha/application/platforms/select.py @@ -63,6 +63,7 @@ class EnumSelectEntity(PlatformEntity): _attr_entity_category = EntityCategory.CONFIG _attribute_name: str _enum: type[Enum] + _translation_keys: dict[str, str] def __init__( self, @@ -75,7 +76,10 @@ def __init__( """Init this select entity.""" self._cluster_handler: ClusterHandler = cluster_handlers[0] self._attribute_name = self._enum.__name__ - self._attr_options = [entry.name.replace("_", " ") for entry in self._enum] + self._translation_keys = { + entry.name.lower(): entry.name for entry in self._enum + } + self._attr_options = [entry.name.lower() for entry in self._enum] super().__init__(unique_id, cluster_handlers, endpoint, device, **kwargs) @functools.cached_property @@ -100,12 +104,12 @@ def current_option(self) -> str | None: option = self._cluster_handler.data_cache.get(self._attribute_name) if option is None: return None - return option.name.replace("_", " ") + return option.name.lower() async def async_select_option(self, option: str) -> None: """Change the selected option.""" self._cluster_handler.data_cache[self._attribute_name] = self._enum[ - option.replace(" ", "_") + self._translation_keys[option] ] self.maybe_emit_state_changed_event() @@ -115,7 +119,10 @@ def restore_external_state_attributes( state: str, ) -> None: """Restore extra state attributes that are stored outside of the ZCL cache.""" - value = state.replace(" ", "_") + try: + value = self._translation_keys[state] + except KeyError: # workaround for existing installations updating + value = state.replace(" ", "_") self._cluster_handler.data_cache[self._attribute_name] = self._enum[value] diff --git a/zha/application/platforms/sensor/__init__.py b/zha/application/platforms/sensor/__init__.py index d46dcbb78..db86ab104 100644 --- a/zha/application/platforms/sensor/__init__.py +++ b/zha/application/platforms/sensor/__init__.py @@ -458,7 +458,7 @@ def __init__( ) -> None: """Init this sensor.""" super().__init__(unique_id, cluster_handlers, endpoint, device, **kwargs) - self._attr_options = [e.name for e in self._enum] + self._attr_options = [e.name.lower() for e in self._enum] # XXX: This class is not meant to be initialized directly, as `unique_id` # depends on the value of `_attribute_name` @@ -473,7 +473,7 @@ def _init_from_quirks_metadata(self, entity_metadata: ZCLEnumMetadata) -> None: def formatter(self, value: int) -> str | None: """Use name of enum.""" assert self._enum is not None - return self._enum(value).name + return self._enum(value).name.lower() @MULTI_MATCH( From f348c0644e3d40cd5a0c8c58677b35b55ea0d224 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 15 Jul 2024 17:46:16 +0200 Subject: [PATCH 3/8] fix tests --- tests/test_select.py | 18 +++++++++--------- tests/test_sensor.py | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/test_select.py b/tests/test_select.py index 380d9de86..dd16b9c44 100644 --- a/tests/test_select.py +++ b/tests/test_select.py @@ -63,13 +63,13 @@ async def test_select( entity = get_entity(zha_device, platform=Platform.SELECT, qualifier=select_name) assert entity.state["state"] is None # unknown in HA assert entity.info_object.options == [ - "Stop", - "Burglar", - "Fire", - "Emergency", - "Police Panic", - "Fire Panic", - "Emergency Panic", + "stop", + "burglar", + "fire", + "emergency", + "police_panic", + "fire_panic", + "emergency_panic", ] assert entity._enum == security.IasWd.Warning.WarningMode @@ -253,9 +253,9 @@ async def test_non_zcl_select_state_restoration( entity.restore_external_state_attributes( state=security.IasWd.Warning.WarningMode.Burglar.name ) - assert entity.state["state"] == security.IasWd.Warning.WarningMode.Burglar.name + assert entity.state["state"] == security.IasWd.Warning.WarningMode.Burglar.name.lower() entity.restore_external_state_attributes( state=security.IasWd.Warning.WarningMode.Fire.name ) - assert entity.state["state"] == security.IasWd.Warning.WarningMode.Fire.name + assert entity.state["state"] == security.IasWd.Warning.WarningMode.Fire.name.lower() diff --git a/tests/test_sensor.py b/tests/test_sensor.py index 0b42a5a55..49ce0cbfa 100644 --- a/tests/test_sensor.py +++ b/tests/test_sensor.py @@ -372,7 +372,7 @@ async def async_test_setpoint_change_source( cluster, {hvac.Thermostat.AttributeDefs.setpoint_change_source.id: 0x01}, ) - assert entity.state["state"] == "Schedule" + assert entity.state["state"] == "schedule" async def async_test_pi_heating_demand( From 0d1d5bde2ee4fbe89c2f58474191aa9b13b7beeb Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 15 Jul 2024 17:50:45 +0200 Subject: [PATCH 4/8] ruff --- tests/test_select.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_select.py b/tests/test_select.py index dd16b9c44..0997bce67 100644 --- a/tests/test_select.py +++ b/tests/test_select.py @@ -253,7 +253,9 @@ async def test_non_zcl_select_state_restoration( entity.restore_external_state_attributes( state=security.IasWd.Warning.WarningMode.Burglar.name ) - assert entity.state["state"] == security.IasWd.Warning.WarningMode.Burglar.name.lower() + assert ( + entity.state["state"] == security.IasWd.Warning.WarningMode.Burglar.name.lower() + ) entity.restore_external_state_attributes( state=security.IasWd.Warning.WarningMode.Fire.name From 305041568a3551b76ae2fc36898f2cc53bcdaa62 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 15 Jul 2024 17:55:37 +0200 Subject: [PATCH 5/8] fix other tests --- tests/test_select.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/test_select.py b/tests/test_select.py index 0997bce67..0d3294042 100644 --- a/tests/test_select.py +++ b/tests/test_select.py @@ -74,9 +74,13 @@ async def test_select( assert entity._enum == security.IasWd.Warning.WarningMode # change value from client - await entity.async_select_option(security.IasWd.Warning.WarningMode.Burglar.name) + await entity.async_select_option( + security.IasWd.Warning.WarningMode.Burglar.name.lower() + ) await zha_gateway.async_block_till_done() - assert entity.state["state"] == security.IasWd.Warning.WarningMode.Burglar.name + assert ( + entity.state["state"] == security.IasWd.Warning.WarningMode.Burglar.name.lower() + ) class MotionSensitivityQuirk(CustomDevice): @@ -251,7 +255,7 @@ async def test_non_zcl_select_state_restoration( assert entity.state["state"] is None entity.restore_external_state_attributes( - state=security.IasWd.Warning.WarningMode.Burglar.name + state=security.IasWd.Warning.WarningMode.Burglar.name.lower() ) assert ( entity.state["state"] == security.IasWd.Warning.WarningMode.Burglar.name.lower() From f2bc83df0e9d3084f394ffd05746658264598a20 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 15 Jul 2024 17:57:58 +0200 Subject: [PATCH 6/8] fix tests after temporary fix is removed --- tests/test_select.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_select.py b/tests/test_select.py index 0d3294042..a1ee20810 100644 --- a/tests/test_select.py +++ b/tests/test_select.py @@ -262,6 +262,6 @@ async def test_non_zcl_select_state_restoration( ) entity.restore_external_state_attributes( - state=security.IasWd.Warning.WarningMode.Fire.name + state=security.IasWd.Warning.WarningMode.Fire.name.lower() ) assert entity.state["state"] == security.IasWd.Warning.WarningMode.Fire.name.lower() From 02f63c428be942d1d3ae8fd40ed238d59e248083 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 15 Jul 2024 18:02:23 +0200 Subject: [PATCH 7/8] fix test_discovery --- tests/test_discover.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_discover.py b/tests/test_discover.py index 7e4a87fb5..d6bda29cd 100644 --- a/tests/test_discover.py +++ b/tests/test_discover.py @@ -647,7 +647,7 @@ class FakeXiaomiAqaraDriverE1(XiaomiAqaraDriverE1): ) assert ( power_source_entity.state["state"] - == BasicCluster.PowerSource.Mains_single_phase.name + == BasicCluster.PowerSource.Mains_single_phase.name.lower() ) hook_state_entity = get_entity( @@ -656,7 +656,7 @@ class FakeXiaomiAqaraDriverE1(XiaomiAqaraDriverE1): exact_entity_type=sensor.EnumSensor, qualifier_func=lambda e: e._enum == AqaraE1HookState, ) - assert hook_state_entity.state["state"] == AqaraE1HookState.Unlocked.name + assert hook_state_entity.state["state"] == AqaraE1HookState.Unlocked.name.lower() error_detected_entity = get_entity( zha_device, From 1f919ff4e551d26c355d84b9bdb88dabef15f713 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 15 Jul 2024 18:15:38 +0200 Subject: [PATCH 8/8] test workaround --- tests/test_select.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_select.py b/tests/test_select.py index a1ee20810..559b7e146 100644 --- a/tests/test_select.py +++ b/tests/test_select.py @@ -265,3 +265,9 @@ async def test_non_zcl_select_state_restoration( state=security.IasWd.Warning.WarningMode.Fire.name.lower() ) assert entity.state["state"] == security.IasWd.Warning.WarningMode.Fire.name.lower() + + # test workaround for existing installations updating + entity.restore_external_state_attributes( + state=security.IasWd.Warning.WarningMode.Fire.name + ) + assert entity.state["state"] == security.IasWd.Warning.WarningMode.Fire.name.lower()