Impress your friends with voice activated party mode using the Amazon Echo (Alexa), Google Home, Hue and LIFX smart bulbs, and Flickerstrip.
Many owners of colored smart bulbs monkey with the colors for a few days before configuring them to a demure white and mostly forgetting about the colors. The problem is not that colored lights aren't a lot of fun, it's that without the occasion and an easy way of triggering them, they're often more trouble than they're worth.
Enter home voice assistants. Alexa and the Google Home make it easy to quickly trigger actions around your home. In this case we're going to teach them how to "get the party started" to instantly spice up the mood lighting and impress your guests.
Overview
This setup has a number of moving parts that all have to work together:
- First, the commands are processed through either Alexa or the Google Home using their respective IFTTT channels.
- Then, IFTTT triggers the "Maker" channel to send the appropriate request to our home network which has an exposed port that will accept these requests and direct them to our NodeJS server.
- The NodeJS server will manage state and talk to our various devices using their respective APIs in the form of NodeJS libraries or simple HTTP requests.
Running a NodeJS Server
While you can use many of the techniques in this tutorial to automate devices around your house without running a server, to truly have powerful and robust control over a variety of devices, I highly recommend running one. My control server runs on a Raspberry Pi that I also use for playing media.
After installing NodeJS (and NPM), you can test the installation with a basic example. Create a folder and run npm install express
and then create a file server.js with contents as follows.
var express = require("express")
var app = express()
app.get("/", function (req, res) {
res.send("Hello World!")
})
app.listen(3000, function () {
console.log("Example app listening on port 3000!")
})
Run your server with node server.js
, you should now be able to access the server in a web browser by IP address. (use ifconfig
if you don't know the IP address of your device) If all has gone well so far, you should see a page that displays simply "Hello world".
Note: At this point, you'll probably want to setup port forwarding on your router to forward external traffic to the server you just started. Notice above that our NodeJS server is running on port 3000. You'll need this for your port forwarding configuration as the destination port. The inbound or external port can be anything you like, but make note of it, you'll need it later.
Interfacing with IFTTT
Now that you've got a server running, it's time to get Alexa and Google Home talking to it. First, we'll modify our NodeJS server to accept commands.
We'll add this small snippet to our server.js code which will respond to requests that look like http://<ip-address>:<your-port>/do?action=something
app.get("/do", function (req, res) {
var action = req.query.action;
console.log("action received: ",action);
res.send("OK")
})
Notice how we're using req.query.action
to retrieve the value after the equals sign in the URL.
IFTTT
Now, we need to set up IFTTT to forward commands from either Alexa or the Google Home to our server. Fortunately this is intentionally made very easy for us.
If you don't have an IFTTT account or haven't configured the required channels, there will be some additional steps here. If you run into trouble, a quick search should get you back on track.
Create a new Applet from the menu on the right and select either "Google Assistant" or "Amazon Alexa" depending on which assistant you're working with. When asked for the trigger, select "Say a simple phrase" or "Say a specific phrase".
You'll be prompted to choose a phrase for each one. Amazon Echo users are unfortunately limited to "Alexa, trigger X" where Google Home users can use "Ok Google" followed by just about any phrase and can even choose a response phrase. I've used "Alexa, trigger party mode" and "Ok Google, let's party" as my primary choices. You can of course choose whatever you like. Select create trigger to continue to the next step.
Now, configure your "That" by searching for the Maker channel and selecting "Make a web request".
Our web request URL will look like this: http://<EXTERNAL_IP_ADDRESS>:<EXTERNAL_PORT>/do?action=party
To address this request, you'll need some information. First of all, your external IP address (which should point to your router). The easiest way to get this is to visit WhatIsMyIp and copying it out of the box there.
Note: Because this is 2016, you may be confronted with a confusing, long, and scary IPv6 address that looks like this: 1234:1111:2222:3333:1234:abcd:defa:aaa
. If you do, Don't Panic to make this kind of address work for you, you'll simply have to wrap it in square braces []
(see below)
The second bit of the URL is the external port that you used when setting up port forwarding above.
Your complete URL will look like one of these, depending on whether you're using IPv6 or not:
http://[1234:1111:2222:3333:1234:abcd:defa:aaa]:3000/do?action=party
http://75.237.30.100:3000/do?action=party
The remaining fields can be left blank, hit "Create Action" and then "Finish" on the next screen.
Now for the fun part, double check that you've re-run your NodeJS server on whatever machine you have it running on and then test it out by addressing Alexa or your Google Home with the appropriate phrase: "Ok Google, Let's party" or "Alexa, trigger party mode".
If all goes well, you should have a rather abbreviated and anticlimatic message displaying in your terminal: action received: party
. If this worked, great! If not, double check that your trigger fired in your IFTTT activity log and whether the URL in your Maker action is correct. You may find it helpful to disconnect from your WiFi network with your phone and try hitting the URL you created to see if it's accessible from outside your network.
Controlling Flickerstrip
This and the next two sections are to be used depending on the kind of devices you have at home. We'll start with Flickerstrip because it's easy.
Using the Flickerstrip app, we can get the local IP address of our strip by clicking on the strip. Using this IP address, we can turn the Flickerstrip on and off using the following endpoints: http://<IP>/power/on
, http://<IP>/power/off
, and http://<IP>/power/toggle
To send these requests from NodeJS, we'll use the request module. Install it with npm install request
and use it in the server.js file that you've been working with as follows:
var request = require("request")
... //code from previous example
app.get("/do", function (req, res) {
var action = req.query.action;
console.log("action received: ",action);
if (action == "party") {
request({uri:"http://192.168.0.107/power/on"});
}
res.send("OK")
})
Now, you should be able to turn your Flickerstrip on by invoking your party trigger that you configured through IFTTT.
Note: To make this work more permanently, you'll want to assign a static IP address to your Flickerstrip. Here's an article describing the process for a D-Link router. Your router is likely to be similar or you can hunt down vendor-specific instructions for your router.
Controlling LIFX bulbs
Now that your Flickerstrip is responding appropriately to your party summons, it's time to get your smart bulbs on the same program. Because of the way that their cloud API works, there's an additional step to retrieve your LIFX Access Token. Follow the instructions on the documentation about API authentication to retrieve this token.
In addition, we'll need the module from the previous section again so be sure to run npm install request
if you haven't already.
Once you have your LIFX access token, you can use the API documentation to learn how to craft the appropriate requests to make your lights do what you want them to do.
To keep things simple, let's just turn all of the lights purple when party mode is invoked:
request({
uri:"https://api.lifx.com/v1/lights/all/state",
method:"PUT",
headers: { "Authorization":"Bearer "+LIFX_TOKEN },
body: JSON.stringify({"color":"purple"}),
});
To use this, you'll put your LIFX_TOKEN
in a variable at the top of the file. Here is the entire server.js file up to this point.
Note: To change which lights you're controlling, see the LIFX selector API documentation. For more information about the color parameters the LIFX color API documentation gives you a better idea of the options available.
Controlling Phillips Hue bulbs
Controlling your Phillips devices is almost a combination of the things you did for Flickerstrip and LIFX. The full set of instructions is available under the Phillips API getting started guide and I highly recommend that you walk through these steps and tinker with your bulbs using the developer console available through the bridge.
Once you have your API key, you'll still need to know the individual URL to control each Hue device. You'll get this by making a request to:
http://<BRIDGE_IP>/api/<HUE_TOKEN>/lights
The resulting JSON will list all of the discovered lights. You may want to run this through a JSON pretty printer to make it easier to read and subsequently retrieve the light ID(s) that you are interested in controlling.
Once you've identified the correct light (in my case, I want to use 3) you can turn the light on with a purple color using the following:
request({
uri: "http://"+HUE_IP+"/api/"+HUE_TOKEN+"/lights/3/state",
method: "PUT",
body: JSON.stringify({"on":true,"sat":254,"bri":254,"hue":52792}),
});
Again, this depends on HUE_IP
and HUE_TOKEN
being set earlier in your program. To see how this is included, see the full code listing up to this point.
Ok, computer, let's party
Now you should have a good basis for your party lights. You have basic control over your Flickerstrips and both your Hue and LIFX bulbs. With a bit of tinkering and study of the documentation for each of these things, you'll be able to start getting creative with exactly what "party mode" means to you.
As an example of taking this a bit further, I've scripted my lights to continuously choose random colors while party mode is on. It's a simple but dramatic effect that subtle enough to make for good party lighting, but clever enough that it gets comments from intrigued guests.
Here's the source code for this version with this advanced behavior included. You'll notice that it includes a behavior for turning the lights on and off as well as disabling party mode and going back to normal lighting. This functionality corresponds to additional IFTTT recipes that I've configured through my account.
You'll also see some code in there that normalizes the color language between Hue and LIFX. This is because they are using different color models. You can avoid this by using English color words, but you'll likely need to do this if you're using both of these systems and want to match the colors.