Warning: To make this work, you need to enable port forwarding on your router. Depending on your security setting this could be a safety risk! At least everyone who knows your IP and port will have access to VC!
Note: During the installation, you will need to register for an Amazon Web Services account, which is free but requires a Credit Card.
If you still want to try it, follow the instructions below:
1. Choose a free port on your computer and write it down. It will be used in several places during this process. Example port: 41000
2. Set up port forwarding on your router using the port in step 1, screens may differ by router type and manufacturer.
Direct it to the internal (LAN) IP of the computer running VoxCommando that you want to send commands to using the Echo. This is a necessary first step and the method will vary depending on your router make and model. Refer to Google search for instructions for your specific setup.
This may be optional, but make sure this is on.
3. Enable the "TCP" plugin in VoxCommando. (Do not confuse it with the TcpMic plugin.)
4. Open the TCP plugin settings:
- Under “Simple Web Server” check the “Enable” box and enter the port used above.
- VoxCommando includes an easy function to enable port forwarding on routers that support this function.
5. Click “Save Settings”, and then click “Launch in browser” to verify that it is working locally.
Optional: If possible, use a friend’s computer to test your port forwarding and TCP plugin settings by trying to access the simple web server from outside your LAN using your WAN IP address and the port above. One way to find your WAN is to use a site like
https://whatismyipaddress.com/6. Go to the Amazon Developer Console:
https://developer.amazon.com/edw/home.html#/skills/list (If you don’t already have an account, you’ll have to create one.)
7. Click
8. Fill in your skill name and make sure the
Custom Skill is selected.
9. Click
10. Make sure the
Start from Scratch model is selected.
11. Click
At this point your going to follow the steps of the skill builder check list:
12. Click
13. Enter your invocation name and click
14. Click the "Build" tab to return to the Developer console
15. Click
16. Enter
"PerformAction" as the intent name no quotes and click the Create custom intent button.
Note: You have to use/spell the intent name as shown or the skill will not work.Here is where you can get creative with the phrases that Alexa will recognize and pass through to VoxCommando, for the tutorial we will keep it simple.
17. Click on the +Add button next to Slot Types (0)
18. Type the word
"COMMANDS" as the slot type name and click the Create custom slot type button.
Note: You have to use/spell the slot type name as shown or the skill will not work.Here you can and add the most common used words of your VC configuration to the list. The list does not have to be complete! Click enter after each command to add it to your list.
19. Click
when you are finished.
20. Click the Performaction Intent you created earlier
21. In the Intent Slots section at the bottom type the word "Action" as the name and click the "+" symbol.
22. There will be a dot next to the word action, color will vary. Select "COMMANDS" as the slot type.
23.In the sample utterances section type "{" you will see your Action intent slot that you created, click on the Action Icon
You should see this now
24.
Hit Enter 25.
Click 26. Note the ID on the top of the page that starts with: amzn1.ask.skill... You will need to add this ID to your code later.
27. Open a new tab in your browser (keep the current page open) and go to
http://aws.amazon.com/. Create an Amazon Web Services account, if you don’t already have one.
28. Log in to the console.
29. Navigate to Services -> Compute -> Lambda
30. Click the region drop-down in the upper-right corner of the console and select either US East (N. Virginia) or EU (Ireland).
31. If you have no Lambda functions yet, click Get Started Now. Otherwise, click
32. Author from Scratch should be selected
33. Give the function a name of your choice.
34.Runtime needs to be set to Node.js 4.3
35. Create a new role from one or more templates
36. Type VCrole in the Role Name section
37. Choose AMI read-only permissions as the policy template.
38. Click
39. Delete everything from the codebox and paste in the following code:
//******* Pulls speech input and passes on to Voxcommando for custom events ******
var http = require('http');
var VC_ip = 'XXX.XXX.XXX.XXX'; // Add your WAN IP or DynDNS Host here
var VC_Port = '8096'; // Add the Port VC is listening to here
var VC_Event = 'EchoToVC'; // The name of the event which is created in VC
var EchoName = 'Room1'; // You can give your Echo a name here, which is transmitted as payload2 to VC. If you have more than one Echo this could
// be used to distinguish which Echo is sending the command to VC. To make us of this you would need to have one skill for each
// Echo, which unfortunately also means that each Echo needs to be assigned to a different Amazon account.
// Hopefully this can be replaced by the actual device name or ID at some time, but currently there is no way to do it.
var Echo_App_ID = "amzn1.ask.skill......."; // Add your Echo App ID here
exports.handler = function (event, context) {
try {
if (event.session.new) {
onSessionStarted({requestId: event.request.requestId}, event.session);
}
if (event.request.type === "LaunchRequest") {
onLaunch(event.request,
event.session,
function callback(sessionAttributes, speechletResponse) {
context.succeed(buildResponse(sessionAttributes, speechletResponse));
});
} else if (event.request.type === "IntentRequest") {
onIntent(event.request,
event.session,
function callback(sessionAttributes, speechletResponse) {
context.succeed(buildResponse(sessionAttributes, speechletResponse));
});
} else if (event.request.type === "SessionEndedRequest") {
onSessionEnded(event.request, event.session);
context.succeed();
}
} catch (e) {
context.fail("Exception: " + e);
}
};
/**
* Called when the session starts.
*/
function onSessionStarted(sessionStartedRequest, session) {}
/**
* Called when the user launches the skill without specifying what they want.
*/
function onLaunch(launchRequest, session, callback) {
// Dispatch to your skill's launch.
getWelcomeResponse(callback);
}
/**
* Called when the user specifies an intent for this skill.
*/
function onIntent(intentRequest, session, callback) {
var intent = intentRequest.intent,
intentName = intentRequest.intent.name;
callEchoToVC(intent, session, callback); // Whatever the Intent is, pass it straight through to VC
}
/**
* Called when the user ends the session.
* Is not called when the skill returns shouldEndSession=true.
*/
function onSessionEnded(sessionEndedRequest, session) {
}
// --------------- Main Intent Processing Function ----------------
function callEchoToVC(intent, session, callback)
{
var sessionAttributes = "{}";
var cardTitle = EchoName;
var shouldEndSession = true;
var payload = "";
var speechOutput = "";
var repromptText = "I could not understand, please try again";
var i = 0;
var slots = intent.slots;
//Pull the spoken text and format
var actionSlot = intent.slots.Action;
var setAction = actionSlot.value.toLowerCase();
var setActionURI = require('querystring').escape(setAction);
var VC_uri = '/api/VC.TriggerEvent&&EchoToVC&&' + setActionURI + '&&' + EchoName;
var get_options = {
host: VC_ip,
port: VC_Port,
path: VC_uri
};
// Set up the request
var get_req = http.request(get_options, function(res) {
var VC_results = "";
res.setEncoding('utf8');
res.on('data', function (chunk) {
VC_results += chunk;
});
res.on('end', function () {
if (res.statusCode === 200) {
//Parse the Body results from VC, if the command was unknow we will repromt
if((VC_results.indexOf('intent: UNKNOWN') > -1)||(VC_results.indexOf('cmd is unknown:') > -1)) {
shouldEndSession=false;
} else {
if(VC_results.indexOf('Return Msg: ') > -1) {
var lines = VC_results.split('\n');
for(var i = 0;i < lines.length;i++){
if(lines[i].indexOf('Return Msg: ') > -1) {
var rtn_msg = lines[i].split('Msg:')[1].trim();
if (rtn_msg !== '') {
setAction = rtn_msg;
}
}
}
}
}
}
callback(sessionAttributes,
buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession)); //Pass stingResult instead of speechOutput for debugging if needed
});
});
get_req.on('error', function (e) {
callback(sessionAttributes,
buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
});
get_req.end();
}
// --------------- WelcomeResponse Function ----------------
function getWelcomeResponse(callback) {
// If we wanted to initialize the session to have some attributes we could add those here.
var sessionAttributes = {};
var cardTitle = "Welcome to Echo To Voxcommando";
var speechOutput = "Hello, I'm this home's automation AI, what can I do for you";
// If the user either does not reply to the welcome message or says something that is not
// understood, they will be prompted again with this text.
var repromptText = "I could not understand, please try again";
var shouldEndSession = false;
callback(sessionAttributes,
buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
}
// --------------- Helper Functions ----------------
function buildSpeechletResponse(title, output, repromptText, shouldEndSession) {
return {
outputSpeech: {
type: "PlainText",
text: output
},
card: {
type: "Simple",
title: "EchoToVoxcommando - " + title,
content: output
},
reprompt: {
outputSpeech: {
type: "PlainText",
text: repromptText
}
},
shouldEndSession: shouldEndSession
};
}
function buildResponse(sessionAttributes, speechletResponse) {
return {
version: "1.0",
sessionAttributes: sessionAttributes,
response: speechletResponse
};
}
IMPORTANT:
Reminder: Make sure you have activated port forwarding for that port in your router settings.
40. Go to
https://whatismyipaddress.com/ to get you WAN IP.
41. Make sure to add your WAN IP and the port VC is listening to the code (line 5/6). Your WAN IP will probably change. In that case you would need to get a dynamic DNS account somewhere (e.g.
www.noip.com).
Optional: If you want, you can change the VC-EventName in line 7 and the name/location of your Echo in line 8.
42. Add your amzn1.ask.skill ID you noted above in line 13.
If you lost it, you can go to
https://developer.amazon.com/edw/home.html#/skills/listEdit your skill
ID will be in the URL
All red arrows are required for the skill to work:
[/img]
43. Click
44. Click "Alexa Skills Kit" from the Add triggers section
45. Add your amzn1.ask.skill ID here and click the "Add" button
46. Click
47. Under "Basic Settings" increase the timeout to 15 seconds or more, depending on how long your voice commands take to respond to the AWS service. If you have voice commands that use TTS.SpeakSync with long phrases or if your internet connection is slow you may need to increase this even more.
48. You should now see your ARN-Number in the upper right corner of the Lamda Management Console. (Starting with ”arn:aws:lambda…”) copy the number.
49. Switch back to the browser tab with the Amazon Developer Console.
50. Click
51. Choose AWS Lambda ARN
52. Paste in your ARN-Number:
53. Click
54. Click
55. Click
to build your skill.
56. To check progess you can click on the Invocation Name Step and you should see a building animation at the top.
57. If all goes well all 4 checkboxes should be green
Enable your new skill in your Alexa app on your phone, search for it by name under the My Skills section.
58. You can test sending events to VoxCommando using the “Test” tab.
59. Enable the test function and type your invocation name
60. If it works then you will get a greeting message.