DIY Smart Home

How to Control Cheap RF Power Sockets from OpenHAB

James Bruce 12-07-2016

Smart power sockets are the simplest way to automate your home, but at around $40 each for a Wi-Fi or ZWave based socket, you’re unlikely to buy more than a few.


You might already have some cheap RF based sockets though – the kind that come with their own custom remote control, and have some channel and ID selectors on the back. Unfortunately, there are no smart home hubs on the market Battle of the Smart Home Hubs: What's Out There and What's Coming? Read More that work with those. Wouldn’t it be great if you could link those into your DIY smart home system somehow? Well, you can – quite easily in fact – with around $10 in parts.

With a little more work, you can also integrate some other bespoke RF-based remote hardware, like this budget cinema screen.

What You Need:

  • ESP8266 NodeMCU v12E dev board (exact model doesn’t matter, v1 or v3 should be fine too). The reason we’re using a NodeMCU board is because we want the easy Wi-Fi connection later. The link is for a pack of 2, which works out at $7 each.
  • Package of 433Mhz transmitter and receiver (around $3).
  • RCSwitch and MQTT libraries, and our code – all available to download from Github.
  • An MQTT server, local or remote.
  • Some RF controlled sockets running on 433 mHz band (it should say on the remote control). I bought mine from Maplin as a pack of 3 for about £20 ($25.89).

If this is your first time programming the NodeMCU board, you’ll need to download the Arduino plugins for it: follow along with the first part of our Arduino Killer introductory guide Meet the Arduino Killer: ESP8266 What if I told you a there's an Arduino-compatible dev board with built-in Wi-Fi for less than $10? Well, there is. Read More for the NodeMCU/ESP8266 chip. You’ll also need CH430 drivers. You can find signed macOS CH430 drivers here, or Windows here.

I’ve used v1.6.5 of the Arduino because anything higher introduces more problems than it solves. Downgrade if you haven’t already.

Before you proceed, I’m going to assume a basic level of knowledge about Arduino programming Arduino Programming for Beginners: Traffic Light Controller Project Tutorial Building an Arduino traffic light controller helps you develop basic coding skills! We get you started. Read More , and that you have your NodeMCU setup in the board manager, and are able to correctly upload some demo code. You should also have added the libraries included in our download to your Arduino/libraries folder.


If you have an existing PubSubClient or MQTT library, back it up and remove it – the one I’ve included in the download is the only one where I could reliably receive messages on NodeMCU, and I tried a lot!

RF Sniffing (Optional)

This step isn’t needed if you only want to control DIP-switch or dial selector plug sockets – those are supported out of the box, and minimal code modification will be needed (this is still interesting to do first, though, so you’ll understand what’s going on behind the scenes).

If you have other RF remotes that you’d like to try adding, you’ll need to first “sniff” the RF codes being transmitted. To do so, load up the ReceiveDemo_Advanced sketch from the Menu -> Examples -> RCSwitch folder, and change the following line from 0

mySwitch.enableReceive(0); // Receiver on interrupt 0 => that is pin #2

to 2.

mySwitch.enableReceive(2); // Receiver on GPIO 2 / D4.

Wire up the receiver module as follows. Looking at the front of the receiver board (it’s the longer of the two, the transmitter is square) – the side with the components on:

  • Far right is GND. Connect to GND on the NodeMCU board.
  • Far left is VCC. Connect to VIN on the NodeMCU board.
  • Middle two pins are the signal. Connect either one to D4 on the NodeMCU (they are connected together, so it doesn’t matter which).

433 wiring-1

Now upload the modified ReceiveDemo_Advanced, and when it’s done, open up the serial monitor and start pressing buttons on your remote controls. Copy out the decimal (including bit length), pulse length, and protocol when you press a button.

screen RF sniffing


After doing this, I found my projector screen was using

  • SCREEN UP: Received 8694273 / 24bit; Pulse length: 355 or 356; Protocol: 1
  • SCREEN DOWN: Received 8694276 / 24bit;Pulse length: 355 or 356;  Protocol: 1

Continue for as many buttons as you need.

Testing the Transmitter

Next, we’re going to try sending codes using the transmitter. Wire the transmitter module (the square one) as follows. Be careful: the labelling on these pins is atrocious.

