zigpy / zha-device-handlers

ZHA device handlers bridge the functionality gap created when manufacturers deviate from the ZCL specification, handling deviations and exceptions by parsing custom messages to and from Zigbee devices.
Apache License 2.0
689 stars 639 forks source link

[Device Support Request] Tuya Smoke Detector TS0601 (_TZE200_uebojraa) #1838

Open marcelkous opened 1 year ago

marcelkous commented 1 year ago

I am looking to help add support for this smoke detector into ZHA. image

I found that it is supported by Zigbee2MQTT (https://zigbee.blakadder.com/Smart9_S9ZB-SA02.html, https://www.zigbee2mqtt.io/devices/TS0601_smoke.html)

Hopefully, it can be added quite easily to ZHA also.

Device signature

``` { "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)", "endpoints": { "1": { "profile_id": 260, "device_type": "0x0051", "in_clusters": [ "0x0000", "0x0004", "0x0005", "0xef00" ], "out_clusters": [ "0x000a", "0x0019" ] } }, "manufacturer": "_TZE200_uebojraa", "model": "TS0601", "class": "zigpy.device.Device" } ```

Device diagnostics

``` { "home_assistant": { "installation_type": "Home Assistant OS", "version": "2022.10.4", "dev": false, "hassio": true, "virtualenv": false, "python_version": "3.10.5", "docker": true, "arch": "x86_64", "timezone": "Europe/Amsterdam", "os_name": "Linux", "os_version": "5.15.72", "supervisor": "2022.10.0", "host_os": "Home Assistant OS 9.2", "docker_version": "20.10.17", "chassis": "vm", "run_as_root": true }, "custom_components": {}, "integration_manifest": { "domain": "zha", "name": "Zigbee Home Automation", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/zha", "requirements": [ "bellows==0.34.2", "pyserial==3.5", "pyserial-asyncio==0.6", "zha-quirks==0.0.82", "zigpy-deconz==0.19.0", "zigpy==0.51.3", "zigpy-xbee==0.16.2", "zigpy-zigate==0.10.2", "zigpy-znp==0.9.1" ], "usb": [ { "vid": "10C4", "pid": "EA60", "description": "*2652*", "known_devices": [ "slae.sh cc2652rb stick" ] }, { "vid": "1A86", "pid": "55D4", "description": "*sonoff*plus*", "known_devices": [ "sonoff zigbee dongle plus v2" ] }, { "vid": "10C4", "pid": "EA60", "description": "*sonoff*plus*", "known_devices": [ "sonoff zigbee dongle plus" ] }, { "vid": "10C4", "pid": "EA60", "description": "*tubeszb*", "known_devices": [ "TubesZB Coordinator" ] }, { "vid": "1A86", "pid": "7523", "description": "*tubeszb*", "known_devices": [ "TubesZB Coordinator" ] }, { "vid": "1A86", "pid": "7523", "description": "*zigstar*", "known_devices": [ "ZigStar Coordinators" ] }, { "vid": "1CF1", "pid": "0030", "description": "*conbee*", "known_devices": [ "Conbee II" ] }, { "vid": "10C4", "pid": "8A2A", "description": "*zigbee*", "known_devices": [ "Nortek HUSBZB-1" ] }, { "vid": "0403", "pid": "6015", "description": "*zigate*", "known_devices": [ "ZiGate+" ] }, { "vid": "10C4", "pid": "EA60", "description": "*zigate*", "known_devices": [ "ZiGate" ] }, { "vid": "10C4", "pid": "8B34", "description": "*bv 2010/10*", "known_devices": [ "Bitron Video AV2010/10" ] } ], "codeowners": [ "@dmulcahey", "@adminiuga", "@puddly" ], "zeroconf": [ { "type": "_esphomelib._tcp.local.", "name": "tube*" }, { "type": "_zigate-zigbee-gateway._tcp.local.", "name": "*zigate*" }, { "type": "_zigstar_gw._tcp.local.", "name": "*zigstar*" } ], "dependencies": [ "file_upload" ], "after_dependencies": [ "onboarding", "usb", "zeroconf" ], "iot_class": "local_polling", "loggers": [ "aiosqlite", "bellows", "crccheck", "pure_pcapy3", "zhaquirks", "zigpy", "zigpy_deconz", "zigpy_xbee", "zigpy_zigate", "zigpy_znp" ], "is_built_in": true }, "data": { "ieee": "**REDACTED**", "nwk": 43698, "manufacturer": "_TZE200_uebojraa", "model": "TS0601", "name": "_TZE200_uebojraa TS0601", "quirk_applied": false, "quirk_class": "zigpy.device.Device", "manufacturer_code": 4417, "power_source": "Battery or Unknown", "lqi": 255, "rssi": -27, "last_seen": "2022-10-18T11:08:57", "available": true, "device_type": "EndDevice", "signature": { "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)", "endpoints": { "1": { "profile_id": 260, "device_type": "0x0051", "in_clusters": [ "0x0000", "0x0004", "0x0005", "0xef00" ], "out_clusters": [ "0x000a", "0x0019" ] } } }, "active_coordinator": false, "entities": [], "neighbors": [], "endpoint_names": [ { "name": "SMART_PLUG" } ], "user_given_name": null, "device_reg_id": "6083f6faff90d7bc03ce1dd8bf3135fd", "area_id": "f94dff210e784ca9a49f31421a22d036", "cluster_details": { "1": { "device_type": { "name": "SMART_PLUG", "id": 81 }, "profile_id": 260, "in_clusters": { "0x0004": { "endpoint_attribute": "groups", "attributes": {}, "unsupported_attributes": {} }, "0x0005": { "endpoint_attribute": "scenes", "attributes": {}, "unsupported_attributes": {} }, "0xef00": { "endpoint_attribute": null, "attributes": {}, "unsupported_attributes": {} }, "0x0000": { "endpoint_attribute": "basic", "attributes": { "0x0001": { "attribute_name": "app_version", "value": 67 }, "0x0004": { "attribute_name": "manufacturer", "value": "_TZE200_uebojraa" }, "0x0005": { "attribute_name": "model", "value": "TS0601" } }, "unsupported_attributes": {} } }, "out_clusters": { "0x0019": { "endpoint_attribute": "ota", "attributes": {}, "unsupported_attributes": {} }, "0x000a": { "endpoint_attribute": "time", "attributes": {}, "unsupported_attributes": {} } } } } } } ```

Additional Logs

#### Adding device log (tried to keep it as clean as possible) ``` [0x7B67:1:0x0b04]: async_update [0x7B67:1:0x0b04]: Reading attributes in chunks: ['active_power', 'rms_current', 'rms_voltage'] [0x7B67:1:0x0b04] Sending request header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=False, direction=, disable_default_response=0, reserved=0, *is_cluster=False, *is_general=True, *is_reply=False), tsn=44, command_id=, *direction=, *is_reply=False) [0x7B67:1:0x0b04] Sending request: Read_Attributes(attribute_ids=[1291, 1288, 1285]) New device 0xaab2 (a4:c1:38:b7:87:51:44:76) joined the network [0xaab2] Scheduling initialization Tries remaining: 3 [0xaab2] Requesting 'Node Descriptor' Tries remaining: 2 [0xaab2] Extending timeout for 0x2e request Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=0, dst=AddrModeAddress(addr_mode=, address=), dst_ep=0, source_route=None, extended_timeout=False, tsn=30, profile_id=0, cluster_id=19, data=Serialized[b'4\xb2\xaavDQ\x87\xb78\xc1\xa4\x80'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-30) Device 0xaab2 (a4:c1:38:b7:87:51:44:76) joined the network [0xaab2] Scheduling initialization [0xaab2] Canceling old initialize call Received frame on uninitialized device from ep 0 to ep 0, cluster 19: b'4\xb2\xaavDQ\x87\xb78\xc1\xa4\x80' [0xaab2:zdo] ZDO request ZDOCmd.Device_annce: [0xAAB2, a4:c1:38:b7:87:51:44:76, 128] Tries remaining: 3 [0xaab2] Requesting 'Node Descriptor' Tries remaining: 2 [0xaab2] Extending timeout for 0x30 request Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=0, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=0, source_route=None, extended_timeout=False, tsn=31, profile_id=0, cluster_id=32770, data=Serialized[b'.\x00\xb2\xaa\x02@\x80A\x11BB\x00\x00*B\x00\x00'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-30) Received frame on uninitialized device from ep 0 to ep 0, cluster 32770: b'.\x00\xb2\xaa\x02@\x80A\x11BB\x00\x00*B\x00\x00' [0xaab2:zdo] ZDO request ZDOCmd.Node_Desc_rsp: [, 0xAAB2, NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)] [0xaab2:zdo] No handler for ZDO request:ZDOCmd.Node_Desc_rsp([, 0xAAB2, NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)]) Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=0, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=0, source_route=None, extended_timeout=False, tsn=32, profile_id=0, cluster_id=32770, data=Serialized[b'0\x00\xb2\xaa\x02@\x80A\x11BB\x00\x00*B\x00\x00'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-30) Received frame on uninitialized device from ep 0 to ep 0, cluster 32770: b'0\x00\xb2\xaa\x02@\x80A\x11BB\x00\x00*B\x00\x00' [0xaab2] Got Node Descriptor: NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False) [0xaab2] Discovering endpoints Tries remaining: 3 [0xaab2] Extending timeout for 0x32 request Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=0, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=0, source_route=None, extended_timeout=False, tsn=33, profile_id=0, cluster_id=32773, data=Serialized[b'2\x00\xb2\xaa\x01\x01'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-30) Received frame on uninitialized device from ep 0 to ep 0, cluster 32773: b'2\x00\xb2\xaa\x01\x01' [0xaab2] Discovered endpoints: [1] [0xaab2] Initializing endpoints [>] [0xaab2:1] Discovering endpoint information Tries remaining: 3 [0xaab2] Extending timeout for 0x34 request Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=0, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=0, source_route=None, extended_timeout=False, tsn=34, profile_id=0, cluster_id=32772, data=Serialized[b'4\x00\xb2\xaa\x14\x01\x04\x01Q\x00\x01\x04\x04\x00\x05\x00\x00\xef\x00\x00\x02\x19\x00\n\x00'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-30) Received frame on uninitialized device from ep 0 to ep 0, cluster 32772: b'4\x00\xb2\xaa\x14\x01\x04\x01Q\x00\x01\x04\x04\x00\x05\x00\x00\xef\x00\x00\x02\x19\x00\n\x00' [0xaab2:1] Discovered endpoint information: SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=81, device_version=1, input_clusters=[4, 5, 61184, 0], output_clusters=[25, 10]) Unknown cluster 0xEF00 [0xAAB2:1:0x0000] Sending request header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=False, direction=, disable_default_response=0, reserved=0, *is_cluster=False, *is_general=True, *is_reply=False), tsn=54, command_id=, *direction=, *is_reply=False) [0xAAB2:1:0x0000] Sending request: Read_Attributes(attribute_ids=[4, 5]) [0xaab2] Extending timeout for 0x36 request Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=35, profile_id=260, cluster_id=0, data=Serialized[b'\x186\x01\x04\x00\x00B\x10_TZE200_uebojraa\x05\x00\x00B\x06TS0601'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-30) [0xAAB2:1:0x0000] Received ZCL frame: b'\x186\x01\x04\x00\x00B\x10_TZE200_uebojraa\x05\x00\x00B\x06TS0601' [0xAAB2:1:0x0000] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, direction=, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True, *is_reply=True), tsn=54, command_id=1, *direction=, *is_reply=True) [0xAAB2:1:0x0000] Decoded ZCL frame: Basic:Read_Attributes_rsp(status_records=[ReadAttributeRecord(attrid=0x0004, status=, value=TypeValue(type=CharacterString, value='_TZE200_uebojraa')), ReadAttributeRecord(attrid=0x0005, status=, value=TypeValue(type=CharacterString, value='TS0601'))]) [0xaab2] Read model 'TS0601' and manufacturer '_TZE200_uebojraa' from > [0xaab2] Discovered basic device information for Device is initialized Checking quirks for _TZE200_uebojraa TS0601 (a4:c1:38:b7:87:51:44:76) Considering Fail because endpoint list mismatch: {1, 2, 242} {1} Considering Fail because endpoint list mismatch: {1, 2, 41, 42, 242, 51, 21, 31} {1} Considering Fail because endpoint list mismatch: {232, 230} {1} Considering Fail because endpoint list mismatch: {232, 230} {1} Considering Fail because device_type mismatch on at least one endpoint Considering Fail because device_type mismatch on at least one endpoint Considering Fail because device_type mismatch on at least one endpoint Considering Fail because device_type mismatch on at least one endpoint Considering Fail because endpoint list mismatch: {11, 13} {1} 'sensor' component -> 'RSSISensor' using ['basic'] 'sensor' component -> 'LQISensor' using ['basic'] device - 0xAAB2:a4:c1:38:b7:87:51:44:76 entering async_device_initialized - is_new_join: True device - 0xAAB2:a4:c1:38:b7:87:51:44:76 has joined the ZHA zigbee network [0xAAB2](TS0601): started configuration [0xAAB2:ZDO](TS0601): 'async_configure' stage succeeded [0xAAB2:1:0x0000]: Configuring cluster attribute reporting [0xAAB2:1:0x0000]: finished channel configuration [0xAAB2:1:0x0019]: finished channel configuration [0xAAB2:1:0x0000]: 'async_configure' stage succeeded [0xAAB2:1:0x0019]: 'async_configure' stage succeeded [0xAAB2](TS0601): completed configuration [0xAAB2](TS0601): started initialization [0xAAB2:ZDO](TS0601): 'async_initialize' stage succeeded [0xAAB2:1:0x0000]: initializing channel: from_cache: False [0xAAB2:1:0x0000]: finished channel initialization [0xAAB2:1:0x0019]: initializing channel: from_cache: False [0xAAB2:1:0x0019]: finished channel initialization [0xAAB2:1:0x0000]: 'async_initialize' stage succeeded [0xAAB2:1:0x0019]: 'async_initialize' stage succeeded [0xAAB2](TS0601): power source: Battery or Unknown [0xAAB2](TS0601): completed initialization Error handling '_save_attribute' event with (a4:c1:38:b7:87:51:44:76, 1, 0, 4, '_TZE200_uebojraa') params: FOREIGN KEY constraint failed Error handling '_save_attribute' event with (a4:c1:38:b7:87:51:44:76, 1, 0, 5, 'TS0601') params: FOREIGN KEY constraint failed Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=0, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=0, source_route=None, extended_timeout=False, tsn=36, profile_id=0, cluster_id=2, data=Serialized[b'5\x00\x00'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-30) [0xaab2:zdo] ZDO request ZDOCmd.Node_Desc_req: [0x0000] [0xaab2:zdo] No handler for ZDO request:ZDOCmd.Node_Desc_req([0x0000]) Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=0, dst=AddrModeAddress(addr_mode=, address=), dst_ep=0, source_route=None, extended_timeout=False, tsn=39, profile_id=0, cluster_id=54, data=Serialized[b'6\xb4\x01'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-30) [0xaab2:zdo] ZDO request ZDOCmd.Mgmt_Permit_Joining_req: [180, ] [0x7B67:1:0x0b04]: failed to get attributes '['active_power', 'rms_current', 'rms_voltage']' on 'electrical_measurement' cluster: Failed to deliver message: Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=40, profile_id=260, cluster_id=61184, data=Serialized[b'\tp\x11\x00;@'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-28) [0xAAB2:1:0xef00] Received ZCL frame: b'\tp\x11\x00;@' [0xAAB2:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, direction=, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False, *is_reply=True), tsn=112, command_id=17, *direction=, *is_reply=True) [0xAAB2:1:0xef00] Unknown cluster command 17 b'\x00;@' [0xAAB2:1:0xef00] Received command 0x11 (TSN 112): b'\x00;@' [0xAAB2:1:0xef00] No explicit handler for cluster command 0x11: b'\x00;@' [0x6306](01MINIZB): Device seen - marking the device available and resetting counter [0x6306](01MINIZB): Update device availability - device available: True - new availability: True - changed: False Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=41, profile_id=260, cluster_id=61184, data=Serialized[b'\tp\x11\x00;@'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-28) [0xAAB2:1:0xef00] Received ZCL frame: b'\tp\x11\x00;@' [0xAAB2:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, direction=, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False, *is_reply=True), tsn=112, command_id=17, *direction=, *is_reply=True) [0xAAB2:1:0xef00] Unknown cluster command 17 b'\x00;@' [0xAAB2:1:0xef00] Received command 0x11 (TSN 112): b'\x00;@' [0xAAB2:1:0xef00] No explicit handler for cluster command 0x11: b'\x00;@' [0xDD77](TRADFRI Signal Repeater): last_seen is 15602398.541951656 seconds ago and ping attempts have been exhausted, marking the device unavailable [0xDD77](TRADFRI Signal Repeater): Update device availability - device available: False - new availability: False - changed: False Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=42, profile_id=260, cluster_id=61184, data=Serialized[b'\tp\x11\x00;@'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-28) [0xAAB2:1:0xef00] Received ZCL frame: b'\tp\x11\x00;@' [0xAAB2:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, direction=, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False, *is_reply=True), tsn=112, command_id=17, *direction=, *is_reply=True) [0xAAB2:1:0xef00] Unknown cluster command 17 b'\x00;@' [0xAAB2:1:0xef00] Received command 0x11 (TSN 112): b'\x00;@' [0xAAB2:1:0xef00] No explicit handler for cluster command 0x11: b'\x00;@' Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=43, profile_id=260, cluster_id=0, data=Serialized[b'\x08q\n\x01\x00 C\xe2\xff 1\xe4\xff \x00'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-27) [0xAAB2:1:0x0000] Received ZCL frame: b'\x08q\n\x01\x00 C\xe2\xff 1\xe4\xff \x00' [0xAAB2:1:0x0000] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, direction=, disable_default_response=0, reserved=0, *is_cluster=False, *is_general=True, *is_reply=True), tsn=113, command_id=10, *direction=, *is_reply=True) [0xAAB2:1:0x0000] Decoded ZCL frame: Basic:Report_Attributes(attribute_reports=[Attribute(attrid=0x0001, value=TypeValue(type=uint8_t, value=67)), Attribute(attrid=0xFFE2, value=TypeValue(type=uint8_t, value=49)), Attribute(attrid=0xFFE4, value=TypeValue(type=uint8_t, value=0))]) [0xAAB2:1:0x0000] Received command 0x0A (TSN 113): Report_Attributes(attribute_reports=[Attribute(attrid=0x0001, value=TypeValue(type=uint8_t, value=67)), Attribute(attrid=0xFFE2, value=TypeValue(type=uint8_t, value=49)), Attribute(attrid=0xFFE4, value=TypeValue(type=uint8_t, value=0))]) [0xAAB2:1:0x0000] Attribute report received: app_version=67, 0xFFE2=49, 0xFFE4=0 [0xAAB2:1:0x0000] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=False, direction=, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True, *is_reply=True), tsn=113, command_id=, *direction=, *is_reply=True) [0xAAB2:1:0x0000] Sending reply: Default_Response(command_id=10, status=) Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=44, profile_id=260, cluster_id=10, data=Serialized[b'\x00r\x00\x07\x00'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-27) [0xAAB2:1:0x000a] Received ZCL frame: b'\x00r\x00\x07\x00' [0xAAB2:1:0x000a] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, direction=, disable_default_response=0, reserved=0, *is_cluster=False, *is_general=True, *is_reply=False), tsn=114, command_id=0, *direction=, *is_reply=False) [0xAAB2:1:0x000a] Decoded ZCL frame: Time:Read_Attributes(attribute_ids=[7]) [0xAAB2:1:0x000a] Received command 0x00 (TSN 114): Read_Attributes(attribute_ids=[7]) [0xAAB2:1:0x000a] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=False, direction=, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True, *is_reply=True), tsn=114, command_id=, *direction=, *is_reply=True) [0xAAB2:1:0x000a] Sending reply: Read_Attributes_rsp(status_records=[ReadAttributeRecord(attrid=0x0007, status=, value=TypeValue(type=LocalTime, value=719406532))]) Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=45, profile_id=260, cluster_id=0, data=Serialized[b'\x08s\n\xdf\xffB\x0f\xb5E\xe1*f\xb5E\xe1*\x13\xb6E\xe1*\x12'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-27) [0xAAB2:1:0x0000] Received ZCL frame: b'\x08s\n\xdf\xffB\x0f\xb5E\xe1*f\xb5E\xe1*\x13\xb6E\xe1*\x12' [0xAAB2:1:0x0000] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, direction=, disable_default_response=0, reserved=0, *is_cluster=False, *is_general=True, *is_reply=True), tsn=115, command_id=10, *direction=, *is_reply=True) [0xAAB2:1:0x0000] Decoded ZCL frame: Basic:Report_Attributes(attribute_reports=[Attribute(attrid=0xFFDF, value=TypeValue(type=CharacterString, value='�E�*f�E�*\x13�E�*\x12'))]) [0xAAB2:1:0x0000] Received command 0x0A (TSN 115): Report_Attributes(attribute_reports=[Attribute(attrid=0xFFDF, value=TypeValue(type=CharacterString, value='�E�*f�E�*\x13�E�*\x12'))]) [0xAAB2:1:0x0000] Attribute report received: 0xFFDF='�E�*f�E�*\x13�E�*\x12' [0xAAB2:1:0x0000] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=False, direction=, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True, *is_reply=True), tsn=115, command_id=, *direction=, *is_reply=True) [0xAAB2:1:0x0000] Sending reply: Default_Response(command_id=10, status=) [0xC582](SYMFONISK Sound Controller): last_seen is 8058877.430959702 seconds ago and ping attempts have been exhausted, marking the device unavailable [0xC582](SYMFONISK Sound Controller): Update device availability - device available: False - new availability: False - changed: False Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=46, profile_id=260, cluster_id=61184, data=Serialized[b'\tt\x02\x00>\x01\x04\x00\x01\x01'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-28) [0xAAB2:1:0xef00] Received ZCL frame: b'\tt\x02\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, direction=, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False, *is_reply=True), tsn=116, command_id=2, *direction=, *is_reply=True) [0xAAB2:1:0xef00] Unknown cluster command 2 b'\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] Received command 0x02 (TSN 116): b'\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] No explicit handler for cluster command 0x02: b'\x00>\x01\x04\x00\x01\x01' Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=47, profile_id=260, cluster_id=61184, data=Serialized[b'\tt\x02\x00>\x01\x04\x00\x01\x01'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-27) [0xAAB2:1:0xef00] Received ZCL frame: b'\tt\x02\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, direction=, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False, *is_reply=True), tsn=116, command_id=2, *direction=, *is_reply=True) [0xAAB2:1:0xef00] Unknown cluster command 2 b'\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] Received command 0x02 (TSN 116): b'\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] No explicit handler for cluster command 0x02: b'\x00>\x01\x04\x00\x01\x01' Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=48, profile_id=260, cluster_id=61184, data=Serialized[b'\tt\x02\x00>\x01\x04\x00\x01\x01'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-27) [0xAAB2:1:0xef00] Received ZCL frame: b'\tt\x02\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, direction=, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False, *is_reply=True), tsn=116, command_id=2, *direction=, *is_reply=True) [0xAAB2:1:0xef00] Unknown cluster command 2 b'\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] Received command 0x02 (TSN 116): b'\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] No explicit handler for cluster command 0x02: b'\x00>\x01\x04\x00\x01\x01' Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=49, profile_id=260, cluster_id=61184, data=Serialized[b'\tt\x02\x00>\x01\x04\x00\x01\x01'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-27) [0xAAB2:1:0xef00] Received ZCL frame: b'\tt\x02\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, direction=, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False, *is_reply=True), tsn=116, command_id=2, *direction=, *is_reply=True) [0xAAB2:1:0xef00] Unknown cluster command 2 b'\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] Received command 0x02 (TSN 116): b'\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] No explicit handler for cluster command 0x02: b'\x00>\x01\x04\x00\x01\x01' Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=50, profile_id=260, cluster_id=61184, data=Serialized[b'\tt\x02\x00>\x01\x04\x00\x01\x01'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-27) [0xAAB2:1:0xef00] Received ZCL frame: b'\tt\x02\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, direction=, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False, *is_reply=True), tsn=116, command_id=2, *direction=, *is_reply=True) [0xAAB2:1:0xef00] Unknown cluster command 2 b'\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] Received command 0x02 (TSN 116): b'\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] No explicit handler for cluster command 0x02: b'\x00>\x01\x04\x00\x01\x01' Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=51, profile_id=260, cluster_id=61184, data=Serialized[b'\tt\x02\x00>\x01\x04\x00\x01\x01'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-27) [0xAAB2:1:0xef00] Received ZCL frame: b'\tt\x02\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, direction=, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False, *is_reply=True), tsn=116, command_id=2, *direction=, *is_reply=True) [0xAAB2:1:0xef00] Unknown cluster command 2 b'\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] Received command 0x02 (TSN 116): b'\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] No explicit handler for cluster command 0x02: b'\x00>\x01\x04\x00\x01\x01' Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=52, profile_id=260, cluster_id=61184, data=Serialized[b'\tt\x02\x00>\x01\x04\x00\x01\x01'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-27) [0xAAB2:1:0xef00] Received ZCL frame: b'\tt\x02\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, direction=, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False, *is_reply=True), tsn=116, command_id=2, *direction=, *is_reply=True) [0xAAB2:1:0xef00] Unknown cluster command 2 b'\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] Received command 0x02 (TSN 116): b'\x00>\x01\x04\x00\x01\x01' [0xAAB2:1:0xef00] No explicit handler for cluster command 0x02: b'\x00>\x01\x04\x00\x01\x01' Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xAAB2), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=53, profile_id=260, cluster_id=61184, data=Serialized[b'\tu\x02\x00?\x0e\x04\x00\x01\x02'], tx_options=, radius=0, non_member_radius=0, lqi=255, rssi=-27) [0xAAB2:1:0xef00] Received ZCL frame: b'\tu\x02\x00?\x0e\x04\x00\x01\x02' [0xAAB2:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, direction=, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False, *is_reply=True), tsn=117, command_id=2, *direction=, *is_reply=True) [0xAAB2:1:0xef00] Unknown cluster command 2 b'\x00?\x0e\x04\x00\x01\x02' [0xAAB2:1:0xef00] Received command 0x02 (TSN 117): b'\x00?\x0e\x04\x00\x01\x02' [0xAAB2:1:0xef00] No explicit handler for cluster command 0x02: b'\x00?\x0e\x04\x00\x01\x02' ```

javicalle commented 1 year ago

Probably it can match with the existing quirks.

There is a guide about enabling custom quirks:

Copy in your local quirks folder the current quirk:

Edit the file, adding your device like this:

        MODELS_INFO: [
            ("_TZE200_aycxwiau", "TS0601"),
            ("_TZE200_ntcy3xu1", "TS0601"),
            ("_TZE200_uebojraa", "TS0601"),
            ("_TZE200_vzekyi4c", "TS0601"),
        ],

Restart HA and pair you device again. Check that the device is loading the quirk and that the device signatura has changed.

marcelkous commented 1 year ago

@javicalle Thank you very much. I'm gonna try this.

marcelkous commented 1 year ago

It is in a 'better' state than before but not completely.

This is what I did to add the local quirk.

I added the custom_zha_quirks folder in the config folder

/config/custom_zha_quirks

In the configuration.yaml file i've added:

zha: 
  custom_quirks_path: /config/custom_zha_quirks/

Then I saved the file from https://github.com/zigpy/zha-device-handlers/blob/dev/zhaquirks/tuya/ts0601_smoke.py into that folder and added the models info like @javicalle described above.

Then a restart of Home Assistant.

After the restart, I removed the 'faulty' device and re-added it again. I saw the following happening in the "Add Device" section. image and then: image After that nothing happened. Normally you see a green box that tells you that the device is added and ready to use (see example below).

Before change

This is what I saw before the change: ![image](https://user-images.githubusercontent.com/61436181/196677003-69d5fcc7-ec63-4d0d-a68b-a28049ca4481.png)

I can see ZHA used the custom quirk image

Also, a sensor appeared: image And when I press the test button on the device the logbook shows the activity. image

So far, so good :-) The only thing that's missing is the Diagnostic section what should show the Battery state and maybe the Identifybutton property.

Like in this example of another brand smoke detector. image

Device signature

``` { "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)", "endpoints": { "1": { "profile_id": 260, "device_type": "0x0402", "in_clusters": [ "0x0000", "0x0004", "0x0005", "0x0500", "0xef00" ], "out_clusters": [ "0x000a", "0x0019" ] } }, "manufacturer": "_TZE200_uebojraa", "model": "TS0601", "class": "ts0601_smoke.TuyaSmokeDetector0601" } ```

The Device diagnostics shows this.

Device diagnostics

``` { "home_assistant": { "installation_type": "Home Assistant OS", "version": "2022.10.4", "dev": false, "hassio": true, "virtualenv": false, "python_version": "3.10.5", "docker": true, "arch": "x86_64", "timezone": "Europe/Amsterdam", "os_name": "Linux", "os_version": "5.15.72", "supervisor": "2022.10.0", "host_os": "Home Assistant OS 9.2", "docker_version": "20.10.17", "chassis": "vm", "run_as_root": true }, "custom_components": {}, "integration_manifest": { "domain": "zha", "name": "Zigbee Home Automation", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/zha", "requirements": [ "bellows==0.34.2", "pyserial==3.5", "pyserial-asyncio==0.6", "zha-quirks==0.0.82", "zigpy-deconz==0.19.0", "zigpy==0.51.3", "zigpy-xbee==0.16.2", "zigpy-zigate==0.10.2", "zigpy-znp==0.9.1" ], "usb": [ { "vid": "10C4", "pid": "EA60", "description": "*2652*", "known_devices": [ "slae.sh cc2652rb stick" ] }, { "vid": "1A86", "pid": "55D4", "description": "*sonoff*plus*", "known_devices": [ "sonoff zigbee dongle plus v2" ] }, { "vid": "10C4", "pid": "EA60", "description": "*sonoff*plus*", "known_devices": [ "sonoff zigbee dongle plus" ] }, { "vid": "10C4", "pid": "EA60", "description": "*tubeszb*", "known_devices": [ "TubesZB Coordinator" ] }, { "vid": "1A86", "pid": "7523", "description": "*tubeszb*", "known_devices": [ "TubesZB Coordinator" ] }, { "vid": "1A86", "pid": "7523", "description": "*zigstar*", "known_devices": [ "ZigStar Coordinators" ] }, { "vid": "1CF1", "pid": "0030", "description": "*conbee*", "known_devices": [ "Conbee II" ] }, { "vid": "10C4", "pid": "8A2A", "description": "*zigbee*", "known_devices": [ "Nortek HUSBZB-1" ] }, { "vid": "0403", "pid": "6015", "description": "*zigate*", "known_devices": [ "ZiGate+" ] }, { "vid": "10C4", "pid": "EA60", "description": "*zigate*", "known_devices": [ "ZiGate" ] }, { "vid": "10C4", "pid": "8B34", "description": "*bv 2010/10*", "known_devices": [ "Bitron Video AV2010/10" ] } ], "codeowners": [ "@dmulcahey", "@adminiuga", "@puddly" ], "zeroconf": [ { "type": "_esphomelib._tcp.local.", "name": "tube*" }, { "type": "_zigate-zigbee-gateway._tcp.local.", "name": "*zigate*" }, { "type": "_zigstar_gw._tcp.local.", "name": "*zigstar*" } ], "dependencies": [ "file_upload" ], "after_dependencies": [ "onboarding", "usb", "zeroconf" ], "iot_class": "local_polling", "loggers": [ "aiosqlite", "bellows", "crccheck", "pure_pcapy3", "zhaquirks", "zigpy", "zigpy_deconz", "zigpy_xbee", "zigpy_zigate", "zigpy_znp" ], "is_built_in": true }, "data": { "ieee": "**REDACTED**", "nwk": 43698, "manufacturer": "_TZE200_uebojraa", "model": "TS0601", "name": "_TZE200_uebojraa TS0601", "quirk_applied": true, "quirk_class": "ts0601_smoke.TuyaSmokeDetector0601", "manufacturer_code": 4417, "power_source": "Battery or Unknown", "lqi": 255, "rssi": -23, "last_seen": "2022-10-19T13:05:34", "available": true, "device_type": "EndDevice", "signature": { "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)", "endpoints": { "1": { "profile_id": 260, "device_type": "0x0402", "in_clusters": [ "0x0000", "0x0004", "0x0005", "0x0500", "0xef00" ], "out_clusters": [ "0x000a", "0x0019" ] } } }, "active_coordinator": false, "entities": [ { "entity_id": "binary_sensor.tze200_uebojraa_ts0601_iaszone", "name": "_TZE200_uebojraa TS0601" } ], "neighbors": [], "endpoint_names": [ { "name": "IAS_ZONE" } ], "user_given_name": null, "device_reg_id": "6083f6faff90d7bc03ce1dd8bf3135fd", "area_id": null, "cluster_details": { "1": { "device_type": { "name": "IAS_ZONE", "id": 1026 }, "profile_id": 260, "in_clusters": { "0x0000": { "endpoint_attribute": "basic", "attributes": { "0x0001": { "attribute_name": "app_version", "value": 67 } }, "unsupported_attributes": {} }, "0x0004": { "endpoint_attribute": "groups", "attributes": {}, "unsupported_attributes": {} }, "0x0005": { "endpoint_attribute": "scenes", "attributes": {}, "unsupported_attributes": {} }, "0x0500": { "endpoint_attribute": "ias_zone", "attributes": { "0x0001": { "attribute_name": "zone_type", "value": 40 }, "0x0002": { "attribute_name": "zone_status", "value": 0 } }, "unsupported_attributes": {} }, "0xef00": { "endpoint_attribute": "tuya_manufacturer", "attributes": { "0x0401": { "attribute_name": "smoke_detected", "value": 1 } }, "unsupported_attributes": {} } }, "out_clusters": { "0x000a": { "endpoint_attribute": "time", "attributes": {}, "unsupported_attributes": {} }, "0x0019": { "endpoint_attribute": "ota", "attributes": {}, "unsupported_attributes": {} } } } } } } ```

javicalle commented 1 year ago

It seems to be a pairing issue. Battery powered devices must be kept awake during the pairing procedure.

To do this, while the pairing lasts, you have to briefly press the button to keep the device awake.

Can you try to remove and pair the device again?

marcelkous commented 1 year ago

I tried paring several times already. I didn't have this issue before, it always ended up green.

But, I tried it again and then pressed the test button several times (auw, sharp beep sound every time) and now it ended 'green' indeed. image There are now three 'properties', the first is the Iaszone (Smoke sensor), and the two others say 'null'. image image One of the 'null' is probably the battery and the other is maybe link quality?

dmulcahey commented 1 year ago

The triangles are how disabled entities show by default. Those are LQI and RSSI

marcelkous commented 1 year ago

Ah, yes. Oke. Any idea how to add the battery state?

marcelkous commented 1 year ago

I see this in the Core logs around the time I added the device again (several times around noon and 5pm).

Logger: homeassistant.components.zha.core.channels.base
Source: components/zha/core/channels/base.py:486
Integration: Zigbee Home Automation (documentation, issues)
First occurred: 12:38:39 PM (12 occurrences)
Last logged: 5:00:38 PM

[0x7B67:1:0x0006]: async_initialize: all attempts have failed: [DeliveryError('Failed to deliver message: <EmberStatus.DELIVERY_FAILED: 102>'), DeliveryError('Failed to deliver message: <EmberStatus.DELIVERY_FAILED: 102>'), DeliveryError('Failed to deliver message: <EmberStatus.DELIVERY_FAILED: 102>'), DeliveryError('Failed to deliver message: <EmberStatus.DELIVERY_FAILED: 102>')]
[0x7B67:1:0x0702]: async_initialize: all attempts have failed: [DeliveryError('Failed to deliver message: <EmberStatus.DELIVERY_FAILED: 102>'), DeliveryError('Failed to deliver message: <EmberStatus.DELIVERY_FAILED: 102>'), DeliveryError('Failed to deliver message: <EmberStatus.DELIVERY_FAILED: 102>'), DeliveryError('Failed to deliver message: <EmberStatus.DELIVERY_FAILED: 102>')]
[0xAAB2:1:0x0500]: 'async_configure' stage failed:
[0xAAB2:1:0x0500]: async_initialize: all attempts have failed: [TimeoutError(), TimeoutError(), TimeoutError(), TimeoutError()]
[0xAAB2:1:0x0500]: 'async_initialize' stage failed: Failed to convert status=Command(status=0, tsn=103, command_id=1025, function=0, data=[1, 1]) from type <class 'zhaquirks.tuya.TuyaManufCluster.Command'> to <enum 'Status'>
javicalle commented 1 year ago

The quirk don't have a 'battery' cluster. Are you sure that the device reports its battery percentage? Blakadder mention just battery_low but Z2M tells abou battery percentage. I think that probably the device will report just the low battery status.

marcelkous commented 1 year ago

Yes, I saw too that it hadn't a PowerConfiguration setting in the quirk.

the Z2M page says that it has a numeric value (0-100) with the unit being % https://www.zigbee2mqtt.io/devices/TS0601_smoke.html#battery-numeric image

I'm looking for TS0205 (Smoke detector) quirk or the TS0212 (CO detector) quirk to see how the PowerConfiguration is handled in there (but I can't find those files) because they are working correct in ZHA.

