Particle Photon + RF Outlets + Echo Dot | Pt.2

This post is Part 2 on setting up your own home automation using RF outlets. The Amazon Echo and Dot portion of the tutorial can be found here. Check out Part 1 for the beginning of this project.

Amazon Echo Add-on

The Amazon Echo has become the de-facto in-home vocal task service via the Alexa Skill set. Alexa Skills let Alexa do more by using her voice matching to run snippets of code to accomplish small actions. In our case, we’d like Alexa to hear us say either a full sentence or secret phrase to turn the house outlets on and off. Creating an Alexa Skill is fairly painless with only a couple of accounts to set up, some Amazon services to configure, and coming up with a cool choice of words to activate the program.

Step 1: Order an Echo or Echo Dot

Image via wonderhowto.com

Ordering an Amazon Echo is easy. If you are one of the few who has never ordered from Amazon, it’s as simple as adding it to your cart and checking out and optionally signing up for an account.

Grabbing the Echo Dot is…restricted…for lack of a better term. To snag one, you’ll need to use either an Android or iOS device to finagle it into your cart. Update (6/13/16): However, since demand has been very high for the Dot, it could be on backorder until the Fall.

The Dot is back! Grab it here.

Buy an Echo, and giggle happily when it arrives!


Step 2: Set up your Echo or Dot

Image via CNet

Amazon provides some good instructions in the Echo’s or Dot’s packaging. Both devices need a connection to your WiFi – which can be set up through an Android or iOS app – and both have speakers for vocal feedback. Though, I’d recommend hooking the Dot up to either a pair of standalone speakers or a Bluetooth one in order to hear Alexa a bit better.


Step 3: Sign up for an Amazon Dev account

Amazon’s developer portal allows you access to a lot of incredible apps that make creating anything from websites to Android apps to Alexa skills a breeze. Sign up for an account as we’ll need it in the next step to create a custom Alexa Skill in order to talk with Alexa about turning the outlets on or off. And, the best part: it’s free!


Step 4: Sign up for an Amazon AWS account

Likewise, you’ll need an AWS account in order to create a free Lambda function – a small Node JS package invoked by giving Alexa a command. And, the sample code I’ve provided also needs AWS’s DynamoDB to store the state of groups of outlets. You can sign up for an AWS account for free, as well. Using a Lambda function and DynamoDB table are also free, though, you may pay nominal fees for Data Transfer (last month’s bill was a whopping 3 cents, as in $0.03).


Step 5: Create a custom Alexa Skill

Buckle up. Here we go.

Step 5a: AWS Lambda Setup

First off to getting the Alexa Skill underway, stroll on over to the Lambda function setup. You can get there by logging into the AWS Console and dropping down the Services button at the top of the page. Choose the “Lambda” link.

If it’s your first visit here, hit the Get Started link. Otherwise, use the Create a Lambda function button. You’ll be taken to the very first step of creating a Lambda function. Congratulations! …Now, skip it. Seriously. While Amazon does offer some great blueprints, we won’t need to use them for this project.

1-lambda-create-function-step-2

That will bring us to Step 2. You’ll need to enter a Name for your function.

Next, you’ll have to upload a Zip file of the code to be run. Since I’ve created an Alexa skill already, you can use my code. Download a copy of the code to your local computer. Before zipping anything for upload, copy the Creds-example.js file to Creds.js and fill in your Particle login email and password. The Lambda function uses Particle to communicate with the outlets, and the credentials gain the function access to the Particle Cloud API to do so. Finally, Zip up the index.js, AlexaSkill.js, node_modules folder, and Creds.js. Upload this zip file via the dialog button.

Lastly for Step 2, on AWS, a role has to be created in order to grant the Lambda function any permission it needs. So, you’ll have to create a “Basic Execution role” as seen at the bottom of the above screenshot. Once you’ve selected that option, you’ll be taken to an AWS Identity and Access Management page just like the one below.

2-lambda-create-iam-role

The role and name will already be filled in for you. Accept the creation of this role by clicking the Allow button at the bottom right, and you’ll be taken back to Step 3 in our Lambda function.

3-lambda-create-function-step-3

After reviewing all settings look good, hit Create Function.

4-lambda-create-function-event-source

Once the function has been added, we’ll need to set one of its invocation points as an Alexa Skill. To do that, go into the function’s options by clicking on its name link. Go to the Event Sources tab, and click the “Add event source” link. Choose “Alexa Skills Kit” and Submit.

5-lambda-code-screen

One final item. Remember (or copy or write down or photograph) the ARN ID number for your Lambda function. We’ll need it later on in the Alexa Skill to reference this Lambda function directly.

