The plug's main purpose is to detect when it gets plugged into a power socket, and notify a remote server about that. After that it waits until it gets unplugged again from the power socket, and once again notifies a remote server about that.

Now, detecting if the plug is plugged in is fairly simple - if it has power, it's plugged in. But once you unplug it, it wouldn't have power anymore. It's just off and couldn't inform anyone about it. So what to do? Let the remote server poll the plug periodically to see if it's still up and running? Send heartbeats to the remote server to do the same? That just seems inefficient. The plug may be useless, but at least I'd want it to be efficiently useless.

So instead, I made sure that once its main power source is removed, the plug remains powered on long enough to send one last message to the server. I've been already looking for ideas to make use of LiPo batteries, so this should be it. The main power supply (a 5V switching power supply connected straight to the mains power) is powering the LiPo charging circuit, which in turn charges the battery and provides the supply voltage to the rest of the hardware. A 3.3V DC-DC regulator makes sure the supply voltage for the ESP8266 is constant and in valid range.

The main power supply voltage is additionally used as detection signal and connected to one of the ESP8266 GPIO pins. When the main power goes off, the battery will take over and the ESP's GPIO interrupt handler will trigger and tell the server again about the new status.

Once the ESP is done notifying the server, the whole system can shut down. However, this actually means, the battery must be disconnected from the system. I was able to achieve this using a p-channel MOSFET as high side switch. NPN transistors will make sure the MOSFET is switching through on power up, and another ESP8266 GPIO pin will keep it switched until the pin state changes and ultimately cuts its own power.

Further details are in this blog article and the Github hardware README.

Firmware

The firmware is rather simple and is written in C with the ESP8266 non-OS SDK. Besides setting up WiFi and the GPIO pins, it sends the plug status to a remote server and kills itself. The remote server being either ThingSpeak's Twitter API or a homebrew Python script running an HTTP server, this can be configured during compile time.

Okay, there is a bit more to the story, but it's mainly failsafe handling and signal debouncing, but just look at the source (or the Github firmware README, or the blog article).

Backend server

Well, more a little Python script than really a backend system. While ThingSpeak would suffice for tweeting, I still wanted to have some extra functionality, and have the full control over it.

So the script runs a simple web server to receive POST requests of plug states, a WebSocket server to pass it on to further clients, and optionally tweets about it. Once again, there's details on Github and more.

Android companion app

And finally, an Android app can receive the WebSocket data and lets you know about the plug state. Real-time as you sit there, plugging in the plug. What a time to be alive!

Videos