Being a little obsessed with home automation, and a guy on a budget, is hard. Turns out smart switches, lights, etc. start to add up really fast and once you start it doesn’t seem like you ever have enough!

One of the first big problems I had when trying to automate my home was the desire to have smart multi-plug/power strip switches. In fact my very first project was a 16 port Raspberry Pi powered smart power strip for my aquaponics and fish systems. Back then, even a modest number of individually controlled smart plugs in a strip cost $60+ dollars each!

This lead to me basically building a bunch of my own smart multi-plug switches using ESP8266 boards flashed with my CoogleIOT (specifically my “coogle-switch” project), variously sized 10A relay modules, and some sort of AC-to-DC transformer circuit that would fit in a 3D printed case.

Today the landscape is pretty dramatically changed. Now you can buy 4-switch smart power strips for under $30 dollars if you hit a good sale. Recently I stumbled across this one in particular, which at the time was on an Amazon lightning sale for only $20 bucks (it’s $30 last time I checked regular price):

Here’s the problem — as more and more companies have come into the scene to make smart devices, more and more security issues have cropped up (even your dishwasher isn’t safe anymore). These devices want you to download some sketchy-looking app to your iPhone and give it your WiFi password… yeah, I love running bot nets too.

So what is a smart home enthusiast on a budget to do? Well as it turns out, a large number of these cheap smart devices are using really standard hardware inside of them (in this case an ESP8266 microprocessor to provide the brains and WiFi connectivity), so all we have to do is figure out a way to re-flash it with something more secure. In my case, I use CoogleIOT as the basis for all my firmwares (and even have a specific firmware to control smart switches), so I wanted to use that.

So how do we hack this smart switch to do our bidding? Well first we need to get one and take it apart. This particular device was an easy disassemble — just a few screws hidden behind the sticker, and a few more under the anti-skid pads. Once inside, we get to check out the guts:

Inside I found an ESP8266 chip (the blue board) soldered to another module that also provided a push-button switch, a few LEDs arranged in a ring, and some power regulation components. We know that the ESP8266 chip runs on 3.3V, and the voltage regulator on the board was an L1117 chip which only works with DC so we can safely assume the transformer that converts the 110V AC input when you plug it in is being converted to some sort of DC voltage before it gets to this control board. The board itself was only attached to the rest of the hardware by a simple 6-pin jumper plug as well. Th relay PCB board contained 4 relays and basically looked like it was the exact same circuitry as your standard 4 relay module board you can buy on e-bay:

Since I had a lot of experience building my own smart switches it was able to quickly draw a few educated guesses and conclusions:

The hardware was divided into two circuit boards. The thin long circuit board was basically exactly the same as a standard 4-relay module board, with an additional transformer circuit built in to convert the AC voltage from the outlet into what was (likely) 5V DC and also provide that AC voltage to the 4 individual power ports

This DC voltage was being fed to the second control board, which contained the brains of the operation. If the DC voltage was 5V coming in then I assumed the L1117 chip brought that down to the 3.3V necessary for the ESP8266 chip on the control board.

Since the connection between the two boards was 6 leads, and I knew typically each relay is going to need its own signal wire, I surmised that two of the leads must be 5V DC and the rest were 3.3V signal lines controlled by the ESP8266 to turn each relay on and off

These assumptions were pretty easy to verify with a voltmeter and a few jumper wires.

With the smart strip taken apart, plug it in the wall. (WARNING: this means you have potentially life-threatening voltage exposed as live leads and you CAN electrocute yourself if you touch them. We are not responsible if you hurt yourself and you must proceed at your own risk).

Using a voltmeter, I started poking around at the 6 contacts connecting the two control boards. Sure enough, I identified the first two leads as DC power (+5V), and the rest didn’t have anything going on.

Using a jumper wire, I took the DC power +5V and shorted it against one of the other four leads and the result was that one of the relays activated! I now was certain I was on the right track.

Okay, so now we can unplug the smart switch and deal strictly with the control board that has the ESP8266 on it. Based on my tests, I was pretty certain all the ESP8266 was doing was giving each relay it’s own GPIO pin and turning that pin HIGH when it needed to turn on the outlet in question. That means if I can figure out a way to re-flash the ESP8266 chip it should be relatively easy to make my firmware do the same thing!

But the question is, how do we reflash the firmware?

To answer that first we need to have a decent understanding of the minimum requirements needed when trying to flash an ESP8266. Now days, a lot of ESP8266 development boards out there have made life easy on us developers. NodeMCU boards for example provide built in serial / programming logic and on board voltage regulation. But we need to do without in this case, which means we should treat this particular flashing job just like if we were trying to flash an ESP8266-01 module.

This was one of the very first modules available to makers, and programming it wasn’t very straightforward. To do so you needed to do a few things:

