Repository: zigpy/zha-device-handlers

Issue:
[Device Support Request] TS011F MS-104BZ (Zigbee + RF) _TZ3000_pmz6mjyu
**Is your feature request related to a problem? Please describe.**
Clusters 0xE000 and 0xE001 are logged as warnings and can't be accessed:
```
2022-01-07 18:31:37 WARNING (MainThread) [zigpy.zcl] Unknown cluster 57344
2022-01-07 18:31:37 WARNING (MainThread) [zigpy.zcl] Unknown cluster 57345
2022-01-07 18:31:37 WARNING (MainThread) [zigpy.zcl] Unknown cluster 57344
2022-01-07 18:31:37 WARNING (MainThread) [zigpy.zcl] Unknown cluster 57345
2022-01-07 18:31:37 WARNING (MainThread) [zigpy.zcl] Unknown cluster 57344
2022-01-07 18:31:37 WARNING (MainThread) [zigpy.zcl] Unknown cluster 57345
2022-01-07 18:31:37 WARNING (MainThread) [zigpy.zcl] Unknown cluster 57344
2022-01-07 18:31:37 WARNING (MainThread) [zigpy.zcl] Unknown cluster 57345
```
Access to 0xE001 is needed to configure Rocker / Reset switch behavior.

**Describe the solution you'd like**
Force Rocker switch behavior to be able to toggle both physical switches at the same time. Right now, if I press both physical switches at the same time only one light is toggled and the other one is ignored.

**Device signature - this can be acquired by removing the device from ZHA and pairing it again from the add devices screen. Be sure to add the entire content of the log panel after pairing the device to a code block below this line.**
```
{
  "node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 142>, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)",
  "endpoints": {
    "1": {
      "profile_id": 260,
      "device_type": "0x010a",
      "in_clusters": [
        "0x0000",
        "0x0003",
        "0x0004",
        "0x0005",
        "0x0006",
        "0xe000",
        "0xe001"
      ],
      "out_clusters": [
        "0x000a",
        "0x0019"
      ]
    },
    "2": {
      "profile_id": 260,
      "device_type": "0x010a",
      "in_clusters": [
        "0x0003",
        "0x0004",
        "0x0005",
        "0x0006",
        "0xe000",
        "0xe001"
      ],
      "out_clusters": []
    },
    "242": {
      "profile_id": 41440,
      "device_type": "0x0061",
      "in_clusters": [],
      "out_clusters": [
        "0x0021"
      ]
    }
  },
  "manufacturer": "_TZ3000_pmz6mjyu",
  "model": "TS011F",
  "class": "zigpy.device.Device"
}
```

