This post may contain affiliate links. Please read my disclaimer for more info.

Have you seen cheap smart plugs on Amazon like these and wondering if you can use them with Home Assistant? Don’t want to rely on some cloud service to toggle your outlets? Well if the answer is yes to these questions you’re in luck, Tuya-Convert to the rescue!

In today’s article, I’m walking through a project called tuya-convert which allows you to replace the firmware on these plugs with whatever you want. I’m a big fan of esphome, so that’s what I’ll be using to build the custom firmware.

So what can we do once the device is freed from the firmware? Use it for automation of course! I’m using one of these plugs to control a lamp next to my desk that notifies when my wife comes home. The light toggles to give me a visual indicator that she opened the garage so I can go help her with groceries or my son. Skip to the end for the automation if you’re already familiar with tuya-convert.

esphome

Before we start changing out the firmware on the device, we need to decide what to put on it. I’m a big fan of the esphome project. It’s a command-line tool that allows you to customize an ESP8266 firmware image using a YAML file. Check out the installation page to install the tool.

ESPHome allows you to enable all sorts of hardware components by just writing some YAML configuration. I’ve used it before in my DIY Sprinkler Controller and ESP8266 Sound Machine to quickly develop firmware images that integrate nicely with Home Assistant. For plugs, we’ll use the basic GPIO switch component and some components to perform power monitoring.

Around the esphome project, there have popped up a community of people collaborating on device configurations for popular smart home devices. The esphome-configs.io website collects these configuration files for the community. This allows you to download a configuration file without having to learn all the components of esphome.

Writing a Configuration File

For the smart plugs I’m using, someone has already written a great esphome config file. On the back of those smart plugs you can see they have the model number AWP04L . Searching on the esphome-configs.io page there is already a config for the AWP04L.

If you’ve got a bunch of plugs you want to flash, it’s best to use a “split configuration”. That means putting all the common configuration into a common YAML file (I called mine awp04l.yaml ) and then creating another YAML file for each plug you are going to convert (mine are just called plug1.yaml , plug2.yaml , etc..).

My plug specific YAML file just looks like:

--- substitutions: device_name: plug1 device_description: Office Left Lamp friendly_name: Plug 1 wattage_calibration: "4054.3 -> 721.2" #Tested using a meter and 722.0W toaster -0.8W from just this plug with toaster off amperage_calibration: "7.4 -> 6.103" #Tested using a meter and 6.122A toaster -0.019A from just this plug with toaster off voltage_calibration1: "294.7 -> 117.8" #Tested using a meter, value while connected toaster was on voltage_calibration2: "321.7 -> 121.6" #value while connected toaster was off <<: !include awp04l.yaml 1 2 3 4 5 6 7 8 9 10 11 12 --- substitutions : device _ name : plug1 device _ description : Office Left Lamp friendly _ name : Plug 1 wattage _ calibration : "4054.3 - > 721 . 2 " #Tested using a meter and 722.0W toaster -0.8W from just this plug with toaster off amperage_calibration: " 7 . 4 - > 6 . 103 " #Tested using a meter and 6.122A toaster -0.019A from just this plug with toaster off voltage_calibration1: " 294 . 7 - > 117 . 8 " #Tested using a meter, value while connected toaster was on voltage_calibration2: " 321 . 7 - > 121 . 6" #value while connected toaster was off < < : !include awp04l.yaml

Modify the first few lights for the plug you want to build firmware for. I kept the calibration data the same as the sample code as I’m not too concerned with the accuracy of power measurements right now. If you are, you can later attach a known load to the plug and tweak these values to match what you expect.

The last line of the file includes the “common” YAML file. Here you can see I include awp04l.yaml which contains all the common esphome configuration for these plugs that I got from esphome-configs.io.

Building a Firmware Image

You’ve got esphome installed and your configuration files are written. Now it’s time to actually build the firmware image. This should be pretty straightforward. Just run:

esphome plug1.yaml compile 1 esphome plug1 .yaml compile

You should see esphome download some libraries and build the firmware according to the YAML configuration files. If everything worked, you should see a firmware.bin file in the plug1/.pioenvs/plug1 directory. That means the firmware compiled successfully and that’s what we’ll load on the smart plug.

Tuya-Convert

To actually run Tuya-Convert you need access to a Linux computer that as a WiFi adapter that can be put into access point mode. The easiest route is to just use a Raspberry Pi 3, which is what I’m doing today.

