Home Automation using Alexa & IoT: Part 1

A two part series on how to automate your house appliances using IoT & Voice Processing Devices.

Shubham Kumar Apr 16
Home Automation using Alexa & IoT: Part 1

If you ever watched any Iron Man series then you must have caught a fancy to Tony Stark’s (Marvel’s fictional character) gadgets and you must’ve wondered how he controls them just through his voice.

Just think! Wouldn’t it be wonderful if you are also able to control all your home appliances just through your voice?

Seems fascinating, doesn’t it? But you must be wondering that implementing this will be a huge challenge to accomplish.

I want to tell you that at the end of this article you will be able to implement a simple model for yourself.

Let’s start the process

What we need to make a simple home automation model:

  1. A Voice Processing Device (we use Alexa for this).
  2. An IoT kit (NodeMCU ESP8266 wifi-enabled kit).
  3. A relay to connect your IoT kit with your appliances.

So this is how the flow goes on. Our first task in the process is to create a custom Alexa skill which interacts with your nodeMCU IOT Kit.

Creating An Alexa Skill

In order to manipulate our voice sample into useful instructions, we need to create a custom Skill on Amazon Alexa Cloud.

Before creating our custom skill, let us understand what Skills are.

Alexa provides a set of built-in capabilities, referred to as skills. For example, Alexa’s abilities include playing music from multiple providers, answering questions, providing weather forecasts, and querying Wikipedia.

The Alexa Skills Kit lets you teach Alexa new skills. Customers can access these new abilities by asking Alexa questions or making requests. You can build skills that provide users with many different types of abilities. For example, a skill might do any one of the following:

  • Look up answers to specific questions (“Alexa, ask tide pooler for the high tide today in Seattle.”)
  • Challenge the user with puzzles or games (“Alexa, play Harry Potter quiz.”)
  • Control lights and other devices in the home (“Alexa, turn on the living room lights.”)
  • Provide audio or text content for a customer’s flash briefing (“Alexa, give me my flash briefing”)

I hope you got a brief idea about what Alexa Skills are. Now let’s create a custom skill for ourselves.

In order to create a skill, we need an Amazon account. I hope you already have an account at amazon. If not, then go to amazon.in or amazon.com and create an account there. It’s quite simple.

Now visit the Amazon developer console, sign-in there using your Amazon credentials and complete the registration by providing your basic info.

Once registration is done and your profile is created, go to the Alexa developer console where we create our custom skill.

This is how it looks when you there for first time.

Click on the create skill button to start the skill creation process. Once clicked, it will navigate you to a different page, when you were asked to enter or select these fields:

  • Skill Name: Give your skill a name.
  • Language: Select a language based on your region and choice.
  • Model: Alexa provides a set of the pre-built model but for now we will go for Custom.
  • Backend: Again Alexa provides hosting options in both Node and Python, but for now we will select provision your own option.

Once done with options click on click skill, it will again navigate you to the next page where you will be asked to choose a template. We will choose Start from Scratch for now.

Once the option is selected and the Choose Button is clicked, you will be navigated to the Build Page.

Here we will provide our Invocation Name, Intents, Utterance, and Endpoint.

Before providing and building these options let us understand them.

  • Invocation Name: An Invocation name is a set of few words which let you interact with your skill. E.g. “Alexa, open Daily Horoscopes”, where Daily Horoscope is an invocation name that lets the user interact with Horoscopes skills.
  • Intents: An intent represents an action that fulfills a user’s spoken request. A skill may have multiple intents to perform different actions. E.g. “Alexa tell my _custom_skill to turn on the light.” This will execute TurnOnTheLight intent that in turn will hit a certain endpoint function and trigger a response.
  • Utterances: These are the sets of sentences/phrases which are mapped to intents. So basically they act as an invoker of an intent.

I hope now you got a pretty good idea about these things. Now we will create one of our own.

Since you are already on the build page, you will see these options in the right panel under the heading Skill builder checklist.

Invocation Name: Click on Invocation name option from the panel. It will navigate you to a new page. Provide your skill invocation name, Once done click on Save Model button and navigate back to home screen.

Intents and Utterance: Click on Intents, Samples and Slot option. You will be navigated to a different page. On it, select Create Custom Intent option, provide the name of the intent but please note here you can’t use space, number and special character for naming, so it’s better to use Pascal Case convention for the same like ‘TurnOnTheLight’.

