It's been my dream for a long time to be able to control the lights in my house from anywhere in the world. Now I can do that without breaking the bank. Using a Raspberry Pi, some Etekcity Remote Control Outlets, and a 433 MHz transmitter, I can control the outlets in my home with Siri and any other HomeKit-enabled app on iOS. In this tutorial, I'll show you how to do it too.

This is the fourth tutorial in a series of tutorials for Raspberry Pis:

Unlike the other tutorials in this series, you'll need a few things for this one:

Required? Item Price
Raspberry Pi 3 Model B $35 USD
Micro SD Card $10 USD
5V USB Power Supply $7 USD
Raspberry Pi Case $8 USD
Etekcity Remote Control Outlets $25 USD
433 MHz Transmitter and Receiver $7 USD
Total $92 USD

Additionally, you'll need some tools and consumables:

Item Price
18 AWG Solid Wire $20 USD
Wire Stripper $5 USD
Lead-Free Solder $5 USD
Soldering Iron $40 USD
Female to Female Jumper Wires $5 USD

The price of this project is quite cheap if you already have a Raspberry Pi and some basic electronic tools and components: just $32 for the RF outlets and the RF modules! That's downright miserly compared to the cost of buying a commercial, ready-made solution.

Updated about 22 hours ago

This project takes some time to complete, so I recommend you plan to complete this project over the course of several days. I've broken it up into steps with completion milestones to give you good stopping points.

Build Antennae

The RF Transmitter and Receiver need antennae to function really well. Without antennae, their range will be limited to just a few meters. You have a couple choices for your antenna design. The simplest choice is to build a quarter-wave monopole. A quarter wave monopole antenna is just a straight piece of wire that is 25% as long as the wavelength RF signals you're working with.

In this case, the Etekcity outlets operate at 433 MHz. We can find the wavelength of 433 MHz waves with the wave equation

c = f * λ

where c is the speed of light (299,792,458 m/s), f is the frequency of the wave (433,000,000 Hz), and λ is the wavelength of the wave (in meters). Using this equation, we find that our antenna should be 173 mm (or 6-13/16 inches):

299,792,458 = 433,000,000 * λ

λ = 299,792,458 / 433,000,000

λ = 0.69236 m = 692 mm

λ/4 = 173.09 mm

Calculating that was the hard part. To make the antenna, just cut a portion of your 18 AWG wire to the correct length and then strip off about 3 mm (or 1/8 inch) of the insulation. You'll need to do this two times: once for the transmitter and once for the receiver. (I chose 18 AWG wire because it was what I had on hand, it didn't bend easily, and it fit nicely into the ANT holes of the RF modules. The diameter of the wire doesn't really matter, but stiffer is better because the antenna should be straight.)

Once you've made your antennae, solder them into the holes marked ANT on your RF transmitter and receivers.

Once you've soldered the antennae to your RF modules, you're done with this step. In the image, I used a different design for my transmitter's antenna called a "coil loaded" antenna. I can't comment on which antenna has better performance, but the coil loaded antenna is slightly more compact.

Connect RF Modules to Raspberry Pi

This step is relatively straightforward. Peel off six jumper wires from your Female to Female Jumper Wires and make the connections in the diagram below.

Here's the same information in a couple tables (the pin locations are described when viewed from the top with the pins on the side closest to you):

Transmitter Pin Name DATA VCC GND
Transmitter Pin Location Left Center Right
Raspberry Pi BCM Pin Number 17 5 V Ground
Raspberry Pi WiringPi Pin Number 0 n/a n/a
Raspberry Pi Physical Pin Number 11 2 6
Receiver Pin Name VCC DATA GND
Receiver Pin Location Left Center (Either) Right
Raspberry Pi BCM Pin Number 5 V 27 Ground
Raspberry Pi WiringPi Pin Number n/a 2 n/a
Raspberry Pi Physical Pin Number 4 13 14

Sniff RF Codes

You'll need to find out what codes are sent to turn on and off each of your outlets.

First, update and upgrade your packages and package repositories:

sudo apt-get update
sudo apt-get upgrade

Then install Git:

sudo apt-get install git

Clone and build the WiringPi utility. It's a library that is used by some other programs we'll be using shortly.

cd ~
git clone git://git.drogon.net/wiringPi
cd wiringPi
./build

Now you can compile a couple utilities, codesend and RFSniffer, that let you send and receive data with your 433 MHz RF modules.

cd ~
git clone --recursive git://github.com/ninjablocks/433Utils.git
cd ./433Utils/RPi_utils
make

