Getting the party started with Alexa/Google

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.

Amazon Alexa and Google Assistant triggers

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".

Alexa and Google Assistant create trigger dialogs

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.

Maker channel, make a web request

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.

The strip details dialog box in the Flickerstrip app

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.

Living room with party lights on

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.