[Release] Tuya/Lonsonho 1-gang and 2-gang zigbee dimmer module driver

Hi all, this is my first attempt at writing a driver for Hubitat. Hope it is of use to others out there.

It supports Tuya (also branded as Lonsonho) 1-gang and 2-gang (1 and 2 channel) Zigbee dimmer modules which are sold white-label under many other brand names, or none at all (I got mine via eBay!). Specifically this driver currently supports these devices:

Model What Identifies via Zigbee as
QS-Zigbee-D02-TRIAC-LN 1 channel (1-gang) dimmer module TS110F
_TYZB01_qezuin6k
QS-Zigbee-D02-TRIAC-2C-LN 2 channel (2-gang) dimmer module TS110F
_TYZB01_v8gtiaed

I suggest the best way to install is using the Hubitat package manager.

Alternatively, install in the traditional way via the Hubitat Elevation web based interface:

  1. Click "Drivers Code" then click "New Driver" then "Import"

  2. Enter this Import URL then click "Import"
    https://raw.githubusercontent.com/matt-hammond-001/hubitat-code/master/drivers/tuya-zigbee-dimmer-module.groovy

  3. Click "Save"

See the README for more details/documentation on how to use the driver

This driver and any others I write in future are available here on GitHub under the BSD 3-clause open source licence. Any suggestions/feedback from more seasoned driver authors will be gratefully received.

4 Likes

Which ones did you buy? I'm in the market for just such a device and there are many listed! :slight_smile:

1 Like

This is the eBay listing that I purchased from:

1 Like

these are the ones I bought myself
hope that they work with these drivers or that it won't be too difficult to to modify the drivers in case my ones are a bit different

Looks like it might be the same one. Let me know if it works!

Will definitely post an update when they do. It might take another month before they get here.

from doing a good bit of research the only alternative I found for UK/Ireland 2-gang are the Aurora AU-A1ZB2WDM2P
They have the advantage that you can still control the dimming at the wall, but they're very expensive and they don't have a neutral wire so they will potentially have issues with lights not fully turning off.

Tuya, Xiaomi Sonoff and other Chinese companies are really impressive at coming out with cheap smart products, some with features that are hard to find at a reasonable price in US or EU products.

Out of curiosity because I'm looking to start writing device drivers, how did you write these drivers? Did you reverse engineer them from scratch and if yes what tools did you use? Or did you find the information in a driver for another platform and just ported it to HE?

Writing drivers - these dimmers use standard ZigBee protocols for dimmers. So actually the biggest challenge was learning how to write a driver for hubitat. In fact I'll be honest and say the learning curve was a bit of a struggle. I looked at other drivers written by people and shared here as well as the examples that hubitat share publicly.

Hubitat's developer documentation frankly leaves a lot to be desired in my opinion. It's largely incomplete and contains virtually no explanations that I could find. I ended up relying on Samsung smartthings developer documentation primarily.

Finally, I also ended up looking at the ZigBee cluster library spec.

Then an awful lot of trial and error.

I don't know if there is a better way, or some better references out there. Would love if anyone can point me anything useful.

I've not come across that Aurora dimmer - looks good. But it's expensive! Especially compared to the Tuya option!!

Thanks very much for the reply. I was afraid your answer was going to be along those lines.

I'll personally wait until my Xbee and CC2531 sniffer arrive and hopefully that will make it somewhat easier for me. Thanks for some of the pointers to some of the things that are useful to read

Ah interesting. Will be good to hear how you get on with it. I've not got any sniffer kit and only have a rudimentary understanding of the protocols thus far.

@fc352bf0a6929e9fa80f
Hey I just received the QS-Zigbee-D02-TRIAC-2C-LN today, and wired it up in a test harness on my desk.
It has the right model listed _TYZB01_v8gtiaed but when I installed it, it didn't create a child device for the second switch.

