smoores.dev

Building stuff on the Internet.

The Perfect Lighting

Sep. 22, 2025

Four years ago, I bought a house in my hometown. The house is around a hundred years old, but it had been recently renovated. Actually, to be more specific, it had been flipped — we were purchasing the house from the flippers.

Mostly, the renovations ranged from acceptable to decent. There weren’t many glaring issues, but the house had the overall feeling of having been designed by someone who had never lived in it. There were many factors contributing to this theme, such as a bathtub whose overflow drain was filled with dry caulk because it wasn’t connected to the actual drain pipe, or brand new undersized furnaces that weren’t powerful enough to maintain the temperature in the still-quite-drafty house.

But the strongest evidence that no one had actually lived in this iteration of the house were its lights. The flippers had replaced every single light fixture in the house with brand-new LED bulbs. And every last one was the brightest, coldest white light you have ever seen. The lights were so bright and harsh that turning them on would engender winces from guests, even during the day. Eventually, one such guest asked us, “Don’t these mess up your sleep cycle? It’s like the middle of the day in here, even late at night.”

As it turned out, my wife and I had been having quite a bit of trouble sleeping since we’d moved in. We hadn’t thought to attribute it to the lights, but once it was pointed out, it seemed obvious. The lights were too bright, and they were too blue. They were destroying our circadian rhythms. But we didn’t just want to get dimmer, warmer lights — we still wanted bright lights during the day. We needed adjustable lights. And if we wanted the lights to change color on their own, then maybe we even needed smart lights?

I already had a Hubitat Elevation set up as a smart home hub. Connected to it were my two Zen smart thermostats and an army of temperature sensors scattered throughout the house, plus a smart button for turning on the LED strip in the backyard. I wasn’t exactly looking forward to the idea of replacing every light bulb in my house, but maybe, I thought, I could just get some smart dimmer switches? Those could be dimmed by automation, and I would only have to replace a handful of switches (actually 13, but I certainly wasn’t counting), rather than every single light bulb.

So I started my journey by purchasing some Enbrighten Zigbee smart dimmer switches. These were pretty nice (and easy to install!), but I immediately ran into an issue: our LEDs weren’t dimmable. Not all LED light drivers are capable of the high frequency flickering that enables some LEDs to appear dimmer, and mine were not. When “dimmed”, they just did a horrible flashing strobe. It was not an improvement.

Back to the drawing board — and faced again with the prospect of needing to replace every light in the house — I started looking into smart bulbs. I knew I could have found simple dimmable LED lights, but they still wouldn’t have allowed us to change the temperature of the light over the course of the day. The thought that I might decide later that I really did want temperature changing lights — and needing to replace every bulb again — made me shudder.

So I bought some Philips Hue bulbs. A lot of them, actually. Almost 20, and that was just for the first floor. After a weekend spent installing them, I finally started programming some automation in Hubitat’s automation designer, and… well, it wasn’t exactly a breeze.

There were several challenges. Firstly, the Enbrighten switches were “smart,” meaning that they could send messages to the Hubitat when the paddle was pressed or held, and the Hubitat could send them messages to, e.g., turn them on. But they were also real electromechanical switches — when they were turned off, they actually disconnected power from the lights.

Anyone who’s ever worked with smart bulbs before knows where this is going. When smart bulbs are powered on, they have to re-establish a connection to the hub, in order to figure out what state they’re meant to be in. In the meantime, depending on the make and model, they will either be in a default (usually bright white) state, or the state they were in before they were disconnected from power. That means that when you first turn a light on in the evening, it’s likely to turn on to bright white, sometimes for a few seconds, before figuring out that it should actually be dim and warm.

This was very frustrating. The experience was actually better overall, but it felt worse, because your expectations were constantly being violated.

I went deeper. I bought a half dozen of Philips “dimmer switches”, which are really just four-button controllers. I command-stripped them onto the walls next to each actual light switch, and hooked them up to my automation.

This was much better. The Philips dimmers told the lights to “turn off” via Zigbee, but never disconnected power. The lights stopped producing light, but they were able to communicate with the hub the whole time. When they were told to “turn on” again, they already knew what settings to use, because the hub had already updated the scene that they were set to.

There were glitches, though. It turns out to be really quite challenging to build automation like this on top of Philips Hue, and I definitely did not (and still don’t, really) understand the mechanics of the system well enough to build something more robust.

Also, I was very unsatisfied with the dimmer switch situation. My wife and I both knew not to touch the actual paddles, but guests did not, and so lights were still constantly being disconnected from power.

It was at this point that I decided on my bar for success. This system had to be as robust as basic electromechanical switches. Any guest had to be able to use it with the same familiarity and ease as the switches they’d used all their lives. I didn’t want our house to be temperamental — the entire reason for this endeavor was to automate work that I did not want to do manually!