Next, you can run RFSniffer to find out what codes are assigned to each of your outlets. RFSniffer won't show any output in your console right away. If you press and hold a button on your Etekcity remote, you should see lines like Recieved 5518604 printed in your console.

sudo ./RFSniffer

Make a table showing which codes correspond to which buttons on your remote. The codes for my remote are below. Your codes will be different.

On Off
1 5510451 5510460
2 5510595 5510604
3 5510915 5510924
4 5512451 5512460
5 5518595 5518604

Once you've created your own table, take a break! You're almost done, and you've completed a good portion of this tutorial.

Confirm RF Codes

Now we can use codesend to confirm our RF codes are correct and our transmitter is functioning correctly.

Plug a lamp into your first outlet, and make sure you can turn it on and off with your remote. Then open up two terminal windows. In the first terminal window, open RFSniffer so you can see the codes that are sent by your remote and the codes that are sent by your transmitter module:

cd ~
cd ./433Utils/RPi_utils
sudo ./RFSniffer

In the second terminal window, you can send some codes to try to turn your outlets on and off. For example, the last line below turns off my first outlet:

cd ~
cd ./433Utils/RPi_utils
sudo ./codesend 5510460 -l 200

5510460 is the code that I got from RFSniffer. the -l argument tells the codesend utility to send the code with a pulse length of 200 us. I was able to control my outlets with pulse lengths between 105 and 1445 us.

You will want to try using different pulse lengths to see what works for your setup. Longer pulse lengths will make it take longer to send a code, but shorter pulse lengths will make it more likely that your code will not be properly received.

I found 200 us to be a good compromise between speed and reliability for me. I'd recommend you use pulse lengths around 200 as well since long pulse lengths can also be unreliable if you get too close to the upper limit for your devices.

After you can successfully turn your outlets on and off with your Raspberry Pi, celebrate! You've completed another milestone in getting your home more automated.

Install Homebridge

Homebridge is a Node.js package that lets you use HomeKit to control devices that weren't designed for HomeKit. We'll use it as he missing link between Siri on iOS and our RF outlets. First, we need to install Node.js:

wget http://node-arm.herokuapp.com/node_latest_armhf.deb 
sudo dpkg -i node_latest_armhf.deb

Confirm that Node and npm are installed correctly by running node -v and npm -v. The output I got is shown below:

[email protected]:~ $ node -v
v4.2.1
[email protected]:~ $ npm -v
2.14.7

Install make and Avahi. Make is used to build binaries for your system, and Avahi gives Homebridge access to Apple's Bonjour protocol.

sudo apt-get install make
sudo apt-get install libavahi-compat-libdnssd-dev

Finally, Install Homebridge:

sudo npm install -g homebridge

Configure a Homebridge Dummy Switch and Pair Your iOS Device

Now we'll add some plugins to Homebridge, configure them, and check to make sure that we can talk to Homebridge from iOS.

First, install the dummy-switch plugin and the rcswitch platform:

npm install -g homebridge-dummy
npm install -g homebridge-platform-rcswitch

Dummy switches are switches that turn off immediately after you turn them on. They're useful just for checking if your iPhone can talk to your Homebridge.

When you install plugins and platforms, you tell Homebridge what type of devices you want it to be able to talk to. The next step is to tell Homebridge how many of those devices you have, what their names are, and how to talk to them. In other words, we need to configure Homebridge. We do that by modifying Homebridge's config.json file.

Overwrite your Homebridge config.json with Nate Henrie's config.json file:

sudo wget https://gist.github.com/n8henrie/639c7f5d72b4202cce7e/raw -O /etc/homebridge/config.json

Here's the content of his config.json file, if you're curious:

{
    "bridge": {
        "name": "Homebridge",
        "username": "CC:22:3D:E3:CE:30",
        "port": 51826,
        "pin": "031-45-154"
    },

    "description": "Example config file to test with a homebridge-dummy switch.",

    "accessories": [
        {
            "accessory": "DummySwitch",
            "name": "A dummy switch"
        }
    ]
}

Update the config file and run Homebridge with the command below:

sudo DEBUG=* /usr/local/bin/homebridge -D -U /etc/homebridge

I believe DEBUG=* and -D put Homebridge into debug mode so it prints more helpful information into the console. I think -U /etc/homebridge tells home bridge to look in that directory for its config.json file and to store any persistence data it might have.

