How To Guides

How to install ESPHome or Tasmota on a cheap smart wifi RGB bulb

How to install ESPHome on cheap wifi smart RGB bulbs

Recently I started looking at alternative ways to achieve Philips Hue lighting, without spending the money that Philips Hue commands. Don’t get me wrong, Philips Hue is a great product and works very well, just that it is a very expensive ecosystem to join.

After a little digging, I found that there are literally thousands of bulbs on Amazon. So where to start?

Luckily, the vast majority of these bulbs come from a single vendor, Tuya, and are then rebranded. This means that they are all pretty much identical under the hood.

Inside of these bulbs is the ever popular esp8266, which, as you guessed, means we can modify it to suit our needs. I’m going to show you how to install ESPHome on your smart bulb here, but the process should be the same for Tasmota or other variations.

Let’s get into it!

Tuya-Convert vs ESPTool/Soldering

Right off the bat, there are 2 ways to install ESPHome or Tasmota on your smart bulb.

The first method is tuya-convert which provides a “solderless” and much easier method of flashing these and can be done with a laptop and a smart phone. This is by far the easier method. Unfortunately Tuya started rolling out patches for this sometime at the start of the year which prevents tuya-convert from working. Some bulbs are on this new firmware out of the box, some are not. My recommendation is to try tuya-convert first – and whatever you do, do not connect your light to the Smart Life app, this will automatically flash the bulb and Tuya-Convert will no longer be an option.

I’d definitely recommend trying Tuya-Convert first, please see my other guide here. 

Parts list:

This guide assumes you have experience soldering and have access to soldering equipment. If you do not, please try the tuya-convert method mentioned above. If I can obtain a compatible device, I will write a guide using that method in the future.


Bulb preparation:

First thing to do is pull the plastic globe/dome from the top of the bulb, the easiest way I found was to twist first to loosen the tiny amount of glue that has been applied, then mine just pulled straight upwards with very little effort. 

Light Bulb with dome removed
Smart bulb with dome removed with little effort.

Now we have direct access to the PCB. If we look closely at the chip, we can confirm that the chip we are working with is indeed an esp8266:

We can then start identifying where we need to solder our wires. You need to identify the following points on the board:

  • 3.3v
  • Ground
  • IO0
  • TX
  • RX

I’ve marked these on my bulb, these may be the same location on yours or slightly different. They should have markings on the PCB which identify these points:

Go ahead and carefully solder these connections, they are quite small and may require a bit of patience.

Once you have your connections, go ahead and wire them up as follows:

ESP Light BulbUSB to Serial Adapter

One very important final step here, make sure you have the jumper on your USB to serial adapter set to 3.3v and NOT 5v – I haven’t tried 5v but I assume it would damage your bulb.

Connecting and reading stock firmware

Before continuing, you read the paragraph above right? Please make sure you have your USB to serial adapter set to 3.3v.

Also take this final opportunity to check you have everything wired correctly as above.

Now proceed to plug your USB adapter into your laptop. It should pick up that you have plugged something in. 

You will need to have python 2.7 installed, as well as PIP. I won’t go over that here, but there is a nice guide here:

  • Windows
  • Linux – much easier here, just search your distro and python 2.7 install and follow the guide. Takes 2 minutes max.

Once you have python installed, run the following command in command prompt or terminal to install esptool:

pip install esptool

Typing “esptool” on its on should confirm it is installed.

We then need to check our which COM port we are using.

To do this on Windows, right click the start menu and choose device manager. It should bring up the device manager window. Scroll down to the “Ports (COM & LPT)” section and expand. Find the entry that has “USB-to-Serial” in the name, it should have a COM Port in brackets at the end. The screenshot below shows that mine is COM4.

Linux users, again depends on the distro but you should be able to type the following command, you can see that mine is ttyUSB0:

dmesg | grep tty

With that out the way, we go back to our esptool terminal. The following command instructs esptool to read the flash memory of our bulb and store it so that we have a backup of our original firmware which can be kept if you want to go back to the original firmware.

To do so, run the following in command prompt/terminal:

esptool --port YOUR_COM_PORT --baud 115200 read_flash 0x00000 0x400000 backup.img

esptool --port /dev/YOUR_COM_PORT --baud 115200 read_flash 0x00000 0x400000 backup.img

Ensuring to replace “YOUR_COM_PORT” with your COM port as we noted above. So for me it would be “COM4” for Windows or “/dev/ttyUSB0” for Linux.