**Additional context**
My device seems to be an updated version of [MS-104BZ](https://zigbee.blakadder.com/Moes_MS-104BZ.html) with both Rocker and Reset switches support.
https://www.moeshouse.com/products/2-gang-tuya-zigbee-3-0-smart-light-switch-module-2mqtt-setup-available



Discussion:
I've tried adding the following quirk (**zhaquirks/tuya/ts011f.py**):
```
"""Tuya TS011F Switches."""

from zigpy.profiles import zha
from zigpy.zcl.clusters.general import (
    Basic,
    GreenPowerProxy,
    Groups,
    Identify,
    OnOff,
    Ota,
    Scenes,
    Time,
)

from zhaquirks.const import (
    DEVICE_TYPE,
    ENDPOINTS,
    INPUT_CLUSTERS,
    MODEL,
    OUTPUT_CLUSTERS,
    PROFILE_ID,
)
from zhaquirks.tuya import (
    TuyaSwitch,
    TuyaZBE000Cluster,
    TuyaZBExternalSwitchTypeCluster,
    TuyaZBOnOffAttributeCluster,
)


class Tuya_2G_Switch(TuyaSwitch):
    """Tuya 2 gang light switch."""

    signature = {
        MODEL: "TS011F",
        ENDPOINTS: {
            # <SimpleDescriptor endpoint=1 profile=260 device_type=266
            # input_clusters=[0, 3, 4, 5, 6, 57344, 57345]
            # output_clusters=[10, 25]>
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_PLUG_IN_UNIT,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Identify.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    OnOff.cluster_id,
                    TuyaZBE000Cluster.cluster_id,
                    TuyaZBExternalSwitchTypeCluster.cluster_id,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
            # <SimpleDescriptor endpoint=2 profile=260 device_type=266
            # input_clusters=[3, 4, 5, 6, 57344, 57345]
            # output_clusters=[]>
            2: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_PLUG_IN_UNIT,
                INPUT_CLUSTERS: [
                    Identify.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    OnOff.cluster_id,
                    TuyaZBE000Cluster.cluster_id,
                    TuyaZBExternalSwitchTypeCluster.cluster_id,
                ],
                OUTPUT_CLUSTERS: [],
            },
            # <SimpleDescriptor endpoint=242 profile=41440 device_type=97
            # input_clusters=[]
            # output_clusters=[33]>
            242: {
                PROFILE_ID: 41440,
                DEVICE_TYPE: 97,
                INPUT_CLUSTERS: [],
                OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
            },
        },
    }
    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Identify.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaZBOnOffAttributeCluster,
                    TuyaZBE000Cluster,
                    TuyaZBExternalSwitchTypeCluster,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
            2: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
                INPUT_CLUSTERS: [
                    Identify.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaZBOnOffAttributeCluster,
                    TuyaZBE000Cluster,
                    TuyaZBExternalSwitchTypeCluster,
                ],
                OUTPUT_CLUSTERS: [],
            },
        },
    }
```

But unfortunately 0xE001 cluster isn't correct, since apparently 0xD030 attribute doesn't exist...
```
2022-01-07 21:20:10 DEBUG (MainThread) [zigpy_deconz.api] APS data indication response: [29, <DeviceState.APSDE_DATA_REQUEST_SLOTS_AVAILABLE|2: 34>, <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0x0000>, 1, <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0xb27b>, 1, 260, 57345, b'\x18\x90\x010\xd0\x86', 0, 175, 255, 49, 44, 152, 0, -49]
2022-01-07 21:20:10 DEBUG (MainThread) [zigpy.zcl] [0xb27b:1:0xe001] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=144 command_id=Command.Read_Attributes_rsp>
2022-01-07 21:20:10 DEBUG (MainThread) [zigpy_deconz.api] 'aps_data_indication' response from <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0xb27b>, ep: 1, profile: 0x0104, cluster_id: 0xe001, data: b'18900130d086'
2022-01-07 21:20:10 DEBUG (MainThread) [homeassistant.components.zha.api] Read attribute for: cluster_id: [57345] cluster_type: [in] endpoint_id: [1] attribute: [53296] manufacturer: [None] response: [None] failure: [{53296: <Status.UNSUPPORTED_ATTRIBUTE: 134>}],
```

How can I list the available cluster attributes and their possible values?
I think your quirk is working OK but i cant see is it loaded OK but you is having it in the log.

The device is responding with <Status.UNSUPPORTED_ATTRIBUTE: 134> = it have getting one request of one attribute but its have not suport for that attribute.

Reason for that can being that the device is not having it implanted or its using it in one other way that we is knowing.

First look in Z2M how they have implanted the same device and if they is asl using the "normal" tuya attribute or is using some more magic.


> I think your quirk is working OK but i cant see is it loaded OK but you is having it in the log.
> 
> The device is responding with <Status.UNSUPPORTED_ATTRIBUTE: 134> = it have getting one request of one attribute but its have not suport for that attribute.
> 
> Reason for that can being that the device is not having it implanted or its using it in one other way that we is knowing.
> 
> First look in Z2M how they have implanted the same device and if they is asl using the "normal" tuya attribute or is using some more magic.

Yes, the quirk is OK, but the 0xE001 cluster (**TuyaZBExternalSwitchTypeCluster**) is missing attributes to configure the external switch, since 0xD030 isn't supported.
How can I list the supported attributes for the 0xE001 cluster?
The cluster and its attribute is implanted in https://github.com/zigpy/zha-device-handlers/blob/b0bbbfb6b1f267b7d87d833b1ba5a5b0b127a9a1/zhaquirks/tuya/__init__.py#L885-L900.
And the finding is documented here: https://github.com/zigpy/zigpy/discussions/823#discussioncomment-1539469.

If you is finding more attributes and commands please help documenting them so we can using them in all devices that is supporting it.

I have some tuya plugs that is not supporting this attributes but its no problem ZHA is only logging not supported and the system and the device is working normal but we cant getting one device supporting attributes that is not implanted in the device firmware only tuya can do that.
> The cluster and its attribute is implanted in https://github.com/zigpy/zha-device-handlers/blob/b0bbbfb6b1f267b7d87d833b1ba5a5b0b127a9a1/zhaquirks/tuya/__init__.py#L885-L900.
> 
> And the finding is documented here: https://github.com/zigpy/zigpy/discussions/823#discussioncomment-1539469.
> 
> 
> 
> If you is finding more attributes and commands please help documenting them so we can using them in all devices that is supporting it.
> 
> 
> 
> I have some tuya plugs that is not supporting this attributes but its no problem ZHA is only logging not supported and the system and the device is working normal but we cant getting one device supporting attributes that is not implanted in the device firmware only tuya can do that.

The thing is I don't know how to find out more cluster attributes...
I've searched but I couldn't find any documentation about it.
From what you say the only possibility is that Tuya reveals that information, right?
Isn't there any way of reading all attribute identifiers and checking which ones are suported?
Zigbee have command for reporting attribute that is supported but its only working if the device is good made and tuya devices is normally not certified and have not implanted or making only half so its not working.

Then i and other user is finding new function we os trying documenting them and then getting it implanted in the system so we can using it.

The best is reading if the manufacturer is writing if the function is supported but its not the same its working in the real life with tuya and many other manufacturers.

Bet is using one tuya ZBGW and sniffing the communication and doing changs and see what is being sent and using the information for the findings. Last sniff findings is undocumented min and max for tuya dimmer switches one user was doing :-)))

