Closed tomasbedrich closed 8 months ago
Do you have more information about how the generic method fails?
service: zha_toolkit.attr_write
data:
ieee: button.ubisys_c4_5504_identify
endpoint: 232
cluster: 64512
attribute: 1
attr_type: 0x48
attr_val: "41040006000d0106000206010d0206000206020d0306000206030d04060002"
read_before_write: true
read_after_write: false
use_cache: false
$ tail -f /config/home-assistant.log | grep "custom_components.zha_toolkit"
2023-10-17 13:11:26.669 INFO (MainThread) [custom_components.zha_toolkit] Running ZHA Toolkit service: <ServiceCall zha_toolkit.attr_write (c:01HCYNAQEB8VBEP9BNR4F4CTCA): ieee=button.ubisys_c4_5504_identify, endpoint=232, cluster=64512, attribute=1, attr_type=72, attr_val=41040006000d0106000206010d0206000206020d0306000206030d04060002, read_before_write=True, read_after_write=False, use_cache=False>
2023-10-17 13:11:26.670 DEBUG (MainThread) [custom_components.zha_toolkit] Got hass.data['zha']/gateway <custom_components.zha.core.gateway.ZHAGateway object at 0xffff9ada28d0>
2023-10-17 13:11:26.694 DEBUG (MainThread) [custom_components.zha_toolkit] module is <module 'custom_components.zha_toolkit' from '/config/custom_components/zha_toolkit/__init__.py'>
2023-10-17 13:11:26.700 DEBUG (MainThread) [custom_components.zha_toolkit.utils] Parameters '{'ieee': 'button.ubisys_c4_5504_identify', 'endpoint': 232, 'cluster': 64512, 'attribute': 1, 'attr_type': 72, 'attr_val': '41040006000d0106000206010d0206000206020d0306000206030d04060002', 'read_before_write': True, 'read_after_write': False, 'use_cache': False}'
2023-10-17 13:11:26.701 DEBUG (MainThread) [custom_components.zha_toolkit.utils] Final manf 'None'
2023-10-17 13:11:26.702 DEBUG (MainThread) [custom_components.zha_toolkit.utils] registry_entity RegistryEntry(entity_id='button.ubisys_c4_5504_identify', unique_id='00:1f:ee:00:00:00:9a:e3-1-3', platform='zha', aliases=set(), area_id=None, capabilities=None, config_entry_id='5e33ebc13289867554f7364db82af185', device_class=None, device_id='c2520a704c74c0b5a187208e684b55fc', disabled_by=None, entity_category=<EntityCategory.DIAGNOSTIC: 'diagnostic'>, hidden_by=None, icon=None, id='80e47e521f856efd43f9a429ec9a1715', has_entity_name=True, name=None, options={'conversation': {'should_expose': False}}, original_device_class='identify', original_icon=None, original_name='Identify', supported_features=0, translation_key=None, unit_of_measurement=None)
2023-10-17 13:11:26.702 DEBUG (MainThread) [custom_components.zha_toolkit.utils] registry_device DeviceEntry(area_id=None, config_entries={'5e33ebc13289867554f7364db82af185'}, configuration_url=None, connections={('zigbee', '00:1f:ee:00:00:00:9a:e3')}, disabled_by=None, entry_type=None, hw_version=None, id='c2520a704c74c0b5a187208e684b55fc', identifiers={('zha', '00:1f:ee:00:00:00:9a:e3')}, manufacturer='ubisys', model='C4 (5504)', name_by_user=None, name='ubisys C4 (5504)', suggested_area=None, sw_version='0x02120404', via_device_id='34cca87150cffeda1beaafec3e4619c1', is_new=False)
2023-10-17 13:11:26.705 DEBUG (MainThread) [custom_components.zha_toolkit] 'ieee' parameter: 'button.ubisys_c4_5504_identify' -> IEEE Addr: '00:1f:ee:00:00:00:9a:e3'
2023-10-17 13:11:26.706 DEBUG (MainThread) [custom_components.zha_toolkit] Default handler for attr_write
2023-10-17 13:11:26.706 DEBUG (MainThread) [custom_components.zha_toolkit] Handler: <function command_handler_default at 0xffff9853c900>
2023-10-17 13:11:26.707 DEBUG (MainThread) [custom_components.zha_toolkit] running default command: <ServiceCall zha_toolkit.attr_write (c:01HCYNAQEB8VBEP9BNR4F4CTCA): ieee=button.ubisys_c4_5504_identify, endpoint=232, cluster=64512, attribute=1, attr_type=72, attr_val=41040006000d0106000206010d0206000206020d0306000206030d04060002, read_before_write=True, read_after_write=False, use_cache=False>
2023-10-17 13:11:26.708 DEBUG (MainThread) [custom_components.zha_toolkit.default] Trying to import custom_components.zha_toolkit.zcl_attr to call attr_write
2023-10-17 13:11:26.715 DEBUG (MainThread) [custom_components.zha_toolkit.zcl_attr] Request attr read [1]
2023-10-17 13:11:26.760 DEBUG (MainThread) [custom_components.zha_toolkit.zcl_attr] Reading attr result (attrs, status): ({1: Array(type=AnonymousLVList, value=[b'\x00\r\x01\x06\x00\x02', b'\x01\r\x02\x06\x00\x02', b'\x02\r\x03\x06\x00\x02', b'\x03\r\x04\x06\x00\x02'])}, {})
2023-10-17 13:11:26.760 DEBUG (MainThread) [custom_components.zha_toolkit.zcl_attr] Type determined from read: 0x48
2023-10-17 13:11:26.761 DEBUG (MainThread) [custom_components.zha_toolkit.utils] Data type '<class 'zigpy.zcl.foundation.Array'>' for attr type 72
2023-10-17 13:11:26.761 DEBUG (MainThread) [custom_components.zha_toolkit.utils] Converted 41040006000d0106000206010d0206000206020d0306000206030d04060002 to TypeValue(type=Array, value=Array(type=NoneType, value=None)) - will compare to Array(type=NoneType, value=None) - Type: 0x48
2023-10-17 13:11:26.761 DEBUG (MainThread) [custom_components.zha_toolkit.zcl_attr] Request attr write [Attribute(attrid=0x0001, value=TypeValue(type=Array, value=Array(type=NoneType, value=None)))]
2023-10-17 13:11:26.762 DEBUG (MainThread) [custom_components.zha_toolkit] event_data {'zha_toolkit_version': 'v1.1.2', 'zigpy_version': '0.58.0.post2+git.80f9f8db', 'zigpy_rf_version': '0.35.9', 'ieee_org': 'button.ubisys_c4_5504_identify', 'ieee': '00:1f:ee:00:00:00:9a:e3', 'command': 'attr_write', 'command_data': None, 'start_time': '2023-10-17T11:11:26.705662+00:00', 'errors': ['AttributeError("\'str\' object has no attribute \'to_bytes\'")'], 'params': {'endpoint_id': 232, 'cluster_id': 64512, 'attr_id': 1, 'attr_type': 72, 'attr_val': '41040006000d0106000206010d0206000206020d0306000206030d04060002', 'dir': 0, 'tries': 1, 'expect_reply': True, 'args': [], 'read_before_write': True}, 'compare_val': Array(type=NoneType, value=None), 'attr_type': '0x48', 'write_is_equal': False, 'read_before': ({1: Array(type=AnonymousLVList, value=[b'\x00\r\x01\x06\x00\x02', b'\x01\r\x02\x06\x00\x02', b'\x02\r\x03\x06\x00\x02', b'\x03\r\x04\x06\x00\x02'])}, {}), 'success': False}
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 468, in _async_step
await getattr(self, handler)()
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 704, in _async_call_service_step
response_data = await self._async_run_long_action(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 666, in _async_run_long_action
return long_task.result()
^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/core.py", line 2012, in async_call
response_data = await coro
^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/core.py", line 2049, in _execute_service
return await target(service_call)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/zha_toolkit/__init__.py", line 816, in toolkit_service
raise handler_exception
File "/config/custom_components/zha_toolkit/__init__.py", line 780, in toolkit_service
handler_result = await handler(
^^^^^^^^^^^^^^
File "/config/custom_components/zha_toolkit/__init__.py", line 882, in command_handler_default
return await default.default(
^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/zha_toolkit/default.py", line 40, in default
await handler(app, listener, ieee, cmd, data, service, params, event_data)
File "/config/custom_components/zha_toolkit/zcl_attr.py", line 462, in attr_write
result_write = await u.cluster__write_attributes(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/zha_toolkit/utils.py", line 964, in cluster__write_attributes
return await cluster._write_attributes(attrs, manufacturer=manufacturer)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/deps/lib/python3.11/site-packages/zigpy/zcl/__init__.py", line 357, in request
hdr, request = self._create_request(
^^^^^^^^^^^^^^^^^^^^^
File "/config/deps/lib/python3.11/site-packages/zigpy/zcl/__init__.py", line 320, in _create_request
request.serialize() # Throw an error before generating a new TSN
^^^^^^^^^^^^^^^^^^^
File "/config/deps/lib/python3.11/site-packages/zigpy/types/struct.py", line 250, in serialize
chunks.append(value.serialize())
^^^^^^^^^^^^^^^^^
File "/config/deps/lib/python3.11/site-packages/zigpy/types/basic.py", line 862, in serialize
return b"".join([self._item_type(i).serialize() for i in self])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/deps/lib/python3.11/site-packages/zigpy/types/basic.py", line 862, in <listcomp>
return b"".join([self._item_type(i).serialize() for i in self])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/deps/lib/python3.11/site-packages/zigpy/types/struct.py", line 250, in serialize
chunks.append(value.serialize())
^^^^^^^^^^^^^^^^^
File "/config/deps/lib/python3.11/site-packages/zigpy/zcl/foundation.py", line 102, in serialize
return self.type.to_bytes(1, "little") + self.value.serialize()
^^^^^^^^^^^^^^^^^^^^^^
File "/config/deps/lib/python3.11/site-packages/zigpy/zcl/foundation.py", line 102, in serialize
return self.type.to_bytes(1, "little") + self.value.serialize()
^^^^^^^^^^^^^^^^^^
AttributeError: 'str' object has no attribute 'to_bytes'
Or another way:
service: zha_toolkit.attr_write
data:
ieee: button.ubisys_c4_5504_identify
endpoint: 232
cluster: 64512
attribute: 1
attr_type: 0x48
attr_val: [65, 4, 0, 6, 0, 13, 1, 6, 0, 2, 6, 1, 13, 2, 6, 0, 2, 6, 2, 13, 3, 6, 0, 2, 6, 3, 13, 4, 6, 0, 2]
read_before_write: true
read_after_write: false
use_cache: false
2023-10-17 13:14:53.801 INFO (MainThread) [custom_components.zha_toolkit] Running ZHA Toolkit service: <ServiceCall zha_toolkit.attr_write (c:01HCYNH1Q6W2EYASQ7CC2ERVA8): ieee=button.ubisys_c4_5504_identify, endpoint=232, cluster=64512, attribute=1, attr_type=72, attr_val=[65, 4, 0, 6, 0, 13, 1, 6, 0, 2, 6, 1, 13, 2, 6, 0, 2, 6, 2, 13, 3, 6, 0, 2, 6, 3, 13, 4, 6, 0, 2], read_before_write=True, read_after_write=False, use_cache=False>
2023-10-17 13:14:53.801 DEBUG (MainThread) [custom_components.zha_toolkit] Got hass.data['zha']/gateway <custom_components.zha.core.gateway.ZHAGateway object at 0xffff9ada28d0>
2023-10-17 13:14:53.826 DEBUG (MainThread) [custom_components.zha_toolkit] module is <module 'custom_components.zha_toolkit' from '/config/custom_components/zha_toolkit/__init__.py'>
2023-10-17 13:14:53.832 DEBUG (MainThread) [custom_components.zha_toolkit.utils] Parameters '{'ieee': 'button.ubisys_c4_5504_identify', 'endpoint': 232, 'cluster': 64512, 'attribute': 1, 'attr_type': 72, 'attr_val': [65, 4, 0, 6, 0, 13, 1, 6, 0, 2, 6, 1, 13, 2, 6, 0, 2, 6, 2, 13, 3, 6, 0, 2, 6, 3, 13, 4, 6, 0, 2], 'read_before_write': True, 'read_after_write': False, 'use_cache': False}'
2023-10-17 13:14:53.832 DEBUG (MainThread) [custom_components.zha_toolkit.utils] Final manf 'None'
2023-10-17 13:14:53.833 DEBUG (MainThread) [custom_components.zha_toolkit.utils] registry_entity RegistryEntry(entity_id='button.ubisys_c4_5504_identify', unique_id='00:1f:ee:00:00:00:9a:e3-1-3', platform='zha', aliases=set(), area_id=None, capabilities=None, config_entry_id='5e33ebc13289867554f7364db82af185', device_class=None, device_id='c2520a704c74c0b5a187208e684b55fc', disabled_by=None, entity_category=<EntityCategory.DIAGNOSTIC: 'diagnostic'>, hidden_by=None, icon=None, id='80e47e521f856efd43f9a429ec9a1715', has_entity_name=True, name=None, options={'conversation': {'should_expose': False}}, original_device_class='identify', original_icon=None, original_name='Identify', supported_features=0, translation_key=None, unit_of_measurement=None)
2023-10-17 13:14:53.833 DEBUG (MainThread) [custom_components.zha_toolkit.utils] registry_device DeviceEntry(area_id=None, config_entries={'5e33ebc13289867554f7364db82af185'}, configuration_url=None, connections={('zigbee', '00:1f:ee:00:00:00:9a:e3')}, disabled_by=None, entry_type=None, hw_version=None, id='c2520a704c74c0b5a187208e684b55fc', identifiers={('zha', '00:1f:ee:00:00:00:9a:e3')}, manufacturer='ubisys', model='C4 (5504)', name_by_user=None, name='ubisys C4 (5504)', suggested_area=None, sw_version='0x02120404', via_device_id='34cca87150cffeda1beaafec3e4619c1', is_new=False)
2023-10-17 13:14:53.835 DEBUG (MainThread) [custom_components.zha_toolkit] 'ieee' parameter: 'button.ubisys_c4_5504_identify' -> IEEE Addr: '00:1f:ee:00:00:00:9a:e3'
2023-10-17 13:14:53.835 DEBUG (MainThread) [custom_components.zha_toolkit] Default handler for attr_write
2023-10-17 13:14:53.836 DEBUG (MainThread) [custom_components.zha_toolkit] Handler: <function command_handler_default at 0xffff9362cf40>
2023-10-17 13:14:53.836 DEBUG (MainThread) [custom_components.zha_toolkit] running default command: <ServiceCall zha_toolkit.attr_write (c:01HCYNH1Q6W2EYASQ7CC2ERVA8): ieee=button.ubisys_c4_5504_identify, endpoint=232, cluster=64512, attribute=1, attr_type=72, attr_val=[65, 4, 0, 6, 0, 13, 1, 6, 0, 2, 6, 1, 13, 2, 6, 0, 2, 6, 2, 13, 3, 6, 0, 2, 6, 3, 13, 4, 6, 0, 2], read_before_write=True, read_after_write=False, use_cache=False>
2023-10-17 13:14:53.838 DEBUG (MainThread) [custom_components.zha_toolkit.default] Trying to import custom_components.zha_toolkit.zcl_attr to call attr_write
2023-10-17 13:14:53.842 DEBUG (MainThread) [custom_components.zha_toolkit.zcl_attr] Request attr read [1]
2023-10-17 13:14:53.884 DEBUG (MainThread) [custom_components.zha_toolkit.zcl_attr] Reading attr result (attrs, status): ({1: Array(type=AnonymousLVList, value=[b'\x00\r\x01\x06\x00\x02', b'\x01\r\x02\x06\x00\x02', b'\x02\r\x03\x06\x00\x02', b'\x03\r\x04\x06\x00\x02'])}, {})
2023-10-17 13:14:53.884 DEBUG (MainThread) [custom_components.zha_toolkit.zcl_attr] Type determined from read: 0x48
2023-10-17 13:14:53.884 DEBUG (MainThread) [custom_components.zha_toolkit.utils] Data type '<class 'zigpy.zcl.foundation.Array'>' for attr type 72
2023-10-17 13:14:53.884 DEBUG (MainThread) [custom_components.zha_toolkit.utils] Converted [65, 4, 0, 6, 0, 13, 1, 6, 0, 2, 6, 1, 13, 2, 6, 0, 2, 6, 2, 13, 3, 6, 0, 2, 6, 3, 13, 4, 6, 0, 2] to TypeValue(type=Array, value=Array(type=NoneType, value=None)) - will compare to Array(type=NoneType, value=None) - Type: 0x48
2023-10-17 13:14:53.885 DEBUG (MainThread) [custom_components.zha_toolkit.zcl_attr] Request attr write [Attribute(attrid=0x0001, value=TypeValue(type=Array, value=Array(type=NoneType, value=None)))]
2023-10-17 13:14:53.886 DEBUG (MainThread) [custom_components.zha_toolkit] event_data {'zha_toolkit_version': 'v1.1.2', 'zigpy_version': '0.58.0.post2+git.80f9f8db', 'zigpy_rf_version': '0.35.9', 'ieee_org': 'button.ubisys_c4_5504_identify', 'ieee': '00:1f:ee:00:00:00:9a:e3', 'command': 'attr_write', 'command_data': None, 'start_time': '2023-10-17T11:14:53.835470+00:00', 'errors': ['AttributeError("\'list\' object has no attribute \'to_bytes\'")'], 'params': {'endpoint_id': 232, 'cluster_id': 64512, 'attr_id': 1, 'attr_type': 72, 'attr_val': [65, 4, 0, 6, 0, 13, 1, 6, 0, 2, 6, 1, 13, 2, 6, 0, 2, 6, 2, 13, 3, 6, 0, 2, 6, 3, 13, 4, 6, 0, 2], 'dir': 0, 'tries': 1, 'expect_reply': True, 'args': [], 'read_before_write': True}, 'compare_val': Array(type=NoneType, value=None), 'attr_type': '0x48', 'write_is_equal': False, 'read_before': ({1: Array(type=AnonymousLVList, value=[b'\x00\r\x01\x06\x00\x02', b'\x01\r\x02\x06\x00\x02', b'\x02\r\x03\x06\x00\x02', b'\x03\r\x04\x06\x00\x02'])}, {}), 'success': False}
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 468, in _async_step
await getattr(self, handler)()
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 704, in _async_call_service_step
response_data = await self._async_run_long_action(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 666, in _async_run_long_action
return long_task.result()
^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/core.py", line 2012, in async_call
response_data = await coro
^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/core.py", line 2049, in _execute_service
return await target(service_call)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/zha_toolkit/__init__.py", line 816, in toolkit_service
raise handler_exception
File "/config/custom_components/zha_toolkit/__init__.py", line 780, in toolkit_service
handler_result = await handler(
^^^^^^^^^^^^^^
File "/config/custom_components/zha_toolkit/__init__.py", line 882, in command_handler_default
return await default.default(
^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/zha_toolkit/default.py", line 40, in default
await handler(app, listener, ieee, cmd, data, service, params, event_data)
File "/config/custom_components/zha_toolkit/zcl_attr.py", line 462, in attr_write
result_write = await u.cluster__write_attributes(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/zha_toolkit/utils.py", line 964, in cluster__write_attributes
return await cluster._write_attributes(attrs, manufacturer=manufacturer)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/deps/lib/python3.11/site-packages/zigpy/zcl/__init__.py", line 357, in request
hdr, request = self._create_request(
^^^^^^^^^^^^^^^^^^^^^
File "/config/deps/lib/python3.11/site-packages/zigpy/zcl/__init__.py", line 320, in _create_request
request.serialize() # Throw an error before generating a new TSN
^^^^^^^^^^^^^^^^^^^
File "/config/deps/lib/python3.11/site-packages/zigpy/types/struct.py", line 250, in serialize
chunks.append(value.serialize())
^^^^^^^^^^^^^^^^^
File "/config/deps/lib/python3.11/site-packages/zigpy/types/basic.py", line 862, in serialize
return b"".join([self._item_type(i).serialize() for i in self])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/deps/lib/python3.11/site-packages/zigpy/types/basic.py", line 862, in <listcomp>
return b"".join([self._item_type(i).serialize() for i in self])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/deps/lib/python3.11/site-packages/zigpy/types/struct.py", line 250, in serialize
chunks.append(value.serialize())
^^^^^^^^^^^^^^^^^
File "/config/deps/lib/python3.11/site-packages/zigpy/zcl/foundation.py", line 102, in serialize
return self.type.to_bytes(1, "little") + self.value.serialize()
^^^^^^^^^^^^^^^^^^^^^^
File "/config/deps/lib/python3.11/site-packages/zigpy/zcl/foundation.py", line 102, in serialize
return self.type.to_bytes(1, "little") + self.value.serialize()
^^^^^^^^^^^^^^^^^^
AttributeError: 'list' object has no attribute 'to_bytes'
Maybe I am just passing attr_value
in a wrong way?
I believe the most important thing is that ZCL Arrays are typed collections. The generic encoding logic only creates an Array object with a single parameter, while Array needs two parameters to be constructed - item type, contents. This can be observed in logs, search for: "Converted "
Maybe I am just passing
attr_value
in a wrong way?
I realized that I can make writes to attributes that do not exist, so I updated the code to fix it so that it works for arrays. I "disabled" the code you added for 0x48 specifically by comparing to 0xFF48 so that it is not lost at this time.
When I tried my code using the following:.
attr_val: [4, 0, 6, 0, 13, 1, 6, 0, 2, 6, 1, 13, 2, 6, 0, 2, 6, 2, 13, 3, 6, 0, 2, 6, 3, 13, 4, 6, 0, 2]
I got:
Attribute Field
Attribute: Unknown (0xfde8)
Data Type: Array (0x48)
Elements Type: 56-Bit Bitmap (0x1e)
Elements Number: 4
Element #1, Bitmap: 020006010d0006
Bitmap56: 0x00020006010d0006
Element #2, Bitmap: 020006020d0106
Bitmap56: 0x00020006020d0106
Element #3, Bitmap: 020006030d0206
Bitmap56: 0x00020006030d0206
Element #4, Bitmap: 020006040d0306
Bitmap56: 0x00020006040d0306
Frame (82 bytes):
0000 61 88 11 0a 88 d4 21 00 00 48 02 d4 21 00 00 1e a.....!..H..!...
0010 f9 28 20 3d df 03 0c 41 6a 01 00 4b 12 00 00 60 .( =...Aj..K...`
0020 bf 63 ac 11 66 0e 6b 43 91 ca 88 be 76 36 33 b8 .c..f.kC....v63.
0030 28 15 91 ca 01 58 85 5c 89 db 75 a4 d8 c0 87 dd (....X.\..u.....
0040 cd 9e 9e 75 37 9a 7c 3f 53 53 57 53 a6 ca d1 c0 ...u7.|?SSWS....
0050 0a eb ..
Decrypted ZigBee Payload (45 bytes):
0000 40 01 00 00 04 01 01 ad 00 51 02 e8 fd 48 1e 04 @........Q...H..
0010 00 06 00 0d 01 06 00 02 06 01 0d 02 06 00 02 06 ................
0020 02 0d 03 06 00 02 06 03 0d 04 06 00 02 .............
However, when using your code, I got:
ZigBee Cluster Library Frame, Command: Write Attributes, Seq: 40
Frame Control Field: Profile-wide (0x00)
.... ..00 = Frame Type: Profile-wide (0x0)
.... .0.. = Manufacturer Specific: False
.... 0... = Direction: Client to Server
...0 .... = Disable Default Response: False
Sequence Number: 40
Command: Write Attributes (0x02)
Attribute Field
Attribute: Unknown (0xfde8)
Data Type: Array (0x48)
Elements Type: Octet String (0x41)
Elements Number: 4
Element #1, Octets: 00:0d:01:06:00:02
Octet String: 00:0d:01:06:00:02
Element #2, Octets: 01:0d:02:06:00:02
Octet String: 01:0d:02:06:00:02
Element #3, Octets: 02:0d:03:06:00:02
Octet String: 02:0d:03:06:00:02
Element #4, Octets: 03:0d:04:06:00:02
Octet String: 03:0d:04:06:00:02
Decrypted ZigBee Payload (45 bytes):
0000 40 01 00 00 04 01 01 ff 00 28 02 e8 fd 48 41 04 @........(...HA.
0010 00 06 00 0d 01 06 00 02 06 01 0d 02 06 00 02 06 ................
0020 02 0d 03 06 00 02 06 03 0d 04 06 00 02 .............
So the latter is better for arrays. However, the questions is:
So the generic method is now better at handling lists, but Arrays still need something specific.
I invite you to verify the "compare_val" as I can try it on a device.
Anything else I can help w.r.t. this PR?
Anything else I can help w.r.t. this PR?
Yes, I invited you to verify the "compare_val" as I can not try it myself on a device.
With version https://github.com/mdeweerd/zha-toolkit/pull/210/commits/561e95e3bbd813530c14f4c9c29678ef844b4cd0, I have this result:
service: zha_toolkit.attr_write
data:
ieee: button.ubisys_c4_5504_identify
endpoint: 232
cluster: 64512
attribute: 1
attr_type: 0x48
attr_val: [65, 4, 0, 6, 0, 13, 1, 6, 0, 2, 6, 1, 13, 2, 6, 0, 2, 6, 2, 13, 3, 6, 0, 2, 6, 3, 13, 4, 6, 0, 2]
read_before_write: false
read_after_write: true
use_cache: false
res:
zha_toolkit_version: v1.1.2
zigpy_version: 0.58.0.post2+git.80f9f8db
zigpy_rf_version: 0.35.9
ieee_org: button.ubisys_c4_5504_identify
ieee: 00:1f:ee:00:00:00:9a:e3
command: attr_write
command_data: null
start_time: "2023-10-18T09:19:18.987042+00:00"
errors: []
params:
endpoint_id: 232
cluster_id: 64512
attr_id: 1
attr_type: 72
attr_val:
- 65
- 4
- 0
- 6
- 0
- 13
- 1
- 6
- 0
- 2
- 6
- 1
- 13
- 2
- 6
- 0
- 2
- 6
- 2
- 13
- 3
- 6
- 0
- 2
- 6
- 3
- 13
- 4
- 6
- 0
- 2
dir: 0
tries: 1
expect_reply: true
args: []
read_after_write: true
compare_val:
- 65
- 4
- 0
- 6
- 0
- 13
- 1
- 6
- 0
- 2
- 6
- 1
- 13
- 2
- 6
- 0
- 2
- 6
- 2
- 13
- 3
- 6
- 0
- 2
- 6
- 3
- 13
- 4
- 6
- 0
- 2
attr_type: "0x48"
write_is_equal: false
result_write:
- - status: 0
attrid: null
result_read: >-
({1: Array(type=AnonymousLVList, value=[b'\x00\r\x01\x06\x00\x02',
b'\x01\r\x02\x06\x00\x02', b'\x02\r\x03\x06\x00\x02',
b'\x03\r\x04\x06\x00\x02'])}, {})
success: false
While the compare_val
equals to what was written, the result read is different because zigpy
parses the Array structure. Based on that, zha_toolkit
returns write_is_equal: false
, which is a bit misleading. This is why I originally returned compare_val = None
for this raw array write.
Ok, zigpy returns the list but I'ld expecte the serialised value is compared, except that the structure is reported.
I've updated the code to report the serialized values when the match fails. So based on that we can update the "compare_val" to what would actually match when the read succeeds. (That code change is untested, so might need some adjustments).
I rebased the branch to incorporate another fixes from main
and ran another series of tests. Now it looks like:
service: zha_toolkit.attr_write
data:
ieee: button.ubisys_c4_5504_identify
endpoint: 232
cluster: 64512
attribute: 1
attr_type: 0x48
attr_val: [65, 4, 0, 6, 0, 13, 1, 6, 0, 2, 6, 1, 13, 2, 6, 0, 2, 6, 2, 13, 3, 6, 0, 2, 6, 3, 13, 4, 6, 0, 2]
read_before_write: false
read_after_write: true
use_cache: false
res:
zha_toolkit_version: v1.1.2
zigpy_version: 0.58.0.post2+git.80f9f8db
zigpy_rf_version: 0.35.9
ieee_org: button.ubisys_c4_5504_identify
ieee: 00:1f:ee:00:00:00:9a:e3
command: attr_write
command_data: null
start_time: "2023-10-19T08:52:32.396584+00:00"
errors: []
params:
endpoint_id: 232
cluster_id: 64512
attr_id: 1
attr_type: 72
attr_val:
- 65
- 4
- 0
- 6
- 0
- 13
- 1
- 6
- 0
- 2
- 6
- 1
- 13
- 2
- 6
- 0
- 2
- 6
- 2
- 13
- 3
- 6
- 0
- 2
- 6
- 3
- 13
- 4
- 6
- 0
- 2
dir: 0
tries: 1
expect_reply: true
args: []
read_after_write: true
compare_val:
- 65
- 4
- 0
- 6
- 0
- 13
- 1
- 6
- 0
- 2
- 6
- 1
- 13
- 2
- 6
- 0
- 2
- 6
- 2
- 13
- 3
- 6
- 0
- 2
- 6
- 3
- 13
- 4
- 6
- 0
- 2
attr_type: "0x48"
write_is_equal: false
result_write:
- - status: 0
attrid: null
warnings:
- >-
Read does not match expected:
b'A\x04\x00\x06\x00\r\x01\x06\x00\x02\x06\x01\r\x02\x06\x00\x02\x06\x02\r\x03\x06\x00\x02\x06\x03\r\x04\x06\x00\x02'
<>
b'A\x04\x00\x06\x00\r\x01\x06\x00\x02\x06\x01\r\x02\x06\x00\x02\x06\x02\r\x03\x06\x00\x02\x06\x03\r\x04\x06\x00\x02'
result_read: >-
({1: Array(type=AnonymousLVList, value=[b'\x00\r\x01\x06\x00\x02',
b'\x01\r\x02\x06\x00\x02', b'\x02\r\x03\x06\x00\x02',
b'\x03\r\x04\x06\x00\x02'])}, {})
success: false
Thank you. I see that the serialized data matches, so this is what needs to be compared - currently that is not the case. You can update the code for that and test or I'll do it later (but I can not test). The serialisation is done when generating the "Read does not match expected" message (added to see if that would match).
I've updated the code to compare serialised values before and after the write.
I also enabled reading Arrays in scan_device - I think I disabled it because I had issues with, now fixed in zigpy.
Can you test this on your device. scan_device might not result in an array read if your device does not support "scanning" that attribute.
As for the scanning, I cannot see any attributes, not even for standard clusters, so I cannot evaluate if this improved the behaviour for Arrays or not:
service: zha_toolkit.scan_device
data:
ieee: button.ubisys_c4_5504_identify
endpoint: [1, 232]
the output is following:
zha_toolkit_version: v1.1.2
zigpy_version: 0.58.0.post2+git.80f9f8db
zigpy_rf_version: 0.35.9
ieee_org: button.ubisys_c4_5504_identify
ieee: 00:1f:ee:00:00:00:9a:e3
command: scan_device
command_data: null
start_time: "2023-10-24T21:49:17.305585+00:00"
errors: []
params:
endpoint_id:
- 1
- 232
dir: 0
tries: 1
expect_reply: true
args: []
read_before_write: true
read_after_write: true
scan:
ieee: 00:1f:ee:00:00:00:9a:e3
nwk: "0xcb79"
model: C4 (5504)
manufacturer: ubisys
manufacturer_id: "0x4338"
endpoints:
- id: 1
device_type: "0x0104"
profile: "0x0104"
in_clusters:
"0x0000":
cluster_id: "0x0000"
title: Basic
name: basic
attributes: {}
commands_received: {}
commands_generated: {}
"0x0003":
cluster_id: "0x0003"
title: Identify
name: identify
attributes: {}
commands_received: {}
commands_generated: {}
out_clusters:
"0x0005":
cluster_id: "0x0005"
title: Scenes
name: scenes
attributes: {}
commands_received: {}
commands_generated: {}
"0x0006":
cluster_id: "0x0006"
title: On/Off
name: on_off
attributes: {}
commands_received: {}
commands_generated: {}
"0x0008":
cluster_id: "0x0008"
title: Level control
name: level
attributes: {}
commands_received: {}
commands_generated: {}
"0x0300":
cluster_id: "0x0300"
title: Color Control
name: light_color
attributes: {}
commands_received: {}
commands_generated: {}
- id: 232
device_type: "0x0507"
profile: "0x0104"
in_clusters:
"0x0000":
cluster_id: "0x0000"
title: Basic
name: basic
attributes: {}
commands_received: {}
commands_generated: {}
"0xfc00":
cluster_id: "0xfc00"
title: Manufacturer Specific
name: manufacturer_specific
attributes: {}
commands_received: {}
commands_generated: {}
out_clusters:
"0x0003":
cluster_id: "0x0003"
title: Identify
name: identify
attributes: {}
commands_received: {}
commands_generated: {}
"0x0019":
cluster_id: "0x0019"
title: Ota
name: ota
attributes: {}
commands_received: {}
commands_generated: {}
success: true
As for the write:
service: zha_toolkit.attr_write
data:
ieee: button.ubisys_c4_5504_identify
endpoint: 232
cluster: 64512
attribute: 1
attr_type: 0x48
attr_val: [65, 4, 0, 6, 0, 13, 1, 6, 0, 2, 6, 1, 13, 2, 6, 0, 2, 6, 2, 13, 3, 6, 0, 2, 6, 3, 13, 4, 6, 0, 2]
This works okay as long as attr_val
is the same as the actual value read:
zha_toolkit_version: v1.1.2
zigpy_version: 0.58.0.post2+git.80f9f8db
zigpy_rf_version: 0.35.9
ieee_org: button.ubisys_c4_5504_identify
ieee: 00:1f:ee:00:00:00:9a:e3
command: attr_write
command_data: null
start_time: "2023-10-24T21:56:22.879429+00:00"
errors: []
params:
endpoint_id: 232
cluster_id: 64512
attr_id: 1
attr_type: 72
attr_val:
- 65
- 4
- 0
- 6
- 0
- 13
- 1
- 6
- 0
- 2
- 6
- 1
- 13
- 2
- 6
- 0
- 2
- 6
- 2
- 13
- 3
- 6
- 0
- 2
- 6
- 3
- 13
- 4
- 6
- 0
- 2
dir: 0
tries: 1
expect_reply: true
args: []
read_before_write: true
read_after_write: true
compare_val:
- 65
- 4
- 0
- 6
- 0
- 13
- 1
- 6
- 0
- 2
- 6
- 1
- 13
- 2
- 6
- 0
- 2
- 6
- 2
- 13
- 3
- 6
- 0
- 2
- 6
- 3
- 13
- 4
- 6
- 0
- 2
attr_type: "0x48"
write_is_equal: true
info: Data read is equal to data to write
result_read: >-
({1: Array(type=AnonymousLVList, value=[b'\x00\r\x01\x06\x00\x02',
b'\x01\r\x02\x06\x00\x02', b'\x02\r\x03\x06\x00\x02',
b'\x03\r\x04\x06\x00\x02'])}, {})
success: true
But, when I change the contents of attr_val
(only a single byte), I get the following error back in HA logs:
2023-10-24 23:54:52.823 DEBUG (MainThread) [custom_components.zha_toolkit.zcl_attr] Reading attr result (attrs, status): ({1: Array(type=AnonymousLVList, value=[b'\x00\r\x02\x06\x00\x02', b'\x01\r\x02\x06\x00\x02', b'\x02\r\x03\x06\x00\x02', b'\x03\r\x04\x06\x00\x02'])}, {})
2023-10-24 23:54:52.831 DEBUG (MainThread) [custom_components.zha_toolkit] event_data {'zha_toolkit_version': 'v1.1.2', 'zigpy_version': '0.58.0.post2+git.80f9f8db', 'zigpy_rf_version': '0.35.9', 'ieee_org': 'button.ubisys_c4_5504_identify', 'ieee': '00:1f:ee:00:00:00:9a:e3', 'command': 'attr_write', 'command_data': None, 'start_time': '2023-10-24T21:54:52.659660+00:00', 'errors': [], 'params': {'endpoint_id': 232, 'cluster_id': 64512, 'attr_id': 1, 'attr_type': 72, 'attr_val': [65, 4, 0, 6, 0, 13, 2, 6, 0, 2, 6, 1, 13, 2, 6, 0, 2, 6, 2, 13, 3, 6, 0, 2, 6, 3, 13, 4, 6, 0, 2], 'dir': 0, 'tries': 1, 'expect_reply': True, 'args': [], 'read_before_write': True, 'read_after_write': True}, 'compare_val': [65, 4, 0, 6, 0, 13, 2, 6, 0, 2, 6, 1, 13, 2, 6, 0, 2, 6, 2, 13, 3, 6, 0, 2, 6, 3, 13, 4, 6, 0, 2], 'attr_type': '0x48', 'write_is_equal': False, 'read_before': ({1: Array(type=AnonymousLVList, value=[b'\x00\r\x01\x06\x00\x02', b'\x01\r\x02\x06\x00\x02', b'\x02\r\x03\x06\x00\x02', b'\x03\r\x04\x06\x00\x02'])}, {}), 'result_write': Write_Attributes_rsp(status_records=[WriteAttributesStatusRecord(status=<Status.SUCCESS: 0>)]), 'result_read': "({1: Array(type=AnonymousLVList, value=[b'\\x00\\r\\x02\\x06\\x00\\x02', b'\\x01\\r\\x02\\x06\\x00\\x02', b'\\x02\\r\\x03\\x06\\x00\\x02', b'\\x03\\r\\x04\\x06\\x00\\x02'])}, {})", 'success': True}
2023-10-24 23:54:52.834 ERROR (MainThread) [homeassistant.components.websocket_api.messages] Unable to serialize to JSON. Bad data found at $.result.response.read_before=({1: Array(type=AnonymousLVList, value=[b'\x00\r\x01\x06\x00\x02', b'\x01\r\x02\x06\x00\x02', b'\x02\r\x03\x06\x00\x02', b'\x03\r\x04\x06\x00\x02'])}, {})(<class 'tuple'>
There was some code to ensure that "result_read" could be converted to json, but not "read_before". I fixed that as well as some regressions for scalar values.
Not there yet:
2023-10-25 09:03:37.801 DEBUG (MainThread) [custom_components.zha_toolkit.zcl_attr] Type determined from read: 0x48
2023-10-25 09:03:37.802 ERROR (MainThread) [custom_components.zha_toolkit.utils] Can't convert to JSON Array(type=AnonymousLVList, value=[b'\x00\r\x01\x06\x00\x02', b'\x01\r\x02\x06\x00\x02', b'\x02\r\x03\x06\x00\x02', b'\x03\r\x04\x06\x00\x02'])
2023-10-25 09:03:37.803 DEBUG (MainThread) [custom_components.zha_toolkit] event_data {'zha_toolkit_version': 'v1.1.2', 'zigpy_version': '0.58.0.post2+git.80f9f8db', 'zigpy_rf_version': '0.35.9', 'ieee_org': 'button.ubisys_c4_5504_identify', 'ieee': '00:1f:ee:00:00:00:9a:e3', 'command': 'attr_write', 'command_data': None, 'start_time': '2023-10-25T07:03:37.717141+00:00', 'errors': [], 'params': {'endpoint_id': 232, 'cluster_id': 64512, 'attr_id': 1, 'attr_type': 72, 'attr_val': [65, 4, 0, 6, 0, 13, 1, 6, 0, 2, 6, 1, 13, 2, 6, 0, 2, 6, 2, 13, 3, 6, 0, 2, 6, 3, 13, 4, 6, 0, 2], 'dir': 0, 'tries': 1, 'expect_reply': True, 'args': [], 'read_before_write': True, 'read_after_write': True}, 'compare_val': [65, 4, 0, 6, 0, 13, 1, 6, 0, 2, 6, 1, 13, 2, 6, 0, 2, 6, 2, 13, 3, 6, 0, 2, 6, 3, 13, 4, 6, 0, 2], 'attr_type': '0x48', 'write_is_equal': True, 'info': 'Data read is equal to data to write', 'result_read': ({1: b'A\x04\x00\x06\x00\r\x01\x06\x00\x02\x06\x01\r\x02\x06\x00\x02\x06\x02\r\x03\x06\x00\x02\x06\x03\r\x04\x06\x00\x02'}, {}), 'success': True}
2023-10-25 09:03:37.805 ERROR (MainThread) [homeassistant.components.websocket_api.messages] Unable to serialize to JSON. Bad data found at $.result.response.result_read=({1: b'A\x04\x00\x06\x00\r\x01\x06\x00\x02\x06\x01\r\x02\x06\x00\x02\x06\x02\r\x03\x06\x00\x02\x06\x03\r\x04\x06\x00\x02'}, {})(<class 'tuple'>
I didn't expect bytes to not be json encodable. I've updated it.
The current state now works on my side:
zha_toolkit_version: v1.1.2
zigpy_version: 0.58.0.post2+git.80f9f8db
zigpy_rf_version: 0.35.9
ieee_org: button.ubisys_c4_5504_identify
ieee: 00:1f:ee:00:00:00:9a:e3
command: attr_write
command_data: null
start_time: "2023-10-26T23:19:39.655990+00:00"
errors: []
params:
endpoint_id: 232
cluster_id: 64512
attr_id: 1
attr_type: 72
attr_val:
- 65
- 4
- 0
- 6
- 0
- 13
- 1
- 6
- 0
- 2
- 6
- 1
- 13
- 2
- 6
- 0
- 2
- 6
- 2
- 13
- 3
- 6
- 0
- 2
- 6
- 3
- 13
- 4
- 6
- 0
- 2
dir: 0
tries: 1
expect_reply: true
args: []
read_before_write: true
read_after_write: true
compare_val:
- 65
- 4
- 0
- 6
- 0
- 13
- 1
- 6
- 0
- 2
- 6
- 1
- 13
- 2
- 6
- 0
- 2
- 6
- 2
- 13
- 3
- 6
- 0
- 2
- 6
- 3
- 13
- 4
- 6
- 0
- 2
attr_type: "0x48"
write_is_equal: false
read_before:
- "1": 41040006000d0206000206010d0206000206020d0306000206030d04060002
- {}
result_write:
- - status: 0
attrid: null
result_read:
- "1": 41040006000d0106000206010d0206000206020d0306000206030d04060002
- {}
success: true
Good news! I can see why the order has to change, but I'ld like to keep the reported values as strings rather than conversions to hexadecimal values. The string value can be reused as the input for another write.
The string value can be reused as the input for another write.
That's exactly why I added 5ba046e just now :)
Up to you, if you think it needs more changes, please go ahead.
Well, providing the data as "hex" was not really the logic up to now, so I'm changing that back to the binary string type (or whatever that is called).
Merged & pre-released.
I can confirm the pre-release works. Thanks.
This PR adds support for ZCL Array type attributes to be written using
zha_toolkit.attr_write
.