Skip to content

Rotary Encoder Support#415

Open
Haydend wants to merge 3 commits into
romasku:mainfrom
Haydend:dunnicliffeh/encoder
Open

Rotary Encoder Support#415
Haydend wants to merge 3 commits into
romasku:mainfrom
Haydend:dunnicliffeh/encoder

Conversation

@Haydend

@Haydend Haydend commented May 2, 2026

Copy link
Copy Markdown
Contributor

Hi,

I've been working on adding support for Rotary Encoders to your firmware. Is this something you'd be interested in merging?
This work is still rough and in progress, just wanted to get it out there early for feedback.
Currently it supports detecting and sending the commands to bound devices. But there is no config or multistate.

Demo

Rotary.Encoder.Demo.720.mp4

Motivation

My dream 'light switch replacement' for my smart home is a device which looks like a normal dimmer switch, is mains powered, and does on/off, brightness and color temp, via bindings. For use with smart bulbs which are always powered. I haven't found such a device, so I decided to look into creating my own. Currently I'm using 3 of the inputs from a TS0004 (https://www.zigbee2mqtt.io/devices/TS0004_switch_module.html) with a basic dev kit rotary encoder (https://www.ebay.co.uk/itm/365206572477).
There are some battery devices which I believe this change would add support for, like https://www.zigbee2mqtt.io/devices/ERS-10TZBVK-AA.html I have some, but I have not tested this on them yet.

Unit Tests

I've dropped these for now to reduce the size of this merge
The branch also includes support for unit tests, using Unity and CMock. This was something I really wanted, as my unfamiliarity with this type of programming meant I was often unsure about behaviour and needed to test it. It can of course be dropped from this merge, but I think it has value.

Disclaimer ;)

I'm a professional Java and Node engineer. But C, Make and programming for embedded systems are completely new to me and very different! (though also very interesting). I have probably brought some of my high-level language habits with me. So please advise on any code smells, etc. Feedback very welcome!

@Haydend Haydend force-pushed the dunnicliffeh/encoder branch from 986df4b to 6569123 Compare May 2, 2026 14:22
Comment thread src/device_config/config_parser.c
@Ctrl-F4

Ctrl-F4 commented May 8, 2026

Copy link
Copy Markdown

Very interesting! I think a valuable addition to this fw!

The ERS-10TZBVK-AA you mention default FW has an annoying issue (trigger accidentally toggle between COMMAND and EVENT mode) If your fw addition could solve this then that would be great.
It seems to have a EFR32MG21 chip inside (bootloader available in this repository)

@Haydend

Haydend commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

Posting to let anyone following know that I'm still working on this and haven't abandoned it. I think it's very close now, I've completed the firmware, tests and converter. Tonight I've managed to build and flash a ERS-10TZBVK-AA device and initial testing looks good. So its now had basic testing on Telink and Silab chips

Over the next few week I plan to clean this branch up, to present clean MR for review.

@Ctrl-F4

Ctrl-F4 commented Jul 4, 2026

Copy link
Copy Markdown

WOW! Thank you very much, i hope Romasku is doing well and can find time to merge this in his fw.
Flashed my ERS-10TZBVK-AA device with your fw bin.
Tested seems to work fine, also direct binding tested: great.

My observations:

turn clockwise => brightness_down  (binded light changes brightness lower)
turn anti clockwise => brightness_up:  (binded light changes brightness higher)

This feels somehow odd i think this behavior should be reversed?

push+clockwise => color_temp_down (binded light changes color_temp higher)
push+anti clockwise => color_temp_down (binded light changes color_temp higher)

I like this behavior (please don't change this behavior) although i think it is meant to work reversed?

Would be ideal if this behavior can be configurable.

edit:
How about current draw? config qja6nq5z;TS004F;LD0i;EB0uA0uA4u; is missing the BT<pin> option? Is your fw bin already suitable for battery use at this moment? Z2M presents it as EndDevice Mains (single phase).

@Haydend Haydend force-pushed the dunnicliffeh/encoder branch from d1265db to 2063c70 Compare July 4, 2026 13:52
Start with support for 1 device: Tuya Smart Knob (https://www.zigbee2mqtt.io/devices/ERS-10TZBVK-AA.html)
@Haydend Haydend force-pushed the dunnicliffeh/encoder branch from 203f3b8 to 7800000 Compare July 4, 2026 14:15
@Haydend

Haydend commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the testing! Your right, I had the A and B pins for the encoder switched in the config string. Have fixed it now.

Currently, clockwise is mapped to level/temp up and anti to down. I agree with you about the colour temp, the up command making the the colour colder feels wrong to me, but I believe its increasing the 'Mireds' which is inverse to Colour Temperature (High Mireds = Low Colour Temp = Cold Light)
I agree, making this behaviour configurable would be best.

I need to look into the Battery config. Hopefully, adding BTXX to the config should be all that is needed.

@Haydend Haydend marked this pull request as ready for review July 4, 2026 15:25
@Haydend

Haydend commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

I have marked this as ready for review as I would be comfortable with it being merged in it's current state.
I plan to add configurability next, if this is still open I will add to this PR else I'll open a new one.

@Ctrl-F4

Ctrl-F4 commented Jul 4, 2026

Copy link
Copy Markdown

Flashed the new fw bin and setting brightness works absolutely fine now.

Have you also tried binding it to a group? I just did, genLevelCtrl, genOnOff and lightingColorCtrl can be bound to a group but the lights of this group don't follow/react.
Adding the ERS-10TZBVK-AA device to this group is giving this error (could be normal? i don't know all of zigbee):

group/members/add: Failed to add to group (ZCL command 0x6c5cb1fffe
f9d626/1 genGroups.add({"groupid":2,"groupname":""}, {"timeout":1000
0,"disableResponse":false,"disableRecovery":false,"disableDefaultRespons
e":true, "direction":0,"reservedBits":0,"writeUndiv":false}) failed (Status 'UN
SUPPORTED_CLUSTER'))

edit:
I know instead of bind it to a goup i can bind it to multiple lights but maybe there could be a (rare) situation those lights getting out of sync (one light on and another off) then the toggle_on_off command does not change this. Maybe a configurable action mode for button press like on_off/off_on/toggle_simple/toggle_smart_sync/toggle_smart_opposite would be nice.

@Haydend

Haydend commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

I haven't tried a group. But its looks like there is a known issue (and a fix!) with binding to group with a Silabs device. #437

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants