And now for the final part of the journey. Getting the commands sent by the lambda functions to the mirror. The idea is that the mirror will read from the CommandQueue dynamoDB table, execute the command, and remove the entry from the queue.
But we first need some trigger for the mirror to start polling for the commands in the queue. To do that I’ll be adapting the AVS java client some more. I’ll create two new functions in the mirror interface :
They are quite straight forward. We can call them from the AVSController java class where the overrides for AlexaSpeechStarted and AlexaSpeechFinish are defined.
Rebuild the java client, and test that thing by issuing a question to Alexa and catching it in the Debug hub :
Works great. Time to change the debug a bit to be able to send those functions to the mirror as well. So some extra buttons in the Alexa.html file :
Now to for some extra code in the mirror software. We first need to do some plumbing like install the AWS SDK. While in the Smartmirrorproject subdirectory enter
sudo npm install aws-sdk
Then copy over the aws.json file from the root of the debug hub folder to the root of the smart mirror project folder. We’ll be using the same settings to talk to our DynamoDB instance.
Now for adding some code to the mirror interface module node helper. Look a the start function override below :
First we configure the DynamoDB and instantiate the docClient variable. We add 2 cases in the switch to handle both the speech-started and speech-stopped commands.
The first one looks for commands in CommandQueue table. It does this by creating a params object and stating the name of the table. Next, we need a projection list. This is a list of columns that is to be returned by the docClient. Well, something annoying came up here. Apparently both the “session” and “timestamp” columns seem to be reserved words. You can’t use them as a column name if you want to query them this way. So, some refactoring needs to be done. I renamed them to session_id and time_stamp.
The data is being read using the “scan” method.
The second command handler deletes the entry from the command queue. But just in case there was an error earlier, and a command has been left in the queue, all the items have been read, and they will all be deleted in the for-loop. The delete is being done by the “delete” method. Below you can find the slightly refactored lambda function with the new column names.
Notice how both the delete and scan object require a callback, and a reference is passed to 2 existing functions. Below you can see their definition.
The handle function sends the actual socket notification but also pushes the delete parameters for the delete command to a local array. The QueueClear handler just issues some logging.
In order to make this work, we will need to change the ipWhiteList setting of the smart mirror. If not, it will not accept requests from the java client. You will also have to make sure the Java client on the Pi sends to the correct address and port.
Ok, so let’s test it. Below is some output of a working session where admitted – by accident – 2 entries were in the queue, but they were both executed succesfully.
What’s left is add some extra functionality to allow showing the default modules as well.
That’s done pretty fast. Extend the lambda function :
And provide an intent schema + utterances in the skill.
And that’s it! A milestone in our development. We got Alexa talking to our start mirror. Time to get to more advanced and cool stuff.