The VCC pin is actually in the middle, not on the left side. I destroyed one module in the process of figuring this out. That thing that says “ATAD” is actually “DATA”, spelled backwards. Again, the data goes to D4, VCC to VIN, and GND to GND (remove the receiver module, you no longer need it).


433 wiring-2

Load up the Examples -> RCSwitch -> TypeB_WithRotaryOrSlidingSwitches, and again, change the data pin:




Note, a variety of examples are in included in the library, and which one works for you will depend on the exact type of switch that you have. Type A (dip switches) and B (dials or sliders) are the most common – refer to the pictures on the RCSwitch page. For type B, turning on and off a socket is as simple as:

mySwitch.switchOn(1, 4);

mySwitch.switchOff(1, 4);

where 1 is the channel ID (the top dial), and 4 is the socket ID (the bottom dial). These were written in roman numerals on my sockets. A maximum of 16 individual sockets can therefore be addressed, though multiple sockets can use the same address if you have multiple devices to turn on at once.

However, my projector screen was a little different – it used a different pulse length. So, to operate those, the following worked. Note you can also define a different protocol if your remote needs it, BUT make sure you define the protocol BEFORE the pulse length. The pulse length is overwritten when changing protocol.

// Note that my screen actually requires TWO button presses (not a long press, but two physical presses), so I'm delaying a bit then sending the same signal again

