Upgrading a Verve Design oyster light with Tasmota and connecting it to Apple HomeKit
Finding affordable smart home devices can be tough. And unlike most consumer electronics which can be bought and imported, most smart home devices need to comply with local standards and regulations.
I was in the market for a bright, nicely diffused light for my bathroom that’s currently undergoing renovation and stumbled upon the Verve Design Hana Ceiling Light. At 2,550 lumens it definitely ticks that first requirement. It also happened to have wifi connectivity and adjustable colour temperature and doesn’t break the bank.
Apple released Adaptive Lighting as part of HomeKit in late 2020 and I’m a big fan of f.lux so I’d love to have all my lights behave in the same way. So I thought “perfect, I can buy this light and surely there’s a Homebridge plugin that’ll allow me to integrate this with HomeKit and Adaptive Lighting”. Yeah nah.
Many days of hard work later I can say that it’s almost there.
The Hana Ceiling Light is advertised as a smart light that connects to GRID Connect — a deployment of Tuya, itself a Chinese company that’s developed a platform that allows companies like Arlec (which operates Verve Design) to deploy their own branded smart home ecosystem (with custom branded hardware and a custom branded app). While it can be hooked up to Google Home and Amazon Alexa, it does not support Apple’s HomeKit. Apple has much more stringent security requirements which can make it quite burdensome for manufacturers to support. Previously this required manufacturers to use Apple certified chips under the MFi program but I believe they have since changed course and allow HomeKit compatibility by implementing all their security requirements through firmware instead.
Another problem with any Tuya-based hardware is that it’s not secure and reportedly sends hundreds of MBs of data back to the cloud. While not necessarily nefarious I don’t quite like the idea of hackable devices on my network potentially sniffing activity on my LAN and sending it to parts unknown. “Aren’t you being a tad alarmist?” Nah, I don’t think so. IoT devices are primary recruits for botnet armies. Here’s a flashback to 2016, and here it’s explained in simple terms.
While I did manage to fully integrate the light into HomeKit, it was not an easy journey only made harder by sparse and incomplete documentation. It required a lot of experimentation to get here. This guide is by no means extensive but hopefully I’ve covered enough so that if you’ve landed here by means of a Google search you’ll end up finding a solution to your problem.
If I had known it’ll take all this effort at the beginning I wouldn’t have done this. I would’ve been okay with a dumb disconnected light.
If this is your first time meddling in smart home devices, turn back now. This is not for the faint of heart. 🛑 WRONG WAY GO BACK 🛑.
Note on Hana Light: It’s susceptible to that hum from the LED PWM when the colour temperature is 50%/both the cool white and the warm white LEDs are on. There is a benefit however that unlike older Hue bulbs, it retains its colour temperature and brightness settings even after a power cycle, so you can use a normal mains switch to still turn the light on/off.
Aren’t there already Tuya plugins for Homebridge?
Yes, but all that I’ve tried weren’t quite compatible with this light. Some didn’t work outright, others had massive bugs. homebridge-tuya is well maintained but didn’t work well with this light. Tuya also doesn’t like it when you place devices in a VLAN (and I’m not sure how well that would work with HomeKit either) so that’s not an option. And like I said before, I’d prefer my bathroom light not to be complicit in bringing down half a nation’s internet.
- You have Homebridge setup and running.
- I will be using Docker for my software deployments. You might face different issues if you choose not too.
Advantages of this solution
- Tasmota is easy to use once you have it setup. If you replace the Tuya firmware with Tasmota, you will no longer have access to the light through the TuyaSmart app or the GRID Connect app, but it will work through Homebridge.
- You’ll probably void warranty.
- You might break something that’s unrepairable.
So you don’t waste your time reading this whole post or implementing all this only to find out it doesn’t work to your liking:
- No Adaptive Lighting support (yet). Yeah, spoiler alert, I did all this work and didn’t achieve my primary goal.
- HomeKit CT (colour temperature) values are non-linear from 153 to 500. The actual middle between cool white and warm white lies much closer to 153 in HomeKit leading to a mismatch between Home.app and what’s actually shown on the light.
- Flash the light’s microcontroller with Tasmota, replacing Tuya’s firmware.
- Configure Tasmota to correctly work with the Hana light.
- Setup an MQTT Broker on your local network.
- Setup homebridge-mqttthing, an MQTT plugin in Homebridge.
1. Flashing Tasmota onto the TYWE2L
Tasmota is an open source firmware for devices powered by the ESP8266 and ESP8266-like chips. It allows you to control connected devices through a web interface by simply typing in their local IP address in your browser while also providing an MQTT interface — more on that later. An alternative to Tasmota is ESPHome.
The microcontroller used in these lights is the Tuya TYWE2L which is based on the ESP8285. This’ll be our target.
Over-the-air firmware upgrade: fail.
tuya-convert allows the flashing of ESP8266-like devices over wifi with no physical connection required. Unfortunately this is not an option for the Hana light (at least for lights manufactured around Feb 2021). Tuya patched the vulnerability that tuya-convert exploits and no workaround has been found so far.
The alternative is to manually solder on connectors to the chip and flash the firmware directly. Time-wise they’re probably on-par. The advantage of using the tuya-convert OTA method is that there’s very little risk of you damaging anything, and some people are just not comfortable with a soldering iron.
Flashing the TYWE2L
This article is a good place to start. I ended up using a Raspberry Pi 3B because I had one lying around and followed this guide. My first preference would’ve been to use a Serial-to-USB adapter like the CH340G or the FTDI FT232 along with Tasmotizer which makes the whole process that much more simple. Tasmotizer also makes it easy to back up the Tuya firmware before flashing it with Tasmota in case you ever want to revert back to it.
You will need to connect up 5 wires to the TYWE2L:
RPi / TYWE2L
The Raspberry Pi won’t provide enough power through its 3V3 pin to power the TYWE2L so you’ll need to provide that from another source. I used my benchtop power supply to supply the 3V3 power. The RPi was powered through its standard USB port at 5V. Make sure that all the devices are grounded together.
Make sure to connect TX to RX and RX to TX. GPIO0 is needed to signal the microcontroller to enter a state where we can flash it. We need to hold GPIO0 at GND at boot. So the steps are:
- Connect GPIO0 to GND.
- Power up the TYWE2L by connecting 3V3.
- Wait a second or two.
- Disconnect GPIO0 from GND and leave it floating.
Tuya are nice enough to provide us with a pinout of the TYWE2L here. Luckily all the nodes we need are exposed on the PCB.
⚠️ Be extremely careful when soldering onto the TX, RX and IO0 pads on the back of the PCB. Handle the chip with care. These copper pads can be easily ripped off if you tug enough on the wire leaving you no other place to connect up to TX, RX or IO0.
For this reason I ended up stripping the jumper cable end and using the bare wire to solder onto these pads. The result looks like this:
You’ll want to keep following the instructions on the guide as to how to flash the firmware and how to setup the wifi connection. You can download the latest Tasmota firmware from here with a simple
wget command in your RPi terminal.
You’ll be able to power up the light normally after flashing it and disconnecting all wires.
2. Configure Tasmota for the Hana light
You’ll now be able to find the light on your wifi network if you’ve set it up correctly. I found its IP through my router’s software. The web interface looks like this:
Update 13 Feb 21: I realised this was for the ACL03HA model while mine is ACL04HA which explains the discrepancies below.
Configuration > Configure Other and you’ll be able to enter the template there.
The guide also says to configure
0 because the hardware has gamma correction included. I tried it both ways but couldn’t identify the difference probably because this thing is so damn bright anyway.
LedTable is a Tasmota command you can enter through the console on the Tasmota web interface. Simply write
LedTable 0 and hit return.
The problem I had with configuration was that the cool white and warm white range was reversed on the actual light compared to the web interface. This sent me down a rabbit hole to
SetOption37which allows the remapping of colour channels. I thought swapping the warm and cool white channels would do it but it had no effect. The fix was in the configuration.
A PWM on
GPIO12 controls the colour temperature and a PWM on
GPIO14 controls the brightness.
PWM_i stands for inverted, so switching the setting from
PWM_i did the trick.
That’s it! If you’re happy to control the light through its web interface all the time, otherwise we have to setup MQTT…
3. Set up an MQTT Broker
What is MQTT?
MQTT is a messaging service for connect devices. It’s a very lightweight protocol and is becoming more commonplace. There is a centralised MQTT broker that acts as an intermediary between smart devices. Devices/clients ‘subscribe’ to ‘topics’. Any message that is sent to the broker labelled as a specific ‘topic’ is also received by all devices subscribed to that topic. It’s kinda like Reddit — you subscribe to a particular subreddit, anyone that posts on that subreddit comes up on your main page. You can post on that subreddit and everyone subscribed will see your post. The MQTT broker is Reddit.
Tasmota allows us to use MQTT to programatically talk to these devices.
Setting up an MQTT broker is supposed to be trivial, but as with most things, it’s not.
I’ll suggest you use whatever computing device you have running Homebridge to also run the MQTT broker. For me that’s a Synology. My preference is to use Docker so that everything is nicely contained. It also makes it easy to keep track of what software is installed and running.
I faced a myriad of issues setting this up. First the Docker container would keep on crashing on boot, and that was because of a permissions issue with the mapped volume that includes the config file for the server. A simple
chmod ended up fixing this. It’s also preferable to have authentication enabled on the MQTT broker. A vector for attack is very low if it’s just running on your local network and not exposed to WAN but still.
I then faced another issue in setting up a username/password with Mosquitto as per this guide. Every time you’d re-enter your password for confirmation in the setup process it’ll come back with a
Killed. Turns out this is a problem with this Mosquitto Docker image on Synology and using the OpenSSL image version instead solved it. Once I had my username and password setup I reverted to using the normal non-SSL image as I’m not sure what strings are attached to the SSL version of the image.
Ooooof. Ok, let’s take a deep breath.
So now we have the MQTT broker setup and running with authentication and we need to connect the light and Homebridge to the broker.
4. Setting up homebridge-mqttthing
Configuring MQTT on the Tasmota is easy. It’s under
Configuration > Configure MQTT. I left everything as default except for
Host, where you enter the IP of the broker on your local network. For me this was the static IP of my Synology, and
Password (what you setup in the previous step).
homebridge-mqttthing is a Homebridge plugin that supports a vast array of HomeKit accessory types.
This guide is long enough so I’ll save you the drama of how I got there and how this works so here’s the final Homebridge config:
"name": "Bathroom Ceiling",
"apply": "return JSON.parse(message).POWER;"
"apply": "return JSON.parse(message).Dimmer;"
"apply": "return JSON.parse(message).CT;"
MQTT-Explorer was very useful in debugging this setup.
The great thing about MQTT is that you don’t need a static IP for your devices, only for the broker. Makes things a whole lot simpler.
Restart Homebridge and there you have it! A fully integrated CT light into HomeKit.
It’s actually quite responsive and has been very reliable through HomeKit so far.
Thanks to MQTT’s Last Will and Testament (LWT) feature, homebridge-mqttthing updates HomeKit and labels the light “No Response” when it is turned off from mains power or is unreachable.
The biggest downside is that the colour temperature wheel in Home.app (and I’m guessing HomeKit itself) is non-linear from CT values of 153 to 500, quite unlike the CT slider in Tasmota. I.e., centring the CT slider at 50% in Tasmota gives you a white that is exactly halfway between 2700K and 6500K. This results in a mismatch between Home.app and what’s actually shown on the light.
Side note: unlike colour temperature in Kelvin (e.g., 2700K), the higher the CT value, the warmer the colour gets.
homebridge-hue has been updated to support HomeKit’s Adaptive Lighting but homebridge-mqttthing has not. It seems Homebridge is making it easier for plugin developers to implement support in the upcoming v1.3.0 release. Here’s hoping for more widespread support soon.