TS0205 Device signature (Smoke Detector)

``` { "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)", "endpoints": { "1": { "profile_id": 260, "device_type": "0x0402", "in_clusters": [ "0x0000", "0x0001", "0x0003", "0x0500", "0x0502" ], "out_clusters": [ "0x0003", "0x0019" ] } }, "manufacturer": "_TYZB01_tob46aoq", "model": "TS0205", "class": "zigpy.device.Device" } ```

TS0212 Device signature (CO Detector)

``` { "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)", "endpoints": { "1": { "profile_id": 260, "device_type": "0x0402", "in_clusters": [ "0x0000", "0x0001", "0x0003", "0x0500" ], "out_clusters": [ "0x0003", "0x0019" ] } }, "manufacturer": "_TYZB01_wpmo3ja3", "model": "TS0212", "class": "zigpy.device.Device" } ```

javicalle commented 1 year ago

There are some reports in Z2M but not clear if device supports or not. Perhaps the most explicit is this:

To be sure you can enable the debug logs and look at the logs when you interact with the physical device. Usually, the device will report its status:

marcelkous commented 1 year ago

Hi,

I've ordered a tuya hub to test and see what all will be visible in there. Will update here what i find out.

marcelkous commented 1 year ago

Hi all,

I've received the zigbee hub and added the smoke sensor to it. At the device level it shows this

