My brother has been working on a small project to control some  Christmas lights with a Raspberry Pi. He is using the Energenie system, and followed MiniGirlGeeks python example to get things working, and set up a cron job to syncronize his four (yes four) sets of lights. He then asked for pointers on controlling them via a web page served from the Pi, and I immediately thought that Node-RED might be a great solution. I don’t have the Energenie setup, but using my Pibrella LEDs as a substiture, I thought I’d put together a quick hack to show him how it might be done.

The first thing I have to say is that the Node-RED part was the easy part! The bit I found most tricky was getting the browser side javascript to work, basically because I haven’t had much experience working with it. Even so, it hasn’t taken too long to come up with a reasonable solution. I’m not going to cover installing NodeJS or Node-RED, that is well documented elsewhere.

The first thing to do was create the ‘backend’ on the Pi that will actually do the heavy lifting. The flow diagram looks like this:

lightswitch2

The HTTP input maps to /lightswitch and as per the notes for that node, we’ll pass in a URL encoded JSON object which contains just one attribute. This will be automatically parsed to a JSON object and passed to the next node.

The Map Input JSON to On/Off node is very simple. There is no error checking, and it assumes that a valid JSON object of the form {newlightstate: state} has been parsed by the HTTP node. For the purposes of this exercise, ‘state’ will be either “1” to turn the lights on, or “0” to turn them off. This value is stored in a global state variable, so we can check state later, and set to be the outgoing msg.payload. This is then passed to the Pibrella nodes mapping to the three LEDs, which will then turn on or off according to the value passed in. The value is also sent to the “Return Status Object” node.

One thing to note is that the Pibrella nodes initialize the output states of the LEDs to 0 (off) when the flow is deployed, so we know the lights are off when we start.

The Return Status Object node is also very simple, it sets the outgoing msg.payload to a JSON object of the format {lightstatus: status}, which will be returned to the requesting client by the HTTP response node. Again, the only expected values for “status” are “1” and “0”.

And that’s it, we now have an HTTP API to turn the Pibrella LEDS on and off, and we wrote just three lines of code, two of which are optional 😉

 

Those optional lines are quite useful though, since they allow us to create a status API call, as follows:

lightswitch3Here the HTTP node maps to /lightstatus and as it’s a GET call, no parameters are required. The Return Status Object returns the global state variable to the client in the same format JSON as the lightswitch API call – {lightstatus: status}. If the variable has not been created yet, it’s initialised to “0” before being returned.

 

The only thing left to do is to create some client code to use the APIs. Since my brother wanted a webpage, we’ll provide one. As it’s a simple case, we’ll serve the webpage required directly from Node-RED. There are of course other, slicker, ways you could do this, but this is a quick and dirty solution. All we do is set up a couple more flows, one for the html and for for the javascript file:

lightswitch1All these flows do is load the relevant file from the filesystem and return it as the body of the response.

 

The HTML and Javascript files are linked to below, and are reasonably self explanatory. The HTML page provides a toggle switch and specific ‘on’ and ‘off’ buttons to show examples of both techniques. The page calls an initialize function on load, which calls the lightstatus API on the Pi to get the current status so it can set appropriate text on the toggle button. The lightSwitch() function takes two parameters, one is not used but potentially could be used for indicating which specific light you wanted to change, the other parameter is the requested light state. The function then makes an Ajax POST request to the lightswitch API, passing the appropriate parameters, and updates the local state based on the response.

 

And that really is it.

Project Files

You’ll need to right click and ‘Save as’ (or equivalent) to save the files locally before opening them in your favourite editor:

The light switch HTML page is here.
The light switch javascript is here.
The Node-RED Flow export is here.