The lights in my home are now (mostly) controlled by 'smart' Bluetooth Low Energy (BLE) switches that replaced the traditional on/off switches in my walls, and most of my 'smart' lights. The most interesting part are the modules, which look like this:
The things I bought are:
- Clipsal CLP5010 2-wire micro dimmer modules
- Clipsal 40MBPRL momentary switches
- totally dumb off-the-shelf LED bulbs.
Just on their own, the dimmer modules and momentary switches change the UX of your fingers physically interacting with the switch. This means:
- to turn a light on or off, just hold the button for a moment
- to change brightness, hold the button down—each hold toggles between brighter or dimmer
- but if a switch is off, holding its button starts at minimum brightness (good for late at night)
The obvious change here is that the physical switch no longer "displays" whether it's on or off. This is fine, because turns out I can see whether the light is on. I also don't need physical dimmers anymore.
Notes on the hardware
The CLP5010's are interesting hardware that end up living in the wall cavity. I didn't buy them to match the physical switches on the wall, although they just happen to be the same brand. They'd work with any momentary switches. There's similar, other products out there, including a lot which are 3-wire: not every point in my house has a neutral wire (as we did renovations and the older part of the house doesn't have the 3rd, neutral wire available at the switches), so 2-wire makes sense.
(Hardware-wise, the 2-wire stuff works by "leaking" a tiny bit of power to run itself. Technically, my LEDs are being powered, but the current is so low that they don't turn on.)
FWIW, I bought the CLP5010's for about ~AU$45 each off eBay. Retail, they're about $150. In Australia, I can't legally do the wiring myself, so it also cost about that much each (probably) for an electrician's time.
Of course the interesting part is that these dimmer modules talk over BLE, which means that they can be controlled remotely or made part of a home automation system.
Clipsal provides an app, but it's... not very good. It does the obvious basics: you can pair your lights (you press the switch a number of times to enable pairing), configure things like each switch's name, and timers. But that's it—there's no hub^ or external hardware, so you can't integrate it with anything or control lights from outside your house.
^I've been told that there now might exist a ZigBee hub, and the lights can be converted to that mode. But this post is about BLE. 🤷
I've instead acquired a PyBoard, which has BLE 4.2+ (a requirement to talk to these lights), and written some Python code. To start with, I've had to pair every switch with this board—in MicroPython, I've mostly just attempted a new connection to every light, one-by-one, until they're all paired. I've also been lucky in that there's a point in my house where the board can easily talk to all the switches, so I didn't need extra or more antennas. 📶
To actually find out how the switches worked, I've paired some switches to my phone, and used an app called nRF Connect to more easily poke at the lights—it can read state and write values over BLE. The protocol of the lights is a bit weird (I would almost say 'bad'), and I don't want to cover it in this post. If you're interested, be sure to read my gist.
One thing I'll note is that the switches constantly announce their current state via public BLE advertising packets. So if you're within a few meters of my house… you can tell if the lights are on or off via your phone. But turns out you could probably see this by looking at my house from certain angles on the street, too. Either way, get away from my house. 🏡👀
It's all well and good to have a PyBoard that talks BLE, but that's not very user-friendly. We use Google Assistant at home, so I want to integrate the lights there to control with my phone, my voice, or other Google devices (like smart screens).
How does this work?
Well, I've set up a test 'integration', and told Google where to find it—literally a https:// address that's hosted on the Linux machine at my house.
This eventually ends up (via https-forward) at a nodeJS webserver (that yes, sometimes just runs in
That webserver needs to accept basically three commands, which are actually pretty simple:
- SYNC, to ask what devices are available here (e.g., I have devices X, Y, Z, and they support on/off/brightness)
- QUERY, to ask the state of the device (e.g., how bright is light X?)
- ACTION, to perform an action (e.g., set light X on at 10%)
There's also an backchannel where you can report a device's state (you just need to do a bit of an OAuth dance for the token so Google accepts your input). For test systems, Google doesn't need you to do this, but they say that to ship a real integration (e.g., if you are literally a lighting company) then you must proactively Google about the current state of any device you provide.
In my test environment, even though I do report the light's state (since they, as mentioned, announce via BLE packets), I actually find that Google sends me constant queries about the state. I wonder whether their policy is really enforced, even for real integrations: some 'smart' devices are never going to have a way to actively report their state (they're poll only). Anyway, calling you constantly seems like just a sane fallback for them and doesn't cost them much in terms of bandwidth!
One interesting point is that even though these lights are on my account, anyone in my Google 'household' can interact with them via voice. And we can see them on screens and devices around the place:
Assistant Design Thoughts
I've built my own Google Assistant integration. I hear good things about Home Assistant, but that's not what I'm looking for; my goals are simple enough that I want to build it myself (no automation, just basic on/off via Google).
What have I learned from this approach?
Don't write code that allows add/remove of devices, just store in code/fixed JSON
If you have a fixed number of lights or devices you're trying to automate, don't overengineer a system to add/remove further ones. Your home is probably going to be constant enough that you don't need it.
You can surface the same device many ways
One light could show up as two, if it has different properties. There's no rule that one physical device actually needs to map to one Assisant or equivalent device; just create as many as you need, perhaps using a combination of MAC + suffix.
Don't try to cache state: if Google or equivalent remote service asks you for device state, go and fetch it
I've had too many problems with trying to 'beat' the Google Assistant at its own game and try to speed up its responses via caching or smarts. When it asks you for the current state of a smart device like a light, just go and fetch it.
Before I finish up, I also have a bit of a history lesson.
I used to have a lot of LiFX bulbs; they were the first real smart light, which was awesome at the time. We used our phones to turn them off and set crazy, colorful scenes. But today they:
- are kind of annoying if you have a real wall switch, since now you have two on/off states
- are totally commoditized and LiFX/Hue/etc are being beaten by dirt cheap white-label bulbs.
They have their place, especially in environments where you do want high quality lights (LiFX can be very pretty), and perhaps in automation or environments where the wall switch isn't part of the normal UX (e.g., a standing lamp with an inaccessible wall switch). I still have some LiFX bulbs in one room of my house, but in general I'm happy to be rid of smart lights in favor of smart switches.
All of the BLE work was enabled by Jim, who works on MicroPython and has written the asyncio-based BLE stack, and is basically a genuis.
This post has been pretty high-level. If you're curious more about individual parts of how the system works, please @-me.