And

It shows the battery level symbol, i don't have an empty or half empty battery to test but for me it's reasonable to assume that the level goes from 0% to 100%, like the compatibility page says for Z2M.

javicalle commented 1 year ago

If it doesn't show any numerical value for battery, my guess is that the device just has a low battery alert as indicated by Blakadder. I bet that Z2M creates a fake cluster where if there is no low battery report the value is 100% and when the report arrives it changes the value to 0%.

marcelkous commented 1 year ago

I have a CO sensor that shows up like this in HA.

And like this in the Tuya app.

I'm not convinced that it can't show the battery level. 🙂

javicalle commented 1 year ago

Well, if it is the case, the device must report the values in any way. Check the HA logs for any unhandled attribute: message from your device. Without a PowerConfiguration cluster, the device only could report the value trought the manufacturer cluster. As, currently, only TUYA_SMOKE_DETECTED_ATTR (0x0401) is checked, any other report will generate a warning log:

https://github.com/zigpy/zha-device-handlers/blob/e8a1570203012ba12777fecd18df82ecd1ff4883/zhaquirks/tuya/ts0601_smoke.py#L35-L51

marcelkous commented 1 year ago

I've enabled again all debug logging but I can't find any entry that says something like unhandled attribute or any other warning or error around this device. 🤷‍♂️