This can take a few minutes to complete so sit tight. Once complete you should have a full firmware backup file, keep this safe if you want to use it again in the future.

Creating an ESPHome firmware

You’ll be glad to know we should be on the home stretch, if you’ve made it this far then the hard work is done.

I’m going to be using esphome in this example, as I like the integration with Home-Assistant. Let me know if you want to see a Tasmota example.

Back in your terminal, we need to install esphome to create a firmware for our smart bulb. This is done simply with pip again:

pip install esphome

Then we run the esphome wizard to create a new project:

esphome livingroom_lamp.yaml wizard

This will run the wizard which will create a basic configuration for you. Follow the steps through and answer each question, make sure to choose esp8266 as the platform and esp01_1m as your board. Also make sure and set your wifi correctly, as well as the password you want to use for OTA updates.

OTA updates stands for “Over the air” updates which allows you to remotely flash your device without having to go through this whole procedure everytime, no solder required, just a single laptop!

You will now have a file with whatever name you chose above, “livingroom_lamp.yaml” in my case. Open this in your favourite editor, it should look something like this:

  name: livingroom_lamp
  platform: ESP8266
  board: esp01_1m

  ssid: "Your Wifi SSID Here"
  password: "Your Wifi Password Here"

# Enable logging

# Enable Home Assistant API
  password: "Your OTA Password Here"

  password: "Your OTA Password Here"

Be aware when it comes to yaml files that spacing and indentation is import, similar to Python if you are familiar with that.

All we need to do is to add a “light” section and an “output” section. Copy and paste the following to the end of the file:

  - platform: rgbw
    name: livingroom_lamp
    red: output_red
    green: output_green
    blue: output_blue
    white: output_white
    restore_mode: ALWAYS_ON

  - platform: esp8266_pwm
    id: output_red
    pin: GPIO14
  - platform: esp8266_pwm
    id: output_green
    pin: GPIO12
  - platform: esp8266_pwm
    id: output_blue
    pin: GPIO13
  - platform: esp8266_pwm
    id: output_white
    pin: GPIO4

I would also personally modify the wifi section so that you can set a static IP. This is optional, I just think it makes the OTA updates be more predictable. If you want to do that, you can modify the wifi section as follows:

  ssid: "Your Wifi SSID Here"
  password: "Your Wifi Password Here"

Be sure to change the values for your network, if you don’t know these then I would skip this step.


Finally its time to upload our work!

Back in your command line window, making sure you are in the same directory as the YAML file you just created, now issue the following command:

esphome livingroom_lamp.yaml run

ESPHome will now compile the YAML file into a firmware (.bin) file that we can upload and install to our smart bulb. This can take several minutes so wait for this to complete. Once this happens, the command will give you an option:

We choose option number 1, to upload via the serial COM port.

At this point, we just need to wait for the file to upload and we are done!

Once the program confirms the upload was successful, you can now give it a test!

Home Assistant should automatically discover the new light and you should be up and running in seconds. You should then see something similar to this in Home Assistant:

And that’s it! Please leave any comments or feedback down below, as well as anything you want to see in the future!

Want to support me?

If you like the content I put out and would like to support me, you can do so using the options below.

I can't state enough how much any support is greatly appreciated and will go directly back into funding new/bigger projects and website upkeep.