Normally Z2M is having the most findings implanted and need looking for the device in there git and then what function its using.
This model supports power on behavior ( https://www.zigbee2mqtt.io/devices/MS-104BZ.html )
I can help testing if someone can add this attribute in the quirk :-)
Thanks
All found functions in implanted in the quirk:
https://github.com/zigpy/zha-device-handlers/blob/dcee551996a0a9e388b6afb1e054dada46897ee5/zhaquirks/tuya/__init__.py#L827-L857
So you shall having one `TuyaZBOnOffAttributeCluster` and the attribute  `{0x8002: ("power_on_state", PowerOnState)` that you can read and writing.
Its working on my LIDL 3Plug 4 USB strip.
PS: its only working if your device have the quirk loaded or you must adding it to the quirk.
Yes. Sorry. Didn't have the quirk loaded. All good, I managed to set another power on state. Thanks
Hi,
I also got one device with one gang (MS-104Z):

![image](https://user-images.githubusercontent.com/657403/153632735-6d934c1c-8b6a-4c23-bfdd-9566f5f249ec.png)

How can I help for a quirk for this one?
Device signature:
```
{
  "node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 142>, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)",
  "endpoints": {
    "1": {
      "profile_id": 260,
      "device_type": "0x0009",
      "in_clusters": [
        "0x0000",
        "0x0004",
        "0x0005",
        "0x0006"
      ],
      "out_clusters": [
        "0x000a",
        "0x0019"
      ]
    }
  },
  "manufacturer": "_TZ3000_zmy1waw6",
  "model": "TS011F",
  "class": "zigpy.device.Device"
}
```
It is working well by default, the only thing I need is the power_on_state attribute, that I need to change in cluster...
You can trying this quirk i have adding your device signature but i have not testing it.
Renaming it without the ` .txt ` and putting in in your (configured) local quirk folder and restarting HA and look if the system is loading the quirk for the device.
[ts011f.py.txt](https://github.com/zigpy/zha-device-handlers/files/8050577/ts011f.py.txt)


I just added the last part to existing ts011f.py. This one:
```
class Tuya_1G_Switch(TuyaSwitch):
    """Tuya 1 gang light switch with RF433."""

    signature = {
        MODEL: "TS011F",
        ENDPOINTS: {
            # <SimpleDescriptor endpoint=1 profile=260 device_type=9
            # input_clusters=[0, 4, 5, 6,]
            # output_clusters=[10, 25]>
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.MAIN_POWER_OUTLET,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    OnOff.cluster_id,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
        },
    }
    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaZBOnOffAttributeCluster,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
        },
    }
```
Because there was some changes to the 2 gang quirk and didn't know if will break something...
![image](https://user-images.githubusercontent.com/657403/153715916-f1eaa7aa-0e7f-4f9f-a477-bbaa2cb4732f.png)

And YES, it's working and I can change the power on state.
Thanks a lot!
Looks great !!
Only one thing: Changing DeviceType can making problems with devices so shall not being made in the quirk. If you need making it then do in HA with custom setting.

Then you is having one working quirk can you doing on PR for adding it so other user can using it  2 ?
I didn't change DeviceType. I have this version [https://github.com/zigpy/zha-device-handlers/blob/dev/zhaquirks/tuya/ts011f.py](https://github.com/zigpy/zha-device-handlers/blob/dev/zhaquirks/tuya/ts011f.py)
In your quirk was changed 😃 
I was only adding the GPP version but in the end it shall being corrected sooner or later before users is getting problems with there devices.

Can you making one PR for you device ??


Are there any special requests for PR?

Resolving patch:
diff --git a/zhaquirks/tuya/ts011f.py b/zhaquirks/tuya/ts011f_switch.py
similarity index 72%
rename from zhaquirks/tuya/ts011f.py
rename to zhaquirks/tuya/ts011f_switch.py
--- a/zhaquirks/tuya/ts011f.py
+++ b/zhaquirks/tuya/ts011f_switch.py
@@ -82,7 +82,7 @@ class Tuya_2G_Switch(TuyaSwitch):
         ENDPOINTS: {
             1: {
                 PROFILE_ID: zha.PROFILE_ID,
-                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
+                DEVICE_TYPE: zha.DeviceType.ON_OFF_PLUG_IN_UNIT,
                 INPUT_CLUSTERS: [
                     Basic.cluster_id,
                     Identify.cluster_id,
@@ -96,7 +96,7 @@ class Tuya_2G_Switch(TuyaSwitch):
             },
             2: {
                 PROFILE_ID: zha.PROFILE_ID,
-                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
+                DEVICE_TYPE: zha.DeviceType.ON_OFF_PLUG_IN_UNIT,
                 INPUT_CLUSTERS: [
                     Identify.cluster_id,
                     Groups.cluster_id,
@@ -115,3 +115,42 @@ class Tuya_2G_Switch(TuyaSwitch):
             },
         },
     }
+
+
+class Tuya_1G_Switch(TuyaSwitch):
+    """Tuya 1 gang light switch with RF433."""
+
+    signature = {
+        MODEL: "TS011F",
+        ENDPOINTS: {
+            # <SimpleDescriptor endpoint=1 profile=260 device_type=9
+            # input_clusters=[0, 4, 5, 6,]
+            # output_clusters=[10, 25]>
+            1: {
+                PROFILE_ID: zha.PROFILE_ID,
+                DEVICE_TYPE: zha.DeviceType.MAIN_POWER_OUTLET,
+                INPUT_CLUSTERS: [
+                    Basic.cluster_id,
+                    Groups.cluster_id,
+                    Scenes.cluster_id,
+                    OnOff.cluster_id,
+                ],
+                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
+            },
+        },
+    }
+    replacement = {
+        ENDPOINTS: {
+            1: {
+                PROFILE_ID: zha.PROFILE_ID,
+                DEVICE_TYPE: zha.DeviceType.MAIN_POWER_OUTLET,
+                INPUT_CLUSTERS: [
+                    Basic.cluster_id,
+                    Groups.cluster_id,
+                    Scenes.cluster_id,
+                    TuyaZBOnOffAttributeCluster,
+                ],
+                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
+            },
+        },
+    }


Test patch: