I have been using my Amazon Echo and a Raspberry Pi running AlexaPi for voice control of lights, appliances and modes using ha-bridge, a Java app that emulates the Philips Hue API which is one of the few devices that the Echo supports natively. I use ha-bridge to call mosquitto_pub to send MQTT messages to my Node-RED based home automation system which allows me to control lights and appliances etc. by saying things such as “Alexa turn on the kitchen lights” or “Alexa switch the stairs lights off” or “Alexa turn cinema mode on”.

This works very well and as it is piggybacking on functionality that the Echo/AVS has built in there is no need for additional keywords but for something more advanced than on/off/brightness control we need to use the Alexa Skills Kit (ASK).

With ASK skills you can add new functionality which is operated by saying something like “Alexa ask the house to….” or “Alexa tell the house to….” where “the house” is the name of your custom skill and what follows can be anything you like. You can also customise the response that the Echo returns to the user so this opens up a lot of opportunities.

I’ve used “Echo” throughout this post but this will work with a real Echo or a Raspberry Pi running AlexaPi or Amazon’s new Java client. It’s easy to set up with Node-RED and certainly beats all that tedious mucking about in hyperspace with IFTTT.

First create a new skill:

Go to Apps & Services and then Alexa and click the button to get started with the Alexa Skills Kit

Click “Add a New Skill” and you will have 3 boxes to fill in:

Name – this is the name that will appear in the Alexa app or on the alexa.amazon.com site.

Invocation Name – this is the name you will activate the skill with, so if you want to say “Alexa tell the house I am going out” the invocation name would be “the house”. You can use “tell” or “ask” to invoke a skill, both will work automatically so don’t include this in your invocation name.

Endpoint – enter the link to an endpoint on your Node-RED install, eg. https://your-server/echo and select the HTTPS option.
Note that you must have HTTPS set up on Node-RED and it must be publicly visible. Rather than expose all my Node-RED http endpoints to the internet using port forwarding I do this using the Apache ProxyPass directive to redirect a single URL to the relevant endpoint on Node-RED. Apache is already running on the server so this made sense for me but you can also do this with ha-proxy.

Click Next to move on to the next page where you will see boxes for:

Intent Schema – Here we have to enter a JSON list with an intent for each command we want to create. eg. here are four, one for a status report and three to set different home/away modes.

Sample Utterances – this is a list of the phrases that you want to use along with which intent they relate to, you can add multiple phrases to each intent eg.

StatusReportIntent for a status report
StatusReportIntent for status
StatusReportIntent about status
ModeHomeIntent I'm home
ModeHomeIntent I'm back
ModeHomeIntent I'm awake
ModeHomeIntent to wake up
ModeBedIntent I'm going to bed
ModeBedIntent I'm off to bed
ModeAwayIntent I'm leaving
ModeAwayIntent I'm going out
ModeAwayIntent I'm away
ModeAwayIntent to close down

Click Next and you will see a spinner next to interaction model on the left indicating that the model is being built.

The next section is SSL certificate, check “My development endpoint has a certificate from a trusted certificate authority” and click next. (I’m assuming you are using a trusted SSL certificate, there’s really no excuse not to now but if you must you can use a self-signed certificate but will need to upload it to Amazon in X.509 format)

Select “no” for Account Linking on the next page then click next, you should now see the testing page states “This skill is enabled for testing on your account.”

That’s the Amazon side done, now onto Node-RED.

The Node-RED side

There is a link to basic flow that can be copied and pasted to do this below but I thought a full explanation would be helpful to understand what is going on. Firstly drag an http in node onto the workspace, set the method as POST and the URL as the one you used for the endpoint in the ASK configuration above, so if you had used the example of https://your-server/echo above you would enter /echo here.

Now add a switch node and change the property to msg.payload.request.type and add rules for the three types of request we might get. Those are LaunchRequest, IntentRequest and SessionEndedRequest, the first and last allow for a more interactive session but I will only be using a “one shot” IntentRequest in this example.

Link the output from the http in node to the input.

Add another switch node and add a rule for each of the intents that you created in the ASK developer site, eg.

Connect the output for the IntentRequest rule in the first switch node to the input of the second switch node.

The outputs from the second switch node can now go to something you want to do when that particular intent is triggered, for example a function node or just to send something to an MQTT topic etc. In my ModeHomeIntent I use the change node to set the payload and topic to put the house into home mode and link the output of that to an MQTT node.

We also need to send a response back to the ASK service to tell it that we are done and to give a voice confirmation for the user, this could be a simple “OK” or something more involved like my status report which grabs information from a number of global contexts and builds a message which the Echo speaks.

You can then add more intents to do more things, just remember that everything should ultimately link into the “Format response” template node to send a response back to Amazon. If you don’t send this response the intent will still fire and Node-RED will do what you ask but the Echo will respond to the user with an error that the skill took too long respond.

You can create multiple skills that all terminate at the same endpoint, for example I have “the house” for controlling home related things and “the camera” is used to control a Raspberry Pi pan/tilt camera.

Thanks for this Nathan, it is exactly what I want to do. However, I think they have changed the developer portal since you wrote this as you need to select Alexa from the menu.
When I develop a skill on this – is it made public? (can I keep it private?)

Have tried adding the flow to my node-red setup which is hosted on AWS. However, I am unable to get Amazon to successfully use the 1880 port of node-red. I could setup a subdomain for node-red, but am unsure of the apache settings. Do you use a proxypass to forward the requests on to port 1880?

I can’t setup Node-red with SSL on my RPi3 for some reason so I tried the option to use a self signed cert and tried to upload this but it just won’t load on the Amazon side. It says it does but the green check on the left doesn’t get set. Go back shows the self cert as empty.

Dave, yes, this is an issue on the Amazon side. I had the same, trying to setup on Ubuntu 16.04. Firstly, I setup a proxypass subdomain that I have Amazon connecting to as the webservice (https://openenergymonitor.org/emon/node/12489), used letsencrypt.org that Nathan recommends to SSL that subdomain and used “trusted” option. All worked immediately. I can’t see why this shouldn’t work on a Pi. Worth a try.

Hi Dave!
Thanks a lot for the information that you have posted.
Can you please try to describe a simple example of using the LaunchRequest and SessionEndedRequest?
I’m trying to make an integration like yours, but I would like to make something more interactive..
Regards,
Joao Duarte

Thanks for the reply Nick.
I’ll try to describe what I’m trying to acomplish..
I’m trying to make an Alexa HomeAssistant where I can control a set of IoT devices in my home.
For example, lights, monitor temperature, check if someone is at my door using a webcam, turn on and off devices (heaters, coffee machine etc,).
Now imagine that I want for example to control my heater based on a temperature value. I would like to have this kind of commands sets:

Say to Alexa: Alexa start HomeAssistant.
Respond from Alexa: Hi, HomeAssistant started. What can I do for you?
Say to Alexa: Alexa what is the temperature of my house?
Respond from Alexa: The temperature is 15ºC. Do you want me to turn the heater on?
Say to Alexa: Yes/No

My question here is how you make this derivation of Yes/No on Node-red???
So far I managed to create linear commands like nathan described, but making sequences of commands would be awsome 😀

Well, I’d like to enhance my heating system. So will look into this as well.

At the moment I ask “Ask home, What’s the lounge temperature.” Then “Ask home, turn heating to xx.c”. This is ideal for a response based system, and can’t be too hard from what Nathan has given us already. I’ll let you know how I get on.