Smart Switches

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:

Clipsal CLP5010 module
The dimmer modules before being put into a wall cavity


The things I bought are:

Just on their own, the dimmer modules and momentary switches change the UX of your fingers physically interacting with the switch. This means:

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.)

Clipsal CLP5010 module
Partially wired modules and switches in wall

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. 🏡👀

Google Assistant

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 screen).

Basic diagram of the connection between Google Assistant and the switches
Google talks to a NodeJS server which talks to MicroPython on a PyBoard

That webserver needs to accept basically three commands, which are actually pretty simple:

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!

The Result

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:

JBL Link View displaying the Living Room lights control panel
Touch a screen to change lights! Or use your phone.


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?

History Lesson

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:

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.