After you run Homebridge you should get an output that looks something like the image above. Once that happens, open a HomeKit-enabled app on your phone such as Elgato Eve, Insteon+, or on iOS 10 you can use the pre-installed Home app. In whichever app you choose, tap the button for "adding an accessory" or something similar. You will be prompted for a 8-digit PIN. Enter the PIN printed into your console by Homebridge. Scanning the pin is usually unreliable, so I suggest typing it in.

At this point you should be able to see a single dummy switch that switches itself off immediately after you switch it on. Congratulations! You've reached another milestone in this project. You've linked your Raspberry Pi to your iPhone through HomeKit and Homebridge.

Configure RC Switches in Homebridge

We're almost done. Now we just have to update our config.json file to tell Homebridge that we have RC switches we want it to control, what their names are, and what codes to send to turn them on or off. To get Homebridge to read the updates you're going to make to the config.json file, we're have to restart Homebridge. I ran into issues with Homebridge not releasing the port it was running on properly, so I found that a reboot was the surest way to cleanly shut down Homebridge.

First, update your config.json file:

sudo nano /etc/homebridge/config.json

I've included my config.json file for your reference. You're want to change the "pin" value to a new PIN so no one else can control your devices. Also, update the "code" lines with the on and off codes you wrote down earlier. If your Etekcity outlets worked well with a pulse length significantly different than 198, update the "pulse" lines as well with your pulse length

{
  "bridge":{
    "name":"Homebridge",
    "username":"AA:BB:CC:DD:EE:FF",
    "port":51826,
    "pin":"753-15-946"
  },
  "description":"A Homebridge with four RC switches.",
  "platforms":[
    {
      "platform":"RCSwitch",
      "name":"RCSwitch Platform",
      "send_pin":0,
      "sniffer_pin":2,
      "tolerance":90,
      "switches":[
        {
          "name":"Kahee's Desk",
          "on":{
            "code":5510451,
            "pulse":198
          },
          "off":{
            "code":5510460,
            "pulse":198
          }
        },
        {
          "name":"Kurt's Desk",
          "on":{
            "code":5510595,
            "pulse":198
          },
          "off":{
            "code":5510604,
            "pulse":198
          }
        },
        {
          "name":"Kurt's Nightstand",
          "on":{
            "code":5510915,
            "pulse":198
          },
          "off":{
            "code":5510924,
            "pulse":198
          }
        },
        {
          "name":"Kahee's Nightstand",
          "on":{
            "code":5512451,
            "pulse":198
          },
          "off":{
            "code":5512460,
            "pulse":198
          }
        },
        {
          "name":"Living Room",
          "on":{
            "code":5518595,
            "pulse":198
          },
          "off":{
            "code":5518604,
            "pulse":198
          }
        }
      ]
    }
  ]
}

Finally, reboot and start Homebridge again. Rebooting might take longer than usual because Homebridge likes to take a long time to shut down:

sudo reboot
sudo DEBUG=* /usr/local/bin/homebridge -D -U /etc/homebridge

At this point you should be able to control your outlets remotely in your HomeKit-enabled app. If not, go back and make sure you can still turn your outlets on and off with codesend and that the codes in your Homebridge config file are correct. Also, make sure that you use the -U /etc/homebridge parameter when running codebridge, otherwise it won't use the config.json file you made.

Run Homebridge at Boot

There are many options for how to get Homebridge to run at boot. You can use systemd, rc.init, cron, and probably 10 other things. My preferred method is with cron. First, open sudo's crontab (and press 2 to use the nano editor if you're given the option):

sudo crontab -e

Then add these lines to the end of your crontab file:

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

@reboot DEBUG=* /usr/local/bin/homebridge -D -U /etc/homebridge > /home/pi/homebridge.log 2>&1

The SHELL=/bin/bash line tells cron to execute your cron jobs with bash, the default login shell on Raspbian. (Normaly cron uses /bin/sh which can make cron behave differently than your normal shell.) The PATH=... line tells cron what folders to look in for executables like Node. Cron uses a minimal PATH variable by default, so it won't find your Node executable without this little bit of help. Finally, the @reboot ... line tells cron to run Homebridge every time your Raspberry Pi boots up. (It doesn't matter if you reboot or halt and then power on; your command will run at every boot. The @reboot syntax is a bit of a misnomer.)

And that's it! You should now be able to control your Etekcity outlets from an iOS device. Congratulations on completing this tutorial.

If you found that I skipped a step or need some help, leave a message in the comments below. If this tutorial worked for you, let me know that as well!