Hello everyone, first post for the community !
I’ve been setting up my HA for 2 months now and had no problem thanks to this forum.
I’ve ordered a Tuya 4 gang switch that is apparently the new model of TS0044 : TS004F
Some people had issues with this on this forum but I could not find any solution. The gang only appears with one switch inside HA using ZHA integration and cannot be used propoerly.
So, I’ve decided to add this new device to zigpy following the protocol.
The problem is that my quirk is recognized but not taken into account :
2021-05-23 20:57:22 DEBUG (MainThread) [zigpy.quirks.registry] Checking quirks for _TZ3000_xabckq1v TS004F (60:a4:23:ff:fe:db:30:83)
2021-05-23 20:57:22 DEBUG (MainThread) [zigpy.quirks.registry] Considering <class 'zhaquirks.ts004f.ZemiSmartRemote004F'>
2021-05-23 20:57:22 DEBUG (MainThread) [zigpy.quirks.registry] Fail because device_type mismatch on at least one endpoint
2021-05-23 20:57:22 DEBUG (MainThread) [zigpy.quirks.registry] Considering <class 'zhaquirks.ts004f.TuyaSmartRemote004F'>
2021-05-23 20:57:22 DEBUG (MainThread) [zigpy.quirks.registry] Fail because device_type mismatch on at least one endpoint
here is the identifier :
{
"node_descriptor": "NodeDescriptor(byte1=2, byte2=64, mac_capability_flags=128, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=0, *allocate_address=True, *complex_descriptor_available=False, *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, *is_valid=True, *logical_type=<LogicalType.EndDevice: 2>, *user_descriptor_available=False)",
"endpoints": {
"1": {
"profile_id": 260,
"device_type": "0x0104",
"in_clusters": [
"0x0000",
"0x0001",
"0x0003",
"0x0004",
"0x0006",
"0x1000"
],
"out_clusters": [
"0x0003",
"0x0004",
"0x0005",
"0x0006",
"0x0008",
"0x000a",
"0x0019",
"0x1000"
]
}
},
"manufacturer": "_TZ3000_xabckq1v",
"model": "TS004F",
"class": "zigpy.device.Device"
}
And here is my quirk :
"""Tuya 4 Button Remote TS004F"""
from zigpy.profiles import zha
from zigpy.quirks import CustomDevice
from zigpy.zcl.clusters.general import Basic, OnOff, Identify, Ota, LevelControl, PowerConfiguration, Time, Groups, Scenes
from zigpy.zcl.clusters.lightlink import LightLink
from zhaquirks.const import (
BUTTON_1,
BUTTON_2,
BUTTON_3,
BUTTON_4,
COMMAND,
DEVICE_TYPE,
DOUBLE_PRESS,
ENDPOINT_ID,
ENDPOINTS,
INPUT_CLUSTERS,
LONG_PRESS,
MODELS_INFO,
OUTPUT_CLUSTERS,
PROFILE_ID,
SHORT_PRESS,
)
from zhaquirks.tuya import TuyaSmartRemoteOnOffCluster
class Tuya4NewButtonTriggers:
"""Tuya 4-button New version remote device triggers."""
device_automation_triggers = {
(SHORT_PRESS, BUTTON_1): {ENDPOINT_ID: 1, COMMAND: SHORT_PRESS},
(LONG_PRESS, BUTTON_1): {ENDPOINT_ID: 1, COMMAND: LONG_PRESS},
(DOUBLE_PRESS, BUTTON_1): {ENDPOINT_ID: 1, COMMAND: DOUBLE_PRESS},
(SHORT_PRESS, BUTTON_2): {ENDPOINT_ID: 1, COMMAND: SHORT_PRESS},
(LONG_PRESS, BUTTON_2): {ENDPOINT_ID: 1, COMMAND: LONG_PRESS},
(DOUBLE_PRESS, BUTTON_2): {ENDPOINT_ID: 1, COMMAND: DOUBLE_PRESS},
(SHORT_PRESS, BUTTON_3): {ENDPOINT_ID: 1, COMMAND: SHORT_PRESS},
(LONG_PRESS, BUTTON_3): {ENDPOINT_ID: 1, COMMAND: LONG_PRESS},
(DOUBLE_PRESS, BUTTON_3): {ENDPOINT_ID: 1, COMMAND: DOUBLE_PRESS},
(SHORT_PRESS, BUTTON_4): {ENDPOINT_ID: 1, COMMAND: SHORT_PRESS},
(LONG_PRESS, BUTTON_4): {ENDPOINT_ID: 1, COMMAND: LONG_PRESS},
(DOUBLE_PRESS, BUTTON_4): {ENDPOINT_ID: 1, COMMAND: DOUBLE_PRESS},
}
class TuyaSmartRemote004F(CustomDevice, Tuya4NewButtonTriggers):
"""Tuya 4-button New version remote device."""
signature = {
# "node_descriptor": "NodeDescriptor(byte1=2, byte2=64, mac_capability_flags=128, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=0, *allocate_address=True, *complex_descriptor_available=False, *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, *is_valid=True, *logical_type=<LogicalType.EndDevice: 2>, *user_descriptor_available=False)",
# SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=260, device_version=1, input_clusters=[0, 1, 3, 4, 6, 4096], output_clusters=[25, 10, 3, 4, 5, 6, 8, 4096])
MODELS_INFO: [("_TZ3000_xabckq1v", "TS004F")],
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfiguration.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
OnOff.cluster_id,
LightLink.cluster_id,
],
OUTPUT_CLUSTERS: [
Ota.cluster_id,
Time.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
LevelControl.cluster_id,
LightLink.cluster_id,
],
}
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfiguration.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
TuyaSmartRemoteOnOffCluster,
LightLink.cluster_id,
],
OUTPUT_CLUSTERS: [
Ota.cluster_id,
Time.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaSmartRemoteOnOffCluster,
LevelControl.cluster_id,
LightLink.cluster_id,
],
}
},
}
class ZemiSmartRemote004F(CustomDevice, Tuya4NewButtonTriggers):
"""Tuya 4-button New version remote device."""
signature = {
# SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=260, device_version=1, input_clusters=[0, 1, 3, 4, 6, 4096], output_clusters=[25, 10, 3, 4, 5, 6, 8, 4096])
MODELS_INFO: [("_TZ3000_xabckq1v", "TS004F")],
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfiguration.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
OnOff.cluster_id,
LightLink.cluster_id,
],
OUTPUT_CLUSTERS: [
Ota.cluster_id,
Time.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
LevelControl.cluster_id,
LightLink.cluster_id,
],
}
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfiguration.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
TuyaSmartRemoteOnOffCluster,
LightLink.cluster_id,
],
OUTPUT_CLUSTERS: [
Ota.cluster_id,
Time.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaSmartRemoteOnOffCluster,
LevelControl.cluster_id,
LightLink.cluster_id,
],
}
},
}
I used the original file of the ts0044 in order to set this up and adapt it. I’ve tried using different signatures including and not including
# "node_descriptor": "NodeDescriptor(byte1=2, byte2=64, mac_capability_flags=128, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=0, *allocate_address=True, *complex_descriptor_available=False, *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, *is_valid=True, *logical_type=<LogicalType.EndDevice: 2>, *user_descriptor_available=False)",
but it does not matter apparently.
Here is the full log for the joining of the device :
2021-05-23 20:57:20 INFO (MainThread) [zigpy.application] Device 0x66f7 (60:a4:23:ff:fe:db:30:83) joined the network
2021-05-23 20:57:20 DEBUG (MainThread) [zigpy.zdo] [0x66f7:zdo] ZDO request ZDOCmd.Device_annce: [0x66F7, 60:a4:23:ff:fe:db:30:83, 128]
2021-05-23 20:57:20 INFO (MainThread) [zigpy.device] [0x66f7] Requesting 'Node Descriptor'
2021-05-23 20:57:20 DEBUG (MainThread) [zigpy.util] Tries remaining: 2
2021-05-23 20:57:20 DEBUG (MainThread) [zigpy.device] [0x66f7] Extending timeout for 0x25 request
2021-05-23 20:57:21 INFO (MainThread) [zigpy.device] [0x66f7] Node Descriptor: NodeDescriptor(byte1=2, byte2=64, mac_capability_flags=128, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=0, *allocate_address=True, *complex_descriptor_available=False, *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, *is_valid=True, *logical_type=<LogicalType.EndDevice: 2>, *user_descriptor_available=False)
2021-05-23 20:57:21 INFO (MainThread) [zigpy.device] [0x66f7] Discovering endpoints
2021-05-23 20:57:21 DEBUG (MainThread) [zigpy.util] Tries remaining: 3
2021-05-23 20:57:21 DEBUG (MainThread) [zigpy.device] [0x66f7] Extending timeout for 0x26 request
2021-05-23 20:57:21 INFO (MainThread) [zigpy.device] [0x66f7] Discovered endpoints: [1]
2021-05-23 20:57:21 INFO (MainThread) [zigpy.endpoint] [0x66f7:1] Discovering endpoint information
2021-05-23 20:57:21 DEBUG (MainThread) [zigpy.util] Tries remaining: 3
2021-05-23 20:57:21 DEBUG (MainThread) [zigpy.device] [0x66f7] Extending timeout for 0x27 request
2021-05-23 20:57:21 INFO (MainThread) [zigpy.endpoint] [0x66f7:1] Discovered endpoint information: SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=260, device_version=1, input_clusters=[0, 1, 3, 4, 6, 4096], output_clusters=[25, 10, 3, 4, 5, 6, 8, 4096])
2021-05-23 20:57:21 DEBUG (MainThread) [zigpy.device] [0x66f7] Extending timeout for 0x28 request
2021-05-23 20:57:22 DEBUG (MainThread) [zigpy.zcl] [0xdbbe:1:0x0006] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=58 command_id=Command.Report_Attributes>
2021-05-23 20:57:22 DEBUG (MainThread) [zigpy.zcl] [0xdbbe:1:0x0006] ZCL request 0x000a: [[Attribute(attrid=0, value=<TypeValue type=int8s, value=0>)]]
2021-05-23 20:57:22 DEBUG (MainThread) [zigpy.zcl] [0xdbbe:1:0x0006] Attribute report received: on_off=0
2021-05-23 20:57:22 DEBUG (MainThread) [zigpy.zcl] [0x66f7:1:0x0000] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=40 command_id=Command.Read_Attributes_rsp>
2021-05-23 20:57:22 DEBUG (MainThread) [zigpy.endpoint] [0x66f7:1] Manufacturer: _TZ3000_xabckq1v
2021-05-23 20:57:22 DEBUG (MainThread) [zigpy.endpoint] [0x66f7:1] Model: TS004F
2021-05-23 20:57:22 DEBUG (MainThread) [zigpy.quirks.registry] Checking quirks for _TZ3000_xabckq1v TS004F (60:a4:23:ff:fe:db:30:83)
2021-05-23 20:57:22 DEBUG (MainThread) [zigpy.quirks.registry] Considering <class 'zhaquirks.ts004f.ZemiSmartRemote004F'>
2021-05-23 20:57:22 DEBUG (MainThread) [zigpy.quirks.registry] Fail because device_type mismatch on at least one endpoint
2021-05-23 20:57:22 DEBUG (MainThread) [zigpy.quirks.registry] Considering <class 'zhaquirks.ts004f.TuyaSmartRemote004F'>
2021-05-23 20:57:22 DEBUG (MainThread) [zigpy.quirks.registry] Fail because device_type mismatch on at least one endpoint
If someone can tell me what I am missing ?
Thanks