Hook up the TX/RX serial leads to a serial port (FTDI Programmer)

Hook up 3.3V power, and short it across the CH_PD (enable chip) and RST leads (reset)

Short GPIO0 to ground when powering up the chip to enable programming mode

Since I like playing with these ESP8266-01 boards I had actually already CNC’d myself a Jig to program them. Basically it just allowed me to plug an ESP8266-01 into it, provided two buttons two reset/pull GPIO0 to ground for programming, and plug in a FTDI programmer board so I could communicate with it from my computer. Just for kicks, I added an LED to the GPIO2 pin as well so I could flash a simple test “blink” script to make sure everything was really working properly.

Note: My FTDI programmer allows me to choose between 3V and 5V when it comes to providing power. Make sure you use 3V — if you use 5V power with the circuit below you’re going to fry the ESP8266 chip!

Here’s what my schematic is for my programming jig. There are a few different variations of this available online, but this one worked for me just fine:

Okay, so now we have a schematic and a way to flash the chip, but how do we flash THIS chip that is sitting on a control board we know nothing about? Well, there are two options in this case. Let’s take a closer look at the board:

It is pretty obvious that the ESP8266 in this case is really just a version of some stand-alone module that just got plugged right into another PCB designed for it and soldered down. That’s great news, because maybe we can find the data sheet that describes how the pins of the surface-mounted ESP8266 chip map to the leads around the edge (more on that later). But more importantly for now, we are hoping that the five pins we need to flash the chip are available in the breakouts:

A Ground pin for the module

A VCC input (3.3V) for the module

GPIO0 so we can bring it to ground to enable programming

TX and RX pins so we can transmit the new firmware

Assuming these leads are available as part of the breakouts, we still need to physically connect them to our programming circuit. Here there are a few options:

Hope the designer of the circuit provided an easy way to program it (look for unsoldered header blocks, test pads, etc)

Create some sort of jig that we can place to connect the breakouts

Solder leads directly to the breakouts, and remove them later once we’re done

Of those options, two of them are probably in most cases more trouble than they are worth. Unless you plan on doing more than 5 or 10 of these, you’re really either going to have to solder leads directly or hope the designer provided a programming method (making a jig to do it less than 5 times is a waste of time IMHO)

Looking back at the control board, we’ve got something really promising on the edge:

Hmm, a 5 pin unsoldered connection — exactly the right number of pins we’d need to program it — and since it’s unsoldered we know it isn’t needed for the standard functions of the board and could be how the ESP was programmed after it was installed into the PCB! Too bad there aren’t any useful labels on the silkscreen (it’s always wonderful when you find the silkscreen labeled “TX” and “RX”), but it’s a start.

Okay, so let’s recap, what do we know and what don’t we know?

We know it’s an ESP8266 chip, and very likely some sort of mass-produced module that was just added to the circuit designed for it

We know it exposes a lot of leads of the chip as a breakout, and since it’s likely mass-produced it most certainly will include the 5 pins we need to program it (that’d be a stupid mass produced module if you couldn’t program it!)

We have a unsoldered 5 lead header on the control board

We don’t know how the pins of the ESP8266 chip itself map to the breakouts of the module

We don’t know if the 5 pins we need to program it map to the unsoldered header, or in what order

Time for a little investigation work! Since we believe this is just a mass-produced module, it’d be fantastic if we could find a datasheet for it that describes the pinouts and technical details. The first thing you should try is look for any model markings or indication on the chip itself (this one had none), but barring that, ESP8266-dedicated forums on Facebook or the ESP8266 community forum are great places to post pictures like this and get suggestions on the module. After a little digging, I found a candidate that looked like it could be the board I needed based on the form factor of the module – the WT8266-S1 WiFi Module.

Here’s the datasheet for it if you’d like to check it out yourself, but here’s the good bits we needed – the pinout.

Okay now we’re getting somewhere! We have a pinout, now we need to pull our voltmeter back out and see which if any of these pins are connected to the unsoldered header we found, and if so what we think they represent (if we assume this module is indeed a WT8266-S1). One by one I tested the resistance between each pin and the header, looking for readings that had little or no resistance to identify connections.

Counting on the header from right to left (rightmost being pin 1):

VCC IO0 GND TX RX

Wow, so either we are absolutely correct that this is an WT8266-S1 module and that this header is exactly the programming port we need, or that’s one heck of a coincidence! There’s really only one way to find out — time to solder header pins on and hook it up to my programming jig!

Now comes the exciting part — can we actually flash it? Time to wire it up to your programming circuit (or in my case, just stick jumper wires in the appropriate header pins of my ESP8266-01 programming jig I already had):