Tagged , , ,
  1. Andi

    Hi Lewis,

    Interesting post, thanks for sharing your idea.

    I’ve got problems installing and addressing esphome on my linux mint machine. First,
    pip install esphome
    constantly brings error message

    [email protected]:~$ pip install esphome
    Traceback (most recent call last):
    File “/usr/bin/pip”, line 9, in
    from pip import main
    ImportError: cannot import name main

    I found that calling installer directly with python with
    python3 -m pip install esphome
    resolves this.

    [email protected]:~$ python3 -m pip install esphome
    Collecting esphome
    Using cached https://files.pythonhosted.org/packages/09/c3/f045334521680d75d3571b2cbeff2f8c5c7316bc431b939ef61c1eeedce3/esphome-1.14.2-py2.py3-none-any.whl
    Collecting platformio==4.0.3 (from esphome)
    Collecting colorlog==4.0.2 (from esphome)
    Using cached https://files.pythonhosted.org/packages/68/4d/892728b0c14547224f0ac40884e722a3d00cb54e7a146aea0b3186806c9e/colorlog-4.0.2-py2.py3-none-any.whl
    Collecting protobuf==3.10.0 (from esphome)
    Using cached https://files.pythonhosted.org/packages/a8/52/d8d2dbff74b8bf517c42db8d44c3f9ef6555e6f5d6caddfa3f207b9143df/protobuf-3.10.0-cp36-cp36m-manylinux1_x86_64.whl
    Collecting pytz==2019.3 (from esphome)
    Using cached https://files.pythonhosted.org/packages/e7/f9/f0b53f88060247251bf481fa6ea62cd0d25bf1b11a87888e53ce5b7c8ad2/pytz-2019.3-py2.py3-none-any.whl
    Collecting paho-mqtt==1.4.0 (from esphome)
    Collecting esptool==2.7 (from esphome)
    Collecting tzlocal==2.0.0 (from esphome)
    Using cached https://files.pythonhosted.org/packages/ef/99/53bd1ac9349262f59c1c421d8fcc2559ae8a5eeffed9202684756b648d33/tzlocal-2.0.0-py2.py3-none-any.whl
    Collecting ifaddr==0.1.6 (from esphome)
    Collecting voluptuous==0.11.7 (from esphome)
    Collecting pyserial==3.4 (from esphome)
    Using cached https://files.pythonhosted.org/packages/0d/e4/2a744dd9e3be04a0c0907414e2a01a7c88bb3915cbe3c8cc06e209f59c30/pyserial-3.4-py2.py3-none-any.whl
    Collecting PyYAML==5.1.2 (from esphome)
    Collecting tornado==5.1.1 (from esphome)
    Collecting colorama (from platformio==4.0.3->esphome)
    Using cached https://files.pythonhosted.org/packages/4f/a6/728666f39bfff1719fc94c481890b2106837da9318031f71a8424b662e12/colorama-0.4.1-py2.py3-none-any.whl
    Collecting bottleesphome)
    Using cached https://files.pythonhosted.org/packages/69/d1/efdd0a5584169cdf791d726264089ce5d96846a8978c44ac6e13ae234327/bottle-0.12.17-py3-none-any.whl
    Collecting requests=2.4.0 (from platformio==4.0.3->esphome)
    Using cached https://files.pythonhosted.org/packages/51/bd/23c926cd341ea6b7dd0b2a00aba99ae0f828be89d72b2190f27c11d4b7fb/requests-2.22.0-py2.py3-none-any.whl
    Collecting click=5 (from platformio==4.0.3->esphome)
    Using cached https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl
    Collecting semantic-version=2.8.1 (from platformio==4.0.3->esphome)
    Using cached https://files.pythonhosted.org/packages/0f/3b/8fee26649a86c71df159ed0ae7ac5f9ac38829bccd8a7404e116f903929b/semantic_version-2.8.2-py2.py3-none-any.whl
    Collecting tabulate=0.8.3 (from platformio==4.0.3->esphome)
    Collecting setuptools (from protobuf==3.10.0->esphome)
    Using cached https://files.pythonhosted.org/packages/d9/de/554b6310ac87c5b921bc45634b07b11394fe63bc4cb5176f5240addf18ab/setuptools-41.6.0-py2.py3-none-any.whl
    Collecting six>=1.9 (from protobuf==3.10.0->esphome)
    Using cached https://files.pythonhosted.org/packages/65/26/32b8464df2a97e6dd1b656ed26b2c194606c16fe163c695a992b36c11cdf/six-1.13.0-py2.py3-none-any.whl
    Collecting ecdsa (from esptool==2.7->esphome)
    Using cached https://files.pythonhosted.org/packages/a2/25/3bb32da623b39a27a07d194cd58e4540224421d924661de2e694304ae4fa/ecdsa-0.14.1-py2.py3-none-any.whl
    Collecting pyaes (from esptool==2.7->esphome)
    Collecting certifi>=2017.4.17 (from requests=2.4.0->platformio==4.0.3->esphome)
    Using cached https://files.pythonhosted.org/packages/18/b0/8146a4f8dd402f60744fa380bc73ca47303cccf8b9190fd16a827281eac2/certifi-2019.9.11-py2.py3-none-any.whl
    Collecting chardet=3.0.2 (from requests=2.4.0->platformio==4.0.3->esphome)
    Using cached https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl
    Collecting idna=2.5 (from requests=2.4.0->platformio==4.0.3->esphome)
    Using cached https://files.pythonhosted.org/packages/14/2c/cd551d81dbe15200be1cf41cd03869a46fe7226e7450af7a6545bfc474c9/idna-2.8-py2.py3-none-any.whl
    Collecting urllib3!=1.25.0,!=1.25.1,=1.21.1 (from requests=2.4.0->platformio==4.0.3->esphome)
    Using cached https://files.pythonhosted.org/packages/e0/da/55f51ea951e1b7c63a579c09dd7db825bb730ec1fe9c0180fc77bfb31448/urllib3-1.25.6-py2.py3-none-any.whl
    Installing collected packages: colorama, bottle, pyserial, certifi, chardet, idna, urllib3, requests, click, semantic-version, tabulate, platformio, colorlog, setuptools, six, protobuf, pytz, paho-mqtt, ecdsa, pyaes, esptool, tzlocal, ifaddr, voluptuous, PyYAML, tornado, esphome
    Successfully installed PyYAML-5.1.2 bottle-0.12.17 certifi-2019.9.11 chardet-3.0.4 click-7.0 colorama-0.4.1 colorlog-4.0.2 ecdsa-0.14.1 esphome-1.14.2 esptool-2.7 idna-2.8 ifaddr-0.1.6 paho-mqtt-1.4.0 platformio-4.0.3 protobuf-3.10.0 pyaes-1.6.1 pyserial-3.4 pytz-2019.3 requests-2.22.0 semantic-version-2.8.2 setuptools-41.6.0 six-1.13.0 tabulate-0.8.5 tornado-5.1.1 tzlocal-2.0.0 urllib3-1.25.6 voluptuous-0.11.7

    Adressing esphome in command line then always says “esphome: command not found”. I’ve tried the following but remain stuck @@

    [email protected]:~$ esphome
    esphome: Befehl nicht gefunden.

    [email protected]:~$ esphome.py -h
    esphome.py: Befehl nicht gefunden.

    Do you have a hint about how to proceed?

    1. Lewis Barclay

      Hey Andi,

      If you check the bin folder, which commands do you have? It could be that mint installs it a different location.

      ls -la /bin/esp*

      Should hopefully list esphome somewhere.

  2. Andi

    Hey Lewis,

    Thx for swift reply. Unfortunately, nothing.

    in folder /bin/ , wildcard search esp* results in nothing found. Doing the same in /usr/bin/ finds esptool and some others giving more infos about symbolic links. This might be related to Linux Mint, is probably the same for Ubuntu.

    But here is nothing about esphome.

    [email protected]:~$ ls -la /usr/bin/esp*
    lrwxrwxrwx 1 root root 28 Nov 6 2017 /usr/bin/espefuse -> ../share/esptool/espefuse.py
    lrwxrwxrwx 1 root root 29 Nov 6 2017 /usr/bin/espsecure -> ../share/esptool/espsecure.py
    lrwxrwxrwx 1 root root 27 Nov 6 2017 /usr/bin/esptool -> ../share/esptool/esptool.py

    I ran a full search on filesystem for esphome and nothing. Bruh, installation showed all successfully installed???

  3. Andi

    used command python3 -m pip show esphome and it gives the following

    Name: esphome
    Version: 1.14.2
    Summary: Make creating custom firmwares for ESP32/ESP8266 super easy.
    Home-page: https://github.com/esphome/esphome
    Author: ESPHome
    Author-email: [email protected]
    License: MIT
    Location: /home/andi/.local/lib/python3.6/site-packages
    Requires: tzlocal, pytz, PyYAML, protobuf, esptool, tornado, colorlog, ifaddr, platformio, voluptuous, pyserial, paho-mqtt

    That’s nonsense, i don’t want to make the ‘home stretch’ the most time consuming and complicated part of it all. I believe many of the esphome users have instaled esphome as hass.io add on and probably don’t want to install esphome apart of their this. It should be possible to plugin in the uart converter directly to RasPi with hass.io installed, choose the COM port on the upper right part of esphome, as dyou describe choose esp8266 as the platform and esp01_1m as board and just complie / upload a very basic code permitting later WiFi and OTA access. i tend to believe this is a easier approch and will follow up as soon as i tried

    1. Lewis Barclay

      Hey Andi,

      What version of Mint are you using? I could try to install to see if I can replicate. I agree you shouldn’t be having anything like the issues you are, everytime I’ve installed its as simple as “pip install esphome” so I can see your frustration!

      Let me know how you get on anyways!

  4. Andi

    Hey Lewis,

    Cool, yes. Please go ahaed with the lates Linux Mint 19.2 Tina, Cinnamon DE, 64bit version. In the mean time I’ll try to setup some things in esphome on hass.io and extract a binary firmware this way.

    All the best, Andi

    1. Lewis Barclay

      Hey Andi,

      So I installed Mint 19.2 and did the following:
      apt update
      apt install python-pip
      pip install esphome

      That gave me the error:
      pip install esphome
      Collecting esphome
      Downloading https://files.pythonhosted.org/packages/09/c3/f045334521680d75d3571b2cbeff2f8c5c7316bc431b939ef61c1eeedce3/esphome-1.14.2-py2.py3-none-any.whl (1.4MB)
      100% |████████████████████████████████| 1.4MB 417kB/s
      Collecting paho-mqtt==1.4.0 (from esphome)
      Downloading https://files.pythonhosted.org/packages/25/63/db25e62979c2a716a74950c9ed658dce431b5cb01fde29eb6cba9489a904/paho-mqtt-1.4.0.tar.gz (88kB)
      100% |████████████████████████████████| 92kB 5.2MB/s
      Complete output from command python setup.py egg_info:
      Traceback (most recent call last):
      File "", line 1, in
      ImportError: No module named setuptools

      I realised mint uses python2 as its default at the moment, check your version by doing:
      python --version

      So I installed python3 with:
      apt install python3 python3-pip

      But still got the same error, this is corrected by running:
      apt install python3-setuptools

      And hopefully now you can run:
      pip3 install esphome

      Which completed successfully and then I was able to use the esphome command with no issues.

  5. Andi

    OK Lewis, new proposal for tying up the horese from the other side 🙂

    – First going to esphome in hass.io adding a new device. Important: the device doesn’t phisically exist or at least isn’t powered up yet.
    – The wizzard will ask you a lot of things. Care about a sensefull name and don’t bother about the other points, just confirm defaults as suggested.
    – Once the [name].yaml file is created, copy the code you’ve posted above and paste in the yaml file.
    – Adapt the code to your environment (wifi, ota password etc.).
    – *** only for esphome in hass.io ! *** in the yaml card, on top right position, click in the 3 points and chose “Complie”. Once finished, click in “DOWNLOAD BINARY” and tadahh, firmware is at your disposal.
    – grab the soldering iron, connect to the usb/uart converter as per descrition above, upload firmawre and restart tuya lamp.
    – double check if you see it comming online in esphome. If not, verify the yaml file if it covers everything that’s needed (wifi and ota password ok?), re compile, doewnload from esphome, upload to lamp until you see the lamp online in esphome.
    – finalize the integratiuon in home assitant and your done 🙂

  6. Thomas

    Lewis, thank you so much for this amazing tutorial. And Andi, thank you for simplifying the creation of the .bin files! You two made quite the impact here. Your work is greatly appreciated!

  7. John Horvath


    I am having a similar problem getting started with the esphome part of this tutorial. I am running Ubuntu 18.04.3 LTS (32 bit) with python 3.6.9 and have the exact same issue, that is, the installation of esphome appears to go smoothly (using pip3 install esphome) and all the files exist in ~/.local/lib/python3.6/site-packages/esphome with the exception of esphome. I searched everywhere (including /bin and /usr/bin) but it simply doesn’t exist. I don’t use hassio so the solution that was provided doesn’t apply in my case. Is there any other way to solve this problem?

    Thanks in advance for any help you can provide.

  8. James


    Great post and I got it programed fairly easily. Soldering on the time pins was tricky. It def works in that I can see and interact with it in HA, but the LDS don’t turn on. I may have damaged something when soldering, but in essence worked !!

    If I could give some advice, remove the HA setup and just link to it. It make the article bigger than it needs to be and puts you on the hook for install issues etc.


    1. Lewis Barclay

      Hey James,

      Thanks for the feedback, appreciate it! Yes they are very tricky to solder, depends on the brand of which one you get, they do seem to vary!

      Glad you managed to follow along, thanks again!


  9. James Macdonald


    Figured out why I could flash and talk to bulb but would not light up. Seems that some, that looks exactly the same, use the SPI interface, rather the direct gpio pins.

    I’ve included my working esphome code below.

    data_pin: GPIO13
    clock_pin: GPIO15
    num_channels: 4
    num_chips: 1

    – platform: my9231
    id: output_blue
    channel: 1
    – platform: my9231
    id: output_red
    channel: 3
    – platform: my9231
    id: output_green
    channel: 2
    – platform: my9231
    id: output_white
    channel: 0

    – platform: rgbw
    name: “wifi_light”
    default_transition_length: 0s
    red: output_red
    green: output_green
    blue: output_blue
    white: output_white

Leave a Reply

Your email address will not be published. Required fields are marked *