Get Raspberry Pi Ready

Download the latest Raspbian Lite image from the Raspberry Pi website. Raspbian Lite is a lightweight image for the Raspberry Pi that only has the barebones packages needed. I copied it over to a new SD card using dd. You can also use a GUI tool like etcher if you prefer a GUI or are on Windows.

# /dev/sdc is the SD card drive sudo dd bs=1M if=2019-09-26-raspbian-buster-lite.img of=/dev/sdc conv=fsync 1 2 # /dev/sdc is the SD card drive sudo dd bs = 1M if = 2019 - 09 - 26 - raspbian - buster - lite . img of =/ dev / sdc conv = fsync

After writing the image to the SD card. I like to enable SSH out of the box so I don’t need to plug the Raspberry Pi into a monitor. You can do this by creating a file named ssh or ssh.txt to the boot partition of the disk. The Raspberry Pi will see this file during the bootup process and will automatically enable an SSH server.

Once your Raspberry Pi boots up, log in using SSH or just by hooking it up to a monitor. On a fresh Raspberry Pi, I like to do a full package update. You should also run sudo raspi-config and go under “Advanced Configuration” and expand the filesystem to fit the whole SD card. Finally, you’ll need the git package to download the latest version of tuya-convert, so install that too.

# Update all the packages sudo apt-get update sudo apt-get dist-upgrade -y # Install git sudo apt-get install -y git # Expand filesystem under advanced configuration sudo raspi-config 1 2 3 4 5 6 7 8 9 # Update all the packages sudo apt - get update sudo apt - get dist - upgrade - y # Install git sudo apt - get install - y git # Expand filesystem under advanced configuration sudo raspi - config

Once that’s all done you’ll have a fresh Raspberry Pi set up and ready to start running Tuya-Convert.

Install Tuya-Convert

The Tuya-Convert project is hosted on GitHub and easily installed by cloning the repository. Just run the following command wherever you want to download Tuya-Convert.

git clone https://github.com/ct-Open-Source/tuya-convert.git 1 git clone https : // github .com / ct - Open - Source / tuya - convert .git

Now, we need to install the rest of the dependencies needed for Tuya-Convert. Luckily, the project comes with a convenient script to install all our dependencies. Go into the newly created tuya-convert directory and run the setup script.

cd tuya-convert ./install_prereq.sh 1 2 cd tuya - convert . / install_prereq .sh

Let it run for a bit, installing everything necessary to run the application. Eventually, you’ll see the following message meaning you’re good to go.

... Successfully built sslpsk Installing collected packages: sslpsk Successfully installed sslpsk-1.0.0 Ready to start upgrade 1 2 3 4 5 . . . Successfully built sslpsk Installing collected packages : sslpsk Successfully installed sslpsk - 1.0.0 Ready to start upgrade

Running Tuya-Convert

Now it’s time to start running Tuya-Convert and actually reflash your device! But first, we need to put the new firmware we want in the tuya-convert directory. Go back to the machine you compiled the esphome firmware on and copy it over to the Raspberry Pi with Tuya-Convert. You can use the scp command to copy the file over ssh. Or you can use a USB drive or something like that.

scp plug1/.pioenvs/plug1/firmware.bin pi@<ip_address_of_raspberry_pi>:~/tuya-convert/files 1 scp plug1 / . pioenvs / plug1 / firmware . bin pi @ < ip_address_of_raspberry_pi > : ~ / tuya - convert / files

Place the firmware file in the files directory within the tuya-convert installation. You should see some other firmware files already there that are provided by Tuya-Convert.

Now it’s really time to get started with flashing your device. Start by running ./start_flash . This kicks off the tool and first prints a warning message that this might render the device unusable.