marcelkous commented 1 year ago

I've tested the Smoke Sensor with a desktop power supply and turned the power down to 2.5V with steps of 0.1V from 3.0V. It shows only "Low" as shown in the image below. So @javicalle, you are probably right it only works with High/Low. But at least something should be possible.

One of my colleagues uses HA with Z2M. It was recognized but not functional, so with ZHA and the quirk I'm further getting it to work than with Z2M. He also didn't see any 'warnings in the logs' ...

javicalle commented 1 year ago

Doesn't report any unhandled attribute: when the power drops to 2.5V? Device would report the 'low battery' in some way. It can be a new attrid != TUYA_SMOKE_DETECTED_ATTR (which would generate a warning ... unhandled attribute: attrid or it could be that report the TUYA_SMOKE_DETECTED_ATTR with a diferent value.

From Z2M I would say that must be from attrid 0x040F or 0x040E.

morenod commented 1 year ago

Please add also this model of fire alarm:

        ("_TZE200_m9skfctm", "TS0601"),

image

image

javicalle commented 1 year ago

Please add also this model of fire alarm:

        ("_TZE200_m9skfctm", "TS0601"),

Which is the working quirk for that device?

morenod commented 1 year ago

Please add also this model of fire alarm:

        ("_TZE200_m9skfctm", "TS0601"),