Once you are done giving it a name, click on the Create Custom Intent button. After it, you will be asked to provide Sample Utterances for this intent. Enter some sets of words or a phrase like turn on the light and once done click on plus icon.

Likewise, you can create multiple utterances and link it with your intent.

Once done, click on Save Model followed by Build Model. This will save and build your model.

Next, click on the Build tab present at the header. You will be again navigated to the build page.

From here, the most important and complex part i.e. connecting your skill with a backend will begin, but don’t worry. Just like the other tasks, this can also be done easily.

The reason why we need a backend for this is to provide response feedback and perform some actions when a particular intent is hit.

So, our next task to accomplish is to create a backend support system, where we map our intent to perform our action and return a response of the same to the user.

For creating our backend, we broadly have two options here. The first one is to use AWS services like LAMBDA where you don’t have to worry about deploying and maintaining your server. 

But in case you don’t have an account in AWS or don’t want to use AWS services for back-end implementation you can go for the second option where we create our own server in Node JS and will deploy it to Heroku. You can jump to heading Using Own Custom Server if you are going for second the option. We discuss both here with code and logic. You can select any of the two options based on your suitability.

AWS

AWS provides a great platform to deploy a serverless backend. Since Alexa is one of Amazon’s products, you can find rich resources and support for the same in AWS. We will use its Lambda service for our backend support.

Before starting it, I hope you already have an account in AWS. If not you need to create an account and register yourself there.

In case you don’t have an account in AWS or don’t want to use AWS services for back-end implementation. You can go here to learn how to create your own backend endpoint.

Moving on, go to AWS Console, search for Lambda and select it from the suggestions.

Now, follow these steps:

  1. From the Region drop-down list in the upper-right corner of the console, select your region of deployment.
  2. Click on Create Function.
  3. Next, enter any function name and choose Python 3.7 as a Run-Time option (If you are confident in another language, you can choose that in place of python) and click on Create Function Button. After this, you will be navigated to an IDE page where you can customize your configurations and write the code.
  4. On this page, You will see a Designer drop-down option, Expand it by clicking on it, there you can find + Add Trigger Button. Click on it.



  5. Search there for Alexa Skills Kit. From the suggestion list, select Alexa Skills Kit.
  6. On the next page, you will be asked to provide your skill ID. For this, go to Alexa Developer Console and click on View Skill ID text appears just below your Skill name. A pop up will appear having the skill Id. Copy the ID from there, paste it inside the Skill ID text box and then click on Add Button after it.

  7. Now our Lambda function is capable of taking requests from our Alexa. Now, we just have to write a simple code that is able to handle our intent request and return a useful response when it gets evoked. Here is a sample code that you can copy or take reference for a simple invocation talk. In case your Intent name is not TurnOnTheLight then replace TurnOnTheLight text with your own Intent name at line no. 12.

    import json
    
    
    def lambda_handler(event, context):
        # TODO implement
        #  to handle the Launch Event. Request type in this case will be "LaunchRequest" 
        if(event["request"]["type"] == "LaunchRequest"):
            return handleLaunch()
            
        #  To handle "TurnOnTheLight" Intent. Request type in this case will be "IntentRequest".
        #  In case your your intentName is differnt change then replace "TurnOnTheLight" text with the name of your Intent.
        if(event["request"]["type"] == "IntentRequest" and event["request"]["intent"]["name"]=="TurnOnTheLight"):
            return handleTurnOnLightIntent()
             
    #  function to handle turnOnTheLight Intent      
    def handleTurnOnLightIntent():
        return {
                "version": "1.0",
                "response": {
                    "outputSpeech": {
                        "type": "PlainText",
                        
                        # The value provided against "text" key will be prompt/ speak by the the ALexa when invoked
                        
                        "text": "Light is Turned On"
                    },
                    "shouldEndSession": ""
                },
                "sessionAttributes": {}
                }
                 
     
    #   function to handle Launch event    
    def handleLaunch():
        return {
                "version": "1.0",
                "response": {
                    "outputSpeech": {
                        "type": "PlainText",
                       
                        # The value provided against "text" key will be prompt/ speak by the the ALexa when invoked
                        
                        "text": "Skill is Launched"
                    },
                    "shouldEndSession": ""
                },
                "sessionAttributes": {}
            }​
  8. Now we just have to connect it with our skill. For this, go to the Build Page and click on the EndPoint option. Select the AWS Lambda ARN option, copy ARN of your Lambda function (you will find this at the top of the page) and paste the value in the textBox against Default Region Label and Click on the Save EndPoint button.


