Every year Christmas light displays get more and more crazy. Pretty much every neighborhood in America now has that one house with an over the top display set to the song Wizards in Winter. In fact, so many people do it, I started to hate that song. There are literally thousands of videos on YouTube of houses with displays to that song. Trans Siberian Orchestra must be rolling in dough from those sweet sweet Christmas display royalties ...

The truth is, it takes a lot of work to build a light show, even if it is just for a for a single song. I don't have that type of time, or even that much of a love for the holidays. But my kids, they love Christmas light shows. And, you know who has lots of time? The internet does.

So, in an effort to please both -- I decided to try and come up with a way for anyone with an internet connection to build their own light show with the lights in my backyard, to whatever music they please.

Yup. That's right. I decided to put my Christmas lights on the internet. How could that possibly end poorly. In fact, my poor wife thought I was bonkers. IIRC, her exact quote was "So, what exactly is your end game here?" ...

Turns out it didn't end poorly. Still have no end game however. But, in fact, it was lots of fun. And I am already working on plans to one up myself for next year. sigh -- Just once, can I find a cheap normal hobby?

So, here is an overview of what I did last year, and how http://www.PlayWithMyLights.com was born.

Hardware I used

  1. Raspberry Pi Model A Revision 2.0 (Kicking it Ol'Skool)
  2. Official RPi wifi dongle
  3. SainSmart iMatic 8 Channels with RJ45 Interface
  4. Power distribution blocks
  5. Misc. 14ga wire
  6. Outdoor power boxes
  7. 4 outlets
  8. All weather 3 prong plug cut off an old sprinkler timer
  9. Misc wood / tupperware / etc.

Software

  1. NodeJs
  2. Apache Webserver
  3. More NodeJs
  4. Powered by a $5 Digital Ocean Server and a cheap domain.
  5. Raspbian Wheezy

The power and control boxes

Control Center Complete

For placing outside I ended up building 2 boxes. One for the electrical pixies, and one for the Raspberry Pi. You can't see it in the picture, but the pi is velcro'd to the lid of the top box in the picture above. This was to try and keep it out of any moisture that may accidentally get in. I also got worried that if I kept them together in the same box the power and relays may interfere with the Wifi. Since they were split and I made it so the only thing connecting these two boxes was an Ethernet cable. This gave me the ability to add more control boxes with the use of a hub, and also be able to separate the boxes so I don't need to rely on installing it somewhere with both good power and good wifi.

Always the f'n wifi .. am I right?

plugs wiring

The wiring for the power box was rather straight forward. Negative ran from a common power rail, straight to each plug. Positive ran from a common power rail, to a relay, and then to the plug. And earth bundled together in a giant ball. I tried to use products rated for outdoors on everything I could. The circuit I was powering this off of was GFCI, so as long as I had good ground and tried to keep it out of as much weather as possible I would be in good shape. Overall I think I left Home depot with only spending $25 in parts. With a total project cost (minus lights) at around ~$70.

relay wiring

Interesting note about the plugs. Out of the box, most wall plugs have a small metal tab that bridges the top and bottom plug together. If you wish to run both plugs independently, like I did, you'll need to break this tab off, otherwise when a relay activates it'll energize both plugs. This isn't in the instructions, well at least not in the instructions for mine.

Also, spending extra time numbering plugs and wiring pays off in the long run. I tried to take some extra time here and work on fit and finish -- I really wanted a solid unit that could take some weather if it had too without gobs of silicone.

Control Box

I know it is tempting to plug everything in and test along the way, but remember there are lots of bare wires and lots of a/c pixies in this box. So be safe, and check everything carefully before you plug it in.

But, of course, I couldn't resist. It's ALIVE!

In the end, the final box had 8 independent channels. Each relay was given its own plug. And each plug then had an extension cord ran directly to its light string. This is how I turned the lights off or on -- by controlling the state of the relays it would then turn the individual plugs off and on and that ultimately controlled the lights.

Software side

The actual software that ran everything was made of of 3 main parts.

  1. The Raspberry Pi Server that controlled the relays.
  2. The middle man server. It translated Website clicks into calls that the Raspberry Pi server understood.
  3. Webserver. This hosted the website for the end user.

What made the whole project so snappy was websockets. Specifically Socket.io. And, this project really made me fall in love with websockets. The socket.io implementation has come a long way, and the lack of flash is very nice. But it made it very easy to be able to use http and javascript to build out hardware controls.

Imagine 10 years ago saying "I'm controlling that hardware with Javascript". Not sure if you would of been smacked or laughed out of the room.

When a user connects to the website, it established a Websocket connection to the middle man server, which is acting as a Websocket command proxy. The middle man server would do two things. First, it would relay the commands to the Raspberry Pi to control the lights, but also broadcast the actions to other users using the service. This way, when multiple users were using the site, everyone could see what was happening. This also keeps from having people connecting directly to my Pi Server. This is for both security and also for scaling.

The Raspberry Pi had two jobs. First, constantly update the middle man with it's current state -- just so the middle man would know if the lights were active or not. If the lights were not active (or the system had crashed), the middle man could then suspend the frontend and put up a message. And second, control the light state based off of the inputs it received from the middle man, ie. turn "Twinkle String #2" into a relay action.

That brings me to the tricky part of the RPi server -- which was getting NodeJs to talk to the SainSmart iMatic 8 Channels with RJ45 Interface I was using for the relays. As far as I can tell, the RJ45 interface on this relay board is just an Arduino or Arduino clone. But, it's tricky, since it is hardware coded to a single static ip Address (192.168.1.4) .. There was a trick for getting that working with the RPi. The trick was, I hard coded the route for the ethernet interface on the Pi, and then plugged them directly into each other. So, everything went out WiFi, except packets destined to 192.168.1.4. Is it stupid if it works? ;)

The other gotcha was that there was no code available for their protocol in Node. But I was able to get it working from the php and python snippets floating around... So, here you go:

#
# NodeJs code for controlling 
# SainSmart iMatic with RJ45 Interface
#

var client = new net.Socket();  
client.connect(30000, '192.168.1.4', function() {  
    console.log('connected to iMatic!');
    reset();
});

var PREFIX  = '\xFD\x02\x20';  
var POSTFIX = "\x5D";

function iMaticOn(relayId) {  
    var relay = String.fromCharCode(relayId);
    var on    = String.fromCharCode(1);
    var cmd   = PREFIX+relay+on+POSTFIX;
    client.write(cmd, 'ascii');
}

function iMaticOff(relayId) {  
    var relay = String.fromCharCode(relayId);
    var off   = String.fromCharCode(0);
    var cmd   = PREFIX+relay+off+POSTFIX;
    client.write(cmd, 'ascii');
}

Above code Gist here.

The final piece was a website for the user to control everything. And really, it just needed to be flat files since it was only a frontend -- all the backend code was contained within the middle man. I went with a simple Bootstrap template, and some inline jQuery..

The website I chose was http://playwithmylights.com. (I put it back up in demo mode so that it can be seen how the interface worked.) But pretty much I tired to keep simple and mobile optimized since it would mostly be used by people out looking at lights and they would be on their phones. Each one of the 8 channels had a button on the page. When pressed, it would turn the string off for 2000ms. I also had a handfull of 'Light shows' which were pre programmed routines that the lights would follow. The light shows would also trigger if the system was idle for 3 minutes. Just as kinda a way to always have the lights dancing.

There was also the ability to Tweet the lights. That never took off. May need to rethink that. I'm open for thoughts on this.

v2.0

Over the next few months, I'm going to work on adding in an open API, and also work on video streaming. Which, this year was the one big missing piece. Without streaming, it's not much fun for people remotely controlling the lights to just button mash. Then again, /r/thebutton got 1,008,316 clicks for no good reason, so who knows? Either way, streaming is where my biggest investment will be this year.

I also plan on allowing duration and sequences to be controlled by the user. With, this version only I had that power -- and couldn't wrap my head around how to easily build out the UI for that feature and not make it confusing. But I think I have figured it out.

I also have some new NodeMCU boards I'm going to play with since I got the protocol down to a few bits. I think these will really help me cut down on power runs, while increasing channels. I think I can build NodeMCU powered relays for < $10. So, that should be fun.

Lights

For the last few years, we have been trying to buy LED's during after Christmas sales. I ended up picking up a few more strings, which gave me an overall total of about 5,000 lights. I really like the GE brand lights. They have been super reliable (which is good for the price) and they have minimal flicker to them. Seriously tho, I warn you to stay away from the cheap LED's. There is a bunch of bargain junk out there that seems to be a great deal -- but it is junk. If you buy good LED's they should last you years.

What amazed me, was the whole system pulled right around 100 watts. Under $.10 a day to run it? Wonder if next year I can make it 100% Solar?

Ahhh ... Next year ... It's so simple to deploy, perhaps I need to spin it up for Halloween as well. Oh, the possibilities ... My wife is still convinced I'm crazy ...

To be continued... ;)