Develop Alexa Custom Skill with AWS Lambda to Control IoT Device
If you have any smart IoT gadgets in your home or office, and had a go at controlling them with Alexa, you may think about how it really works. In this guide, you will find out about building a custom Alexa skill with AWS Lambda to control your smart devices. You will be able to turn a light specific light on/off through Alexa.
While these gadgets are without a doubt popular, recent reports on AI-powered voice assistants demonstrate that once the curiosity rubs off, people don’t see much value in them. Amazon opening up Alexa with the capacity to add custom skills was one of the greatest progressions to the voice ecosystem we’ve ever observed. Amazon Alexa is a virtual assistant created by Amazon, which is capable of voice interaction, making to-do lists, music playback, setting alarms, playing audiobooks, streaming podcasts, and providing traffic, sports, climate, and other real-time information, such as news. Amazon offers two different ways for Alexa to interface with your custom logic. It’s either executed as an AWS Lambda function or you’re required to have your own web server. The two alternatives require a lot of bootstrapping and code so as to implement even the simplest of Alexa skills.
What’s more, as a developer, the Alexa opens up an extraordinary road to build custom abilities and change over voice into machine commands where we can perform numerous tasks, such as controlling IoT devices. This post is concentrating on the well-ordered implementation of building an Alexa custom skill, incorporate it with an AWS Lambda function and send commands to an IoT device. Here I set up together a clear Alexa skills kit tutorial for a custom skill that you may truly find valuable.
The use case
In this sample application what we are trying to do is control 3 lights ( Red , Green and Orange LEDs ) which are attached to a NodeMCU controller. We are not focusing on how to program the NodeMCU module in this post, The NodeMCU module is connected to a state server where it can get its pin statuses and update the GPIO values accordingly.
The Solution Design
In this post , we are focusing on how to invoke Alexa custom skill and the integration with the AWS Lambda function.
Build a Custom Alexa Skill
First of all you need to log in to your Amazon developer portal. If you do not have an account you can create one free. Navigate to Alexa → Your Alexa consoles → Skills
You can create a new skill by using the “Create Skill” button. You need to enter a skill name and select the preferred language as well. Select the “Custom” tab and create the skill.
Then you will be navigated to the Skills page.
An Alexa Custom skill contains following main features.
Invocation : This is the command that user should provide in order to start the custom skill.
Intents : Intents are the individual commands that you should provide within the skill to trigger different events.
Slots : Slots can be identified as parameters to intents where you can pass in different values.
Endpoint : Where you should integrate you newly build skills. There are two options there as AWS Lambda ARN and HTTPS. In this tutorial we are going to use the AWS Lambda ARN option.
By default, you can see there are 3 intents already created such as AMAZON.CencelIntent , AMAZON.HelpIntent and AMAZON.StopIntent. Lets create a new custom intent.
Invocation
Navigating to the Invocation tab , you can provide the command in skill invocation name section which you like to start your custom skill.
Create a new Intent
You can create a new intent by using the Add intent button.
You need to give a proper name to your intent and create the custom intent. Next we need to provide the sample utterances for this intent. Utterances represents the actual voice commands that user would provide to invoke this intent. As an example we can specify “turn on the red light”.
But if we continue in this way, we would be facing a small problem. Since we are having 3 lights, there are 6 states that we need to maintain. ie : we need to create 6 different intents to control our 3 lights. This is in efficient and hard to maintain. We can use slots to get rid of this problem and pass the light status and the light color as parameters to our intent.
In the utterances section, you can specify the required slot in a curly braces. The tool would ask you to create a new slot using the lightstatus in this instance. We need to add a slot to the light color as well.
Now you can see that the Skills tool add two slots for our utterance as in the image above. Next, we need to select a Slot types for our newly created slots. There are Amazon build-in slot types that you can select from the slot type drop down. For the lightcolor slot, i can use the AMAZON.Color type. But there is no pre-defined slot type for the lightstatus slot. Hence we need to create custom slot type for that.
You can use the add button to create custom slot type in the slot types section.
Then we can go back the intent and select the newly created slot type for the lightstatus slot.
Now we are done with our intent and using this one intent we can control all statuses in our light.
Next we need to build the lambda function that needs to integrated with this skill.
Develop the Lambda Function
First of all you need to log into the AWS Console. If you do not have an account you can create it free.
Search the “Lambda” in the AWS services search bar. You can create a function by using the “create function” button.
Im using the Author from scratch option with NodeJs. If you do not have an existing role, select the create a custom role or create new role from template. The AWS would create a default role for you.
This will create index.js default file and provide you with a default js code.
First Im gonna create helper functions as follows.
// These are the helper functions
function buildSpeechletResponse(title, output, repromptText, shouldEndSession) {
return {
outputSpeech: {
type: 'PlainText',
text: output,
},
card: {
type: 'Simple',
title: `SessionSpeechlet - ${title}`,
content: `SessionSpeechlet - ${output}`,
},
reprompt: {
outputSpeech: {
type: 'PlainText',
text: repromptText,
},
},
shouldEndSession,
};
}
function buildResponse(sessionAttributes, speechletResponse) {
return {
version: '1.0',
sessionAttributes,
response: speechletResponse,
};
}
These helper functions builds the speech responses that needs to pass back to the Alexa custom skill upon executing some commands.
Next the functions to support the sessions start and the skill launch.
function onSessionStarted(sessionStartedRequest, session) {
console.log(`onSessionStarted requestId=${sessionStartedRequest.requestId}, sessionId=${session.sessionId}`);
}
function onLaunch(launchRequest, session, callback) {
console.log(`onLaunch requestId=${launchRequest.requestId}, sessionId=${session.sessionId}`);
// Dispatch to your skill's launch.
getWelcomeResponse(callback);
}
function getWelcomeResponse(callback) {
const sessionAttributes = {};
const cardTitle = 'Welcome';
const speechOutput = 'Welcome to the light demo ' ;
const repromptText = 'You can say: what switch to control ' ;
const shouldEndSession = false;
callback(sessionAttributes,
buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
}
In here you can specify the Welcome message and the re prompt messages if user do not give any voice input. The callback function uses the helper function we built earlier. Once user invokes the skill using the correct invocation phrase, the lambda creates a session for current instance of the customs skill.
Next, we need to specify the Session end request onSessionEnded event as below.
function handleSessionEndRequest(callback) {
const cardTitle = 'Session Ended';
const speechOutput = 'Thank you for using light control , have a great day!';
const shouldEndSession = true;
callback({}, buildSpeechletResponse(cardTitle, speechOutput, null, shouldEndSession));
}
function onSessionEnded(sessionEndedRequest, session) {
console.log(`onSessionEnded requestId=${sessionEndedRequest.requestId}, sessionId=${session.sessionId}`);
// Add cleanup logic here
}
The most important function is the intent handler. This is where we are mapping the Alexa custom skill’s intents, into the Lambda function.
function onIntent(intentRequest, session, callback) {
console.log(`onIntent requestId=${intentRequest.requestId}, sessionId=${session.sessionId}`);
const intent = intentRequest.intent;
const intentName = intentRequest.intent.name;
// Dispatch to your skill's intent handlers
if (intentName === 'AMAZON.HelpIntent') {
getWelcomeResponse(callback);
} else if (intentName === 'AMAZON.StopIntent') {
handleSessionEndRequest(callback);
} else if (intentName === 'lightcontrol') {
var color = intent.slots.color.value;
var lightstatus = intent.slots.lightstatus.value;
lights(callback,color,lightstatus);
}
}
You can see that we are handling the lightcontrol intent we have created in our custom skill. We are retrieving the slot values using the intent.slots attribute and assigned them to local variables.
Next , we need to build the lights function where we are going to interface with our IoT server as below.
function lights(callback,color,lightstatus) {
var _switch = "";
var _status = "";
if(color == "red")
_switch = "V1";
else if(color == "green")
_switch = "V2";
else if(color == "orange")
_switch = "V0";
else
_switch = "error";
if(lightstatus == "on")
_status = "1";
else if(lightstatus == "off")
_status = "0";
var endpoint = "http://<myip>:8080/<myport>/update/"+_switch+"?value="+_status;
var status ="offline";
var body = "";
http.get(endpoint, (response) => {
console.log("Got response: " + response.statusCode)
response.on('data', (chunk) => { body += chunk })
response.on('end', () => {
})
});
const sessionAttributes = {};
//Get card title from data
const cardTitle = 'device status';
//Get output from data
const speechOutput = 'The ' + color + ' light is turned '+ lightstatus;
const repromptText = '' ;
const shouldEndSession = false;
callback(sessionAttributes,
buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
}
To control my IoT device I have implemented a java based state server which can be integrated with a REST API. First of all, the function builds the required endpoint values based on the slot values we got from the intent. Then it calls to the IoT state server with required values. The IoT device listening to the state server would update its GPIO values accordingly.
You can find the full source code in this git repo.
Testing the Lambda function
You can test your Lambda function by using the build-in test framework. Go to the configure test events and configure a new test event.
The lightcontrol intent’s test script should be as follows. We need to specify the samples values for our slots as in the test script.
{
"session": {
"new": false,
"sessionId": "amzn1.echo-api.session.[unique-value-here]",
"attributes": {},
"user": {
"userId": "amzn1.ask.account.[unique-value-here]"
},
"application": {
"applicationId": "amzn1.ask.skill.[unique-value-here]"
}
},
"version": "1.0",
"request": {
"locale": "en-US",
"timestamp": "2016-10-27T21:06:28Z",
"type": "IntentRequest",
"requestId": "amzn1.echo-api.request.[unique-value-here]",
"intent": {
"slots": {
"color": {
"name": "color",
"value": "red"
},
"lightstatus": {
"name": "lightstatus",
"value": "on"
}
},
"name": "lightcontrol"
}
},
"context": {
"AudioPlayer": {
"playerActivity": "IDLE"
},
"System": {
"device": {
"supportedInterfaces": {
"AudioPlayer": {}
}
},
"application": {
"applicationId": "amzn1.ask.skill.[unique-value-here]"
},
"user": {
"userId": "amzn1.ask.account.[unique-value-here]"
}
}
}
}
You can get the test result and the status as below in the Execution Results window.
Great ! Now our tests are passed and as the next step, we need to link the Lambda function and Alexa custom skill that we have developed.
Link the Lambda function and the custom skill
To link the Lambda function and Alexa custom skill, copy the ARN value of the Lambda function to your clipboard.
Go to your custom skill and select the EndPoint tab and select the AWS Lambda ARN. Enter the ARN value in to the Default Region section as below.
Next, you need to copy the Skill Id and enter in your Lambda function as in steps explained below.
In the light control function, add the trigger “Alexa Skills Kit”.
Go to the Configure section of the Alexa Skills Kit and add your Custom skill’s Skill ID.
Save both the Lambda function and the custom skill.
Next, Build the custom skill using the Build Model button.
Congratulations ! Now we have a properly configured Custom skill. Next we need to test the custom skill itself!
Testing the Alexa Custom Skill
In order to test this custom skill, navigate to the Test tab on the top of your console. Enable the Test for this skill.
There are two ways we can test our skill.
- By Voice
- 2. By Text
Just simply type the invocation name you have specified for your skill. Apart from the speech output , the console is spitting out the JSON inputs and outputs as well for the particular test.
Next, you can test your intents as well.
Congratulations guys !
You have done it !
If you own an Amazon Echo Dot or Amazon Alexa, this is a good time to test your skill with your own voice ! :)
Wrap up
As we have seen, it is moderately straightforward to build up a custom skill for the Amazon Echo platform. The Alexa service abstracts away countless traditional complexities developers face once operating with voice interfaces, because it manages with the advanced speech recognition and text to speech aspects of the framework.
Developers have the adaptability to run and auto-scale their Skill’s backend rationale utilizing AWS Lambda, other AWS hosting choices such as Elastic Beanstalk or EC2 or to run scale and deal the code anyplace that the Alexa platform can reach with an SSL encrypted HTTP request.
If you are interested in exploring the code for this example skill some more, this is a good time to head up. Amazon additionally gives phenomenal tutorials and reference materials for Alexa developers, together with a walkthrough of creating an interaction model, a Lambda function, and sample utterances.
Join Coinmonks Telegram Channel and Youtube Channel get daily Crypto News
Also, Read
- Copy Trading | Crypto Tax Software
- Grid Trading | Crypto Hardware Wallet
- Crypto Telegram Signals | Crypto Trading Bot
- Best Crypto Exchange | Best Crypto Exchange in India
- Best Crypto APIs for Developers
- Best Crypto Lending Platform
- Free Crypto Signals | Crypto Trading Bots
- An ultimate guide to Leveraged Token