From 8bf6dfad632d16547d0a29442932f6eb32414ea1 Mon Sep 17 00:00:00 2001 From: Marcel Steinbach Date: Fri, 6 Sep 2024 18:11:38 +0200 Subject: [PATCH 1/7] fix representation of group id in binds_get group id is unit16 in DstAddress.nwk, needs conversion to hex so that we can prefix with 0x --- custom_components/zha_toolkit/binds.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/zha_toolkit/binds.py b/custom_components/zha_toolkit/binds.py index 41629e3..4a3af2a 100644 --- a/custom_components/zha_toolkit/binds.py +++ b/custom_components/zha_toolkit/binds.py @@ -612,7 +612,7 @@ async def binds_get( if binding.DstAddress.addrmode == 1: dst_info = { "addrmode": binding.DstAddress.addrmode, - "group": f"0x{binding.DstAddress.nwk}", + "group": f"0x{binding.DstAddress.nwk:04X}", } elif binding.DstAddress.addrmode == 3: dst_info = { From 2cb2e02c6830e42109e1fae34a29f80bdbbcc53d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Modzelewski?= Date: Tue, 17 Sep 2024 12:53:11 +0200 Subject: [PATCH 2/7] Pass zha_gw_hass to utils.get_hass to avoid attribute error fixes: #258 --- custom_components/zha_toolkit/__init__.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/custom_components/zha_toolkit/__init__.py b/custom_components/zha_toolkit/__init__.py index 6a59ac4..7d05f37 100644 --- a/custom_components/zha_toolkit/__init__.py +++ b/custom_components/zha_toolkit/__init__.py @@ -806,15 +806,19 @@ async def toolkit_service(service): LOGGER.debug( "Fire %s -> %s", params[p.EVT_SUCCESS], event_data ) - u.get_hass(zha_gw).bus.fire(params[p.EVT_SUCCESS], event_data) + u.get_hass(zha_gw_hass).bus.fire( + params[p.EVT_SUCCESS], event_data + ) else: if params[p.EVT_FAIL] is not None: LOGGER.debug("Fire %s -> %s", params[p.EVT_FAIL], event_data) - u.get_hass(zha_gw).bus.fire(params[p.EVT_FAIL], event_data) + u.get_hass(zha_gw_hass).bus.fire( + params[p.EVT_FAIL], event_data + ) if params[p.EVT_DONE] is not None: LOGGER.debug("Fire %s -> %s", params[p.EVT_DONE], event_data) - u.get_hass(zha_gw).bus.fire(params[p.EVT_DONE], event_data) + u.get_hass(zha_gw_hass).bus.fire(params[p.EVT_DONE], event_data) if handler_exception is not None: LOGGER.error( From f27fa190bae773b510f310c59367aedd42d58a34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Modzelewski?= Date: Tue, 17 Sep 2024 13:06:30 +0200 Subject: [PATCH 3/7] Migrate from DATA_TYPES to DataType fixes: #261 --- custom_components/zha_toolkit/scan_device.py | 9 ++++++--- custom_components/zha_toolkit/utils.py | 6 +++--- custom_components/zha_toolkit/zcl_attr.py | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/custom_components/zha_toolkit/scan_device.py b/custom_components/zha_toolkit/scan_device.py index d9fce9b..3525685 100644 --- a/custom_components/zha_toolkit/scan_device.py +++ b/custom_components/zha_toolkit/scan_device.py @@ -216,7 +216,10 @@ async def discover_attributes_extended(cluster, manufacturer=None, tries=3): attr_name = attr_def.name else: attr_name = attr_def[0] - attr_type = foundation.DATA_TYPES.get(attr_rec.datatype) + try: + attr_type = foundation.DataType.from_type_id(attr_rec.datatype) + except KeyError: + attr_type = None access_acl = t.uint8_t(attr_rec.acl) # Note: reading back Array type was fixed in zigpy 0.58.1 . @@ -229,8 +232,8 @@ async def discover_attributes_extended(cluster, manufacturer=None, tries=3): if attr_type: attr_type = [ attr_type_hex, - attr_type[1].__name__, - attr_type[2].__name__, + attr_type.python_type.__name__, + attr_type.type_class.__name__, ] else: attr_type = attr_type_hex diff --git a/custom_components/zha_toolkit/utils.py b/custom_components/zha_toolkit/utils.py index 866ccc0..20acab9 100644 --- a/custom_components/zha_toolkit/utils.py +++ b/custom_components/zha_toolkit/utils.py @@ -631,7 +631,7 @@ def record_read_data( attr_name = params[p.CSV_LABEL] else: python_type = type(read_resp[0][attr_id]) - attr_type = f.DATA_TYPES.pytype_to_datatype_id(python_type) + attr_type = f.DataType.from_python_type(python_type).type_id try: attr_def = cluster.attributes.get( @@ -690,7 +690,7 @@ def get_attr_type(cluster, attr_id): else: attr_type = attr_def[1] - return f.DATA_TYPES.pytype_to_datatype_id(attr_type) + return f.DataType.from_python_type(attr_type).type_id except Exception: # nosec LOGGER.debug("Could not find type for %s in %r", attr_id, cluster) @@ -800,7 +800,7 @@ def attr_encode(attr_val_in, attr_type): # noqa C901 else: # Try to apply conversion using foundation DATA_TYPES table # Note: this is not perfect and specific conversions may be needed. - data_type = f.DATA_TYPES[attr_type][1] + data_type = f.DataType.from_type_id(attr_type).python_type LOGGER.debug(f"Data type '{data_type}' for attr type {attr_type}") if isinstance(attr_val_in, list): # Without length byte after serialisation: diff --git a/custom_components/zha_toolkit/zcl_attr.py b/custom_components/zha_toolkit/zcl_attr.py index 62e1c96..596506c 100644 --- a/custom_components/zha_toolkit/zcl_attr.py +++ b/custom_components/zha_toolkit/zcl_attr.py @@ -382,9 +382,9 @@ async def attr_write( # noqa: C901 # Try to get attribute type if success and (attr_id in result_read[0]): python_type = type(result_read[0][attr_id]) - found_attr_type = f.DATA_TYPES.pytype_to_datatype_id( + found_attr_type = f.DataType.from_python_type( python_type - ) + ).type_id LOGGER.debug( "Type determined from read: 0x%02x", found_attr_type ) From 55f440af55f3b28cb37ed7acb396e14bfa5e72c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Modzelewski?= Date: Tue, 17 Sep 2024 13:09:25 +0200 Subject: [PATCH 4/7] Require 2024.9.0 --- hacs.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hacs.json b/hacs.json index b09835a..f43d65d 100644 --- a/hacs.json +++ b/hacs.json @@ -5,5 +5,5 @@ "filename": "zha-toolkit.zip", "render_readme": true, "persistent_directory": "local", - "homeassistant": "2024.8.0" + "homeassistant": "2024.9.0" } From 3fc0ec764c09da7e17e87b1d8576af7078e66ac1 Mon Sep 17 00:00:00 2001 From: Stephen Just Date: Sat, 21 Sep 2024 22:46:01 -0700 Subject: [PATCH 5/7] Add Scenes and Widnow Coverings as bindable clusters For Somfy Zigbee window coverings, remotes are paired with window coverings by binding the Window Coverings (0x0102) and Scenes (0x0005) clusters. Window Coverings handles open/close/stop commands, whereas the Scenes cluster handles save/recall of presets. --- custom_components/zha_toolkit/binds.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/custom_components/zha_toolkit/binds.py b/custom_components/zha_toolkit/binds.py index 41629e3..61b64dd 100644 --- a/custom_components/zha_toolkit/binds.py +++ b/custom_components/zha_toolkit/binds.py @@ -12,8 +12,10 @@ LOGGER = logging.getLogger(__name__) BINDABLE_OUT_CLUSTERS = [ + 0x0005, # Scenes 0x0006, # OnOff 0x0008, # Level + 0x0102, # Window Covering 0x0300, # Color Control ] BINDABLE_IN_CLUSTERS = [ From 4f0b657138399e1a567f0dd8e9888d6f538fd15a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Modzelewski?= Date: Wed, 30 Oct 2024 13:01:29 +0100 Subject: [PATCH 6/7] fixup! Migrate from DATA_TYPES to DataType --- custom_components/zha_toolkit/scan_device.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/zha_toolkit/scan_device.py b/custom_components/zha_toolkit/scan_device.py index 3525685..5ab4ad4 100644 --- a/custom_components/zha_toolkit/scan_device.py +++ b/custom_components/zha_toolkit/scan_device.py @@ -233,7 +233,7 @@ async def discover_attributes_extended(cluster, manufacturer=None, tries=3): attr_type = [ attr_type_hex, attr_type.python_type.__name__, - attr_type.type_class.__name__, + attr_type.type_class.name, ] else: attr_type = attr_type_hex From 9c63447e33e2856580a827417842335bb41bd427 Mon Sep 17 00:00:00 2001 From: mdeweerd Date: Sat, 21 Dec 2024 19:53:15 +0100 Subject: [PATCH 7/7] Fix translations for hassfest --- custom_components/zha_toolkit/translations/en.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/custom_components/zha_toolkit/translations/en.json b/custom_components/zha_toolkit/translations/en.json index b12c852..8be32b2 100644 --- a/custom_components/zha_toolkit/translations/en.json +++ b/custom_components/zha_toolkit/translations/en.json @@ -82,11 +82,11 @@ }, "force_update": { "name": "Force Update", - "description": "Force an update event when the state is written When not set or false, if the state value is unchanged, the update may not trigger an automation.\n" + "description": "Force an update event when the state is written When not set or false, if the state value is unchanged, the update may not trigger an automation." }, "use_cache": { "name": "Use Cache", - "description": "Use zigpy attribute cache to get the value of an attribute. (Does not send a zigbee packet to read the attribute)\n" + "description": "Use zigpy attribute cache to get the value of an attribute. (Does not send a zigbee packet to read the attribute)" }, "event_success": { "name": "Success Event Name", @@ -278,11 +278,11 @@ }, "force_update": { "name": "Force Update", - "description": "Force an update event when the state is written When not set or false, if the state value is unchanged, the update may not trigger an automation.\n" + "description": "Force an update event when the state is written When not set or false, if the state value is unchanged, the update may not trigger an automation." }, "use_cache": { "name": "Use Cache", - "description": "Use zigpy attribute cache to get the value of an attribute. (Does not send a zigbee packet to read the attribute)\n" + "description": "Use zigpy attribute cache to get the value of an attribute. (Does not send a zigbee packet to read the attribute)" }, "event_success": { "name": "Success Event Name", @@ -352,7 +352,7 @@ }, "use_cache": { "name": "Use Cache", - "description": "Use zigpy attribute cache to get the value of an attribute. (Does not send a zigbee packet to read the attribute)\n" + "description": "Use zigpy attribute cache to get the value of an attribute. (Does not send a zigbee packet to read the attribute)" }, "tries": { "name": "Tries",