====================================================== PLEASE READ THIS CAREFULLY! ====================================================== TUYA-CONVERT creates a fake update server environment for ESP8266/85 based tuya devices. It enables you to backup your devices firmware and upload an alternative one (e.g. ESPEasy, Tasmota, Espurna) without the need to open the device and solder a serial connection (OTA, Over-the-air). Please make sure that you understand the consequences of flashing an alternative firmware, since you might lose functionality! Flashing an alternative firmware can cause unexpected device behavior and/or render the device unusable. Be aware that you do use this software at YOUR OWN RISK! Please acknowledge that VTRUST and c't Magazine (or Heise Medien GmbH & Co. KG) CAN NOT be held accountable for ANY DAMAGE or LOSS OF FUNCTIONALITY by typing yes + Enter 1 2 3 4 5 6 7 ====================================================== PLEASE READ THIS CAREFULLY! ====================================================== TUYA-CONVERT creates a fake update server environment for ESP8266/85 based tuya devices. It enables you to backup your devices firmware and upload an alternative one (e.g. ESPEasy, Tasmota, Espurna) without the need to open the device and solder a serial connection (OTA, Over-the-air). Please make sure that you understand the consequences of flashing an alternative firmware, since you might lose functionality! Flashing an alternative firmware can cause unexpected device behavior and/or render the device unusable. Be aware that you do use this software at YOUR OWN RISK! Please acknowledge that VTRUST and c't Magazine (or Heise Medien GmbH & Co. KG) CAN NOT be held accountable for ANY DAMAGE or LOSS OF FUNCTIONALITY by typing yes + Enter

Type yes and press enter to continue. Depending on how you have your Raspberry Pi set up, it might detect that dnsmasq is running. If it is, no big deal just allow it to terminate dnsmasq by typing Y so it can continue.

Checking for network interface wlan0... Found. Checking UDP port 53... Occupied by dnsmasq with PID 7857. Port 53 is needed to resolve DNS queries Do you wish to terminate dnsmasq? [y/N] 1 2 3 4 Checking for network interface wlan0... Found. Checking UDP port 53... Occupied by dnsmasq with PID 7857. Port 53 is needed to resolve DNS queries Do you wish to terminate dnsmasq? [y/N]

You also might get a similar message about mosquitto. Type Y again to terminate the process.

Checking TCP port 1883... Occupied by mosquitto with PID 8297. Port 1883 is needed to run MQTT Do you wish to terminate mosquitto? [y/N] 1 2 3 Checking TCP port 1883... Occupied by mosquitto with PID 8297. Port 1883 is needed to run MQTT Do you wish to terminate mosquitto? [y/N]

Next, tuya-convert will start using port 8886. It should start up an access point called vtrust-flash . Connect to that network using your phone.

After your phone is connected, you need to put the plug into autoconfig/smartconfig/pairing mode. For the plug I’m using, you hold down the button for 6 seconds until the LED starts to blink fast. Once that happens go back to your terminal and press “enter”.

After a bit of output, it should back up the existing firmware from the device and prompt you to choose a new firmware.

................. SmartConfig complete. Resending SmartConfig Packets ....................................... IoT-device is online with ip 10.42.42.42 Fetching firmware backup % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1024k 100 1024k 0 0 30122 0 0:00:34 0:00:34 --:--:-- 28587 curl: Saved to filename 'firmware-8680d4.bin' ====================================================== Getting Info from IoT-device VTRUST-FLASH 1.5 (c) VTRUST GMBH https://www.vtrust.de/35c3/ READ FLASH: http://10.42.42.42/backup ChipID: 8680d4 MAC: EC:FA:BC:86:80:D4 BootVersion: 4 BootMode: normal FlashMode: 1M QIO @ 40MHz FlashChipId: 1440a1 FlashChipRealSize: 1024K Active Userspace: user2 0x81000 ====================================================== Ready to flash third party firmware! For your convenience, the following firmware images are already included in this repository: Tasmota v7.0.0.3 (wifiman) ESPurna 1.13.5 (base) You can also provide your own image by placing it in the /files directory Please ensure the firmware fits the device and includes the bootloader MAXIMUM SIZE IS 512KB Available options: 0) return to stock 1) flash espurna.bin 2) flash firmware.bin 3) flash tasmota.bin q) quit; do nothing Please select 0-3: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 ................. SmartConfig complete. Resending SmartConfig Packets ....................................... IoT-device is online with ip 10.42.42.42 Fetching firmware backup % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1024k 100 1024k 0 0 30122 0 0:00:34 0:00:34 --:--:-- 28587 curl: Saved to filename 'firmware-8680d4.bin' ====================================================== Getting Info from IoT-device VTRUST-FLASH 1.5 (c) VTRUST GMBH https://www.vtrust.de/35c3/ READ FLASH: http://10.42.42.42/backup ChipID: 8680d4 MAC: EC:FA:BC:86:80:D4 BootVersion: 4 BootMode: normal FlashMode: 1M QIO @ 40MHz FlashChipId: 1440a1 FlashChipRealSize: 1024K Active Userspace: user2 0x81000 ====================================================== Ready to flash third party firmware! For your convenience, the following firmware images are already included in this repository: Tasmota v7.0.0.3 (wifiman) ESPurna 1.13.5 (base) You can also provide your own image by placing it in the /files directory Please ensure the firmware fits the device and includes the bootloader MAXIMUM SIZE IS 512KB Available options: 0) return to stock 1) flash espurna.bin 2) flash firmware.bin 3) flash tasmota.bin q) quit; do nothing Please select 0-3:

