Arduino Power Socket Control (Web Server) for home automation

Posted: 31/03/2013 in Arduino

This post will detail how I created a simple home automation project to control multiple power outlets using an Arduino Mega microcontroller.

Project highlights:
•    Reduce the amount of systems left on standby and ultimately reduce the amount of wasted energy.
•    Remotely control the power state of multiple devices.
•    Power on and off a media server by using the Power button on the front of the computer.
•    Control a collection of radio frequency (RF) devices, including single sockets and power strips.
•    Control a couple of Power Distribution Unit’s (PDU).
•    Collect and present power state information via a web page that is iDevice mobile friendly.
•    Control all the above using a single Arduino Mega with an Arduino Wiznet Ethernet Shield.

The ability to remotely manage the power states of a computer or external device over the internet can be very expensive using traditional off the shelf products, in this post I’m going to show you how I achieved this using a single Arduino. I use wireless RF and IP controlled devices for all mains power related switching so there is no risk of high voltage shocks.
This project could be recreated exactly by others but I believe that it’s more likely that people will pick and choose areas of this project and implement these into their own. The code has been made available and is fairly simple to follow due to the use of functions and comments.

As this is a physical computing project I decided to do a quick overview video to accompany this post.

This video is best viewed in 1080p HD.

Bill of materials:

# Name Price Shop
1 Arduino Mega £20 Google/eBay
2 433 Mhz Transmitter and Receiver £3 eBay: search for “Arduino 433″ or “RF Link kit”
3 Energenie Trailing Gang with Four Radio Controlled Surge Protected Sockets £20 https://energenie4u.co.uk www.amazon.co.uk
4 Opengear IP PDU ? http://www.digipower.com.tw/PDU/BravoPDUswitched.htm
5 Breadboard and a few jumper cables Google/eBay
6 2N2222 NPN bipolar junction transistor £1 http://en.wikipedia.org/wiki/2N2222

Step One – Directly connected PC
I thought it would be interesting to use a remote method to power up and shutdown a PC by directly connecting to the power button. I opened the case and popped the power switch out, on inspection it was clear that this is just a little push switch. I cut into the cable and added an electrical block connector and gave a quick test to confirm I could power it on and off by simply connecting these two wires. As I wanted to have an Arduino create the connection I decided to use a 2N2222 transistor as I had a couple of these already, you could just as easily use a relay. The connections were as follows:

Pin (flat side to front) Name  Arduino
E – Left Emitter Ground
B – Middle Base Signal (from Arduino)
C – Right Collector Power

I used a 10k resistor between the Arduino and the base of the transistor to add a little protection to the Arduino. You can see from the code that I connected the base pin to pin 8 on the Arduino. Pin 8 need to be set to OUTPUT (pinMode(8, OUTPUT);) and then I to simulate a button press I used the following code:

digitalWrite(8,HIGH);
delay(500);               // wait for half a second
digitalWrite(8,LOW);

To check that the operating system is up I wanted to send ping packets and report on the response, I found a ping library at http://www.blake-foster.com/projects/ICMPPing.zip. Blake created a similar project to this step and I encourage you to check out his site.

Step Two – Energenie RF Power Sockets
This step has been covered in separate blog posts so as not to repeat myself I will provide the links below.
Capture the RF codes for your Energenie Power Strip
https://jfrmilner.wordpress.com/2012/12/30/powershell-power-sockets-arduinorf-part-1-capture-the-rf-codes-for-your-energenie-power-strip/
Configure the circuit like I did in the following post, the code/sketch is similar with the most obvious change being the use of serial as input over web which I’m using in this project.
https://jfrmilner.wordpress.com/2012/12/30/powershell-power-sockets-arduinorf-part-2-configure-the-arduino-with-the-rf-transmission-sketch-for-your-energenie-power-strip/