Which is the working quirk for that device?

https://github.com/zigpy/zha-device-handlers/blob/dev/zhaquirks/tuya/ts0601_smoke.py

github-actions[bot] commented 11 months ago

There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates. Please make sure to update to the latest version and check if that solves the issue. Let us know if that works for you by adding a comment 👍 This issue has now been marked as stale and will be closed if no further activity occurs. Thank you for your contributions.

git-peterk commented 10 months ago

I just ordered 2 of these sensors, which I think are using the same data structrure for communication as used by the devices mentioned in this thread.

Looks like mine came with yet another manufacturer info: "TS0601" from "_TZE204_ntcy3xu1" The device was working fine with the released ts0601_smoke.py quirk after adding my own device's model to it, but I did not like it was not reporting battery status, so I created this custom quirk which adds both the battery status and the tampered state:

"""
DY-YG400A Smoke Sensor, TS0601 from _TZE204_ntcy3xu1
https://www.aliexpress.com/item/1005005863519099.html
https://www.aliexpress.com/item/1005005854203557.html
"""

import logging

import zigpy.profiles.zha
from zigpy.quirks import CustomDevice
import zigpy.types as t
from zigpy.zcl.clusters.general import (
    Basic,
    Groups,
    Ota,
    Scenes,
    Time,
    BinaryInput,
    BatterySize,
)
from zigpy.zcl.clusters.security import IasZone
from zhaquirks import Bus
from zhaquirks.const import (
    DEVICE_TYPE,
    ENDPOINTS,
    INPUT_CLUSTERS,
    MODELS_INFO,
    OUTPUT_CLUSTERS,
    PROFILE_ID,
    ZONE_TYPE,
)
from zhaquirks.tuya import (
    TuyaLocalCluster,
    TuyaManufCluster,
    TuyaManufClusterAttributes,
    TuyaPowerConfigurationCluster,
)

