Controlling radio switches with a Raspberry Pi

November 23, 2019


During the Holiday season of 2018, I thought it would be really cool to control Christmas lights remotely from a phone or website. In fact, we already had our Christmas tree lights hooked up to a radio controlled switch with a remote. It seemed trivial to instead have a Raspberry Pi send radio signals to the switches rather than a remote. All I needed to know was what frequency and signal to send.


First, I started just like I start all other projects: with lots of research. First, I wanted to know what frequency the switches listened to. A quick look at the product page for the switches shows us this information:


Etekcity ZAP Remote Outlet Switches
Voltage: 120V/60Hz
Frequency: 433.92MHz

I continued with research into the 433.92MHz Frequency. Quickly, I found that our switch transmits on a very common radio band known as LPD443. LPD443 is used for low-power devices such as Smart Home devices and keyless entry systems. Our switch specifically listens to channel 35 of LPD443 at 433.925MHz.

Now that I knew what frequency to transmit on, I needed to know what to transmit. Using my RTL-SDR radio dongle, I tuned to that frequency, pressed the button, and listened with GQRX, a radio receiving program.

What I saw (and heard) wasn’t as exciting as you might think: I saw a tiny little blip on the screen and a short burst of static noise. Wow, I thought, That tells me literally nothing! So obviously I needed some sort of decoding tool to analyse this signal.

Decoding the Signal

RTL-433 does exactly that. I downloaded the github repository, compiled the program, and ran it. Here’s what I saw:

Terminal Output

RTL-433 showed me exactly what the remote control was transmitting to turn the lights on and off. Further experimentation and analysis of the signals yielded these patterns:

Switch 1 on:
00000100 00010101 00110011 0
...repeats for 7 more packets
00000100 00010101 00000000 0

Switch 1 off:
00000100 00010101 00111100 0
...repeats for 7 more packets
00000100 00010101 00000000 0

Switch 2 on:
00000100 00010101 11000011 0
...repeats for 7 more packets
00000100 00010101 10000000 0

It seems the first 2 bytes are the remote identifier, which changes with each set of remote and switches (I tested another set that my mom bought). The last 2 bytes are the control sequence, which is unique for switch 1,2,3 and on or off.

Now all that’s left is to program a raspberry pi to transmit PWM signals with those bytes and everything should work (keyword should).

Transmitting Signals with a Raspberry Pi

After doing some considerable searching about transmitting signals directly with the raspberry pi’s GPIO pins (something I’ve done before with pifm), I struggled to find any reasonable articles that provided a solution. Most articles I found discussed using GPIO pins to transmit FM signals. I initially inferred that if FM signals can be transmitted by GPIO pins then so should PWM signals.

With no solution in using the pins themselves to transmit signals, I searched for other options.

I discovered, signals on the 433MHz frequency can be easily transmitted using a transmitter module like the one found here. I ordered the pack of 10 transmitter and receiver modules (only 10 bucks!) and a Raspberry pi kit (I already had an RPI2B) with breadboard so I could connect the transmitters to the raspberry pi.

While waiting for the shipment to come in, I started work on a python project that listened for HTTP requests with specific paths that let me control the radio switches. The project is hosted on Github here. It’s gone through a couple of revisions since I first wrote the software, but the idea is still the same. As a bit of a coding challenge, I decided to make the project modular and scalable with other switches and devices that I may want to control in the future. The software is running live at

Finishing the Project

To make a long story short, after my raspberry pi kit came in, I managed to fry my board by plugging some wires in wrong. This was my first time ever using a breadboard and jumper wires, so I was pretty distraught. My blunder put the project on hold for a couple of weeks.

Fast forward, a new Raspberry Pi 3 arrived in the mail. I wired up the transmitter and breadboard (correctly, this time) and fired up my raspberry pi. In order to transmit signals, I needed another utility program, 433Utils, to send PWM signals on a GPIO pin connected to the transmitter. Looking at some example code and modifying an existing file, I wrote this script to send codes, which my python interface would call.


#include "../../rc-switch/RCSwitch.h"
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[]) {
    if (argc < 3) {
        printf("more arugments!\n");
        return -1;

    int switchnum = atoi(argv[1]);
    int command = atoi(argv[2]);
    int code = 0;
    int endcode = 0;

    if(switchnum < 1 || switchnum > 3 || command < 0 || command > 1) {
        printf("Invalid switch/command range");
        return -1;

    if(wiringPiSetup() == -1) return 1;
    RCSwitch rx = RCSwitch();

    if(switchnum == 1) {
        endcode = 267520;
        if(command == 1) {
            code = 267571;
        } else {
            code = 267580;

    } else if (switchnum == 2) {
        endcode = 267520;
        if(command == 1) {
            code = 267715;
        } else {
            code = 267724;
    } else if (switchnum == 3) {
        endcode = 267520;
        if(command == 1) {
            code = 268035;
        } else {
            code = 268044;

    rx.send(code, 24);
    rx.send(endcode, 24);
    return 0;


The compiled script is called through the python interface with a subprocess. This was my first time coding in C++, and I really enjoyed it!


In the end, the project was unfortunately finished after Christmas day, but I was still able to test my code using the lights on the christmas tree. I can’t describe the joy I felt tapping a button on my phone and seeing the lights turn on. The best part was, I made that happen; I was the one who coded the back end. Christmas is also my favorite holiday.

I continued refining the code and web interface after my initial tests. The site on is hosted on my main server, and requests to the python interface are proxied through Nginx.

I really enjoyed working on the project since I learned so much about radio technology and coding. It was also a great exercise to practice my coding skills in python and html/javascript. This project is probably one of the most important projects I’ve done, since I still use it on a daily basis for my bedroom lights!

Writing this from the future, there are some major improvements I could make to the code and the methods used. I now know of WSGI applications, so instead of hosting the websever directly in python, I could use something like gunicorn to handle requests far more efficiently. I could have also used a web framework like Flask to handle request parsing. In fact, looking at the code now, I see some major vulnerabilities in the way I handle request strings! I should probably fix that since the site is open to the web…