Instructing the mirror to show a picture

Write some code to show a picture on the mirror as instructed by the debug hub.

As for the next step of the project I need to make sure that the mirror can display an image when it is asked to do so.  We need to take a few steps in order to accomplish that.

As a first step I will extend the debug hub to mimic the Alexa behaviour of adding an “SHOW-PICTURE” command to the DynamoDB command queue table.

For this, I will be extending the already existing “messaging.html” file.

But first, for good measure I’ll add another javascript file to contain a function which I would potentially need on other places as well :

Schermafbeelding 2017-02-12 om 18.22.19.png

The content is fairly simple :

Schermafbeelding 2017-02-12 om 18.23.15.png

It’s very similar to what the lambda function is doing actually.  Instantiate an AWS object and configure it.  Put an item and a payload in the command queue.

Ok, so now to extend the messaging section of the debug hub with another text area.

Schermafbeelding 2017-02-12 om 18.24.43.png

I gave the 2 text area’s an Id : command & content, and the button as well : submit.

As for the code : a simple call to the function we just created.

Schermafbeelding 2017-02-12 om 18.25.57.png

Notice how the text area values are obtained using a jQuery command.

Let’s test this.

Schermafbeelding 2017-02-12 om 18.26.45.png

Click the send button, an there’s the result :

Schermafbeelding 2017-02-12 om 18.27.16.png

The next step is to extend the magic mirror module for the Alexa interface.  In an earlier post I showed you how I used a “handleCommands” function searches for the items in the DynamoDB table and reads them to pass them on using the “sendSocketNotification” function.  I’ve added a little bit of code here.

Schermafbeelding 2017-02-12 om 18.28.58.png

Notice how I construct a JSON object and add the command and the content to it.  This is the payload of the “sendSocketNotification“.  This way, the module knows the command, but also the content it needs to display.

In the mirror module itself, this type of command is now handled by this piece of code in the socketNotificationReceived function :

Schermafbeelding 2017-02-12 om 18.31.45.png

Essentially, this is also fairly simple.  All it does is construct its own payload from the payload it’s receiving.  This is passed to a notification with as type “INFO-DISPLAY“.  This notification is to be handled by another module that takes care of the display functionality.  Notice how I deliberately didn’t call it “show picture” or anything.  Theoretically this info could be something totally different from a picture, so I’ve made it a bit more generic.

As it happens, I don’t have this module yet, so I decided to create it.  Here it is :

Schermafbeelding 2017-02-12 om 18.34.26.png

Our next little module.  Its configuration is easy :

Schermafbeelding 2017-02-12 om 18.35.01.png

Just put it in the middle of the screen.  That’s it.  No fuss (for now).

The code is pretty straight forward.  The standard stuff for a basic mirror module, but the “notificationReceived” function looks like this :

Schermafbeelding 2017-02-12 om 18.35.54.png

Here I check if the notification is “INFO-DISPLAY”.  Notice how I don’t check for the “type” attribute of the payload yet. I’m just assuming that it’s some name of someone or something I’m getting passed a long, of which I need to show the picture.

The showing of the picture is setting the “src” attribute of an image, and setting it to visible.  I’m sorry if I’m violating some copyrights here by taking an online image, but that’s just the easiest way to test this.

The “this.imagepointer” is a variable that is created in the “getDom” function of the magic mirror module.  It looks like this :

Schermafbeelding 2017-02-12 om 18.38.37.png

Just create an “img” tag and append it to the wrapper.  Reset the “src” attribute, give it some dimensions and hide it.  From here on, the “this.imagepointer” can be used in the mirror module without a problem, and that’s just what happens in the “notificationReceived” function.

I’ve got a node helper for this one, but it doesn’t do anything for now.  That’s the next step: have it get a picture from the content that it has been passed, and pass it back to the mirror module to be shown.

But that’s for the next post.  Here is the result for now :

Schermafbeelding 2017-02-12 om 18.42.55.png

Cheers!

Connecting to DynamoDB using the debug hub

Modify the debug hub to create a connection to the DynamoDB table.

In my last post I showed you how I created a new table in DynamoDB.  Now it’s time to access it, and then the contents to our Debug Hub.

In order to do so I will need the AWS SDK (software development kit) installed in my project.  You can find the details here :

https://www.npmjs.com/package/aws-sdk

Just install it into the debug hub project.

sudo npm install aws-sdk

So I’ve extended the index.html page of the Debug Server to allow a new item in the sidebar, pointing to a newly create html page.  I called it “Dynamo DB”.

Schermafbeelding 2017-01-31 om 19.12.42.png

I will be connecting to the service with my own credentials.  That is : the credentials I created in my last post, the “smartmirror” user.

Schermafbeelding 2017-01-31 om 20.37.46.png

To do this efficiently, I will create a new JSON file in the root of my project.  In it, I will have to specify the following things :

  • The Access Key ID.  Information I got when creating the user.
  • The secret Access Key.  Also obtained after creating the user.
  • The region.  Very important.
  • The endpoint : the URL at which the AWS service can be reached. Notice how the region is part of the endpoint as well.

If you want to know the region, you can check out the details of the table created in DynamoDB.  It has a unique ARN (amazon resource name).  In it, you can see the code of the region you’re in.

Schermafbeelding 2017-01-31 om 19.43.55.png

So now for the code.  I will start by editing the dynamodb.html file to add a button and a grid.  The button will start a function that retrieves the data from the table. The grid will display the result.  This is quite straight forward.  We did that before when creating the page for the debug server.

Schermafbeelding 2017-01-31 om 20.37.25.png

Notice how I called the button “getcommands”.

The code is visible in the screenshot below.