_LOGGER = logging.getLogger(__name__)

TUYA_SMOKE_DETECTED_ATTR = 0x0401  # [0]/[1] [Detected]/[Clear]!
TUYA_SMOKE_TAMPERED_ATTR = 0x0104  # [0]/[1] [Clear]/[Tampered]!
TUYA_SMOKE_BATTERY_ATTR = 0x040e  # [0]/[1]/[2] [Low]/[Med]]/[Full]!

class TuyaSmokeDetectorCluster(TuyaManufClusterAttributes):
    """Manufacturer Specific Cluster of the TS0601 smoke detector."""

    attributes = {
        TUYA_SMOKE_DETECTED_ATTR: ("smoke_detected", t.uint8_t, True),
        TUYA_SMOKE_TAMPERED_ATTR: ("tampered_device", t.uint8_t, True),
        TUYA_SMOKE_BATTERY_ATTR: ("battery_status", t.uint8_t, True),
    }

    def _update_attribute(self, attrid, value):
        super()._update_attribute(attrid, value)
        if attrid == TUYA_SMOKE_DETECTED_ATTR:
            status = IasZone.ZoneStatus.Alarm_1 if value == 0 else 0
            self.endpoint.device.ias_bus.listener_event("update_attribute", "zone_status", status)
        elif attrid == TUYA_SMOKE_TAMPERED_ATTR:
            self.endpoint.device.tamper_detection_bus.listener_event(
                "update_attribute", "present_value", bool(value)
            )
        elif attrid == TUYA_SMOKE_BATTERY_ATTR:
            batt = 5 if value == 0 else 40 if value == 1 else 100
            self.endpoint.device.battery_bus.listener_event("battery_change", batt)
        else:
            _LOGGER.warning(
                "[0x%04x:%s:0x%04x] unhandled attribute: 0x%04x",
                self.endpoint.device.nwk,
                self.endpoint.endpoint_id,
                self.cluster_id,
                attrid,
            )

class TuyaIasZone(TuyaLocalCluster, IasZone):
    """
    IAS Zone: this generates the "Smoke" entity for HA.
    Receives updates from TuyaSmokeDetectorCluster.
    """

    _CONSTANT_ATTRIBUTES = {ZONE_TYPE: IasZone.ZoneType.Fire_Sensor}

    def __init__(self, *args, **kwargs):
        """Init."""
        super().__init__(*args, **kwargs)
        self.endpoint.device.ias_bus.add_listener(self)

class TuyaPowerConfigCluster(TuyaPowerConfigurationCluster):
    """
    Power Config Cluster: this generates the "Battery" entity for HA.
    Receives updates from TuyaSmokeDetectorCluster.
    """

    _CONSTANT_ATTRIBUTES = {
        TuyaPowerConfigurationCluster.attributes_by_name["battery_size"].id: BatterySize.AAA,
        TuyaPowerConfigurationCluster.attributes_by_name["battery_quantity"].id: 2,
        TuyaPowerConfigurationCluster.attributes_by_name["battery_rated_voltage"].id: 15,
    }

class TuyaTamperDetection(TuyaLocalCluster, BinaryInput):
    """
    Tamper Detection Cluster: this generates the "Binary input" entity for HA, which is updated
    with the Tampered state. Receives updates from TuyaSmokeDetectorCluster.
    """

    _CONSTANT_ATTRIBUTES = {
        BinaryInput.attributes_by_name["description"].id: "Tamper Detected",
        BinaryInput.attributes_by_name["active_text"].id: "Tampered",
        BinaryInput.attributes_by_name["inactive_text"].id: "Clear",
    }

    def __init__(self, *args, **kwargs):
        """Init."""
        super().__init__(*args, **kwargs)
        self.endpoint.device.tamper_detection_bus.add_listener(self)