Step Three – IP PDU’s
Again, this step has been covered in a previous post – https://jfrmilner.wordpress.com/2013/01/06/controlling-an-ip-pdu-with-powershell/. As I needed to have the Arduino do the authentication to the IP PDUs I needed to form an HTTP GET request with the username and password encoded. I used the website http://www.motobit.com/util/base64-decoder-encoder.asp which allowed me to encode the default credentials, for example
Username:snmp
Password:1234
Concatenated with a colon join: snmp:1234
Base64 encoded string: c25tcDoxMjM0

To complete the example, below is a code sample of one of the functions I use to collect state information from the PDUs. This clearly shows the use of the authentication code:

client.print("GET /");
client.print(powerState);
client.print("s.cgi?led=");
client.print(LEDCode);
client.println("0000000000000000");
client.print("Host: ");
client.println(hostname);
client.println("Authorization: Basic c25tcDoxMjM0");
client.println("User-Agent: Arduino Sketch/1.0 snmp@1234");

Step Four – The Web Portal/Server
Writing a web server for an Arduino is challenging mainly due to the amount of RAM available. Originally I started this project with an Arduino Uno which is limited to 2K, I maxed this out almost immediately* so I decided to get an Arduino Mega with 8k of RAM. Using the Simple Web Server sketch provided in the Arduino IDE as the starting point I created an HTML table to display the power buttons of the Energenie power strip, this code used up a lot of the available RAM. When I started to add further table rows I soon realised that I would not be able to fit the desired 21 I needed using this format. The solution I used is to have the unique information about these devices within an array and then loop through them to build the page for each client request. This made the code a little more complex but allowed massive reductions in the amount of code I needed to store within RAM.

* see the freeRam code block at – http://playground.arduino.cc/Code/AvailableMemory for an easy way to see memory utilization

Using the original web portal interface for the IP PDUs it required multiple actions to change a power state which I didn’t want and as I have two PDUs I needed to log into each one individually. This should not be considered as a design issue with the devices it’s just that they were not designed for such frequent use or outside a server cabinet for that matter!

IPPDU-05

Instead I wanted it to be mobile friendly so I needed large buttons that were colour coded to their respective devices power state, the below screenshot is taken from my iPad

WebPortal-iPad-1

You will notice that the page fits perfectly; this was achieved by adding this line to the HTML page

<meta name="viewport" content="width=device-width" />

It basically resizes the table to fit to the mobile devices landscape screen resolution and works well on all my iDevices.

In effort to keep the code line count and size down you will notice I created three functions within the Arduino sketch
1.    PDUWebStatus  – Enumerate power states on PDUs
This code queries the current power state of the PDUs and stores the results in an array for use by the aforementioned HTML table loops.
2.    PDUWebCommand – Issue power state changes on the PDUs
This code actions PDU power state change requests.
3.    PDUWebCommandPush – Collect current power state and rotate
This code uses the above two functions to action the HTML button pushes.

Whenever a user presses one of the HTML buttons they call a small javascript function that then calls the PDUWebCommandPush function mentioned above. This makes the users browser send a GET request to the Arduino which then gets matched to one of the predefined actions, for example Energenie Socket 1 On button would trigger the following action

if(buffer.indexOf("GET /?E1=ON")&gt;=0) {
mySwitch.send(4314015, 24);
refreshRequired = 1;
}

You will also notice that this sets the refreshRequired variable, this is used to force the client back to the webservers root directory and allow the changes of power states to be show on the page. I found that redirecting the users back to the root also prevented the refresh button on a browser sending an additional GET request to an already completed request.

Sets
At the time of writing this blog post I only have a single Set as listed on the above image as “Set – 1” but I have plans to add several more. Sets allow me change the power state on multiple devices at once even if they differ power source and/or control method. I have used this to power on my desktop computer and all associated monitors, this is shown in the demo video which accompanies this post.

A note on security
I have controlled access to the Arduino web server using the firewall on my router. This has allowed me to restrict access to my place of work and my internal LAN only.

The Code
The Arduino Sketch can be found over on my GitHub

Well I hope you’ve enjoyed reading about this project as much as I enjoyed putting it together. Please use any of the ideas and code in your own projects but please do give credit to the original author.

Kind Regards

jfrmilner

