Ever since I built a smart mirror with Alexa onboard, I have been looking for more ways to connect various hardware and home automation devices throughout our house. When I heard the new Alexa Smart Home API allows you to control custom devices directly, I decided to give it a try.
This Echo controlled Christmas Tree uses an older version of the API, but served as a great jumping off point and pointed me toward the IoT targeted Arduino Yún. This gives you a Linux system and a microcontroller all in one handy package.
The task I set for myself was the "hello word" equivalent of smart home skills... Just turn on and off an LED using my voice. Since I had a 2x3 LED array lying around, though I decided to turn that on and off for style points.
Full details can be found below, but here's how it turned out!
Project OverviewThis project aims to connect an Arduino Yún board to an Alexa Smart Home v3 skill. This is done using an Alexa Smart Home Skill (v3), an AWS Lambda Function, an AWS IoT Thing, and an Arduino Yún which is subscribed to the IoT Thing.
In the diagram below, you can see all the major pieces of this project involved in turning the light on.
I would recommend taking it one piece at a time and testing while you go. Nothing in the project is very challenging, but there are a lot of interconnected pieces. So don't be discouraged if you're scratching your head a bit while working through this.
I would think of each step as a mini project, potentially taking 1+ hours each.
Step 1: Create a Smart Home Skill and Connected Lambda.
Here you create a Smart Home Skill, create a Lambda function, and link these two together. This process is very well covered in this tutorial. Make sure to follow the LWA steps to get your client id and client secret used in the Skill Configuration.
At this stage, if you are able to login to the Alexa dashboard and discover your new smart home device (at this point just a Lambda function response), you're off to a good start.
Note, that tutorial uses Python 3.6, but I used Python2.7 instead. You can copy the handle_discovery
portion from my lambda function, but that's all that will work at this point.
Step 2: Create an IoT Thing.
Discovery isn't much good if you can't do anything, so let's give it something to connecting to by creating an AWS IoT Thing.
This can be done by following the steps on this page. We will be using the "Thing Shadow" of what you create, which is a copy of the state of a thing, along with the desired changes. The Arduino will subscribe to a notification feed that publishes the changes ("delta") to this Thing Shadow. Checkout this link here for more info the Thing Shadows.
Once you have created your Thing, navigate to the security tab in the Thing IoT web dashboard and download the public key, private key, and certificate. Once this is done, click "Activate" which will give you the Root Certificate Authority key. Save this as well. These will be used by your Arduino to authenticate to the IoT shadow.
Navigate to the Shadow tab of your thing, and click edit. Add a property to your shadow so it looks like:
{
"reported": {
"light": "on"
}
}
Step 3: Connect your Lambda to your Thing.
With your Thing in place, now you can update your Lambda code to update the thing shadow. Now you can copy the full code from my lambda function, but make sure to keep any Discovery related changes you made.
You should also make sure your AWS IAM role associated with the Lambda function has "AWSIoTFullAccess" permissions. You can see your role at the bottom of the Lambda Configuration web dashboard. This permission allows you to connect to the AWS IoT Thing.
Once this is done, navigate to the Lambda function configuration page. Under the test tab of your function, add a directive called "TurnOff" with the following v3 specific JSON. You can add a second test called "TurnOn" as well where you just change the header name to "TurnOn".
{
"directive": {
"header": {
"namespace": "Alexa.PowerController",
"name": "TurnOff",
"payloadVersion": "3",
"messageId": "1bd5d003-31b9-476f-ad03-71d471922820",
"correlationToken": "1234"
},
"endpoint": {
"scope": {
"type": "BearerToken",
"token": "some-access-token"
},
"endpointId": "appliance-001",
"cookie": {}
},
"payload": {}
}
}
When you run the TurnOn and TurnOff tests, you should see the Thing Shadow report a desired state consistent with the action. If you're seeing this result, all is well.
Step 4: Set up your Arduino Yún.
Time to setup the Arduino Yún hardware. I found this guide to be more useful than the Arduino guide. A few notes - if you're a windows user, when formatting the SD make sure to use FAT32 (exFAT is not supported). I also wasn't able to see the "upgrade" page properly until I was connected with ethernet. Once configured, wifi worked just fine.
You have completed this step when you have seen this option and followed the steps:
You should also be able to successfully ssh into your Arduino. I'd recommend running "df -h" as well and looking for a volume that suggests your SD card has been added.
Opening the Arduino IDE and verifying you can run the Blink example would also be good at this stage.
Step 6: Connect your Yún to AWS IoT.
With the Arduino up and running, let's get it talking to the IoT Thing. This is done by installing the AWS Arduino IoT SDK, and running an example sketch to monitor Thing Shadow deltas.
I recommend starting with this tutorial which does an excellent job walking you through the SDK installation process. Note to Windows users, if you're using cygwin just follow the Mac/Linux instructions (I had no trouble with the "expect" dependency). In particular, running the follow script from your host system makes life much easier:
./AWSIoTArduinoYunInstallAll.sh <Board IP> <UserName> <Board Password>
That tutorial ends by adding the AWS-IoT-SDK to the the Arduino IDE. Now when you open the Arduino IDE, you should find the ShadowThing example under File->Examples->AWS-IoT-Arduino-Yun-Library.
Open this sketch, and edit the aws_iot_config.h
file to contain your relevant endpoints and certificate / key names.
Running this sketch should show you a serial output indicating connection status was successful. If you change your thing shadow in the IoT dashboard, you should get a notification in the Serial logger.
If you are having problems at this stage, make sure your certificates are in the correct paths, and verify you have copied the Root-CA text into a file correctly.
Step 7: Connect your Yún to AWS IoT.
Now all that's left is actually handling the changes to your Thing Shadow on the Arduino. You should be able to simply copying the contents of my sketch.
My sketch is basically just the ThingShadow sketch example, except it looks specifically for changes to the key "light". When these are received, it sets all the pins in ledArray to HIGH or LOW based on whether light was "on" or "off".
This ledArray includes the onboard pin 13, so with no additional LEDs plugged in you will see the onboard YUN LED turn on and off based on your voice commands. If you want a fancier LED cube like I'm using, checkout this project which will tell you how to wire it up. Then just add the positive pin numbers to the ledArray in my sketch.
You'll know you're done this step when you are able to ask your Alexa device to turn on and off your custom smart thing.
If this isn't working as expected, I would suggest trying with your Lambda TestOn and TestOff functions in the web dashboard. This gives you more information about what may be going wrong.
Post comments with any issues you encounter that aren't covered and I'll address them as fast as I can!
Step 9: Celebrate!
If you made it this far, well done! Arduinos can do just about anything you want, and now you know how to kick that off with a simple voice command through Alexa. Celebrate your accomplishment by turning the light on and off many times. The IoT world is your oyster!
Comments