class TuyaSmokeDetector0601(CustomDevice):
    """TS0601 Smoke detector quirk."""

    def __init__(self, *args, **kwargs):
        """Init."""
        self.ias_bus = Bus()
        self.battery_bus = Bus()
        self.tamper_detection_bus = Bus()
        super().__init__(*args, **kwargs)

    signature = {
        MODELS_INFO: [
            ("_TZE204_ntcy3xu1", "TS0601"),
        ],
        ENDPOINTS: {
            1: {
                PROFILE_ID: zigpy.profiles.zha.PROFILE_ID,
                DEVICE_TYPE: zigpy.profiles.zha.DeviceType.SMART_PLUG,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaManufCluster.cluster_id,
                ],
                OUTPUT_CLUSTERS: [
                    Time.cluster_id,
                    Ota.cluster_id,
                ],
            },
        },
    }

    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: zigpy.profiles.zha.PROFILE_ID,
                DEVICE_TYPE: zigpy.profiles.zha.DeviceType.IAS_ZONE,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaIasZone,
                    TuyaSmokeDetectorCluster,
                    TuyaPowerConfigCluster,
                    TuyaTamperDetection,
                ],
                OUTPUT_CLUSTERS: [
                    Time.cluster_id,
                    Ota.cluster_id,
                ],
            },
        },
    }

The only "downside" was that due to how the BinaryInput (that I'm using to represent the Tampered input) is implemented in Home Assistant, it will be added as an entity named "Binary input". kép

So I had to manually fix this by clicking "Settings" on the "Binary input" entity: kép

and changing its "Name", "Show As" and "Entity ID" as follows: kép

Now all enetities show up correctly in Home Assistant: kép

Note:

erkr commented 9 months ago

@git-peterk THANKS!!!!! This works so much better than the quirk in the distribution that only exposes the smoke detection. @TheJulianJES Please adopt this improved version above in the release. I can confirm it works great by adding tampered and battery

git-peterk commented 9 months ago

@erkr, I did not create a PR with this change, as:

erkr commented 9 months ago

I'm trying to adopt your code for another version (I received two models in the same batch :-( ). The other version is ("_TZ3210_up3pngle", "TS0205"). That one was default reporting an opening binary sensor (that naming doesn't help either what it is.), That tampering sensor doesn't work, so I adopt your solution to test and I will report back if tampering works.

erkr commented 9 months ago

Update, that device has a different signature, and tampering still doesn't work on that one:

    signature = {
        MODELS_INFO: [
            ("_TZ3210_up3pngle", "TS0205"),
        ],
        ENDPOINTS: {
            1: {
                PROFILE_ID: zigpy.profiles.zha.PROFILE_ID,
                DEVICE_TYPE: zigpy.profiles.zha.DeviceType.IAS_ZONE,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    PowerConfiguration.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    IasZone.cluster_id,
                ],
                OUTPUT_CLUSTERS: [
                    Identify.cluster_id,
                    Groups.cluster_id,
                    Time.cluster_id,
                    OnOff.cluster_id,
                    Ota.cluster_id,
                    LightLink.cluster_id, 
                ],
            },
        },
    }

I simply added your tampering class, which adds the binary sensor on top of the opening sensor, both not triggered when I opened the cover. But I can just copy examples, as I don't fully understand the code

This is in my log and problem related to the opening sensor that doesn't report tampering:

Logger: homeassistant.components.zha.core.cluster_handlers
Source: components/zha/core/cluster_handlers/security.py:377
Integration: Zigbee Home Automation (documentation, issues) 
First occurred: 12:45:54 (2 occurrences) 
Last logged: 12:50:48

[0x5E37:1:0x0500]: 'async_configure' stage failed: 'NoneType' object is not subscriptable
[0x0697:1:0x0500]: 'async_configure' stage failed: 'NoneType' object is not subscriptable
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/zha/core/cluster_handlers/security.py", line 377, in async_configure
    res[0],
    ~~~^^^
TypeError: 'NoneType' object is not subscriptable
liouma commented 8 months ago

Hello, I bought 5 of those smoke sensors TZE200_m9skfctm My version does not have the tamper switch (triggered when the sensor is detached from the ceiling). I tried both quirks:

In all cases the smoke signal is working but I can not get any battery information.

Does anyone have the battery signal working ? Any help will be really welcome. Thanks !!

harrlih commented 7 months ago

@git-peterk - great work! many thanks - finally got the battery status!! 👍

liouma commented 7 months ago

@git-peterk - great work! many thanks - finally got the battery status!! 👍

Hello, can you please show me the exact model of your smoke sensor ? Unfortunately it doesn't work with mine

harrlih commented 7 months ago

Hello, can you please show me the exact model of your smoke sensor ? Unfortunately it doesn't work with mine

Hi @liouma, I have a TZE204_ntcy3xu1 device - unfortunateley I can't be of any further help - too inexperienced - too inexperienced with the tuya quirks...

n0tOdd commented 7 months ago

TZE204_ntcy3xu1

Worked perfectly for " TZE200_ntcy3xu1" to, i just needed to add the model info

hellebauer commented 4 months ago

_TZE200_aycxwiau (Woox Smoke Detector R7049)

No luck with above model. Pairing works, but nothing works beyond that.
UPDATE: A true smoke alarm (I used smoldering paper) does get through on ZHA , but the test button will not