Advertisements
Comments
  1. Rodrigo says:

    hello
    I really liked your project
    I’m doing a project similar to yours, but I have problems
    I want to control a LED from a web, but can not you connect the Arduino to hosting
    I need help with the code
    I can help

  2. Art says:

    Hi,
    This looks like a great project. I tried to download your ino file but getting an error. Is it gone?
    Thanks for posting this.
    Art

  3. Kent says:

    Your project is great. I’ve been looking for a way to get a refresh like yours to work, so that it updates the page contents to show what is on vs. off. A manual redirect to my Arduino Mega web server’s root directory works, but I can’t seem to get it to work automatically, other than a timed redirect every ‘x’ seconds; didn’t really like the continuous refreshing when nothing has changed with that method. I just tried doing what you’ve done with ‘if (refreshRequired==1){‘, but I must be missing something. I even started over from your sketch, but removed the things that don’t exist like your PDUs, but still no glory.

    I am wondering if your implementation requires http://1.1.1.1 to be added to your hosts file (or your OS’s equivalent to a Windows host file), pointing back to your Arduino web server’s IP. Any additional details that you can share about how this works in your project would be greatly appreciated. I’d love to do this without needing to learn AJAX or JSON.

    Thanks for sharing your project!

    • jfrmilner says:

      Hi Kent,

      Thanks for the kind words. 1.1.1.1 was just the IP address I used to hide my actual internal IP address and should be changed to the IP address you would like alocated to your Arduino.
      Due to the limited capabilities on an Arduino (RAM etc) using AJAX is unpractical. My work around was to push a 5 second Meta Refresh (http://en.wikipedia.org/wiki/Meta_refresh) to the client if they triggered a change, this as you can see works and gives the elusion it detected a state change. Unfortunately if a state change happened external to the web portal it would go unnoticed until a user manually performs a refresh from their browser.

      Hope this answers your question

  4. dave says:

    HI,
    I saw your wonderful programing of arduino.

    I’m very new to arduino.

    I like to do a project but i’m having such a hard time with it,

    what I like to do is to control for example 8 switch for on and off (easy part I know),
    but over the ethernet web
    and also I need it to have log in and password.

    for example you go to web: 192.168.1.177 and 1st it shows log in and password, you put them in, then it directs you the botton page?

    do you have that by any chance? if so would you please share the code?
    Thank you
    Dave
    davejava126@hotmail.com

    • jfrmilner says:

      Hi Dave,

      You will struggle setting up authentication with a typical Arduino such as the Uno/Mega because of their limited RAM. However, I believe the Arduino Yún could suite your needs but I don’t have one myself. I’d suggest asking the question over on the Arduino Forums – http://forum.arduino.cc.

      Good luck

  5. Kazem says:

    Hi ,
    you have done a great work.
    I’ve a question sir; with this project that u have done we are able to turn devices On/Off from web and online but I’m looking for a method to make me able to control a switch through web and manually as well, in the other words: I wan to control a switch from 2 different sides, manually and with web. hope my question be clear.
    plz guide me, appreciate u in advance.

  6. peter says:

    Great!! Very good work!

  7. daniel says:

    Hi, Nice to meet you.

    My name is Daniel, at WIZnet in Korea.  
    We have been searching some application references in which WIZnet solution is applied, and found your project “Arduino Power Socket Control (Web Server) for home automation“ using Ethernet Shield. In the Ethernet Shield WZnet’s W5100 chip is embedded. Your development looks very cool & smart. 
    Recently we opened WIZnet Museum (http://wiznetmuseum.com) site. This is a academic-purposed collection of open projects, tutorials, articles and etc from our global customers.

    If you are O.K. we would like to introduce your projects in here. Hopefully, you will allow this.

    Hopefully, keep contacting us for the friendship.

    Thank you very much

    Daniel.

  8. Davor says:

    Hi John,

    I just wanted to leave a reply, and say, what a great job you did here. One can certainly say that this is enormous contribute to Arduino community aswell as automation projects that can derive from this article.

    Thank you for your exceptional work, you saved me a ton of time…

    Cheers, all thumbs up and keep the good work—

    Davor

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s