It would be really great to have an imp agent handle Alexa voice commands, I’m surprised this hasn’t already been covered here. I’ve noticed the provision of the AWSRequestV4 library but I’m just not understanding how this all fits together. Where’s Aron when you need him?
I got my Dot a couple days ago and while I didn’t write any custom skill yet like Aron did, last night it took me about 10 minutes to get Alexa to trigger LEDs on my imp via IFTTT. Not as cool as using a custom skill but pretty easy to do.
If anyone is interested in details, I can provide them but in a nutshell, I used IFTTT with Alexa “Say a specific phrase” trigger to make a web request to the Maker channel which calls an endpoint in my agent code. Very simple integration that unfortunately doesn’t send back any content that Alexa can say but it works.
For some arcane reason, IFTTT isn’t available to Alexa in the UK so that simple method won’t work for me. There is, however, a walk-through guide (https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/steps-to-create-a-smart-home-skill) that pretty much delivers the goods. It just needs an http request to the agent to be inserted in function “callDeviceCloud”. The walk-through creates a skill adaptor for Smart Home integration rather than a general skill which suited me better, but once you get into writing skills it’s all pretty similar.
I played around and did a quick&dirty integration with a general skill.
i like how amazon implemented to Test the Skill.
thanks async agent to device communication i have basic code running to get/do different things with alexa+imp.
Alexa, ask Imp about my indoor/outdoor temperature (humidity)
Alexa, tell imp to open/close the Garage Door
Alexa, tell imp to switch the heater on/off
after cleaning the code a little bit and giving a few credits i could put it to my github repository.
That sounds very cool Chrischi. do you have some code running on the Lambda compute service that talks to your imp agent or is there a direct communication? I found it very hard working with the online IDE for Lambda so I ended up trimming down the handler function to the point where it just passed entire events to the imp agent which does all the parsing. I didn’t get around to finding out if there was any way of bypassing the handler altogether and passing the event out direct to my agent.
`
//agent code
const TIMEOUT = 15; // close hanging async requests after 15 seconds
responses <- {};
// create unique keys for responses table
function generateKey() {
local key = math.rand();
while (key in responses) key = math.rand();
return key.tostring();
}
function responseWatchdog() {
imp.wakeup(1, responseWatchdog);
local t = time();
foreach(key, response in responses) {
if (t - response.t > TIMEOUT) {
responses[key].resp.send(408, "Agent Timeout");
delete responses[key];
}
}
} responseWatchdog();
device.on(“asyncdata”, function(data) {
if (!(data.k in responses)) {
server.log(format(“response %s already timed-out.”, data.t));
return;
}
responses[data.k].resp.send(200, http.jsonencode(data.d));
delete responses[data.k];
});
http.onrequest(function(req, resp) {
try {
local path = req.path.tolower();
// if user sends response to /asyncdata/...
if (path.find("/alexa") == 0) {
// generate key, and store the response object
local responseKey = generateKey();
responses[responseKey] <- { resp = resp, t = time() };
// this is what we're asking the agent for
local requestedData = "unknown";
if (path == "/alexa/temp" || path == "/alexa/temp/") requestedData = "temp";
else if (path == "/alexa/outtemp" || path == "/alexa/outtemp/") requestedData = "outtemp";
else if (path == "/alexa/hum" || path == "/alexa/hum/") requestedData = "hum";
// request asyncdata from the device:
// k is the response key - we'll use this in the response
// r is what we're looking for from the device
// d is an object that will store the data
device.send("alexa", { k = responseKey, r = requestedData, d = null });
return;
}
if ("garage" in req.query) {
device.send("garage", req.query["garage"]);
resp.send(204, html);
}
else {
// if they send a response anywhere else, just send a 200 back
resp.send(404, "Unknown");
}
} catch(ex) {
// if there was an error, send a 500 back
resp.send(500, "Internal Agent Error: " + ex);
}
});
`
Quick & Dirty. Don’t know from where i got the async code.
So credits go to some unknown guy.