Step 5b: AWS DynamoDB Setup

Next, we’ll need a JSON database – more widely known as NoSQL. Amazon offers DynamoDB to do just that. You can get there by logging into the AWS Console and dropping down the Services button at the top of the page. Choose the “DynamoDB” link. Hit the “Create table” button.

1-DynamoDB-create-table

Name the table something like “Switch” – as seen in the screenshot. Create a Primary Key for the table also. I used “SwitchID”. These names are important as they are referenced in the Lambda function code. If you do want to change them, you’ll also need to make changes to the index.js file, as well. Once you hit Create, the table should go through the initialize process. It’ll take a moment, but maybe go grab that cup of tea now to keep you going through the rest of this step-by-step.

Once you are back at the main dashboard, hit the Tables section in the left sidebar, select your Switch table, and go to the Items tab.

2-DynamoDB-add-items

This area shows the data being kept persistently for use in the Lambda function. If you hit “Create Item,” you can add a new row to this table. In my example, use the SwitchID to reference a unique location, and then you’ll also be able to add strings for description, location, and toggle via the “+” button.

2b-DynamoDB - add item

Once you’ve initialized these rows in DynamoDB, that’s it! Great job. Be sure to grab the ARN of this DynamoDB table, as it’ll be needed in the next partial step.

3-DynamoDB-table-resource-ID

Step 5c: AWS IAM Setup

For our next trick, we want to give the Lambda function the permission to change things in DynamoDB. To do that, Amazon offers the ability to add/change/remove policies that control access to certain actions via the IAM (Identity and Access Management). To get there, drop down the Services menu from the top left, and select IAM.

Once IAM loads, go to the Roles section by way of the left sidebar.

1-iam-roles-screen

From here, you should already see the role that we set up earlier in Step 5a. Let’s click on this one and see a little more info on it.

2-iam-dynamodb-policy-add

We need to add a policy to this role, and to do that, click the “Create Role Policy” button.

3-iam-dynamodb-policy-specifics

Choose the Custom Policy option and hit the Select button. Name your policy something descriptive of its purpose – like DynamoDB_Switch_read_write. Copy the below JSON into the policy body section, making sure to change the “Resource” to match the ARN ID string from your DynamoDB table that you saved earlier.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:GetItem",
                "dynamodb:UpdateItem"
            ],
            "Resource": [
                "arn:aws:dynamodb:------------:table/Switch"
            ]
        }
    ]
}

Hit the “Apply Policy” button, and you’ll be in good shape to continue onto the final task: Creating the actual Alexa Skill.

Step 5d: Alexa Skill Options

We begin our adventure at the start: the Amazon Dev Console.
1-dev-console

Head over to the Alexa section of the Dev Console via the menu at the top.

2-dev-console-alexa

Next, you’ll see a choice for delving into either an Alexa Skill or Alexa Voice Service. Choose the Skills Kit. Select the “Add a New Skill” button.

The first step of the Alexa Skill is three-fold: select the skill type, name it, and choose what you’ll say to Alexa to activate it. Here’s where you have freedom to use whatever command you want. But remember, with great power comes great responsibility. Name it something you don’t mind saying every day.

3-alexa-interaction-model

The Interaction Model is arguably the most important part of setting up any Alexa Skill. It’s how Alexa takes what you say and interprets it to actual actions and responses. My own Alexa Skill – The Cantina – uses this Intent Schema compatible with the Lambda function I wrote.

{
  "intents": [
    {
      "intent": "switchLightsState",
      "slots": [
        {
          "name": "switch",
          "type": "ON_OR_OFF"
        },
        {
          "name": "roomlights",
          "type": "ROOM_LOCATION"
        }
      ]
    }
  ]
}

Custom Slot Types allow for sending in dynamic values like the location of the action and the action itself (in my case, “on” or “off” for the outlets). Add these types in via the “Add Slot Type” button.

Lastly on this page, Alexa needs a primer on how to match what you say to action items under the Sample Utterances section. To do this, add any variation that you anticipate of how to say your command. Focus on anything that adds determiners like ‘a’, ‘the’, or ‘every’ or prepositions that include more detail about the action. See mine here:

switchLightsState turn lights {switch} in the {roomlights}
switchLightsState turn the lights {switch} in the {roomlights}
switchLightsState turn {switch} {roomlights} lights
switchLightsState turn {switch} the {roomlights} lights
switchLightsState turn {roomlights} lights {switch}
switchLightsState turn the {roomlights} lights {switch}
switchLightsState turn {switch} the lights in the {roomlights}
switchLightsState {roomlights} lights {switch}

