Repository: zigpy/zha-device-handlers

Issue:
[Device Support Request] Device support for Tuya TS110E
I am not sure if this is a device request, or if the device itself is just not working. Maybe someone can halp?

I ordered two of these in-wall dimmers:

* [blakadder.com entry](https://zigbee.blakadder.com/Lonsonho_QS-Zigbee-D02-TRIAC-LN.html)
* [Device on aliexpress.com](https://www.aliexpress.com/item/4001279149071.html?spm=a2g0o.9042311.0.0.de834c4d9jmLG4)

If successfully installed it and paired it with home assistant (I'm using zha) and was able to use the on-off switch right away, but the dimmer slider wouldn't do anything. So naturally I thought I'd need a quirk. However, I wasn't able to get the dimmer slider working.

I pasted the device signature below and you can see that the `in_clusters` already have `"0x0006"` and `"0x0008"` which is [`OnOff`](https://github.com/zigpy/zigpy/blob/fc8e923e2f2482810b9643c0b2bde149a56a1930/zigpy/zcl/clusters/general.py#L385) and [`LevelControl`](https://github.com/zigpy/zigpy/blob/fc8e923e2f2482810b9643c0b2bde149a56a1930/zigpy/zcl/clusters/general.py#L426). A lot of the other tuya quirks for the dimmers didn't have those, so I understand that a quirk was necessary. In this case however I was surprised that it wasn't working right out of the box, because the [blakadder.com entry](https://zigbee.blakadder.com/Lonsonho_QS-Zigbee-D02-TRIAC-LN.html) confirmed it working with ZHA. However, the blakadder.com entry lists it as `Zigbee ID: "TS110F"; "_TYZB01_qezuin6k"`, while the one I actually got it `Zigbee ID: "TS110E"; "_TZ3210_ngqk6jia"`. So a small difference, even though the device itself looks exactly as on the pictures on blakadder.com and aliexpress.com.

I came up with the following quirk that I stored in `tuya/ts110e.py`:
```python
class DimmerSwitchWithNeutral1Gang(TuyaDimmerSwitch):
    """Tuya Dimmer Switch Module With Neutral 1 Gang"""

    signature = {
        MODELS_INFO: [("_TZ3210_ngqk6jia", "TS110E")],
        ENDPOINTS: {
            # <SimpleDescriptor endpoint=1 profile=260 device_type=257
            # input_clusters=[0, 4, 5, 6, 8, 57345]
            # output_clusters=[10, 25]>
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    OnOff.cluster_id,
                    LevelControl.cluster_id,
                    TuyaZBExternalSwitchTypeCluster.cluster_id,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
            242: {
                # <SimpleDescriptor endpoint=242 profile=41440 device_type=97
                # input_clusters=[]
                # output_clusters=[33]
                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.DIMMABLE_LIGHT,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    OnOff.cluster_id,
                    LevelControl.cluster_id,
                    # TuyaManufacturerClusterOnOff,
                    # TuyaOnOff,
                    # TuyaManufacturerLevelControl,
                    # TuyaLevelControl,
                    TuyaZBExternalSwitchTypeCluster.cluster_id,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
            242: {
                PROFILE_ID: 41440,
                DEVICE_TYPE: 97,
                INPUT_CLUSTERS: [],
                OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
            },
        },
    }
```

The quirk is seen by home assistant (I see the `Quirk: zhaquirks.tuya.ts110e.DimmerSwitchWithNeutral1Gang` on the device in the home assistant UI). As you can see I experimented with all combinations of the `OnOff` and `LevelControl` alternatives. So far only the original 
```
                    OnOff.cluster_id,
                    LevelControl.cluster_id,
```
works for at least the switch but not the dimmer.  
Other combinations i tried:
```
                    TuyaOnOff,
                    TuyaLevelControl,
```
that comes with error
```
2022-03-06 22:48:32 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [548252938000] 'DimmerSwitchWithNeutral1Gang' object has no attribute 'command_bus'
```
Which makes sense. So I tried
```
                    TuyaManufacturerClusterOnOff,
                    TuyaOnOff,
                    TuyaManufacturerLevelControl,
                    TuyaLevelControl,
```
Which didn't throw an error and allowed me to call the switch in the UI of home assistant, but it wouldn't turn on the light and the switch in the UI jumps back like 2 seconds later.

Does anyone have any other suggestions of what I could try?

# Device signature:
```json
{
  "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=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, 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": "0x0101",
      "in_clusters": [
        "0x0000",
        "0x0004",
        "0x0005",
        "0x0006",
        "0x0008",
        "0xe001"
      ],
      "out_clusters": [
        "0x000a",
        "0x0019"
      ]
    },
    "242": {
      "profile_id": 41440,
      "device_type": "0x0061",
      "in_clusters": [],
      "out_clusters": [
        "0x0021"
      ]
    }
  },
  "manufacturer": "_TZ3210_ngqk6jia",
  "model": "TS110E",
  "class": "zhaquirks.tuya.ts110e.DimmerSwitchWithNeutral1Gang"
}
```

**Additional context**
Add any other context or screenshots about the feature request here.



Discussion:
I suggest you to remove your quirk and post the 'original' device signature. The one you have posted is with the quirk applied.
Also can be useful to attach the logs when you operate the physical device. Enable debug logs as described here:
https://www.home-assistant.io/integrations/zha/#debug-logging
Thanks so much for getting back to me!
Ah I didn't realize that was the device signature with the quirk enabled. I ran `rm zhaquirks/tuya/ts110e.py` and restarted home assistant. As expected, the quirk doesn't show in the home assistant UI:
![Screen Shot 2022-03-06 at 5 44 32 PM](https://user-images.githubusercontent.com/18717376/156953805-e152d784-3b05-4ada-b08f-a4cccdb09ad6.png)
The device signature looks pretty close to what I originally posted, just the last line is different. It says `"class": "zigpy.device.Device"` now:
```json
{
  "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=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, 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": "0x0101",
      "in_clusters": [
        "0x0000",
        "0x0004",
        "0x0005",
        "0x0006",
        "0x0008",
        "0xe001"
      ],
      "out_clusters": [
        "0x000a",
        "0x0019"
      ]
    },
    "242": {
      "profile_id": 41440,
      "device_type": "0x0061",
      "in_clusters": [],
      "out_clusters": [
        "0x0021"
      ]
    }
  },
  "manufacturer": "_TZ3210_ngqk6jia",
  "model": "TS110E",
  "class": "zigpy.device.Device"
}
```

I also activated the logs (thanks for the link) and got these logs when clicking the switch on the home assistant UI to 'off':
```
2022-03-07 01:48:32 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=light, service=turn_off, service_data=entity_id=light.kitchen_backsplash_2_level_on_off>
2022-03-07 01:48:32 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=6, TSN=39, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK|ACK_REQUEST: 48>, Radius=30, Data=b'\x01\x27\x00')
2022-03-07 01:48:32 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-07 01:48:32 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=39)
2022-03-07 01:48:32 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=6, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=75, SecurityUse=<Bool.false: 0>, TimeStamp=647701, TSN=0, Data=b'\x18\x27\x0B\x00\x00', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-07 01:48:32 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0006] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=39 command_id=Command.Default_Response>
2022-03-07 01:48:32 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=6, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=75, SecurityUse=<Bool.false: 0>, TimeStamp=647903, TSN=0, Data=b'\x08\x63\x0A\x00\x00\x10\x00', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-07 01:48:32 DEBUG (MainThread) [zigpy.zcl] [0x3891: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=99 command_id=Command.Report_Attributes>
2022-03-07 01:48:32 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0006] ZCL request 0x000a: [[Attribute(attrid=0, value=<TypeValue type=Bool, value=Bool.false>)]]
2022-03-07 01:48:32 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0006] Attribute report received: on_off=0
2022-03-07 01:48:32 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=light.kitchen_backsplash_2_level_on_off, old_state=<state light.kitchen_backsplash_2_level_on_off=on; supported_color_modes=['brightness'], color_mode=brightness, brightness=201, off_brightness=None, friendly_name=Kitchen Backsplash 2 level, on_off, supported_features=33 @ 2022-03-07T01:42:40.532954+00:00>, new_state=<state light.kitchen_backsplash_2_level_on_off=off; supported_color_modes=['brightness'], off_brightness=None, friendly_name=Kitchen Backsplash 2 level, on_off, supported_features=33 @ 2022-03-07T01:48:32.570891+00:00>>
2022-03-07 01:48:32 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=6, TSN=99, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x63\x0B\x0A\x00')
2022-03-07 01:48:32 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0006]: executed 'off' command with args: '()' kwargs: '{}' result: [0, <Status.SUCCESS: 0>]
2022-03-07 01:48:32 DEBUG (MainThread) [homeassistant.components.zha.entity] light.kitchen_backsplash_2_level_on_off: turned off: [0, <Status.SUCCESS: 0>]
2022-03-07 01:48:32 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-07 01:48:32 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=99)
```

Then I used the home assistant UI to slide the brightness to 49 and got these logs:
```
2022-03-07 01:56:22 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=light, service=turn_on, service_data=entity_id=light.kitchen_backsplash_2_level_on_off, brightness_pct=49>
2022-03-07 01:56:22 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=40, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK|ACK_REQUEST: 48>, Radius=30, Data=b'\x01\x28\x04\x7D\x01\x00')
2022-03-07 01:56:22 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-07 01:56:22 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=40)
2022-03-07 01:56:22 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=75, SecurityUse=<Bool.false: 0>, TimeStamp=14300235, TSN=0, Data=b'\x18\x28\x0B\x04\x00', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-07 01:56:22 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] 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.Default_Response>
2022-03-07 01:56:22 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: executed 'move_to_level_with_on_off' command with args: '(125, 1)' kwargs: '{}' result: [4, <Status.SUCCESS: 0>]
2022-03-07 01:56:22 DEBUG (MainThread) [homeassistant.components.zha.entity] light.kitchen_backsplash_2_level_on_off: turned on: {'move_to_level_with_on_off': [4, <Status.SUCCESS: 0>]}
2022-03-07 01:56:22 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=light.kitchen_backsplash_2_level_on_off, old_state=<state light.kitchen_backsplash_2_level_on_off=off; supported_color_modes=['brightness'], off_brightness=None, friendly_name=Kitchen Backsplash 2 level, on_off, supported_features=33 @ 2022-03-07T01:48:32.570891+00:00>, new_state=<state light.kitchen_backsplash_2_level_on_off=on; supported_color_modes=['brightness'], color_mode=brightness, brightness=125, off_brightness=None, friendly_name=Kitchen Backsplash 2 level, on_off, supported_features=33 @ 2022-03-07T01:56:22.649522+00:00>>
```

Only interesting thing I can find in the logs is that the off command shows something like `brightness=201` and the brightness command shows something like `brightness=125`. Maybe all the brightnesses ever set are over 100?
Hmm inspecting this closer I don't think the problem is that the brightness is over 100. It seems like brightness is a scale from 0 to 255. Like when I slide the slider to 2, there is a
```
executed 'move_to_level_with_on_off' command with args: '(5, 1)'
```
full logs for that:
```
2022-03-07 02:03:23 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=light, service=turn_on, service_data=entity_id=light.kitchen_backsplash_2_level_on_off, brightness_pct=2>
2022-03-07 02:03:23 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=44, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK|ACK_REQUEST: 48>, Radius=30, Data=b'\x01\x2C\x04\x05\x01\x00')
2022-03-07 02:03:23 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-07 02:03:23 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=44)
2022-03-07 02:03:23 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=72, SecurityUse=<Bool.false: 0>, TimeStamp=9161317, TSN=0, Data=b'\x18\x2C\x0B\x04\x00', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-07 02:03:23 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=44 command_id=Command.Default_Response>
2022-03-07 02:03:23 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: executed 'move_to_level_with_on_off' command with args: '(5, 1)' kwargs: '{}' result: [4, <Status.SUCCESS: 0>]
2022-03-07 02:03:23 DEBUG (MainThread) [homeassistant.components.zha.entity] light.kitchen_backsplash_2_level_on_off: turned on: {'move_to_level_with_on_off': [4, <Status.SUCCESS: 0>]}
2022-03-07 02:03:23 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=light.kitchen_backsplash_2_level_on_off, old_state=<state light.kitchen_backsplash_2_level_on_off=on; supported_color_modes=['brightness'], color_mode=brightness, brightness=252, off_brightness=None, friendly_name=Kitchen Backsplash 2 level, on_off, supported_features=33 @ 2022-03-07T01:56:22.649522+00:00>, new_state=<state light.kitchen_backsplash_2_level_on_off=on; supported_color_modes=['brightness'], color_mode=brightness, brightness=5, off_brightness=None, friendly_name=Kitchen Backsplash 2 level, on_off, supported_features=33 @ 2022-03-07T01:56:22.649522+00:00>>
```

And If I move it to 98 there is a
```
executed 'move_to_level_with_on_off' command with args: '(250, 1)'
```
full logs for that
```
2022-03-07 02:06:34 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=light, service=turn_on, service_data=entity_id=light.kitchen_backsplash_2_level_on_off, brightness_pct=98>
2022-03-07 02:06:34 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=45, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK|ACK_REQUEST: 48>, Radius=30, Data=b'\x01\x2D\x04\xFA\x01\x00')
2022-03-07 02:06:34 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-07 02:06:34 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=45)
2022-03-07 02:06:34 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=72, SecurityUse=<Bool.false: 0>, TimeStamp=5381833, TSN=0, Data=b'\x18\x2D\x0B\x04\x00', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-07 02:06:34 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=45 command_id=Command.Default_Response>
2022-03-07 02:06:34 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: executed 'move_to_level_with_on_off' command with args: '(250, 1)' kwargs: '{}' result: [4, <Status.SUCCESS: 0>]
2022-03-07 02:06:34 DEBUG (MainThread) [homeassistant.components.zha.entity] light.kitchen_backsplash_2_level_on_off: turned on: {'move_to_level_with_on_off': [4, <Status.SUCCESS: 0>]}
2022-03-07 02:06:34 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=light.kitchen_backsplash_2_level_on_off, old_state=<state light.kitchen_backsplash_2_level_on_off=on; supported_color_modes=['brightness'], color_mode=brightness, brightness=5, off_brightness=None, friendly_name=Kitchen Backsplash 2 level, on_off, supported_features=33 @ 2022-03-07T01:56:22.649522+00:00>, new_state=<state light.kitchen_backsplash_2_level_on_off=on; supported_color_modes=['brightness'], color_mode=brightness, brightness=250, off_brightness=None, friendly_name=Kitchen Backsplash 2 level, on_off, supported_features=33 @ 2022-03-07T01:56:22.649522+00:00>>
```

Is there anything else interesting you can find in the logs?
Thanks for the signature.

It seems that your device its a 'normal' zigbee device with the `0xe001` cluster from Tuya. Your quirk seems adequate for device signature, but for some reason the dim events don't seem to arrive/come from the proper cluster.

Try to get traces from operate the **physical device**. Usually when you interact with the device, it reports its status and we can get some information from that message.

PS: dim values are from 0 to 255 😉 
I see now what you meant. Not just control the slider of the UI, but actually the physical device.
So I did that and got a good chunk of logs. Attached are the logs for me dimming the light from all the way bright to all the way dark.

I can't quite wrap my head around yet what I can make out of that yet. The slider in the UI for the dimmer doesn't move at all when I dim the physical light.

I do see log lines like 
```
2022-03-08 04:48:25 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL request 0x000a: [[Attribute(attrid=61440, value=<TypeValue type=uint16_t, value=75>)]]
2022-03-08 04:48:25 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Attribute report received: 61440=75
2022-03-08 04:48:25 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: received attribute: 61440 update with value: 75
```

I see that the dim values from the device itself are between 0 and 1000. So that has to be mapped to the dim values 0 to 255. I think for the existing quirks that's done here:
https://github.com/zigpy/zha-device-handlers/blob/e3fa034284437595d1997326a8597086d623f413/zhaquirks/tuya/__init__.py#L1156

So I probably somehow have to incorporate that `TuyaLevelControl` class. Which I tried before with no success.

I also see that `0x0008` in there, which translates to the generic [`LevelControl`](https://github.com/zigpy/zigpy/blob/fc8e923e2f2482810b9643c0b2bde149a56a1930/zigpy/zcl/clusters/general.py#L426), so I think that's a good thing.

I also see that attribute `0x3891` and `61440` but not sure what that means.

Do you see anything in the logs when operating the physical device below that could give me a hint of what I'm missing?

```
2022-03-08 04:48:25 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=90, SecurityUse=<Bool.false: 0>, TimeStamp=3993970, TSN=0, Data=b'\x08\x87\x0A\x00\xF0\x21\x4B\x00', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-08 04:48:25 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=135 command_id=Command.Report_Attributes>
2022-03-08 04:48:25 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL request 0x000a: [[Attribute(attrid=61440, value=<TypeValue type=uint16_t, value=75>)]]
2022-03-08 04:48:25 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Attribute report received: 61440=75
2022-03-08 04:48:25 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: received attribute: 61440 update with value: 75
2022-03-08 04:48:25 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=135, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x87\x0B\x0A\x00')
2022-03-08 04:48:25 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-08 04:48:25 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=135)
2022-03-08 04:48:26 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=84, SecurityUse=<Bool.false: 0>, TimeStamp=4019549, TSN=0, Data=b'\x08\x88\x0A\x00\xF0\x21\x89\x00', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-08 04:48:26 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=136 command_id=Command.Report_Attributes>
2022-03-08 04:48:26 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL request 0x000a: [[Attribute(attrid=61440, value=<TypeValue type=uint16_t, value=137>)]]
2022-03-08 04:48:26 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Attribute report received: 61440=137
2022-03-08 04:48:26 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: received attribute: 61440 update with value: 137
2022-03-08 04:48:26 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=136, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x88\x0B\x0A\x00')
2022-03-08 04:48:26 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-08 04:48:26 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=136)
2022-03-08 04:48:26 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=96, SecurityUse=<Bool.false: 0>, TimeStamp=4045189, TSN=0, Data=b'\x08\x89\x0A\x00\xF0\x21\xC8\x00', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-08 04:48:26 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=137 command_id=Command.Report_Attributes>
2022-03-08 04:48:26 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL request 0x000a: [[Attribute(attrid=61440, value=<TypeValue type=uint16_t, value=200>)]]
2022-03-08 04:48:26 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Attribute report received: 61440=200
2022-03-08 04:48:26 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: received attribute: 61440 update with value: 200
2022-03-08 04:48:26 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=137, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x89\x0B\x0A\x00')
2022-03-08 04:48:26 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-08 04:48:26 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=137)
2022-03-08 04:48:26 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=90, SecurityUse=<Bool.false: 0>, TimeStamp=4070767, TSN=0, Data=b'\x08\x8A\x0A\x00\xF0\x21\x07\x01', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-08 04:48:26 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=138 command_id=Command.Report_Attributes>
2022-03-08 04:48:26 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL request 0x000a: [[Attribute(attrid=61440, value=<TypeValue type=uint16_t, value=263>)]]
2022-03-08 04:48:26 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Attribute report received: 61440=263
2022-03-08 04:48:26 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: received attribute: 61440 update with value: 263
2022-03-08 04:48:26 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=138, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x8A\x0B\x0A\x00')
2022-03-08 04:48:27 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-08 04:48:27 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=138)
2022-03-08 04:48:27 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=90, SecurityUse=<Bool.false: 0>, TimeStamp=4096392, TSN=0, Data=b'\x08\x8B\x0A\x00\xF0\x21\x45\x01', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-08 04:48:27 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=139 command_id=Command.Report_Attributes>
2022-03-08 04:48:27 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL request 0x000a: [[Attribute(attrid=61440, value=<TypeValue type=uint16_t, value=325>)]]
2022-03-08 04:48:27 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Attribute report received: 61440=325
2022-03-08 04:48:27 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: received attribute: 61440 update with value: 325
2022-03-08 04:48:27 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=139, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x8B\x0B\x0A\x00')
2022-03-08 04:48:27 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-08 04:48:27 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=139)
2022-03-08 04:48:27 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=84, SecurityUse=<Bool.false: 0>, TimeStamp=4121931, TSN=0, Data=b'\x08\x8C\x0A\x00\xF0\x21\x84\x01', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-08 04:48:27 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=140 command_id=Command.Report_Attributes>
2022-03-08 04:48:27 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL request 0x000a: [[Attribute(attrid=61440, value=<TypeValue type=uint16_t, value=388>)]]
2022-03-08 04:48:27 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Attribute report received: 61440=388
2022-03-08 04:48:27 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: received attribute: 61440 update with value: 388
2022-03-08 04:48:27 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=140, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x8C\x0B\x0A\x00')
2022-03-08 04:48:27 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-08 04:48:27 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=140)
2022-03-08 04:48:28 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=87, SecurityUse=<Bool.false: 0>, TimeStamp=4147594, TSN=0, Data=b'\x08\x8D\x0A\x00\xF0\x21\xC3\x01', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-08 04:48:28 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=141 command_id=Command.Report_Attributes>
2022-03-08 04:48:28 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL request 0x000a: [[Attribute(attrid=61440, value=<TypeValue type=uint16_t, value=451>)]]
2022-03-08 04:48:28 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Attribute report received: 61440=451
2022-03-08 04:48:28 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: received attribute: 61440 update with value: 451
2022-03-08 04:48:28 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=141, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x8D\x0B\x0A\x00')
2022-03-08 04:48:28 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-08 04:48:28 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=141)
2022-03-08 04:48:28 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=90, SecurityUse=<Bool.false: 0>, TimeStamp=4173234, TSN=0, Data=b'\x08\x8E\x0A\x00\xF0\x21\x02\x02', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-08 04:48:28 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=142 command_id=Command.Report_Attributes>
2022-03-08 04:48:28 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL request 0x000a: [[Attribute(attrid=61440, value=<TypeValue type=uint16_t, value=514>)]]
2022-03-08 04:48:28 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Attribute report received: 61440=514
2022-03-08 04:48:28 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: received attribute: 61440 update with value: 514
2022-03-08 04:48:28 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=142, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x8E\x0B\x0A\x00')
2022-03-08 04:48:28 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-08 04:48:28 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=142)
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=90, SecurityUse=<Bool.false: 0>, TimeStamp=4198871, TSN=0, Data=b'\x08\x8F\x0A\x00\xF0\x21\x40\x02', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=143 command_id=Command.Report_Attributes>
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL request 0x000a: [[Attribute(attrid=61440, value=<TypeValue type=uint16_t, value=576>)]]
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Attribute report received: 61440=576
2022-03-08 04:48:29 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: received attribute: 61440 update with value: 576
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=143, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x8F\x0B\x0A\x00')
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=143)
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=90, SecurityUse=<Bool.false: 0>, TimeStamp=4224444, TSN=0, Data=b'\x08\x90\x0A\x00\xF0\x21\x7F\x02', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=144 command_id=Command.Report_Attributes>
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL request 0x000a: [[Attribute(attrid=61440, value=<TypeValue type=uint16_t, value=639>)]]
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Attribute report received: 61440=639
2022-03-08 04:48:29 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: received attribute: 61440 update with value: 639
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=144, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x90\x0B\x0A\x00')
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=144)
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=87, SecurityUse=<Bool.false: 0>, TimeStamp=4250026, TSN=0, Data=b'\x08\x91\x0A\x00\xF0\x21\xBE\x02', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=145 command_id=Command.Report_Attributes>
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL request 0x000a: [[Attribute(attrid=61440, value=<TypeValue type=uint16_t, value=702>)]]
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Attribute report received: 61440=702
2022-03-08 04:48:29 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: received attribute: 61440 update with value: 702
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=145, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x91\x0B\x0A\x00')
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-08 04:48:29 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=145)
2022-03-08 04:48:30 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=87, SecurityUse=<Bool.false: 0>, TimeStamp=4275645, TSN=0, Data=b'\x08\x92\x0A\x00\xF0\x21\xFD\x02', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-08 04:48:30 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=146 command_id=Command.Report_Attributes>
2022-03-08 04:48:30 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL request 0x000a: [[Attribute(attrid=61440, value=<TypeValue type=uint16_t, value=765>)]]
2022-03-08 04:48:30 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Attribute report received: 61440=765
2022-03-08 04:48:30 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: received attribute: 61440 update with value: 765
2022-03-08 04:48:30 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=146, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x92\x0B\x0A\x00')
2022-03-08 04:48:30 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-08 04:48:30 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=146)
2022-03-08 04:48:30 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=87, SecurityUse=<Bool.false: 0>, TimeStamp=4301214, TSN=0, Data=b'\x08\x93\x0A\x00\xF0\x21\x3B\x03', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-08 04:48:30 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=147 command_id=Command.Report_Attributes>
2022-03-08 04:48:30 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL request 0x000a: [[Attribute(attrid=61440, value=<TypeValue type=uint16_t, value=827>)]]
2022-03-08 04:48:30 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Attribute report received: 61440=827
2022-03-08 04:48:30 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: received attribute: 61440 update with value: 827
2022-03-08 04:48:30 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=147, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x93\x0B\x0A\x00')
2022-03-08 04:48:30 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-08 04:48:30 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=147)
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=84, SecurityUse=<Bool.false: 0>, TimeStamp=4326890, TSN=0, Data=b'\x08\x94\x0A\x00\xF0\x21\x7A\x03', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=148 command_id=Command.Report_Attributes>
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL request 0x000a: [[Attribute(attrid=61440, value=<TypeValue type=uint16_t, value=890>)]]
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Attribute report received: 61440=890
2022-03-08 04:48:31 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: received attribute: 61440 update with value: 890
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=148, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x94\x0B\x0A\x00')
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=148)
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=87, SecurityUse=<Bool.false: 0>, TimeStamp=4352469, TSN=0, Data=b'\x08\x95\x0A\x00\xF0\x21\xB9\x03', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=149 command_id=Command.Report_Attributes>
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL request 0x000a: [[Attribute(attrid=61440, value=<TypeValue type=uint16_t, value=953>)]]
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Attribute report received: 61440=953
2022-03-08 04:48:31 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: received attribute: 61440 update with value: 953
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=149, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x95\x0B\x0A\x00')
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=149)
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=87, SecurityUse=<Bool.false: 0>, TimeStamp=4372171, TSN=0, Data=b'\x08\x96\x0A\x00\xF0\x21\xE4\x03', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=150 command_id=Command.Report_Attributes>
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL request 0x000a: [[Attribute(attrid=61440, value=<TypeValue type=uint16_t, value=996>)]]
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Attribute report received: 61440=996
2022-03-08 04:48:31 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: received attribute: 61440 update with value: 996
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=150, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x96\x0B\x0A\x00')
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-08 04:48:31 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=150)
```
Maybe interesting: When I bring back my custom quirk with these input clusters enabled:
```
                    TuyaManufacturerClusterOnOff,
                    TuyaOnOff,
                    TuyaManufacturerLevelControl,
                    TuyaLevelControl,
```
And then setting the brightness via UI slider I get
```
2022-03-08 06:13:36 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=light, service=turn_on, service_data=entity_id=light.kitchen_backsplash_2_level_on_off, brightness_pct=53>
2022-03-08 06:13:36 DEBUG (MainThread) [zhaquirks.tuya] a4:c1:38:76:3f:03:3e:46 Sending Tuya Cluster Command.. Cluster Command is 4, Arguments are (135, 1)
2022-03-08 06:13:36 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=61184, TSN=25, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK|ACK_REQUEST: 48>, Radius=30, Data=b'\x05\x41\x11\x19\x00\x00\x00\x02\x02\x00\x04\x00\x00\x02\x11')
2022-03-08 06:13:36 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-08 06:13:36 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=25)
2022-03-08 06:13:36 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=61184, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=84, SecurityUse=<Bool.false: 0>, TimeStamp=2763000, TSN=0, Data=b'\x18\x19\x0B\x00\x83', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-08 06:13:36 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=25 command_id=Command.Default_Response>
2022-03-08 06:13:36 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: executed 'move_to_level_with_on_off' command with args: '(135, 1)' kwargs: '{}' result: [0, <Status.UNSUP_MANUF_CLUSTER_COMMAND: 131>]
2022-03-08 06:13:36 DEBUG (MainThread) [homeassistant.components.zha.entity] light.kitchen_backsplash_2_level_on_off: turned on: {'move_to_level_with_on_off': [0, <Status.UNSUP_MANUF_CLUSTER_COMMAND: 131>]}
```
Which has a different `ClusterId=61184` and it says `result: [0, <Status.UNSUP_MANUF_CLUSTER_COMMAND: 131>]`.

But I do I get my quirk to set this attribute `61440` (which is `0xF000`) to a value between 0 and 1000?
Ok, first I am going to try to explain to you what we are seeing and then we will see what can be done.

> 2022-03-08 04:48:25 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL request 0x000a: [[Attribute(attrid=61440, value=<TypeValue type=uint16_t, value=75>)]]

Here we have an attributte report from the device.
This `[0x3891:1:0x0008]` is some standard part of ZHA messages and is telling us that the device `0x3891` from endpoint `1` and cluster `0x0008` is sending the attribute report.
Tha part is correct. You can see in the device signature this endpoint and this cluster (which, as you said, corresponds to the `LevelControl`)

The second part is telling us that the attribute `61440` is updating its value (from 0 to 1000). And that is a problem.
HA (and the Zigbee standard) expect dim values (`current_level`) to be reported in the `0x0000` attribute (and not the `0xF000` as that device is doing):

https://github.com/zigpy/zigpy/blob/0c4b9a8a25c5eef5b008d66c2e56aae3f8d5e769/zigpy/zcl/clusters/general.py#L696-L716

Also, the expected that values are from 0 to 255.

And, what can be done?
Obviously we need to create a quirk for this cluster. It is necessary to convert the `attrid` and its value both ways ZHA --> device and device --> ZHA

Create a new quirk for this `LevelControl` cluster. It may be something like:
```python
  class F000LevelControlCluster(LevelControl):
    """LevelControlCluster that reports to attrid 0xF000."""

    class TuyaLevelPayload(t.Struct):
        """Tuya Level payload."""

        level: t.uint16_t
        transtime: t.uint16_t

    manufacturer_attributes = {0xF000: ("manufacturer_current_level", t.uint16_t),} 

    manufacturer_server_commands = {
        0x00F0: ("moveToLevelTuya", (TuyaLevelPayload,), False),
    }

    # 0xF000 reported values are 0-1000, convert to 0-255
    def _update_attribute(self, attrid, value):
        if attrid == 0xF000:
            value = (value * 255) // 1000
            attrid = 0x0000

        super()._update_attribute(attrid, value)

    async def command(
        self,
        command_id: Union[foundation.Command, int, t.uint8_t],
        *args,
        manufacturer: Optional[Union[int, t.uint16_t]] = None,
        expect_reply: bool = True,
        tsn: Optional[Union[int, t.uint8_t]] = None,
    ):
        """Override the default Cluster command."""
        self.debug(
            "Sending Cluster Command. Cluster Command is %x, Arguments are %s",
            command_id,
            args,
        )
        # move_to_level, move, move_to_level_with_on_off
        if command_id in (0x0000, 0x0001, 0x0004):
            # convert dim values to 0-1000
            brightness = (args[0] * 1000) // 255
            return await super().command(
                0x00F0, 
                TuyaLevelPayload(level=brightness, transtime=0), 
                manufacturer, 
                expect_reply,
                tsn
            )

        return super().command(command_id, *args, manufacturer, expect_reply, tsn)
```

Be carefull with new imports.

Then you can use this cluster in your quirk:
```python
class DimmerSwitchWithNeutral1Gang(TuyaDimmerSwitch):
    """Tuya Dimmer Switch Module With Neutral 1 Gang"""

    signature = {
        MODELS_INFO: [("_TZ3210_ngqk6jia", "TS110E")],
        ENDPOINTS: {
            # <SimpleDescriptor endpoint=1 profile=260 device_type=257
            # input_clusters=[0, 4, 5, 6, 8, 57345]
            # output_clusters=[10, 25]>
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    OnOff.cluster_id,
                    LevelControl.cluster_id,
                    TuyaZBExternalSwitchTypeCluster.cluster_id,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
            242: {
                # <SimpleDescriptor endpoint=242 profile=41440 device_type=97
                # input_clusters=[]
                # output_clusters=[33]
                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.DIMMABLE_LIGHT,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    OnOff.cluster_id,
                    F000LevelControlCluster,
                    TuyaZBExternalSwitchTypeCluster.cluster_id,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
            242: {
                PROFILE_ID: 41440,
                DEVICE_TYPE: 97,
                INPUT_CLUSTERS: [],
                OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
            },
        },
    }
```

The `_update_attribute` will handle "device --> ZHA" messages and is responsible for the reported values being updated in HA.
The `command` will be in charge of sending the values that the device expects. This part makes me more doubtful because I haven't located a similar implementation.

edit: code update
Only for info i have one 2 gang with no neutral version `TS110F _TZ3000_92chsky7` that is working OK but  its not having the extra function with min and max dim level cluster (0xE001) (what i knowing) that this is having and is working OK in ZHA without quirk.
This devices its little normal tuya devices we is having but its working nice (until IKEA was taking the group binding away and i cant controlling the gangs from them only the all the device on / off).
@MattWestb do you know about any quirk that is 'translating' from one cluster attribute (`0xF000` here) to other one (the standard `0x0000`)? 
I haven't find any implementation like this and I'm not sure about the "HA --> device" part.
I have not seen one, then tuya is making all thing not 100% the same like the power on default is 2/3 function OK and have leaving it on the tuya attribute and not "converting" it to ZCL standard.

Perhaps the tuya TRVs is using many attributes but i dont knowing is some is being "moved" to ZCL standard but its not the same then its to and from DP commands.

Perhaps our @puddly  is knowing if some Xiaomi devices is doing it (they using different attributes / commands strings for attribute reporting and setting)?
I have putting in the new found attribute in the matrix as WIP and linked here. https://github.com/zigpy/zigpy/discussions/823#discussioncomment-1539469

Then have the level working is the device very likely have more attributes that is not implanted but can being done like what Bulb type is connected (found in latest tuya dev docks and all is not tested but some is working like min and may dim).
Wow awesome, thanks so much for your help so far. So you were exactly right, the `_update_attribute` function works as expected. As I dim on the physical device I can see the brightness slider in the home assistant UI change in real time. That's pretty cool.  

```
2022-03-08 22:21:36 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL request 0x000a: [[Attribute(attrid=61440, value=<TypeValue type=uint16_t, value=494>)]]
2022-03-08 22:21:36 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Attribute report received: 61440=494
2022-03-08 22:21:36 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: received attribute: 0 update with value: 125
```

You were also right that the `command` function doesn't quite work yet, so I can't update the brightness from home assistant yet.
First I got an error that I fixed quickly by adding an `async`  before the `def command` because it told me `await` can't be in a function without `async`.  
Now home assistant starts up and successfully updates the values as I dim the physical device, but whenever I move the slider int he UI I get 
```
2022-03-08 22:22:41 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Sending Cluster Command. Cluster Command is 4, Arguments are (138, 1)
2022-03-08 22:22:41 ERROR (MainThread) [zigpy.zcl] [0x3891:1:0x0008] 61440 is not a valid attribute id
```
and then a little further down
```
2022-03-08 22:22:41 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [546955499648] list index out of range
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 185, in handle_call_service
    await hass.services.async_call(
  File "/usr/src/homeassistant/homeassistant/core.py", line 1495, in async_call
    task.result()
  File "/usr/src/homeassistant/homeassistant/core.py", line 1530, in _execute_service
    await handler.job.target(service_call)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 209, in handle_service
    await self.hass.helpers.service.entity_service_call(
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 663, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 896, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 700, in _handle_entity_call
    await result
  File "/usr/src/homeassistant/homeassistant/components/light/__init__.py", line 494, in async_handle_light_on_service
    await light.async_turn_on(**filter_turn_on_params(light, params))
  File "/usr/src/homeassistant/homeassistant/components/zha/light.py", line 236, in async_turn_on
    if not isinstance(result, list) or result[1] is not Status.SUCCESS:
IndexError: list index out of range
```

So it expects `result[1]` to be there.
I guess what we're returning in `return await self.write_attributes({0xF000: brightness}, manufacturer=manufacturer)` somehow needs to return a list?

Is it now guesswork to find out what command the device needs?
Do you think something similar to this helps? 
https://github.com/zigpy/zha-device-handlers/blob/e3fa034284437595d1997326a8597086d623f413/zhaquirks/tuya/__init__.py#L429-L450

I already tries some variations with now success yet.
Try uncomment this line from `F000LevelControlCluster`:
```python
    manufacturer_attributes = {0xF000: ("current_level", t.uint8_t),} # maybe needed for write_attributes

```

Hmm no, still the same error: 
```
  File "/usr/src/homeassistant/homeassistant/components/zha/light.py", line 236, in async_turn_on
    if not isinstance(result, list) or result[1] is not Status.SUCCESS:
IndexError: list index out of range
```

But what's new is that for every tuya value greater than 256 I get this error as well:
```
2022-03-08 23:17:28 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Sending Cluster Command. Cluster Command is 4, Arguments are (102, 1)
2022-03-08 23:17:28 ERROR (MainThread) [zigpy.zcl] [0x3891:1:0x0008] 400 is not an unsigned 8 bit integer
```
changing it to
```
    manufacturer_attributes = {0xF000: ("current_level", t.uint16_t),} # maybe needed for write_attributes
```
removes the second error, but still has the first error...
Maybe this way (as a quick&dirty workaround):
```python

    async def command(
        self,
        command_id: Union[foundation.Command, int, t.uint8_t],
        *args,
        manufacturer: Optional[Union[int, t.uint16_t]] = None,
        expect_reply: bool = True,
        tsn: Optional[Union[int, t.uint8_t]] = None,
    ):
        """Override the default Cluster command."""
        self.debug(
            "Sending Cluster Command. Cluster Command is %x, Arguments are %s",
            command_id,
            args,
        )
        # move_to_level, move, move_to_level_with_on_off
        if command_id in (0x0000, 0x0001, 0x0004):
            # convert dim values to 0-1000
            brightness = (args[0] * 1000) // 255
            self.write_attributes({0xF000: brightness}, manufacturer=manufacturer)
            return [[foundation.WriteAttributesStatusRecord(foundation.Status.SUCCESS)]] 

        return super().command(command_id, *args, manufacturer, expect_reply, tsn)
```

I'll keep looking...
I think that there is a better approach:
```python

    async def command(
        self,
        command_id: Union[foundation.Command, int, t.uint8_t],
        *args,
        manufacturer: Optional[Union[int, t.uint16_t]] = None,
        expect_reply: bool = True,
        tsn: Optional[Union[int, t.uint8_t]] = None,
    ):
        """Override the default Cluster command."""
        self.debug(
            "Sending Cluster Command. Cluster Command is %x, Arguments are %s",
            command_id,
            args,
        )
        # move_to_level, move, move_to_level_with_on_off
        if command_id in (0x0000, 0x0001, 0x0004):
            # convert dim values to 0-1000
            brightness = (args[0] * 1000) // 255
            (res,) = await self.write_attributes({0xF000: brightness}, manufacturer=manufacturer)
            return [command_id, res[0].status]

        return super().command(command_id, *args, manufacturer, expect_reply, tsn)
```

🤞🏻 
Another test you can perform is try to read & update this attribute from cluster `F000LevelControlCluster`.
From the device view --> "Manage clusters" --> Select 'F000LevelControlCluster' --> Select attribute from cluster 'current_level (id: 0xF000)' --> 'Get zigbee attribute'

You can try to put a 0-255 value and hit 'Set zigbee attribute', this should change the dim value from device.

Look at the logs and attach all you find relevant.
So I tried the second better approach you sent and no error anymore, but also not changing the brightness on the device.
Log of sliding the brightness to a new point:
```
2022-03-08 23:56:44 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=light, service=turn_on, service_data=entity_id=light.kitchen_backsplash_2_level_on_off, brightness_pct=78>
2022-03-08 23:56:44 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] Sending Cluster Command. Cluster Command is 4, Arguments are (199, 1)
2022-03-08 23:56:44 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x3891), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=8, TSN=25, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK|ACK_REQUEST: 48>, Radius=30, Data=b'\x00\x19\x02\x00\xF0\x21\x0C\x03')
2022-03-08 23:56:44 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-03-08 23:56:44 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=25)
2022-03-08 23:56:44 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=8, SrcAddr=0x3891, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=87, SecurityUse=<Bool.false: 0>, TimeStamp=6899442, TSN=0, Data=b'\x18\x19\x04\x00', MacSrcAddr=0x3891, MsgResultRadius=29)
2022-03-08 23:56:44 DEBUG (MainThread) [zigpy.zcl] [0x3891:1:0x0008] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=25 command_id=Command.Write_Attributes_rsp>
2022-03-08 23:56:44 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x3891:1:0x0008]: executed 'move_to_level_with_on_off' command with args: '(199, 1)' kwargs: '{}' result: [4, <Status.SUCCESS: 0>]
2022-03-08 23:56:44 DEBUG (MainThread) [homeassistant.components.zha.entity] light.kitchen_backsplash_2_level_on_off: turned on: {'move_to_level_with_on_off': [4, <Status.SUCCESS: 0>]}
2022-03-08 23:56:44 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=light.kitchen_backsplash_2_level_on_off, old_state=<state light.kitchen_backsplash_2_level_on_off=on; supported_color_modes=['brightness'], color_mode=brightness, brightness=110, off_brightness=None, friendly_name=Kitchen Backsplash 2 level, on_off, supported_features=33 @ 2022-03-08T23:55:22.696105+00:00>, new_state=<state light.kitchen_backsplash_2_level_on_off=on; supported_color_modes=['brightness'], color_mode=brightness, brightness=199, off_brightness=None, friendly_name=Kitchen Backsplash 2 level, on_off, supported_features=33 @ 2022-03-08T23:55:22.696105+00:00>>
```

I will try the "Manage clusters" read and update attribute next.
First thing that's interesting there is that there's two `current_level` attributes with different ids:
<img width="581" alt="Screen Shot 2022-03-08 at 4 00 40 PM" src="https://user-images.githubusercontent.com/18717376/157346308-6a4866f6-9421-45d1-aa67-5b32df45b150.png">
Does this look wrong?

No, that is what I has expected.

`0xF000` is the `manufacturer_attribute` that we have defined you can change the `current_level` to whatever you want. Also is the attribute that this device is using to report the dim values.
`0x0000` is the zigbee standar `current_level` attribute for dimmers.

The problem is that HA will 'talk' with the 0x0000 attribute, but it seems that device is listening to the 0xF000.
It would be probably more appropriate to rename it to `manufacturer_current_level` 🤷🏻‍♂️ 
hmm so I tried all combinations in the "Manage Cluster" interface. But all I got working from there was the on and off commands from the on off cluster.
<img width="564" alt="Screen Shot 2022-03-08 at 4 13 44 PM" src="https://user-images.githubusercontent.com/18717376/157347785-95d64b36-d2da-4de0-9eb6-1c17f7123614.png">
No attributes or commands of the `F000LevelControlCluster` were working yet. They all didn't change the brightness.
What's also interesting is that if I move the slider in the UI and click 'Get Zigbee Attribute', then I get the updated value. If I change the brightness on the physical dimmer, then the click on 'Get Zigbee Attribute' doesn't give me a new value...

If I click 'Issue Zigbee Command' for `move_to_level_with_on_off`, I get this error:
```
  File "/usr/local/lib/python3.9/site-packages/zhaquirks/tuya/ts110e.py", line 81, in command
    brightness = (args[0] * 1000) // 255
IndexError: tuple index out of range
```

Resolving patch:
diff --git a/zhaquirks/tuya/ts110e.py b/zhaquirks/tuya/ts110e.py
new file mode 100644
--- /dev/null
+++ b/zhaquirks/tuya/ts110e.py
@@ -0,0 +1,178 @@
+"""Tuya Dimmer TS110E."""
+from typing import Optional, Union
+
+from zigpy.profiles import zha
+import zigpy.types as t
+from zigpy.zcl import foundation
+from zigpy.zcl.clusters.general import (
+    Basic,
+    GreenPowerProxy,
+    Groups,
+    LevelControl,
+    OnOff,
+    Ota,
+    Scenes,
+    Time,
+)
+
+from zhaquirks.const import (
+    DEVICE_TYPE,
+    ENDPOINTS,
+    INPUT_CLUSTERS,
+    MODELS_INFO,
+    OUTPUT_CLUSTERS,
+    PROFILE_ID,
+)
+from zhaquirks.tuya import (
+    NoManufacturerCluster,
+    TuyaDimmerSwitch,
+    TuyaZBExternalSwitchTypeCluster,
+)
+
+TUYA_LEVEL_ATTRIBUTE = 0xF000
+TUYA_BULB_TYPE_ATTRIBUTE = 0xFC02
+TUYA_MIN_LEVEL_ATTRIBUTE = 0xFC03
+TUYA_MAX_LEVEL_ATTRIBUTE = 0xFC04
+TUYA_CUSTOM_LEVEL_COMMAND = 0x00F0
+
+
+class TuyaLevelPayload(t.Struct):
+    """Tuya Level payload."""
+
+    level: t.uint16_t
+    transtime: t.uint16_t
+
+
+class TuyaBulbType(t.enum8):
+    """Tuya bulb type."""
+
+    LED = 0x00
+    INCANDESCENT = 0x01
+    HALOGEN = 0x02
+
+
+class F000LevelControlCluster(NoManufacturerCluster, LevelControl):
+    """LevelControlCluster that reports to attrid 0xF000."""
+
+    server_commands = LevelControl.server_commands.copy()
+    server_commands[TUYA_CUSTOM_LEVEL_COMMAND] = foundation.ZCLCommandDef(
+        "moveToLevelTuya",
+        (TuyaLevelPayload,),
+        is_manufacturer_specific=False,
+    )
+
+    attributes = LevelControl.attributes.copy()
+    attributes.update(
+        {
+            # 0xF000
+            TUYA_LEVEL_ATTRIBUTE: ("manufacturer_current_level", t.uint16_t),
+            # 0xFC02
+            TUYA_BULB_TYPE_ATTRIBUTE: ("bulb_type", TuyaBulbType),
+            # 0xFC03
+            TUYA_MIN_LEVEL_ATTRIBUTE: ("manufacturer_min_level", t.uint16_t),
+            # 0xFC04
+            TUYA_MAX_LEVEL_ATTRIBUTE: ("manufacturer_max_level", t.uint16_t),
+        }
+    )
+
+    # 0xF000 reported values are 10-1000, convert to 0-254
+    def _update_attribute(self, attrid, value):
+        if attrid == TUYA_LEVEL_ATTRIBUTE:
+            self.debug(
+                "Getting brightness %s",
+                value,
+            )
+            value = (value + 4 - 10) * 254 // (1000 - 10)
+            attrid = 0x0000
+
+        super()._update_attribute(attrid, value)
+
+    async def command(
+        self,
+        command_id: Union[foundation.Command, int, t.uint8_t],
+        *args,
+        manufacturer: Optional[Union[int, t.uint16_t]] = None,
+        expect_reply: bool = True,
+        tsn: Optional[Union[int, t.uint8_t]] = None,
+    ):
+        """Override the default Cluster command."""
+        self.debug(
+            "Sending Cluster Command. Cluster Command is %x, Arguments are %s",
+            command_id,
+            args,
+        )
+        # move_to_level, move, move_to_level_with_on_off
+        if command_id in (0x0000, 0x0001, 0x0004):
+            # convert dim values to 10-1000
+            brightness = args[0] * (1000 - 10) // 254 + 10
+            self.debug(
+                "Setting brightness to %s",
+                brightness,
+            )
+            return await super().command(
+                TUYA_CUSTOM_LEVEL_COMMAND,
+                TuyaLevelPayload(level=brightness, transtime=0),
+                manufacturer=manufacturer,
+                expect_reply=expect_reply,
+                tsn=tsn,
+            )
+
+        return super().command(command_id, *args, manufacturer, expect_reply, tsn)
+
+
+class DimmerSwitchWithNeutral1Gang(TuyaDimmerSwitch):
+    """Tuya Dimmer Switch Module With Neutral 1 Gang."""
+
+    signature = {
+        MODELS_INFO: [("_TZ3210_ngqk6jia", "TS110E")],
+        ENDPOINTS: {
+            # <SimpleDescriptor endpoint=1 profile=260 device_type=257
+            # input_clusters=[0, 4, 5, 6, 8, 57345]
+            # output_clusters=[10, 25]>
+            1: {
+                PROFILE_ID: zha.PROFILE_ID,
+                DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT,
+                INPUT_CLUSTERS: [
+                    Basic.cluster_id,
+                    Groups.cluster_id,
+                    Scenes.cluster_id,
+                    OnOff.cluster_id,
+                    LevelControl.cluster_id,
+                    TuyaZBExternalSwitchTypeCluster.cluster_id,
+                ],
+                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
+            },
+            242: {
+                # <SimpleDescriptor endpoint=242 profile=41440 device_type=97
+                # input_clusters=[]
+                # output_clusters=[33]
+                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.DIMMABLE_LIGHT,
+                INPUT_CLUSTERS: [
+                    Basic.cluster_id,
+                    Groups.cluster_id,
+                    Scenes.cluster_id,
+                    OnOff.cluster_id,
+                    F000LevelControlCluster,
+                    TuyaZBExternalSwitchTypeCluster,
+                ],
+                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
+            },
+            242: {
+                PROFILE_ID: 41440,
+                DEVICE_TYPE: 97,
+                INPUT_CLUSTERS: [],
+                OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
+            },
+        },
+    }


Test patch: