Link to first post: Creating My Own House Jarvis - part 1
Now that we have built an intent (HouseLightsIntent) and we have predefined slots and values . . . lets get into some coding:
For my HouseLightsIntent, I have the following Utterances:
- to turn {action} {entity}
- {entity} to {action}
- set {entity} lights {action}
- {entity} to {percentage_brightness} percent
- switch the {entity} {action}
- set {entity} to {color}
- {entity} lights {action}
- set {entity} to {percentage_brightness}
- set {entity} to {action}
- turn {entity} {action}
As you can see in the above âUtterancesâ, I have the following slot types:
- Action
- Entity
- Percentage_brightness
- Color
Each one of these is a âslotâ as defined in the slot types section on your left hand nav of the Skills console. My values for my Entity Slot are as follows:
- HVAC
- H. V. A. C.
- heater
- heat
- airconditioning
- air conditioning
- bathroom fan
- bathroom vanity
- kitchen cabinets
- kitchen cabinet
- homestead
- house
- thermostat
- laundry room motion sensor
- hallway motion sensor
- bathroom motion sensor
- bedroom motion sensor
- kitchen motion sensor
- kitchen overhead
- living room overhead
- living room lamp
- living room
- sunroom
- sun room
- hallway
- hall
- master bedroom
- bedroom
- kitchen
And my values for my âactionâ slot are as follows:
- brighten
- auto
- cool
- heat
- set brightness percent
- dim
- off
- on
Iâve put this here to help provide context. As you can see, with these two lists, I can then âtriggerâ my âHouseLightsIntentâ with phrases such as:
- Turn kitchen on
- Turn kitchen lights on
- Turn h. v. a. c to auto
- Set kitchen to red
Remember . . . you have to save and build your model for Amazon to understand how to âlistenâ to you.
Code
Node RED
So this is where the magic happens. Lets set up the âhowâ to communicate with Node Red first. Hop over to Node Red and do a node search for âHttpâ. You want this node:
Drag to your flow, and provide an endpoint name. Also make sure that it is set to âgetâ. This is VERY important in order to talk back to your skill. For my âHouseLightsIntentâ, I set my endpoint name to it lights. (attach a debug node to this too, set to entire message object) These endpoints will live under http(s)://yourdomain:1800/endpoint/ (in my case http://mydomain:1880/endpoints/lights)
Deploy your node. Hop over to your favorite API testing tool (I like Postman), and put in the full URL as we just discussed. Make sure that you are set to send a âGETâ request. Also (and this is key), you will need to set up âbasic authenticationâ which uses the USERNAME and PASSWORD as defined in your node-red config.
Hit send and see your debug output!! (if you have gotten it all right, and I havenât missed anything, you should see a msg object in your sidebar)
Alexa Lamda Code
Iâm assuming that you have already used postman to validate that your node red and that it is public and responds.
Hop back over to VS Code. First, at the top of your index.js file, add the following code:
const axios = require('axios');
(just put it right under the const Alexa = require('ask-sdk-core');
line). This is needed for us to talk to our webservice.
At the bottom of your file, but above this line: exports.handler = Alexa.SkillBuilders.custom()
, add this block of code (replace the XXXXXXX with the appropriate values from your node-red configuration):
const fetchURLwithJSON = async (url, jsonobj) => {
try {
let config = {
auth:
{
username: âXXXXXXXXâ,
password: âXXXXXXXX'
},
params: {
jsonobj
}
};
const { data } = await axios.get(url, config);
return data;
} catch (error) {
console.error('cannot fetch quotes', error);
}
};
const fetchURL = async (url) => {
try {
const { data } = await axios.get(url, {
auth: {
username: âXXXXXXXXâ,
password: âXXXXXXXX'
}
});
return data;
} catch (error) {
console.error('cannot fetch quotes', error);
}
};
What you just added was two different ways for you to communicate with your node-red http endpoint. One call allows for you to pass JSON to your endpoint (fetchURLwithJSON), and the other allows you to do so without any data (fetchURL). I created fetchURL this as my son wanted a ârandom dinosaur factâ, so all I care about is a response, I donât need to pass any data around.
Now . . . find a a code block that you can copy and paste. The hello world intent is a good place to start. Find this code:
const HelloWorldIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'HelloWorldIntent';
},
handle(handlerInput) {
const speakOutput = 'Hello World!';
return handlerInput.responseBuilder
.speak(speakOutput)
//.reprompt('add a reprompt if you want to keep the session open for the user to respond')
.getResponse();
}
};
Copy / Paste it and change it to look like this:
const HouseLightsIntent = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === âHouseLightsIntentâ;
},
async handle(handlerInput) {
const speakOutput = 'Hello World!';
return handlerInput.responseBuilder
.speak(speakOutput)
//.reprompt('add a reprompt if you want to keep the session open for the user to respond')
.getResponse();
}
};
Note: we made changes on the first, and fourth lines (replacing âHelloWorldIntentâ with âHouseLightsIntentâ), and on the sixth line, we added the âasyncâ key word in front of the âhandlesâ statement. We had to do this or our webservice calls wonât work.
Then at the VERY bottom of the file, find the âexports.handler
â line. Add âHouseLightsIntent,â just under the âLaunchRequestHandler
â (donât forget your comma), and your code should look like this:
exports.handler = Alexa.SkillBuilders.custom()
.addRequestHandlers(
LaunchRequestHandler,
HouseLightsIntent,
HelloWorldIntentHandler,
HelpIntentHandler,
Note: you will have to do this for EVERY intent you write, as the backend runtime uses reflection to find the methods it needs to execute. Save your code, and save often. Iâm assuming that you are still in VS code . . . so do the git command thing in your git terminal. This will push your code to Amazon, and make it your âcurrent version of code to executeâ. Switch back over to your AWS Skill console. At the top you will see a link that says code . . .open that bad boy in a new window and you should see your edits appear. If you donât, it means you didnât push your code right (go back and try again).
If you do see your code changes . . . click that deploy button. Wait for your deployment to be finished, and BOBâs Your Uncle!!! You have just edited the back end of your alexa skill and deployed it. It wonât do anything for you, but this is the start of your skillâs greatness.
Part 3 to come