Schermafbeelding 2017-01-31 om 20.37.39.png

There are some things to be said about this code.  At the bottom you can see the jQuery statement linking the button to the getCommandQueue function, which will do all the dirty work.

This function first requires the “aws-sdk” module, which we installed earlier.  It then configures it using the JSON file we created.  This way we can configure the connection with one single statement instead of having to set the access keys every single time.  That wouldn’t be very secure either.

Next a new variable is created called “params”.  This is an object that will be sent along with the query, and contains all the information needed to get data from the table :

  • The table name
  • An expression showing a filter
  • A mapping to the correctie field
  • A mapping to the correct value

the condition has a syntax whereby the field is represented by a placeholder prefixed with a # symbol, and a value placeholder prefixed with a : symbol.

These placeholders are resolved in the next 2 attributes of this parameter JSON : we map the column to the “Session” attribute, and we map the value to hardcoded “1234”, which is the key I specified when creating a record in the table.

And next, we’re all good to go.  The query method is called of the docClient object which is responsible for the communication with the DynamoDB  service.  The param is passed along, and there’s also a callback function.  It has 2 parameters.  When an error is returned, the “err” parameter will contain the details of the error.  When the call is successful, the data will be in the “data” parameter.  With this “data”, a foreach loop is executed, and it adds the result to the table.  The AddRow function can be seen below.

Schermafbeelding 2017-01-31 om 21.53.17.png

That that’s it.  Below is the result of this endeavour.

Schermafbeelding 2017-01-31 om 20.35.04.png

Good Luck!

Creating a DynamoDB Table

Steps to create a new table in DynamoDB, and populate it with some values.

Now it’s time to get cracking with DynamoDB.  DynamoDB is one of the services you can use with Amazon Web Services.

In order to access these, just go to http://aws.amazon.com.

If you’ve registered for it, you can log into the console at the top right hand side of the screen.  Once you did that you will see your console.  The top of the page will look a bit like the screenshot below.  I’ve added some extra buttons at the top, but what’s important is the region at the right hand side of the screen.

Schermafbeelding 2017-01-31 om 21.08.34.png

With me it’s set to “Oregon“.  Which was the default when I logged on.  It’s important you keep it at this one.  If you go and use one of the services in this region, and you switch to another region later on, you won’t see the tables you created for example.  Also, not all services are available in all regions.  So keep that in mind.

But before I begin, I want to create a new user that is able to connect to the service.  You can do that in another service called “IAM“.  Locate the IAM service in the services overview you can find by clicking the “Services” dropdown at the top left hand side of the screen.

Schermafbeelding 2017-01-31 om 19.13.16.png

In the screenshot above you can see my recently used services, and IAM is one of them.

If select it, you are able to create a user.

Schermafbeelding 2017-01-31 om 19.00.05.png

I will go ahead and do so by clicking the “Add user” button.  The system prompts me for a user name and I’ll call it “smartmirror“.

Schermafbeelding 2017-01-31 om 19.00.39.png

I made sure sure to click the “programmatic access” type in order to be able to connect with it from an external application.

Next, you’re able to give the user some permissions.

Schermafbeelding 2017-01-31 om 19.01.59.png

There are 3 ways to do so : by adding him to a group, by copying existing permissions, or by attaching policies.  I will choose the last one and search for the “AdministratorAccess” policy.  This will allow the user to do everything including create and drop tables, insert, query, etc.  Just click the checkbox and confirm.

When the process is complete you will see an overview like the one you see in the screenshot below.

Schermafbeelding 2017-01-31 om 19.02.32.png

 

You can see the user got a unique access key ID, and a secret.  These 2 things, we can use to connect to the mirror using the “smartmirror” user credentials.

Ok, so now it’s time to create a new table.

In fact, before doing so, you should familiarise yourself with the concept of a NoSQL database, because that’s what DynamoDB is.  It is very different from a relational database like the most of you will know in that sense that it is not optimised for storage, but rather for read speed.  In order to accomplish this, it uses a different technology in which the rows (or items if you want to call them) are stored in a JSON format in tables.  Unlike relational tables these tables hardly have a fixed structure.  The structure of the table can vary row per row (or item per item if you will).  Just google it, or watch some video tutorials on it.  Digging deeper is beyond the scope of this blog post.

So, go back to the console and this time choose the DynamoDB service.  If all is well you should get to a welcome page where you will be prompted to create your very first table.  Just click that button, and the page you will see next will resemble the one below.

Schermafbeelding 2017-01-31 om 19.16.17.png

You will have to choose a table name.  I called it “CommandQueue”.  This is the table in which I will store the commands issued to Alexa, and which are to be sent to the mirror.  Or rather, for which the mirror will poll.

I have to specify a partition key.  This is the primary key of the table.  I can also add a sort key, but that’s about it when it comes to metadata.  I call them “Session” and “Timestamp”.  Also keep the default settings activated, and click create.  The details of what a partition key and a sort key is, is beyond the scope of this article, so please google to get more information on the NoSQL principals for more info.

If all is well, that will bring to the the AWS DynamoDB console.  The interface will look similar to the screenshot below.  You can see the table was created, and there are currently no items in it.  Check it out by clicking the “Items” tab at the right hand side of the screen.

Schermafbeelding 2017-01-31 om 19.16.59.png

We will go ahead and add a new item.  In the interface you will be able to give a value for the Session and Timestamp attributes, but I can also add other parts, as I will do here.  I will add a “command”, as a string value, and set it to “HIDE-ALL-MODULES”.

Schermafbeelding 2017-01-31 om 19.19.01.png

Check out the result below.

Schermafbeelding 2017-01-31 om 19.19.11.png

Allright.  All ready now to start reading from the table.