void screenUp(){
  mySwitch.send(8694273,24); // (decimal code, number of bits)
void screenDown(){

Test all your codes are working first before you move on to the next step.

Controlling via MQTT

Open up the sketch you downloaded from Github named mqtt_rcswitch.ino, and start by modifying the network SSID and password for your home. Then, change the channel name if you wish, and set the MQTT server. If you don’t already have an MQTT server running on your OpenHAB install, read part 2 of our OpenHAB beginner’s guide OpenHAB Beginner's Guide Part 2: ZWave, MQTT, Rules and Charting OpenHAB, the open source home automation software, far exceeds the capabilities of other home automation systems on the market – but it's not easy to get set up. In fact, it can be downright frustrating. Read More . Note that my code is designed for type B (rotary switch) sockets, though you could easily modify it for DIP switches too.

The most important part of the code is the messageReceived() function, which responds to incoming MQTT commands. In this function, we’re first checking for the major keyword – I chose “switch” and “screen”. In the case of “switch”, we then parse out the channel and plug ID; then check the payload body for the command.

void messageReceived(String topic, String payload, char * bytes, unsigned int length) {
  if (topic.indexOf("switch") >=0){
    //switch control, parse out the channel and plug id 
    int channel = getValue(topic,'/',3).toInt();
    int plug = getValue(topic,'/',4).toInt();
    if(payload == "on"){   
      mySwitch.switchOn(channel, plug);
      mySwitch.switchOff(channel, plug);
  else if (topic.indexOf("screen") >=0){
    //screen control
    if(payload == "up"){
    else if(payload == "down"){
  /* add another else if here to listen for more commands (or just modify the one above if you dont want screen) */

By default then, the following MQTT commands work:

livingroom/control/switch/X/Y (where X is channel, and Y is plug ID; with message body on or off)
livingroom/control/screen (with message body up or down)

Use the command line or a GUI MQTT client to test your devices before adding to OpenHAB.

Adding to OpenHAB

As a last step, we just need to create some items for these switches in OpenHAB. I’ve defined the following items for now, but you should be able to figure out how to add more:

/* RF433mHz devices */
Switch CinemaScreen "Screen"  (Cinema) { mqtt=">[broker:livingroom/control/screen:command:ON:down],>[broker:livingroom/control/screen:command:OFF:up]"}
Switch Switch41 "Switch41"  (Cinema) {mqtt=">[broker:livingroom/control/switch/4/1:command:ON:on],>[broker:livingroom/control/switch/4/1:command:OFF:off]"}
Switch Switch42 "Switch42"  (Cinema) {mqtt=">[broker:livingroom/control/switch/4/2:command:ON:on],>[broker:livingroom/control/switch/4/2:command:OFF:off]"}

You should now be able to control your RF devices from OpenHAB! One thing I was pleasantly surprised by was the range – a single node was able to cover most of my house. You can of course add another node, listening to the same channel, which simply repeats the same commands, if you need further coverage.

The only limitation to bear in mind is that the sockets themselves can’t report their status, so if you use the original remote, control the status of the socket may not be accurately reflected within OpenHAB. Stick to using just the OpenHAB interface and you should be fine.

Questions or problems? Ask away in the comments, and I’ll do my best to help. If you’d like to improve on my code, feel free to submit a pull request.

Related topics: Home Automation, Smart Plugs.

Affiliate Disclosure: By buying the products we recommend, you help keep the site alive. Read more.

Whatsapp Pinterest

Leave a Reply

Your email address will not be published. Required fields are marked *

  1. Chamith
    February 3, 2018 at 8:00 am

    Not enough details on adding to Open Hab.

  2. Chamith
    February 3, 2018 at 7:59 am

    no enough details on adding to open hab

  3. Anthony
    September 24, 2017 at 1:40 pm

    Hey there, thanks for the great write up! I'm trying to find a solution for the integration of my ADT alarm and Milocks dead bolt, which both use rf remotes that I don't want to have to carry around all the time. I'll have to give this a shot, and see what needs to be changed to adapt with HAAS.

    Thanks again!

  4. Bob Bell
    May 28, 2017 at 9:55 pm

    Hi James, thanks for the article and you've really inspired me to try to get into expanding my home automation in a more hands on way! I've got my ESP8266 and RF transmitter/receiver. I have all the software installed and I've tested the basic LED blink and wifi scan sketches and they worked perfectly. I've connected up the receiver and uploaded the ReceiveDemo_Advanced sketch but when I check the serial monitor I get 1 line of miscellaneous characters and if I push buttons on the RF remote I get nothing additional. Any ideas what I could be doing wrong?

    • Bob Bell
      June 1, 2017 at 8:41 am

      Hi again, I've answered the first question since. My impatience! Basically I wasn't holding the transmitter close enough or for long enough to the RF receiver for the codes to start being received. I now have all of the codes for 2 remotes and it works perfectly when sending with something like MQTTspy. It also works perfectly (at first) via openhab and the 8266.

      What's happening now, though, is that after (x) time has passed, the MCU will stop responding to messages. If I restart it will start receiving immediately and even seems to process the missed queue. If I connect Arduino IDE and open the serial monitor it also seems to fire up and start processing messages.

      I am temporarily running off of a USB hub but have also tried direct power connections but this doesn't seem to make a difference. Is there some sort of keep-alive command I should be issuing? Should I run the restart procedure more often than once a day?

      Thanks for your help!

      • James Bruce
        June 1, 2017 at 8:46 am

        Glad you got it sorted Bob, thanks for updating us. As you say, try the restart every 8 hours or something - doesn't seem to be exact science. 1 day has been working well for me, but perhaps different model board from different manufacturers etc.

        • Bob
          June 6, 2017 at 12:20 am

          Hi James, after some troubleshooting it appears the reset routine itself was causing the problems. I've done a bit of searching and noticed that other NodeMCU users have an issue with ESP.restart where there devices stop running code after the restart command is issued. I have had no problems since commenting out the restart command and haven't run into the memory problems it is meant to alleviate yet. Still continuing to investigate the workarounds for getting ESP.restart working the way it should!

  5. eXi-Clem
    April 8, 2017 at 6:14 pm

    Hy James, I Have a problem with my esp (i guess?) the first time I send a command to the esp with my mqtt client everything work.
    But when i want to re-send another command, the ESP receive it and (i guess) try to sent it to the RF plug but nothing happens ... the blue LED is blinking when the command is received but my RF plug doesn't seems to receive the RF signal ...
    I'm not sure if u can understand what i want to explain, but i'm trying to do my best :D (i'm french so sorry for my english :P and i'm a beginner in arduino language as well :D)
    i have modify this string but i'm not shure if this is what i need to modify ...
    Please Help Me ^^

    if (topic.indexOf("switch") >=0){
    //switch control, parse out the channel and plug id

    int channel = getValue(topic,'/',3).toInt();
    int plug = getValue(topic,'/',4).toInt();

    if(payload == "on"){
    mySwitch.switchOn(1, 1);
    mySwitch.switchOff(1, 1);
    else if (topic.indexOf("screen") >=0){
    //screen control
    if(payload == "up"){
    else if(payload == "down"){

    • James Bruce
      April 9, 2017 at 8:02 am

      I would start by adding some debug lines, things that output to the serial window to tell you exactly what it's received, and whether it's triggering the correct statement.

      Add serial.println(topic); just before that IF statement starts, so you can see what it's receiving.

      And maybe serial.println("switching off socket 1!"); in the first ELSE section. If it's firing correctly, your plug might be incompatible with the basic switchOff(1,1) command, so you'll need to look into capturing the raw codes and figuring out why it's wrong.

  6. Patrick S.
    January 4, 2017 at 12:06 am

    Awesome article and thanks for getting me started on this project. I wanted to check with you to see if you ran into any issues with being able to receive a message.

    I was able to connect to the WiFi and also to the MQTT broker ok.
    I had to add in a username and password, as my MQTT broker requires them,

    so I declared the 2 constants and changed the following line:

    if (client.connect((char*) clientName.c_str()),mqttuser,mqttPwd)

    After connecting, I cannot for the life of me get the NodeMCU to receive the message.

    I have tested my broker using MQTT.fx, and I can successfully subscribe to and publish to the same topic (I used exactly the same as you have for testing).


    On the NodeMCU, after the "Subscribed to: livingroom/control/#", I cannot get it do anything more.

    Any ideas on where to go, as far as testing, on where the issue may lie?

    Thanks for any help!

    • Patrick S.
      January 4, 2017 at 2:35 pm

      For anyone else experiencing this issue. I did figure out where the issue lies, just not sure how to fix it. Removing authentication from my Mosquitto MQTT broker and then not passing the username and password in the NodeMCU, allowed me to connect and receive messages to the topics and turn the plugs on and off.

      This is, of course, not ideal when your MQTT server is exposed to the outside world for other services I use. So, I will continue to tinker with it and try and locate why the authentication is causing an issue.

      Thanks again for this great tutorial!!

  7. Rob Markowitz
    December 31, 2016 at 4:59 am

    Sorry, I don't have any wedding card spam, just an actual question :). I'm a little unclear on the final steps: I've loaded my sketch for Type C Intertechno (no dip switches or sliders on mine) and modified the script to accommodate just one outlet to start with that I've defined as a,1,1 (Outlet #1 as labeled out of the box and defined by the included remote). You say to test your codes before proceeding, but I'm not figuring how to do that after uploading the sketch to my ESP8266.

    I've also set up a Raspi Zero with OpenHab and Mosquito/MQTT as per your guides and that seems to be working properly according to the test I ran with MQTTFX, but I'm also stymied as to what to with the mqtt_rcswitch.ino sketch after I've modified it. Do I want to upload it to the ESP8266 as well? That would overwrite the Type C Sketch then, wouldn't it? I'm guessing I want to somehow get it on the Raspi instead.

    Any clarification you can provide would be greatly appreciated, I think I have a pretty good grasp of the concepts, but I think I'm getting tripped up by syntax and my lack of experience with this type of project.


    • James Bruce
      December 31, 2016 at 8:36 am

      Once you've got the lines you need from the Type C sketch and figured out how you activate them, you'll need to copy those lines into the mqtt_rcswitch code, and modify the messageReceived function. It's in that function that the codes reside for switching on the rotary switch ones.

      Specifically, ths bit:

      if(payload == "on"){
      mySwitch.switchOn(channel, plug);
      mySwitch.switchOff(channel, plug);

      change mySwitch.switchOn for whatever code it is you use for your socket (I'm not familiar with the type C codes, but it sounds like you've got them working). The channel and plug number are fetched from the MQTT message.

    November 30, 2016 at 1:57 pm

    How do I best honor a friend who'd not going to be in the bridal party? My bridal party is made up of old friends who I've known for over a decade, and one girl I've gotten closer with over the last year or so won't be in I didn't want to ask her to take it on when we hadn't known each other very long, but I'd love to have her participate in the wedding We both love books more than anything else, so I was wondering about having her do one or more of the readings? I'm not sure who else would do them, to be Most of my friends are taken up in the bridal Thoughts?