The way I installed it was to add the driver to my list of drivers, plugged in the module and the light started flashing (the physical switch was turned off), when I saw the light flashing I started the pairing mode and the device was added to the network.

I wouldn't think this would make a difference, but I only have 1 light connected to the module instead of 2. I wouldn't have expected the device + driver to be that smart that it would detect that I didn't connect a second light and not create the child devices.

Any help would be appreciate. Not sure what logs you might find useful. I didn't have the log opened up when I paired it anyway

edit:

actually I had more of a play around after enabling debug logging and found this issue:

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:34:21.786 [debug](http://192.168.1.5/device/edit/79)onSwitchLevel: Value=183 level=72

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:34:21.771 [debug](http://192.168.1.5/device/edit/79)onSwitchLevel: value=183

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:34:21.766 [debug](http://192.168.1.5/device/edit/79)Received parsed: [raw:9BAE01000808000020B7, dni:9BAE, endpoint:01, cluster:0008, size:08, attrId:0000, encoding:20, command:0A, value:B7, clusterInt:8, attrInt:0]

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:34:21.761 [info](http://192.168.1.5/device/edit/79)Received raw: read attr - raw: 9BAE01000808000020B7, dni: 9BAE, endpoint: 01, cluster: 0008, size: 08, attrId: 0000, encoding: 20, command: 0A, value: B7

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:34:15.731 [debug](http://192.168.1.5/device/edit/79)true Living Room Lights Living Room Lights 1

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:34:15.726 [debug](http://192.168.1.5/device/edit/79)Received parsed: [raw:9BAE0100060800001001, dni:9BAE, endpoint:01, cluster:0006, size:08, attrId:0000, encoding:10, command:0A, value:01, clusterInt:6, attrInt:0]

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:34:15.722 [info](http://192.168.1.5/device/edit/79)Received raw: read attr - raw: 9BAE0100060800001001, dni: 9BAE, endpoint: 01, cluster: 0006, size: 08, attrId: 0000, encoding: 10, command: 0A, value: 01

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:33:48.367 [debug](http://192.168.1.5/device/edit/79)true Living Room Lights Living Room Lights 0

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:33:48.362 [debug](http://192.168.1.5/device/edit/79)Received parsed: [raw:9BAE0100060800001000, dni:9BAE, endpoint:01, cluster:0006, size:08, attrId:0000, encoding:10, command:0A, value:00, clusterInt:6, attrInt:0]

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:33:48.358 [info](http://192.168.1.5/device/edit/79)Received raw: read attr - raw: 9BAE0100060800001000, dni: 9BAE, endpoint: 01, cluster: 0006, size: 08, attrId: 0000, encoding: 10, command: 0A, value: 00

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:33:43.660 [debug](http://192.168.1.5/device/edit/79)true Living Room Lights Living Room Lights 1

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:33:43.655 [debug](http://192.168.1.5/device/edit/79)Received parsed: [raw:9BAE0100060800001001, dni:9BAE, endpoint:01, cluster:0006, size:08, attrId:0000, encoding:10, command:0A, value:01, clusterInt:6, attrInt:0]

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:33:43.651 [info](http://192.168.1.5/device/edit/79)Received raw: read attr - raw: 9BAE0100060800001001, dni: 9BAE, endpoint: 01, cluster: 0006, size: 08, attrId: 0000, encoding: 10, command: 0A, value: 01

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:33:26.892 [debug](http://192.168.1.5/device/edit/79)true Living Room Lights Living Room Lights 0

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:33:26.884 [debug](http://192.168.1.5/device/edit/79)Received parsed: [raw:9BAE0100060800001000, dni:9BAE, endpoint:01, cluster:0006, size:08, attrId:0000, encoding:10, command:0A, value:00, clusterInt:6, attrInt:0]

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:33:26.880 [info](http://192.168.1.5/device/edit/79)Received raw: read attr - raw: 9BAE0100060800001000, dni: 9BAE, endpoint: 01, cluster: 0006, size: 08, attrId: 0000, encoding: 10, command: 0A, value: 00

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:33:11.752 [error](http://192.168.1.5/device/edit/79)com.hubitat.app.exception.UnknownDeviceTypeException: Device type 'Tuya Zigbee dimmer module V2' in namespace 'matthammonddotorg' not found on line 205 (updated)

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:33:11.711 [info](http://192.168.1.5/device/edit/79)Creating child 0 with dni 9BAE-01

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:33:11.700 [debug](http://192.168.1.5/device/edit/79){application=41, manufacturer=_TYZB01_v8gtiaed, model=TS110F}

[dev:79](http://192.168.1.5/logs#dev79)2021-01-23 00:33:11.666 [info](http://192.168.1.5/device/edit/79)updated parent->child

Hmm. Probably a mistake on my part in the driver initialisation code. Try going into the device and clicking "configure" ... That ought to definitely cause try child device to be created.

I agree it ought to not make a difference whether one or both are wired up or not!

Let me know if this works. I'll take a more detailed look at the logs later and let you know if I spot anything else.

Aah. Think I just spotted the bug - thanks to the logs you provided! Try re-importing the driver source code then either going to the device and clicking "configure" or deleting the device and re-pairing with the dimmer.

1 Like

Brilliant, that did it.
I just needed to hit configure and the child devices were created. Thanks very much for the fix.

I looked at the git history and saw that it was indeed a tiny typo :slight_smile:

Good to hear that it works for you!

I've now made this driver available via the hubitat package manager

2 Likes

that's great :slight_smile:
I was actually thinking of doing an pull request to add it to the hubitat package manager for you :slight_smile:

Hey,

I've noticed a potential improvement that could be made to these drivers.

I'm using device watchdog to monitor if any devices drop off the network either because the battery dies, the device is unplugged it for some other reason it falls off the network.

Device watchdog uses the "last activity at" field to decide if the device is working ok or if it's dropped off.

I'm wondering do these devices send updates back to the hub on a regular basis?
If yes would it be possible for the driver to update that timestamp?
At the moment the only time that timestamp gets updated is if the state of the device actually changes.

If I understood correctly you can send a state update from the driver to Hub even if the state hasn't changed and in that case the hub platform will filter out the state so that no automations get retriggered, but the last activity at date will be updated accordingly

Interesting question. Do you definitely mean lastActivityAt, or do you mean lastUpdateTime?

I'm honestly not sure if they do send a regular update. Can I suggest turning on debug mode and checking the logs for a period of time to see if any zigbee messages are logged by the driver? I'm doing the same.

I've noticed that there is a catchall message that my driver seems to receive, but I'm not sure when that occurs or how to interpret it. I think it only happens when there is a state change though. Example:

Received parsed: [raw:catchall: 0104 0008 01 01 0040 00 0812 00 00 0000 0B 01 0400, profileId:0104, clusterId:0008, clusterInt:8, sourceEndpoint:01, destinationEndpoint:01, options:0040, messageType:00, dni:0812, isClusterSpecific:false, isManufacturerSpecific:false, manufacturerId:0000, command:0B, direction:01, data:[04, 00]]

If it did occur regularly without state changes, then I guess it could be treated as an event worthy of updating the timestamp?

Sorry I didn't see your reply there.
Yeah good idea I'll turn on device logging and monitor it.

Yes I'm sure it's the "last activity at"
That's the field that various community apps like device watchdog use so that you can figure out if a battery device has died or if a powered device was "unplugged"

Last update time seems to be related to wherever device preferences are saved or something like that. Not too sure about this one.

If there isn't a regular update sent from the device, from looking at various drivers it might be possible at initial configuration to configure the device to automatically send the value of a specific cluster at a regular intervals. Similar to how temperature devices can be configured to report their temperature for changes of 0.1 degrees or higher changes it's also possible to set a minimum and maximum time reporting interval