With the completion of the last step, our skill is now ready to use. In order to test its working, click on the
test tab present in the header of the Page.

Enter the complete phrase by combining your invocation name and utterances. If it returns the right response, then your skill is working perfectly. You can also check it on your echo device but make sure that your device is connected with the same account from which you have created your skill.


But in case you don’t have an account in AWS or don't want to use AWS services for back-end implementation. You can use the second option.

Using Own Custom End-Point Server:

There are a few things that we need to create our own backend endpoint to handle an Alexa request:

  1. NodeJs: To build a back-end server which processes requests and returns a response.
  2. A special npm package alexa-app, which helps us in mapping intents and returning responses.
  3. Heroku: To deploy our server, in order to access it from anywhere.

Let's start with the NodeJs part. I hope your system is already configured with node and npm. If not, go to their official websites and set up them in your system. npm tool is shipped with Node, so once you install NodeJs in your system, npm will be automatically available.

Link: https://nodejs.org/en/download/

Next:

  1. Create a Node project with npm init command.
  2. Install Express and alexa-app packages via npm install <package_name> command.
  3. Copy the code sample provided below and paste it in the index.js file.

    var express = require("express");
    var alexa = require("alexa-app");
    
    var PORT = process.env.PORT || 8080;
    var app = express();
    
    // ALWAYS setup the alexa app and attach it to express before anything else.
    var alexaApp = new alexa.app("test");
    
    alexaApp.express({
        expressApp: app,
        //router: express.Router(),
    
        // verifies requests come from amazon alexa. Must be enabled for production.
        // You can disable this if you're running a dev environment and want to POST
        // things to test behavior. enabled by default.
        checkCert: false,
    
        // sets up a GET route when set to true. This is handy for testing in
        // development, but not recommended for production. disabled by default
        debug: true
    });
    
    // now POST calls to /test in express will be handled by the app.request() function
    
    // from here on you can setup any other express routes or middlewares as normal
    app.set("view engine", "ejs");
    
    alexaApp.launch(function(request, response) {
        response.say("You launched the app!");
    });
    
    
    alexaApp.intent('MakeTheLightOn', {
        "utterances": ["turn the light on"]
    }, function(req, res) {
        res.say('light is turned on');
    });
    
    
    
    server = app.listen(PORT, () => {
        console.log("Listening on port " + PORT + ".");
    })


The code is very simple to understand and implement, we use Express here to create the server and once the server is created we attach
alexaApp module to our server and define an end-point to handle all the requests coming from Alexa. Here, test is our endpoint name.

var alexaApp = new alexa.app("test");

After which, we define the Intent and launch handler by using the intent and launch method of alexa-app the module.

alexaApp.intent(‘MakeTheLightOn’, {

“utterances”: [“turn the light on”]

},

function(req, res) {

res.say(‘light is turned on’);

});


As you can see in the code, it is quite easy to implement. We just need to provide the Intent name and in its callback function, we are returning the response. For the response output here, we have used
res.say() here, which gives an audio output as a response against the request.

Now our implementation is ready to be deployed, for which we use Heroku. If you want, you can also use any other deployment server.

Follow this documentation to set up and deploy your server in Horuku.

Once deployed you will get a URL to access your server. It looks like this:

https://glacial-plateau-xxxx.herokuapp.com/

Now, we need to link our backend with our Alexa Skill. For this, go to the build page of your skill and click on the Endpoint option.

On the page that appears, select the HTTPS option. In the default region, paste the URL by appending the endpoint (https://glacial-plateau-xxxx.herokuapp.com/test) under the default region.

Just below that you will find the option to provide the SSL certification of your end point. Since we configured our server to accept any certificates, we will select ‘My development endpoint is a sub-domain of a domain that has a wildcard certificate from a certificate authority’ from the drop-down list.

After it, click on Save Endpoint Button to save the changes.



In order to check its working, click on the Test tab button present at the header of the page and try to invoke your skill and intent. If it returns the expected response then it means our implementation works perfectly.

Phew! With this we’re at the end of the Skill Implementation in Alexa.in the second part, we will see the IOT implementation of this entire setup and automate your home appliances.

Thank you so much for reading. I hope you found this post helpful.
Don't forget to follow me on Twitter if you want to know more about the project or just want to talk.

See you in the next part!

2020 © All rights reserved. GeekyAnts India Pvt Ltd.