
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 do http GET requests to endpoints on 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:
Log in to the Amazon developer site at https://developer.amazon.com/
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.
{"intents": [ {"intent": "StatusReportIntent" }, {"intent": "ModeHomeIntent" }, {"intent": "ModeAwayIntent" }, {"intent": "ModeBedIntent" } ] }
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.
Add a template node with the following:
{"version": "1.0","response": {"outputSpeech": {"type": "PlainText","text": "{{payload}}" },"shouldEndSession": true } }
The msg.payload we send into this template node will be what the Echo speaks.
Finally the output from the template needs to go via a JSON node into an http response node to send the response to Amazon.
If you want to save a bit of time here is a copy of the above flow that you can just copy and paste into the Node-RED import from clipboard window.
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.