It was at this point, too, that I started looking into Home Assistant. Some beautiful soul had built Adaptive Lighting, a Home Assistant component that automatically synced your lights with the rising and setting of the sun. It was very compelling — it seemed someone had already done all of the hard work for me.

So I bought some 3D-printed magnetic light switch covers that allowed me to stick my Philips dimmers on top of my “real” light switches. And then I set up Home Assistant, used the Hubitat integration to pull in all of my switches, and the Philips Hub integration to pull in all of my lights, and configured Adaptive Lighting.

This was very, very close to meeting my success bar. For a time, I even thought that I’d done it. But there were still two rough edges, and eventually they started to wear on us.

First, the magnets holding the dimmer switches onto the lights were not strong enough. As I mentioned earlier, not all of the renovations in our home were exactly top-notch, and some of the light switch cover panels were seated imperfectly and warped slightly. The less flat and square the panel, the more likely it was that a Philips dimmer would be accidentally knocked clean off the wall by a searching hand. This was especially bad in our bedroom and bathroom, where we were often feeling our way for the light in the dark, and an errant poke could set the whole apparatus scattering.

Second, because the automation ran through Home Assistant, rather than directly through the Philips Hub, there was a very noticeable delay between pressing a button and seeing the adjustment in the lights. This made the actual dimming function pretty unpleasant to use.

This first frustration led to a different approach when I expanded the scope of the lighting automation to include the second floor hallway and other bedrooms. Instead of Philips dimmers, I purchased some Lutron Aurora rotary switches. Like the Philips dimmers, these were purely Zigbee switches. Unlike the Philips dimmers, they were actually designed to cover your physical switches, and affixed to them properly.

Unfortunately, the Auroras were primarily designed to affix to “toggle”-style switches, not the paddles that our house had. On the toggle switches, they simply clamped the toggle in the on position, and then the rotary button sat on top. For our paddles, we would need to actually remove the electromechanical switch entirely, hardwire the load and line together (essentially fixing the circuit “on”, permanently), and then install an immovable dummy switch in place of the old paddle.

This was a bit more work, but it was still much easier than installing the Enbrighten switches. At first, the work seemed worth it — the switches were certainly not going to be knocked off the wall! But the old problem was ultimately replaced by a few new ones. For one thing, the message delivery delay meant that turning the dial to dim the lights could have very erratic results, as messages raced each other to the hub and could be processed out of order. For another, the switch had its own internal brightness level, and it always emitted that level. That level couldn’t be adjusted by the driver. This meant that when the brightness of the lights was adjusted by the Adaptive Lighting automation, the switch’s level didn’t change. When you turned the dial down to dim the lights, they would sometimes brighten, because the new internal dimmed level was higher than the level that Adaptive Lighting had adjusted them to.

I worked on this problem on and off for a long, long time. I used a community driver for the Auroras that attempted to maintain an externally adjustable level in driver state. I learned Groovy (woof) and built my own driver. Then I went back to the community driver. Then I built another driver myself.

Then, one day, I found Hue Scheduler. Hue Scheduler, my friends, is the way. It is the light. It has eased my pains and sorrows.

Hue Scheduler is a standalone service that manages a scene in the Philips Hue Hub. All of my switches and lights are now connected directly to the Hue Hub. The switches are programmed to toggle the lights on and off to the managed HueScheduler scene. As the day goes on, Hue Scheduler updates the scene with the correct temperature and brightness, so that lights are always turned on to the correct settings instantly.

Because everything is connected to the Hue Hub, the lights are much more responsive, and dimming feels much better. I believe Philips employs some tricks in order to accomplish this — having switches communicate directly with their assigned lights, rather than sending all messages through the hub. It’s a little unfortunate that this doesn’t work with third party smart hubs, but it’s also nice that it’s possible at all.

I replaced the rest of the switches in the house with the Auroras, and got rid of all of the Philips dimmers. The two switches at the front and back doors of the house are programmed to turn off all of the lights in the house when their buttons are held.

It’s perfect.

By the way, in case anyone is interested, here’s my very simple Hue Scheduler configuration. Also, if you’re trying this at home, make sure to enable --enable-scene-sync (or the environment variable, ENABLE_SCENE_SYNC=true) on Hue Scheduler!

# In the evening, starting an hour before civil dusk,
# dim to 70% and turn up the warmth
Home civil_dusk ct:2000 bri:70% tr-before:60min

# During the day, starting an hour after civil dawn,
# turn the brightness up and the warmth down
Home civil_dawn+60 ct:6500 bri:100% tr-before:60min

# Late at night, starting around 11pm, turn the
# brightness way down. Basically a night light mode.
Home 23:30 ct:2000 bri:10% tr-before:30min