Edit: Updated the YML defintion to remove
${friendly_name}
from the Sensorname:
attribute since this isn’t substituted
Table of Contents
- Target Framework
- Chips
- Flashing Chips
- Smart Plugs
- Bulbs
- ESPHome Firmware
- It didn’t connect!
- Connecting the device to Home Assistant
- Speeding it up
- Troubleshooting
- Incorrect WiFi setup
As part of my exploration into more local control, I went on a journey with some smart devices that, at a high level, look the same, but in reality have some differences!
I’ve been running Home Assistant for years, I’ve had a lot of great success with a weird mismatch of devices (WiFi, ZWave, Zigbee) and cloud platform providers (Tuya, SmartHome, SmartThings, Google, Amazon, etc…)
Since moving to a new house in October 2024, I decied to take a strong local control approach, this means that I needed to look at all my devices and work out how to:
- Remove dependencies on external clouds (Sorry Sofabaton, your horrendous insecure external API is a no-go)
- Examine ways to do local audio control (no more Alexa/Google Home)
- Improve the local interface (tablet interface)
This blog post is covering one of the big external cloud dependencies I (and many others have): Tuya
Tuya is a massive white-label company, there’s hundreds of products that can be easily resold with custom applications (rebranded Tuya) and under a custom brand (I’ve seen Globe, and Dals Connect personally)
There’s projects like Local Tuya that have been succesfull in bridging the cloud-local gap a small amount, the idea is that you can communicate with the devices over the local IP addresses instead of going through Tuyas API. I’d been using this for a while without any issues. But recently (the last 3-4 months) it’s become more unstable, with devices getting “lost” by LocalTuya (Local Tuya won’t see them), until I open the Tuya official app and toggle the states manually. This is really painful for times when I’m on vacation, and I don’t want to have to set up alerts that say “Hey, your devices are desynced and you need to go and poke X devices to make them work again”, this isn’t a slight on the LocalTuya project, they’ve done really good work here.
There’s also solutions like Tuya Convert and Tuya Cloudcutter, there’s a reason there’s two different projects here
Target Framework
There’s some choices that you’ll get here, you can choose to flash a local Tuya Cloud (not localTuya, but MockTuyaCloud I think, I never went down this route), OpenBeken, or ESPHome
I personally went with ESPHome because I have a lot of other devices that use ESPHome, and I like the ESPHome Builder add on for Home Assistant OS. I don’t need to manage my own containers for ESPHome, and I can do all my editing, flashing, and log viewing from the Home Assistant Web UI, which is great for me when I’m remote and troubleshooting things.
Chips
A lot of these smart devices were originally based around the ESP8266 style chips, these were (and still are) cheap System On Chip (SOC) with WiFi and could easily be adapted for many uses. As with all capitalism, companies will look for alternatives over time, both from a price standpoint, and to keep people locked into their ecosystem. The ESP8266 chips were easy to reprogram, they’re designed that way, so you reduce vendor lockin unintentionally.
Cue, the BK72xx chips, these were less well known and harder to just attach cables to program custom firmware and release consumers from the Tuya ecosystem.
Finally, at least from what I’ve seen, Tuya have been shipping their own custom chips, the WRD8P. To my knowledge, these do not have any current way to jailbreak/flash custom firmware on.
To flash the others, there’s choices (and some not-so-much-choices)
Flashing Chips
If you get lucky, you can use Tuya Convert or Tuya Cloud Cutter with Over The Air (OTA) flashing to wirelessly reprogram these devices. Sometimes the chips come with exploitable firmware out of the box, sometimes you need to update the software so they can be exploited, sometimes you can’t exploit them this way.
When the chips have un-exploitable firmware, you can potentially fall back to the option of attaching wires and manually programming them (one of my friends has blogged about his experience here).
But, I’m lazy, and it’s really hard to attach wires to the controller chip in a light bulb, they’re tight, and fiddly, and I don’t want to do it. So I went with the OTA method for both my light bulbs and my smart plugs!
Smart Plugs
Similar to Roos adventure, I have a bunch of Globe Smart Plugs from Costco, and they have the Beken chipsets. So I know I can’t use tuya-convert, I have to use tuya-cloudcutter
I downloaded the tuya-cloudcutter repository to my Debian based laptop (it’s uses Pop_os! 24.04, so alpha software) to use as my host attack machine!
HERE BE DRAGONS! Don’t do anything you aren’t comfortable with. There’s a non-zero chance this won’t work, may leave your laptop in a weird state, may brick (make unusable) your target device!
git clone https://github.com/tuya-cloudcutter/tuya-cloudcutter
cd tuya-cloudcutter
From here, you need to confirm a couple of things
- You have everything you need to get started, you’re going to lose the internet until the flash process is complete (unless you have a second network interface, such as a second wifi client, or a wired connection)
- You’re 100% certain that you know you want to continue.
- As you get more comfortable with this, you may want to setup your target “final” firmware that you want to use. See the section below for these steps
When you’re ready, the simplest approach is to just launch the script and run through the steps manually. It walks you through things in an interactive way
sudo ./tuya-cloudcutter.sh
The first phase is setting up the device profile and the target firmware, for these plugs there’s two ways to select the profile, personally I opt to select by Manufacter/Device Name but I’ve also done it by firmware version, I just find the former easier to do (and slightly less scrolling). There’s no type-ahead filtering here, so just scrolling down to Globe Electric and then selecting 50329 Smart Plug, for me, I only had one firmware to choose from. If you have multiple options here, you will need to try each one in turn, or connect it to the Tuya app so see what firmware is loaded.
1) Detach from the cloud and run Tuya firmware locally
2) Flash 3rd Party Firmware
[?] Select your desired operation [1/2]: 2
Loading options, please wait...
[?] How do you want to choose the device?: By manufacturer/device name
► By manufacturer/device name
By firmware version and name
From device-profiles (i.e. custom profile)
[?] Select the brand of your device: Globe Electric
Feit
Filohome
Firefly
Fitop
FLSNT
Geeni
► Globe Electric
Globo Lighting
Gosund
Hama
Helloify
HeuxGir
Hihome
[?] Select the article number of your device: 35804 RGB E26 LED Bulb
35798 A19 RGBCT Bulb v1.3.21
35804 RGB E26 LED Bulb
35851 E26 RGB Bulb
37783 RGBCT Bulb v2.0.0
37783 RGBCT Bulb v2.0.3
50151 Smart 2-Outlet Outdoor Plug
50239 Motion Night Light
50323 RGBCT Recessed Light
► 50329 Smart Plug
50347 Smart-Plug
[?] Select the firmware version and name: 1.1.8 - BK7231T / oem_bk7231s_rnd_switch
► 1.1.8 - BK7231T / oem_bk7231s_rnd_switch
Then there’s some safety checks, I personally have always let it terminate systemd-resolve and apparmor for the duration of these flashes. I’m not sure if it’s needed, but it felt right.
Final setup step, you’ll be asked to select the firmware, as I said, I use ESPHome, so I went with that.
[?] Select your custom firmware file for BK7231T chip: ESPHome-Kickstart-v23.08.29_bk7231t_app.ota.ug.bin
► ESPHome-Kickstart-v23.08.29_bk7231t_app.ota.ug.bin
OpenBeken-v1.18.31_bk7231t.ug.bin
You’ll now get a presentation of what was selected, if you end up doing this flash multiple times, you’ll want to note/copy down this information as you’ll use it again to save time!
Selected Device Slug: globe-electric-50329-smart-plug
Selected Profile: oem-bk7231s-rnd-switch-1.1.8-sdk-1.0.2-40.00
Selected Firmware: ESPHome-Kickstart-v23.08.29_bk7231t_app.ota.ug.bin
Now the flashing process starts! The script will tell you what to do.
For the plugs, I held down the power button for a few seconds until it clicked, and this put the plug into pairing mode (which is a fast blink on the button LED), then repeated this and it entered AP Mode (which is a slow blink, or “breathing” on the button LED)
================================================================================
Place your device in AP (slow blink) mode. This can usually be accomplished by either:
Power cycling off/on - 3 times and wait for the device to fast-blink, then repeat 3 more times. Some devices need 4 or 5 times on each side of the pause
Long press the power/reset button on the device until it starts fast-blinking, then releasing, and then holding the power/reset button again until the device starts slow-blinking.
See https://support.tuya.com/en/help/_detail/K9hut3w10nby8 for more information.
================================================================================
Scanning for open Tuya SmartLife AP
......................
Found access point name: "Globe Suite-18AD", trying to connect...
Error: Connection activation failed: The Wi-Fi network could not be found.
................................
Found access point name: "Globe Suite-18AD", trying to connect...
Device 'wlp0s20f3' successfully activated with '055d86b5-b09c-423e-a0ac-d6dbba32c770'.
.
Found access point name: "Globe Suite-18AD", trying to connect...
Device 'wlp0s20f3' successfully activated with '055d86b5-b09c-423e-a0ac-d6dbba32c770'.
Connected to access point.
Waiting 1 sec to allow device to set itself up...
Running initial exploit toolchain...
Exploit run, saved device config too!
output=/work/configured-devices/tQ6NtVtsxRQ7.deviceconfig
Saved device config in /work/configured-devices/tQ6NtVtsxRQ7.deviceconfig
You can see it struggled to connect the first couple of times, then it succeeded and worked! The exploit is in play.
Make sure you fully powercycle (unplug, wait a few seconds, and plug it back in) before continuing.
Sometimes the device will go back into AP mode straight away after this, so wait a few seconds to make sure it doesn’t get picked up automatically.
You will probably need to repeat the AP process (long hold x2) to get the device flashed
================================================================================
Power cycle and place your device in AP (slow blink) mode again. This can usually be accomplished by either:
Power cycling off/on - 3 times and wait for the device to fast-blink, then repeat 3 more times. Some devices need 4 or 5 times on each side of the pause
Long press the power/reset button on the device until it starts fast-blinking, then releasing, and then holding the power/reset button again until the device starts slow-blinking.
See https://support.tuya.com/en/help/_detail/K9hut3w10nby8 for more information.
================================================================================
Scanning for open Tuya SmartLife AP
............
Found access point name: "A-18AD", trying to connect...
Device 'wlp0s20f3' successfully activated with '12631878-8862-40d8-adb8-50411acc2427'.
.
Found access point name: "A-18AD", trying to connect...
Device 'wlp0s20f3' successfully activated with '12631878-8862-40d8-adb8-50411acc2427'.
Connected to access point.
Configured device to connect to 'cloudcutterflash'
Device is connecting to 'cloudcutterflash' access point. Passphrase for the AP is 'abcdabcd' (without ')
Flashing custom firmware...================================================================================
Wait for up to 10-120 seconds for the device to connect to 'cloudcutterflash'. This script will then show the firmware upgrade requests sent by the device.
================================================================================
Using WLAN adapter: wlp0s20f3
Configuration file: /dev/stdin
Using interface wlp0s20f3 with hwaddr 40:ec:99:f3:3a:a4 and ssid "cloudcutterflash"
wlp0s20f3: interface state UNINITIALIZED->ENABLED
wlp0s20f3: AP-ENABLED
If your device gets stuck here with no progress after several (at least two) minutes, see https://github.com/tuya-cloudcutter/tuya-cloudcutter/wiki/FAQ#my-device-gets-stuck-after-dhcp-what-can-i-do for additional steps
Using PSK v1 - Received PSK ID version 01
Processing endpoint /v1/url_config
Processing endpoint tuya.device.active
Processing endpoint tuya.device.dynamic.config.get
Processing endpoint tuya.device.upgrade.get
Processing endpoint tuya.device.upgrade.status.update
Processing endpoint /files/ESPHome-Kickstart-v23.08.29_bk7231t_app.ota.ug.bin
Processing endpoint tuya.device.uuid.pskkey.get
Firmware update progress: 19%
Firmware update progress: 30%
Firmware update progress: 60%
[Firmware Upload] /files/ESPHome-Kickstart-v23.08.29_bk7231t_app.ota.ug.bin send complete, request range: bytes=0-438751/438752
Firmware update progress: 90%
Firmware update progress: 98%
Firmware file has been sent and MQTT reported a progress of nearly complete. Waiting 15 seconds to ensure flashing completes.
Flashing should be complete. It takes about 15 seconds for the device to reboot and verify the flash was valid.
Please wait about 30 seconds then look for signs of activity from the firmware you supplied (either watch for AP mode or check if it joined your network).
Device MAC address: cc:8c:bf:4e:18:ad
While this is a bit messy, it’s clear (to me) what it’s doing and what the expectations are. When it’s done the device will reboot into the custom firmware framework. And sit broadcasting it’s own kickstart
access point

Don’t connect to this quite yet, I found it easiest to get my ESPHome Firmware ready first
Bulbs
I also have a few Globe Lighting RGB Bulbs from Costco, these ones are also BK7231T chipsets so I can flash these as well
This was almost exactly the same process as above, but selecting a different device
[?] How do you want to choose the device?: By manufacturer/device name
► By manufacturer/device name
By firmware version and name
From device-profiles (i.e. custom profile)
[?] Select the brand of your device: Globe Electric
Feit
Filohome
Firefly
Fitop
FLSNT
Geeni
► Globe Electric
Globo Lighting
Gosund
Hama
Helloify
HeuxGir
Hihome
[?] Select the article number of your device: 35804 RGB E26 LED Bulb
35798 A19 RGBCT Bulb v1.3.21
► 35804 RGB E26 LED Bulb
35851 E26 RGB Bulb
37783 RGBCT Bulb v2.0.0
37783 RGBCT Bulb v2.0.3
50151 Smart 2-Outlet Outdoor Plug
50239 Motion Night Light
50323 RGBCT Recessed Light
50329 Smart Plug
50347 Smart-Plug
[?] Select the firmware version and name: 2.9.16 - BK7231T / oem_bk7231s_light_ty
► 2.9.16 - BK7231T / oem_bk7231s_light_ty
For the bulbs, putting them into access point mode was a bit more tedious, you have to turn them off and on again 3 times to get them into pairing mode, and then 3 times again to get them into access point mode. For this, I used a desk lamp with the appropriate fitting.
You can’t toggle them too quickly though, there’s a capacitor in there that takes a short time to discharge, so I turn it off, wait a second, then turn it back on, then repeat.
You’ll get the same fast to slow flash cycle, but because these are light bulbs, it’s a lot brighter, so watch your eyes.
ESPHome Firmware
My firmware is setup in a way that I can easily copy and paste the setup and just change one field to make it work.
I have a couple of secrets in my ESPHome configuration wifi_ssid
and wifi_password
so I don’t need to expose my secrets when sharing the configuration file
There’s a couple of ways you can add this configuration file
- Create a new device in the ESPHome Builder UI, setup the basics, and then just copy and paste the content below in
- Using the Home Assistant Terminal (I use the Addon for this), and editing the file directly in
~/config/esphome
(i.e.vim ~/config/esphome/globe-plug-1.yaml
)- I use this approach to copy to multiple devices too (
cp globe-plug-1.yaml globe-plug-2.yaml
and edit thenumber: "1"
line)
- I use this approach to copy to multiple devices too (
# Globe Electric 50329 smart plug
substitutions:
number: "1"
device_name: globe-plug-${number}
device_description: Globe Electric 50329 Smart plug
friendly_name: Globe Plug ${number}
esphome:
name: ${device_name}
comment: ${device_description}
bk72xx:
board: wb2s
# Enable logging
logger:
# Enable Home Assistant API
api:
web_server:
ota:
- platform: esphome
id: ota_esphome
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
time:
- platform: homeassistant
id: homeassistant_time
sensor:
- platform: uptime
name: Uptime
unit_of_measurement: minutes
filters:
- lambda: return x / 60.0;
- platform: wifi_signal
name: Signal
update_interval: 60s
light:
- platform: status_led
name: "led"
internal: true
id: led
pin:
number: P7
inverted: true
binary_sensor:
- platform: gpio
pin:
number: P26
inverted: true
id: button1
filters:
- delayed_on: 10ms
- delayed_off: 10ms
on_click:
- switch.toggle: outlet
- platform: status
name: Status
switch:
- platform: gpio
name: Outlet
id: outlet
pin: P24
icon: mdi:power-socket-us
on_turn_on:
- light.turn_on: led
on_turn_off:
- light.turn_off: led
And for the RGB Bulbs it is more complex!
esphome:
name: "globe-rgb-1"
#Restore light to 3700K when turned on
on_boot:
priority: 600
then:
- light.turn_on:
id: light_rgbww
brightness: 100%
color_mode: COLOR_TEMPERATURE
bk72xx:
board: generic-bk7231t-qfn32-tuya
logger:
web_server:
captive_portal:
mdns:
api:
ota:
- platform: esphome
id: ota_esphome
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
text_sensor:
- platform: libretiny
version:
name: LibreTiny Version
sm2135:
clock_pin: P8
data_pin: P26
rgb_current: 20mA
cw_current: 55mA
output:
- platform: sm2135
id: output_red
channel: 2
- platform: sm2135
id: output_green
channel: 1
- platform: sm2135
id: output_blue
channel: 0
- platform: sm2135
id: output_cold
channel: 4
- platform: sm2135
id: output_warm
channel: 3
light:
- platform: rgbww
id: light_rgbww
name: Light
color_interlock: true
cold_white_color_temperature: 6500 K
warm_white_color_temperature: 2700 K
red: output_red
green: output_green
blue: output_blue
cold_white: output_cold
warm_white: output_warm
From here, you’ll want to go back to ESPHome Builder and edit the file you created, then click Install on the top right of the window (ignore the name in this screenshot, that’s just because I don’t have the exact one to hand), and select Manual Download

The next screen will ask you for a format, I use the UF2
package since that just works. But you can also create a cloudcutter image so you can simplify your steps and pass that directly to cloudcutter when you want to jailbreak your device.

Finally, ESPHome will get compiling! This can take a bit of time if there’s a lot of dependencies to download, but don’t close the window, that can cause other problems
When it’s done, you’ll get the file automatically downloaded (or you can click the Download
button if it didn’t do that)

Again, ignore the filename here, that’s just because I took these screenshots for my Globe RGB Bulbs (see below)
Now you can connect to the kickstart-bk7231t
access point

If you’ve done everything correctly, you can visit 192.168.4.1
in your browser, scroll to the bottom for the OTA Update

Click Choose file
and select the .uf2
file you downloaded from ESPHome

Click Update
, you won’t get immediate feedback of something happening (if you look at the tab title you may see a loading icon), but when it’s complete you’ll get a simple page telling you it’s done!

The device should reboot and connect to the WiFi you selected in ESPHome builder.
It didn’t connect!
If you didn’t specify an SSID and password in the ESPHome Config file, the device will reboot into AP mode again with an SSID that matches the device name, you can connect to it directly and specify the WiFi access point to use. Personally, I like to explicitly declare my AP details so I don’t need to think about this step.
Connecting the device to Home Assistant
Home Assistant should now notify you it’s found a new device, just click on the notification -> Check it Out! -> Add -> You shouldn’t need to change anything here.

Congratulations! You’ve succesfully flashed your device and added it to Home Assistant with ESPHome.
Now just go and repeat these steps for the rest of your devices…
Speeding it up
As mentioned, you can speed the flashing process up a bit, from the output you got after selecting your device manually, you can extract the profile and the firmware, these can be providded as command line options for tuya cloudcutter. Oddly the device slug is the -p
option for me.
For the smart plug:
Selected Device Slug: globe-electric-50329-smart-plug
Selected Profile: oem-bk7231s-rnd-switch-1.1.8-sdk-1.0.2-40.00
Selected Firmware: ESPHome-Kickstart-v23.08.29_bk7231t_app.ota.ug.bin
sudo ./tuya-cloudcutter.sh -p globe-electric-50329-smart-plug -f ESPHome-Kickstart-v23.08.29_bk7231t_app.ota.ug.bin
And the RGB Bulb:
Selected Device Slug: globe-electric-35804-rgb-e26-led-bulb
Selected Profile: oem-bk7231s-light-ty-2.9.16-sdk-1.0.8-40.00
Selected Firmware: ESPHome-Kickstart-v23.08.29_bk7231t_app.ota.ug.bin
sudo ./tuya-cloudcutter.sh -p globe-electric-35804-rgb-e26-led-bulb -f ESPHome-Kickstart-v23.08.29_bk7231t_app.ota.ug.bin
That makes it a bit easier, and as mentioned briefly you can setup all your ESPHome configurations in advance, and download the .u2
file to directly flash your devices immediately with the target firmware to avoid connecting to the hotspot
If you go this route, make sure you put the firmware in the custom-firmwares
directory in the checked out tuya-cloudcutter
repository, since this is mounted in the docker containers for use, it can’t acces your $HOME
directory.
Troubleshooting
I had a couple of unused devices that wouldn’t work out of the box, it ended with The profile you selected did not result in a succesfull exploit
Scanning for open Tuya SmartLife AP
....
Found access point name: "Globe Suite-F01A", trying to connect...
Device 'wlp0s20f3' successfully activated with 'f4ab1af2-5e3d-4ca0-94c2-d7b331bd0ec6'.
.
Found access point name: "Globe Suite-F01A", trying to connect...
Device 'wlp0s20f3' successfully activated with 'f4ab1af2-5e3d-4ca0-94c2-d7b331bd0ec6'.
Connected to access point.
================================================================================
[!] The profile you selected did not result in a successful exploit.
================================================================================
I had two issues here
- One device I just selected the wrong profile! D’oh
- One device needed to be updated to the right firmware version
Looking at the selected profile output, and comparing the version in it to the Firmware version on the device would show the issue
Selected Profile: oem-bk7231s-light-ty-2.9.16-sdk-1.0.8-40.00
My light was running on an older firmware, a quick update via the Tuya app fixed this!
Incorrect WiFi setup
If you got your WiFi information mixed up and try to connect to the devices local access point after flashing the ESPHome Firmware, there’s a chance of a recovery issue. A friend of mine encountered this
When he connected with his laptop, he could visit 192.168.4.1
but nothing would show. Viewing the page source he could see the following
<!DOCTYPE html><html><head><meta charset=UTF-8><link rel=icon href=data:></head><body><esp-app></esp-app><script src="https://oi.esphome.io/v2/www.js"></script></body></html>
The issue is that the JS file is stored online and he only had one Wireless connection (being used by the device) so it couldn’t download the javascript file.
The options are:
- Connect a second network connection to the laptop (wireless or wired, just as long it can access the internet)
- Use your cellphone to connect to the bulbs Access Point, your mobile data will download the javascript for you
Leave a Reply