Remember to hit the Save button at the bottom when you are finished.


Also, the Lambda code is written in such a way that if a phrase such as “Alexa, launch The Cantina” is used – no extra detail is given – it defaults the location to “living room” and toggles the switch position. You can change the default location by modifying the Lambda function code here:

.... 
//index.js, line 87

if (intent != undefined && intent.hasOwnProperty('slots') && intent.slots.hasOwnProperty('roomlights') && intent.slots.roomlights.value != undefined) {
	location = intent.slots.roomlights.value.replace(/ /g,'');
	raw_loc = intent.slots.roomlights.value;
}
else {
	location = 'livingroom';
	raw_loc = 'living room';
}
....

Next, we’ll move on to the Configuration step.

4-alexa-config

Here’s the place to copy-pasta the ARN ID of the Lambda function from Step 5a. It looked a little something like this:

5-lambda-code-screen

Select ‘No’ for Account Linking and Save the Configuration, as well.

Now, head to the Test page.

6-test-screen

In order for your Echo to be able to use this new Alexa Skill, you’ll need to hit Enable on the testing if it isn’t set to that already.


Test It

Try launching your new Alexa Skill by talking to your Echo or Dot. If everything went right, you should be able to toggle the outlets you set up in Part 1 all by talking to Alexa.

If you do run into issues, or it flat out doesn’t work, there are some troubleshooting options to try.

Incorrect Alexa Response

If you don’t hear Alexa say “May the lights be with you!” (the default response in my Lambda function code), then that usually points to a syntax or execution error in the Node JS code for the Lambda function. To see exactly what the Lambda function is doing and possibly where it is stopping abruptly, visit the log files for your Lambda function.

Lambda-function-monitoring
Lambda-function-logs

Outlets Don’t Switch

If outlets aren’t switching, a few places may hold the key as to why not. Besides actually seeing the toggling from on to off and vice versa in the DynamoDB Switch table, the Particle Photon shows logs in the Particle Dashboard with signals it has received for location and switch position. If you aren’t seeing consistent on/off toggling, check the credentials you gave in the Creds.js file work correctly.

Also, it’s possible that the Lambda function still doesn’t have correct permissions to modify DynamoDB. Check the IAM access policy for the lambda_basic_execution role by matching the policy definition with DynamoDB policy generator:

dynamodb-policy-gen

Leave the “Condition” section of the policy out as its restriction isn’t necessary for Lambda to access DynamoDB via your own AWS account.

Lastly, check all ARN ID numbers were entered correctly in their respective places during the tutorial as that’s a common and easily fixed issue too.


Where From Here?

If you are anything like me – let’s be honest, that’s a mixed bag – then you are probably wondering “how could I improve this?” or “what can I add?” or “when can I control this with my brain?”. Other than that last question, I do have some thoughts on the simpler requests. You be the judge if they are worthy of pursuit.

Organize the Outlets/Devices in a Database

If you saw my “spaghetti code” in the .ino file (Part 1), you may have been thinking “why?” or “wtf?!?!” or “stop”. And, I don’t blame you. Let me defend myself by saying I just haven’t gotten around to making it better yet. But, a way I would improve the code is by taking all the hard-coded elements like the outlet RF codes, the locations the outlets live in the house, and maybe even a tracker for if they are on or off, and move them into AWS’s DynamoDB as a means of storage.

Customize Outlet Groups

Your house or apartment setup isn’t like mine. So, you’ll definitely want to customize a lot of my code in order to match your setup. My Lambda function code index.js file defaults to sending any command that doesn’t specify a room – like “Alexa, open The Cantina” – to toggling the outlets for just the “living room.” You’ll want to change that to work with your home configuration instead.

Add New 433MHz Devices

Many devices such as garage door openers, home alarm systems, smoke detectors, and the like have 433MHz versions which can be controlled via keypresses over RF from afar. Adding these devices to the system wouldn’t be very difficult if you can identify the RF codes/format/etc.

Use Alexa Smart Home API

Amazon’s Alexa Smart Home API came out shortly before I finished making the custom Alexa Skill. At that point, I wasn’t turning back to use something new since I knew I had something that worked. In order to really shortcut the Alexa app launch speech format and use a more natural way of speaking – like “Alexa, turn the lights off” – you can use this Smart Home framework in your Alexa Skill instead.



I had a lot of fun tinkering on this project and I hope that for just one person, this little tut was useful. Thanks for checking it out (and suffering some bad jokes along the way), and don’t be afraid to comment either. I hope to help in any way I can!



Leave a Reply

Your email address will not be published. Required fields are marked *