Hey everyone - Today was a great day in a way that nearly no one in my real life (certainly not my wife) can appreciate. Today months (really??) of tinkering came together to yeild a little nicety I’ve wanted for a long time.
TL;DR: I now have a Zigbee rotary knob (Tuya TS004F) that smoothly and reliably controls a group of bathroom lights, all dimming in sync, even though the underlying bulbs/drivers behave very differently. The path to get there ended up producing a few reusable things that others might find useful.
(Detailed project writeup if you’re interested.)
What I was trying to solve
My bathroom has multiple lights from different vendors. Out of the box:
- They all have different minimum brightness levels
- They ramp up/down at different perceived speeds
- Some flicker at low values, others don’t
The end result: if you put them in a standard light group and dim them together, it never feels right. Some are too bright, some too dim, and the low end is especially ugly.
What I really wanted was:
- One physical rotary knob on the wall
- All lights in the room dimming together and smoothly
- A setup I could reuse in other rooms later
What came out of the project
To get that experience, I ended up creating three pieces:
-
A custom integration to normalize dimming behavior
This integration introduces “normalized” light proxies in front of real lights. Each proxy:- Maps 0–255 to a custom curve between a Low Light Value (LLV) and High Light Dimming (HLD) for that specific light
- Lets me tune the low/high ends per bulb so that perceived brightness is aligned across fixtures
- Keeps the underlying lights in sync when adjusting brightness on the proxy
The end result: when the proxy is at, say, 40%, all physical lights look like they’re at roughly the same brightness, even though they’re using different raw levels behind the scenes.
-
A HACS-published custom integration for log level management (
logger_manager)
While building and tuning the proxies, I needed to crank logging up and down frequently to watch:- Zigbee events
- Light state changes
- Service calls going through Home Assistant
The
logger_managerintegration lets you manage logger levels from the UI instead of editing YAML or restarting just to tweak logging.
-
A blueprint that maps Tuya TS004F knob events to a light entity
The TS004F is a quirky little device, so I built a blueprint that:- Handles rotate left/right for dimming
- Handles short/long presses for actions like on/off or “jump to preset”
- Debounces events so it feels smooth with a dimmable light or light group
You can point the blueprint at any light or light group, which in my case is the normalized bathroom group.
Blueprint: ha-resources/ha-assets/blueprints/tuya-ts004f at main · gunnjr/ha-resources · GitHub
How it all works together
The flow now looks like this:
- Each physical bathroom light is wrapped in a normalized proxy (via the custom integration)
- Those normalized proxies are combined into a Home Assistant light group
- The TS004F blueprint targets that light group
- Rotating the knob sends dimming events → the group adjusts → the integration maps that to per-light normalized levels
From my perspective as a user:
- I walk into the bathroom
- Turn the knob
- All lights rise and fall together in a way that finally feels natural and consistent
No more mismatched brightness levels, no more “one light is blinding while another is barely on.”
Why I’m sharing this
I’m not trying to present this as the “right” way to do it — I’m just a guy who went down a rabbit hole and ended up with:
- A normalized dimming layer for mixed hardware
- A logging helper to make debugging less painful
- A reusable knob blueprint that ties everything together
If you:
- Have mixed dimmers/lights that don’t play nicely together, or
- Use the Tuya TS004F and want it to behave more like a traditional dimmer
…then pieces of this might be helpful.
Feedback, ideas, and next steps
I’d love any feedback on:
- Better ways to model the dimming curve (right now it’s LLV/HLD-based)
- Improvements to the TS004F blueprint behavior
- Ideas for extending this to room-level controllers or more complex scenes
If there’s interest, I can also add more detailed docs, config examples, or diagrams of how the entities are wired together.
Thanks for reading — and huge shoutout to the HA community in general; this project only exists because of all the examples, quirks, and discussions people have shared over the years.