Novostella reached out to me, to review their smart bulb (review) and floodlights (review). I met my obligations (which are basically: keep the device working until the b-roll is shot), so it’s time to abuse the products in a less favourable way. The bulb was my first victim since it was easier to take it apart, but it turned out that none of that is needed to flash Tasmota on Novostella products. All I needed is a couple of minutes of my time, tuya-convert and I can enjoy Tasmota on Novostalla smart bulb and floodlights.
Start with Tuya-Convert
It’s a completely wireless way of flashing Tasmota on Novostella smart lights, or other compatible devices. Note that not all devices would work, but anything running ESP chips has a great success rate. The process is surprisingly simple, polished and quick. To get started you will need:
- Linux machine with WiFi (Raspberry Pi will do!)
- A spare WiFi device (mobile phone, computer, WiFi toaster)
- A compatible Tuya device – in this case Novostella 1300 lumen RGB smart bulb and floodlights
Installation instructions are are straight forward as long as you have Git installed on your machine (sudo apt-get install git
). Open a terminal window with your favourite SSH client (Sollar PuTTY is mine) and complete the tuya-convert installation:
git clone https://github.com/ct-Open-Source/tuya-convert
cd tuya-convert
./install_prereq.sh
Your Raspberry Pi (or whatever Linux machine you are using) is ready to flash Tasmota on Novostella smart light bulb.
How to flash Tasmota on Novostella smart bulb
Before you press the proverbial “no return button”, please know that things can go sideways and I’m not responsible for whatever happens next. You will also override the original firmware – to pay attention to the backup file – just in case! To flash Tasmota on Novostella smart bulb type:
./start_flash.sh
If you are running this on a Raspberry Pi that also runs MQTT server, NodeRED and any other network-enabled programs, tuya-convert will ask you to terminate it. Allow it, you will get everything back after the reboot.
Do you wish to terminate dnsmasq? [y/N] y Attempting to stop dnsmasq.service ... Port 1883 is needed to run MQTT Do you wish to terminate mosquitto? [y/N] y
It’s time to use that WiFi enabled toaster (or mobile phone). Your SSH client will show you a prompt to look for a new WiFi network (SSID: vtrust-flash
) and connect your device to it. I’m not into technical details to why this step is needed, but it does something important otherwise things don’t work as planned:
IMPORTANT Connect any other device (a smartphone or something) to the WIFI vtrust-flash This step is IMPORTANT otherwise the smartconfig may not work! Put your IoT device in autoconfig/smartconfig/pairing mode (LED will blink fast). This is usually done by pressing and holding the primary button of the device Make sure nothing else is plugged into your IoT device while attempting to flash. Press ENTER to continue
It’s time to put the Novostella bulb into a pairing mode. It’s less insane than on other bulbs. Toggle it 3 times and it will blink. This is where tuya-convert will connect to the bulb and attempt to make a backup of the original firmware. If all went well you should see a file name that you should care about for another 5 minutes.
curl: Saved to filename 'firmware-f2c3c0.bin' // named like this or similar
Next up, is a waiting game. The tasmota-wifiman.bin (or ESPurna if that’s your thing) that I mentioned before will be uploaded to the device and the bulb will reboot into AP mode. This is where you have to connect to Tasmota WiFi (SSID: Tasmota-xxxxx
) and enter your network credentials.
Fixing Tasmota on Novostella smart bulb
We are not quite home yet! Tasmota is flashed but the firmware has no idea how to use the device. Thankfully, someone did whole homework for me, and all you have to do is to go to Tasmota -> Configuration -> Configure other and enter this template:
Novostella 13W RGB smart bulb:
{"NAME":"Novostella 13W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18}
Novostella Smart Floodlights (yes these are the same):
{"NAME":"Floodlight","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18}
Check the “activate” option and save the configuration. Head back to the Configuration -> Configure Module and select whatever you put in the name of your template – Novostella 13W
(or whatever you want). Reboot the device and you should see the control panel looking much more familiar:
Novostella smart bulb in NodeRED
If you follow me enough, you know what will happen next. Time to open up NodeRED and play! I will show you how to:
- toggle the bulb
- change the brightness
- change the temperature
- change the colour values
- Use Alexa to control the light
- Use Google Assistant to control the light
Then you can integrate the bulb with everything you wish – I have a couple of good tutorials for lights:
Let’s take a look at NodeRED – bear in mind I’m awkward and I usually swap the %topic
and %prefix
in my MQTT Tasmota flow around. It wouldn’t be a complete NodeRED revamp without a nice Dashboard widget to go with it so each section comes with the associated dashboard features.
It’s a good practice to have the state of each bulb available in the flow context, so I will take care of this first. I already know some of that code will be used later on while processing Google Assistant responses so I modified the update so it always holds the last values:
var current = flow.get("Novostella_light_1"); var data = msg.payload; var state; if(data.POWER === "ON"){ data.POWER = true; msg.label = "ON"; } if(data.POWER === "OFF"){ data.POWER = false; msg.label = "OFF"; } var save = Object.assign(current, data); flow.set("Novostella_light_1", save); return msg;
For the sake of consistency, I translated the ON|OFF
payloads to true|false
.
Toggle
Turning things on and off with Tasmota is an easy task. Tasmota is able to accept ON|OFF
, 1|0
and true|false
values. For the sake of consistency, I use true|false in my flows. Submit the msg.payload
of your choice to the correct topic /novostella/cmnd/Power
. Now that the programming warm-up is over, let’s move to the more exciting stuff.
Brightness
To change the brightness level, an integer 0-100
has to be sent to novostella/cmnd/Dimmer
topic. There are many ways in which you can set the brightness. I have included in my flow a random value, an inject node, and a dashboard slider.
The slider comes with 2 buttons set to min (10) and max (100) for quick toggling. Why min value of 10? If you want to turn the light off just use a toggle!
White temperature range 2700K – 6500K
Novostella floodlights and smart bulb come with a separate channel to control the temperature of the white light. This is displayed as 2700K (warm white) and 6500K (cold white). Tasmota takes the colour values via this topic: novostella/cmnd/CT
. There is a plot twist, these values are from 153 - 500
with the 500 being the warm colour and 153 representing the highest temperature.
If you want a slider that shows the temperature rather than arbitrary values, you have to remap these to the temperature range. I can achieve that with a simple equation:
var color = msg.payload -2700; var warm =153; var cold =500; var minK = 2700; var maxK = 6500; var range = cold - warm; var rangeK = maxK - minK; msg.payload = cold - Math.round((range*color)/rangeK); return msg;
If you provide the temperature in K, the function node will spit out a msg.payload
with the correct value for the CT
range.
Colours (HSB or HSV or HSL)
By far this was the most annoying to figure out. Mostly because of the HSx naming standard. Regardless of the name HSB, HSV, HSL it represents the same thing and once you know how to send the correct values it’s not that complicated.
There is a colour picker in NodeRED dashboard that can actually deliver HSV data to NodeRED. The data isn’t directly usable, so to convert it to a string that is formatted like this (H [0-360], S [0-100], V [0-100])
a function node is required.
var h = Math.round(msg.payload.h); var s = msg.payload.s *100; var v = msg.payload.v *100; msg.topic = "novostella/cmnd/HSBCOLOR"; msg.payload = h.toString() +","+s.toString()+"," + v.toString(); return msg;
Tasmota requires the payload to be a string with Saturation and Value as %
rather than ranges from 0-1
. So that’s what this script does. Now I can pick the colours using colour picker with the HSV option.
Alexa (NodeRED skill)
This skill is my go-to for IoT devices in my house. It’s relatively easy to use, and I wrote about it extensively before. Take a look at how to use Alexa in NodeRED, as here I will only explain the conversion that needs to take place to make the voice commands for toggle, brightness, temperature and colour working.
var command = msg.command;
if(command === "TurnOnRequest" || command === "TurnOffRequest"){
msg.topic = "novostella/cmnd/Power"; return msg;
}
if(command === "SetPercentageRequest"){
msg.topic = "novostella/cmnd/Dimmer";
return msg;
}
if(command === "SetColorRequest"){
var h = Math.round(msg.payload.hue);
var s = msg.payload.saturation * 100;
var v = msg.payload.brightness * 100;
msg.topic = "novostella/cmnd/HSBCOLOR";
msg.payload = h.toString() +","+s.toString()+"," + v.toString();
return msg;
}
Alexa node issues different commands for each action. I’m taking advantage of this to create 3 different if() conditions to set the correct values and send it to the correct topic (MQTT out node won’t be configured for that).
The toggle action is self-explanatory and Alexa’s payload is already true|false
. Simple enough. Dimming action is works in a similar way, and the payload comes as a value set between 0-100
. With colour, I needed to repurpose the script I made for the HSV control. Fortunately, the values provided by Alexa are the same so it was a simple copy and paste job.
Google Assistant (NORA)
I’m using NORA to emulate the Google home – if you want to know in detail how NORA works – there is an entire write up about connecting NORA in NodeRED. I will cover the changes in the light device that had to be made to use voice and widget control correctly.
Unlike Alexa, requests coming from NORA don’t have the command information. I’m not able to tell what changed without looking at the values directly. I need a different system to deal with it. I’m going to save the updated values in a flow context (learn how to save the context data), and use these to compare the differences.
function convert(y){
y = y.toFixed(2)
return y;
}
function color_convert(h,s,v){
let h1 = Math.round(h);
let s1 = convert(s) * 100;
let v1 = convert(v) * 100;
let z = h1.toString() +","+s1.toString()+"," + v1.toString(); return z;
}
var msg1 = null;
var msg2 = null;
var hue = msg.payload.color.spectrumHsv.hue;
var sat = msg.payload.color.spectrumHsv.saturation;
var val = msg.payload.color.spectrumHsv.value;
// passed value
var color_val = color_convert(hue, sat, val);
// current values
var data = flow.get("Novostella_light_1");
var power = data.POWER;
var dimmer = data.Dimmer;
var colour = data.HSBColor;
var ct = data.CT;
// toggle
if(msg.payload.on !== power) {
msg = {payload: msg.payload.on, topic: "novostella/cmnd/Power"};
return msg;
}
// dimmer
if(msg.payload.brightness !== dimmer || color_val === colour) {
msg1 = {payload: 350, topic: "novostella/cmnd/CT"};
msg2 = {payload: msg.payload.brightness, topic: "novostella/cmnd/Dimmer"};
return [[msg1,msg2]];
}
// colour
if(color_val !== colour) {
msg1 = {payload: color_val, topic: "novostella/cmnd/HSBCOLOR"};
msg2 = {payload: msg.payload.brightness, topic: "novostella/cmnd/Dimmer"};
return [[msg1,msg2]];
}
Unfortunately, the system isn’t perfect. I had to come up with a solution to colour changes, as each colour from the Google Home widget would supply a different brightness level. At the moment, the flow will set the arbitrary colour temperature to control the brightness since NORA doesn’t support temperature changes directly.
On top of that to change the colour in this situation I have to change the colour value first and then adjust the brightness which results in a small flash. I had very little to work with and this is the best I could come up with.
Final thoughts
The process was relatively simple. It’s nice that Novostella doesn’t make you toggle the lights like 20 times to reset it🤦♂️. You can achieve Tasmota in no time, and then use this flow to control the lights just the way you want. If I come up with a better Google Assistant controls I will update this. Until then it’s “sold as is”! Let me know what do you think about this in this Reddit thread.
Project Download
Download project files here. Bear in mind that Patreon supporters have early access to project files and videos.