From f5fe6bcab46975b5846e16053666adf133a276ec Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Sun, 30 Nov 2025 02:31:30 +0100 Subject: [PATCH 1/2] Add the onoff attribute cluster to ts004f These attributes are not available on the output side, only on the input side. This fixes warnings about direction being wrong on the onoff cluster, since the onoff cluster was removed on the input side. --- zhaquirks/tuya/ts004f.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/zhaquirks/tuya/ts004f.py b/zhaquirks/tuya/ts004f.py index 1e679f1114..49fb054b81 100644 --- a/zhaquirks/tuya/ts004f.py +++ b/zhaquirks/tuya/ts004f.py @@ -62,6 +62,7 @@ TuyaNoBindPowerConfigurationCluster, TuyaSmartRemoteOnOffCluster, TuyaZBExternalSwitchTypeCluster, + TuyaZBOnOffAttributeCluster, ) @@ -116,6 +117,7 @@ class TuyaSmartRemote004FROK(EnchantedDevice): TuyaNoBindPowerConfigurationCluster, Identify.cluster_id, Groups.cluster_id, # Is needed for adding group then binding is not working. + TuyaZBOnOffAttributeCluster, LightLink.cluster_id, ], OUTPUT_CLUSTERS: [ @@ -233,6 +235,7 @@ class TuyaSmartRemote004FDMS(EnchantedDevice): TuyaNoBindPowerConfigurationCluster, Identify.cluster_id, Groups.cluster_id, # Is needed for adding group then binding is not working. + TuyaZBOnOffAttributeCluster, LightLink.cluster_id, ], OUTPUT_CLUSTERS: [ @@ -367,6 +370,7 @@ class TuyaSmartRemote004FSK(EnchantedDevice): TuyaNoBindPowerConfigurationCluster, Identify.cluster_id, Groups.cluster_id, # Is needed for adding group then binding is not working. + TuyaZBOnOffAttributeCluster, LightLink.cluster_id, TuyaZBExternalSwitchTypeCluster, ], @@ -483,6 +487,7 @@ class TuyaSmartRemote004F(EnchantedDevice): TuyaNoBindPowerConfigurationCluster, Identify.cluster_id, Groups.cluster_id, # Is needed for adding group then binding is not working. + TuyaZBOnOffAttributeCluster, LightLink.cluster_id, ], OUTPUT_CLUSTERS: [ From 0ad7af7c03762d79f061985f2c9db44ced66f1a6 Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Sun, 30 Nov 2025 03:51:15 +0100 Subject: [PATCH 2/2] Add tuya plug quirk --- zhaquirks/tuya/ts004f.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/zhaquirks/tuya/ts004f.py b/zhaquirks/tuya/ts004f.py index 49fb054b81..426ce45124 100644 --- a/zhaquirks/tuya/ts004f.py +++ b/zhaquirks/tuya/ts004f.py @@ -57,6 +57,7 @@ TURN_OFF, TURN_ON, ) +from zhaquirks.quirk_ids import TUYA_PLUG_ONOFF from zhaquirks.tuya import ( EnchantedDevice, TuyaNoBindPowerConfigurationCluster, @@ -69,6 +70,8 @@ class TuyaSmartRemote004FROK(EnchantedDevice): """Tuya Smart (rotating) Knob device.""" + quirk_id = TUYA_PLUG_ONOFF + 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=, *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]) @@ -191,6 +194,8 @@ class TuyaSmartRemote004FROK(EnchantedDevice): class TuyaSmartRemote004FDMS(EnchantedDevice): """Tuya 4 btton dimmer switch / remote device.""" + quirk_id = TUYA_PLUG_ONOFF + 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=, *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]) @@ -327,6 +332,8 @@ class TuyaSmartRemote004FDMS(EnchantedDevice): class TuyaSmartRemote004FSK(EnchantedDevice): """Tuya Smart (Single) Knob device.""" + quirk_id = TUYA_PLUG_ONOFF + 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=, *user_descriptor_available=False)", # SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=260, device_version=1, input_clusters=[0, 1, 3, 4, 6, 4096, 57345], output_clusters=[25, 10, 3, 4, 6, 8, 4096]) @@ -447,6 +454,8 @@ class TuyaSmartRemote004FSK_v2(TuyaSmartRemote004FSK): class TuyaSmartRemote004F(EnchantedDevice): """Tuya 4-button New version remote device.""" + quirk_id = TUYA_PLUG_ONOFF + 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=, *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])