Type the number next to the firmware you want to flash and press enter. In my case, you can see firmware.bin in the output above as option #2. Let tuya-convert flash the firmware. Once completed, you’ve got a cloud-free smart plug!

Home Assistant

Adding esphome devices to Home Assistant is done completely through the integration page through the UI.

Open up Home Assistant and choose “Configurations” on the left-hand side panel.

After that, choose “Integrations” and click the big “Plus Sign” button in the bottom right of the screen.

You’ll be greeted with a new screen to add an integration. Find “esphome” and type in the IP address of the device that was just flashed.

Click “Submit” and that should be it! The device is now added to your Home Assistant configuration. If you are using the configuration I used, there are light entities for the red and blue LEDs on the device. Sensor entities for power monitoring and a switch entity for toggling the plug itself.

If you are using the switch to control a lamp, consider using the Light Switch integration to tell Home Assistant that a light is controlled by the outlet. My plug is controlling a lamp to the left of my desk so I created a light entity out of it.

--- # Office lamp to the left of desk platform: switch name: Office Lamp left entity_id: switch.plug_1 1 2 3 4 5 6 --- # Office lamp to the left of desk platform : switch name : Office Lamp left entity _ id : switch.plug_1

Automations

There’s no limit to what automations you can write for your new plug. For mine, I’m going to use it to alert myself whenever my wife gets home. I’m often working in the office on the other side of the house so I toggle the light on and off 6 times as a visual indicator that my wife is home and I can go greet her and my son coming home from work. If I know she’s coming from the grocery store, I can start walking to the car to help her if I’m not in the middle of something.

To achieve this, I’ll be using AppDaemon to write my automation. You could complete something like this using the built-in Home Assistant method to write automations. Or you could use something like NodeRed if you’re more comfortable with that. For me, I’m already handy with Python and prefer to write my automations that way. If you’re interested in AppDaemon, check out my article on Create Telegram Bot for Home Assistant where I go over the basics of setting up AppDaemon.

Below is the little automation I wrote:

import appdaemon.plugins.hass.hassapi as hass class HomeNotification(hass.Hass): def initialize(self): self.garage_door = self.args["garage_door"] self.lights = self.args["lights"] self.listen_state(self.start_toggle, entity=self.garage_door, new="open") def start_toggle(self, entity, attribute, old, new, kwargs): self.flashcount = 0 self.run_in(self.flash, 1) def flash(self, kwargs): self.toggle(self.lights) self.flashcount += 1 if self.flashcount < 6: self.run_in(self.flash, 1) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import appdaemon . plugins . hass . hassapi as hass class HomeNotification ( hass . Hass ) : def initialize ( self ) : self . garage_door = self . args [ "garage_door" ] self . lights = self . args [ "lights" ] self . listen_state ( self . start_toggle , entity = self . garage_door , new = "open" ) def start_toggle ( self , entity , attribute , old , new , kwargs ) : self . flashcount = 0 self . run_in ( self . flash , 1 ) def flash ( self , kwargs ) : self . toggle ( self . lights ) self . flashcount += 1 if self . flashcount < 6 : self . run_in ( self . flash , 1 )

Hopefully, the code is pretty straightforward. It waits until my garage door opens, then starts toggling the lamp. Every second it toggles it again for 6 seconds. You’ll want to choose an even number for the number of toggles so the light ends up in the same state as you started.

Conclusion

I hope you enjoyed my walkthrough of using Tuya-Convert to free your smart plugs from the cloud. It’s a great tool to have to take full control of cheap smart plugs and run esphome or other firwmare on them.

If you liked this article, you might some of these other ones from my blog:

If you found this tutorial helpful, please consider supporting the blog by joining my mailing list, following the blog on social media or directly through Buy Me a Coffee. Thanks for reading!