IoT Everywhere

Everything, and I mean everything is “smart” these days. Everyone has heard of the Internet of Things, and we are living through the emergence of some incredibly revolutionary connectivity. Some pretty cool and useful concepts have come out of it, admittedly, but there’s also some drawbacks.

I really enjoy the idea of having smart outlets that I can command with my voice, and there are outlets-a-plenty on Amazon, but can I trust them? I’ve decided to use my engineering skills to put a one of these outlets to the test.

Project Plan

Test Subject

I purchased a pack of Etekcity Smart Plugs which claim to be Alexa-enabled, and feature energy monitoring.

Test Plan

I want to test many aspects about the smart plug, so I laid out a test plan of tests I want to run.

  • Record the network traffic coming and going from the device (couldn’t complete, see below)
  • Pop open the device, see what hardware is under the hood
  • Write some custom firmware for the device

Project Execution

Preparation

These devices generally work in the following way:

  1. Connect to the device while it’s acting as an Access Point (AP)
  2. Configure the device via a proprietary app
  3. Device transitions from AP to Station Mode and connects to your local network
  4. User connects Alexa/Google/etc services to device

When I started to look at the app for these devices, I decided against installing and using it per the user documentation. Here’s why.

The app for setting up the plug required the following permissions:

  • Camera
  • Contacts
  • Location
  • Call logs
  • Phone
  • Storage
  • way, way more.

See the screenshot below for the full list.

So right off the bat, I decided to not install this app, simply because it had way, way too many permission oddities.

Opening the Device Up

I unpackaged these units and immediately noticed that there’s nary a screw anywhere. Upon closer inspection, you could see a thin line where the unit was clamshelled together. I grabbed my tools (a skinny flat-head screwdriver and a 3D printer sharpened spatula) and started poking for the release tabs.

After prodding the device for a few moments, I heard the distinctive “pop” of a plastic catch tab unclasping. I was able to raise up the edge of the clamshell and began working my way around the unit. Within seconds, the unit was open and the guts were exposed.

Inside face/inside of front of unit

Jackpot!

The first thing I noticed was that the WiFi module is labeled as an ESP01! Very fortuitous for me since there is so much open source goodness out there the ESP8266 and ESP8285. Next up is figuring out how to flash this device. Others I’ve looked at hid the traces for the TX, RX, and GPIO0 on the backside, so after the module was soldered on, it was pretty much inaccessible. Not so, with this guy! There were test points on the PCB, perfectly labeled for everything I needed: TX, RX, GPIO0, 5V and GND.

Inside of unit / PCB View

I tacked on some temporary wires as shown in the photo and connected to my laptop via a USB-TTL Serial cable. My cable is a 3.3V logic cable with 5V on the VCC wire, so I powered the chip from my cable as well.

I opened picocom and set the baud rate to 115200, and voila! I had terminal output. Regrettably, I didn’t capture the terminal output, but it mentioned some version numbers, the ESP SDK version, and had the classic boot up text from the ESP01.

On the less fortuitous side, I couldn’t see any other chips (like the one used for energy monitoring), so I suppose they are on the opposite side of the PCB, which is molded into the shell.

Flashing the Device

I had all the right inputs, but would it flash? The answer was yes! I fired up the Arduino IDE and wrote a simple Hello, World app, and performed the flashing procedure: pull GPIO0 low, apply power, let GPIO0 float, begin flashing.

Without any fuss and to my surprise, the unit flashed without delay. I now had a working smart plug unit that I could flash very easily! I wrote up some custom firmware that allowed over-the-air (OTA) updates and removed my temp wires.

Removed temporary wires, ready for reassembly

Custom Firmware

After a few iterations of writing “probing” apps and loading it onto the device, I figured out that the pinout from the ESP01 was the following (irrelavent pins ignored):

Pin #Function
0Flash
4Relay (Active High)
5Blue LED (Active High)
12Pulsed Energy Monitor (Voltage)
13Pulsed Energy Monitor (Power or Current??)
14Front Panel Switch (High => Switch Pushed)
16Amber LED (Active High)

Of these pins, I knew how to use most right away. It was those energy monitoring pins I couldn’t figure out. Since I didn’t know how to understand the output, and I didn’t know what IC was generating the output, I couldn’t really make use of it. I noted a few characteristics about the signals however:

  1. The signal on P12 stayed constant in time. I measured the low and high pulse duration, and they were the same (within 1 uS).
  2. The signal on P13 was constant low when the relay was inactive, and toggled when there was a device connected and the relay was active.

From these observations, I made the assumption that P12 was the voltage pin, and P13 must be current or power. I also made the assumption that the signal must be a 50% DC signal which varies in frequency only. Using a pin change interrupt I was able to verify this assumption.

Now that I understood the signal profile, I needed to understand how to convert it to something usable. I had to do a lot of Googling around, but I stumbled upon a forum which showed many of these cheap WiFi outlets use a Chinese chip HLW8012. There’s only a Chinese language datasheet available for the HLW8012 on the web, but again, a little Googling revealed this guy’s website which is in English! He had a ton of useful information on his website, and it corroborated the signals I was observing, so I again made the assumption that this is the right chip.

Using the formulas outline on the last website I found, I was able to turn the P12 signal pulse width into a voltage, and verify that it was pretty darn close using my Kill-a-Watt. ( I highly recommend these little devices, they are super useful if you like to tinker). I got values that were ± 0.75% and so I concluded this was the right chip. Next was determining if the P13 pulse was a power or current. Since it stopped with the opening of the relay and started with the closing of the relay, it could have been both. From the previous website, the poster noted that the HL8012 chip had two outputs, CF and CF1. One of the inputs (SEL) made one output switch between voltage and current, and the other was always power. There was my answer! If the output on P12 was constant regardless of load, and I’d been able to get a voltage from the readings which was fairly accurate, then the other has to be power. Converting the P13 pulse to power also jived with my Kill-a-Watt’s readings (although with a little worse accuracy, it is ± 3% by my best estimation).

First Release

When I had identified how to operate all the parts of this little device, I set about writing a firmware load which enabled all the uses I desired. I ended up with the following feature-set in my first release:

  • Alexa integration via Phillips Hue emulation
  • Over-the-Air updates for touch-free updating
  • Web Interface
    • Device Control
    • Device debug information
    • Device Energy Monitoring graphs
  • LED indication for device state
  • Button interface for manual on/off
ESP Smart Switch Web Interface

Wrapping Up

I only accomplished 2 of my 3 stated goals, but I did have a ton of fun doing it! At the end of the day, I’ve got two functional smart outlets with energy monitoring which have custom firmware. By virtue of using custom firmware, I can control what is needed to control the device as well, so no shady apps with too many permissions. I liked these so much, and they were so easy to customize, I have decided to ordered 4 more for around the house!