From here, we need to get on our computer and start trying to figure out if we can talk to the ESP8266. Because we need to treat this like an ESP8266-01, we’re going to need to make sure before we attempt any communication we first reset the device with GPIO0 pulled to ground. For my jig you can see I have two push buttons (one for GPIO0 to ground, one for reset) I can use.

Rather than trying to jump right to flashing a firmware, let’s see if we can probe out some basic information about the module first. If we can we know we’re on the right track, and it’ll also tell us some important details we are going to need to know anyway (like the size of the flash memory chip). For this, we’re going to use the Espressif Bootloader Utility, esptool.py to query the chip and see if we can get a response:

$ esptool.py --port /dev/cu.usbserial-A90JXYQ7 flash_id esptool.py v2.3.1 options { Connecting.... Detecting chip type... ESP8266 Chip is ESP8266EX Features: WiFi Uploading stub... Running stub... Stub running... Manufacturer: 0e Device: 4015 Detected flash size: 2MB Hard resetting via RTS pin...

Here I am using the esptool.py utility to get data about the flash chip. In this example /dev/cu.usbserial-A90JXYQ7 is the device my FTDI programmer comes in as on my Macbook, yours will be different depending on device and operating system.

The result: SUCCESS!

As we can see from the output (make sure you pull GPIO0 to ground right before running this command) we were able to successfully connect to the ESP8266 chip and detected the flash size as 2 Megabytes — plenty of space to run a CoogleIOT firmware!

All of this work, and we’re still not done though! We’ve determined we can communicate with the chip and flash new firmware — but now we need to figure out how to actually program the chip to control the various things we want to control. Remember:

We determined early on there are four signal wires connecting to four relays, so we are most likely looking for 4 GPIO pins to set HIGH on the ESP8266 to map to each of those relays to turn them on/off

The push button on the control board must map somehow to the ESP8266 as well as an input pin

The LED ring, based on the original instructions, is controlled by the ESP8266 somehow as well. The instructions state if you hold the button down for a few seconds the LEDs will pulse.

The WT8266-S1 module itself has a built in LED that must also map to a GPIO pin

My first attempts to figure out what pins controlled things proved frustrating. Trying to use a voltmeter to trace the connections wasn’t very successful and was very error-prone. I also wasn’t really interested in the push-button or LED ring controls (maybe later). So I personally decided the best thing to do was to just repeatedly flash the new firmware on to the chip, testing each GPIO pin one at a time to see if I could get the relays to turn on and off.

Lucky for you my dear reader, after trying all of the pins one by one in a very slow and annoying process I was able to determine exactly what pins controlled which relays and you can just skip to the good part:

GPIO 0 – This might be some sort of control for the LED ring, it was the only pin that affected it at all in my tests

GPIO 1 – Nothing / Could be the Push button Input

GPIO 2 – Nothing / Could be the Push button Input

GPIO 3 – Nothing / Could be the Push button Input

GPIO 4 – Controls the on board LED of the ESP module

GPIO 5 – Switch 4

GPIO 12 – Switch 1

GPIO 13 – Nothing / Could be the Push button Input

GPIO 14 – Switch 2

GPIO 15 – Switch 3

So my CoogleIOT powered firmware can be configured to control 4 switches, using GPIOs 12, 14, 15, and 5. This is done in the coogle-switch code base by editing config.h as follows:

#ifndef COOGLESWITCH_H #define COOGLESWITCH_H #define NUM_SWITCHES 4 #define TOPIC_ID "test-power" #define SWITCH_BASE_TOPIC "" // List of pins, in order, that we will be switching on/off static int switches[NUM_SWITCHES] = { 12, 14, 15, 5 }; #endif

With this new firmware flashed using the same method you’d flash any firmware (Arduino IDE, Eclipse Sloeber, INO, whatever), we should be all set! My firmware using MQTT for communication and this particular code base maps an MQTT topic to a specific pin to turn on and off. So when I publish a ‘1’ to (in this case) the ‘/test-power/switch/1’ topic, it should set GPIO12 to HIGH and turn on my relay — and it did (as did the other relays).

We’re done, since CoogleIOT has built in over-the-air firmware updating we can disconnect our control board, reinstall it in the case and screw everything back together — if we want to do any updates in the future we can just upload a new firmware.

Awesome! We have successfully hacked our cheap WiFI/ESP8266 smart switch and turned it into a high quality and secure smart switch! From here the sky’s the limit. Since I already did all of the hard work for you, you will be able to save yourself a ton of time and just solder a header on and get flashing — but hopefully you enjoyed reading about how to figure out how to do it as well.

In fact, if you are feeling hacky, I’d love someone to do the legwork on figuring out how to control the LED ring and which GPIO pin accepts the push button signal. If you figure it out, share with your fellow makers in the comments!