Software apps and online services
The goal of this tutorial is to make a light sensor turn on my office light when the ambient light levels fall below a certain level.
The purpose of this tutorial is to show how through AWS services, IoT devices like the Intel Edison can be used to enhance consumer out-of-the-box products like the Philips Hue home automation lighting system.
This tutorial uses a collection of services and IoT hardware. When at all possible, I've purposely taken "the path of least resistance" when designing the project architecture. I've also tried to keep the components used in the architecture as modular as possible. For example, you can still use the AWS framework described here, but aren't restricted to only using the Intel Edison as your IoT device. That being said, there are probably more sophisticated solutions to my project's goal, but for now I just needed to give myself a baseline to work from.
With goal in mind, we need the following "solutions":
- Something to sense light levels and transmit the information to a service that can do something with it. (Intel Edison + AWS IoT)
- A service that can use my sensor's input and make a decision about turning my light on or off. (AWS IoT)
- A service that can send a decision for my light to my Hue. (AWS Lambda, IFTTT)
- Something to let all of the services talk to each other in a common way. (AWS SNS)
Below is a high level end-to-end schematic of the project design. In summary, the Edison transmits the light level to AWS IoT. IoT accepts the input and in real-time makes a decision to pass along the data or ignore it. In this case IoT only passes along data messages if the light sensor reading is less than 400 lux. AWS IAM verifies IoT has permissions to publish messages to AWS SNS. SNS funnels the message to a topic to which our AWS Lambda function is subscribed. IAM verifies SNS has the permissions to trigger Lambda to execute some code. Lambda runs its code, which sends a message off to IFTTT. IFTTT is listening for messages from us on the IFTTT Maker channel. When IFTTT receives a message it runs the recipe function we've setup to tell the Hue to turn my office light on.
* This tutorial assumes you have configured the Edison and Edison breakout board to accept connections to sensors. It is assumed you also have connected the Edison to your wifi network and can upload your code using the Intel XDK IoT Edition. *
If you need to configure your Edison, please view my tutorial: Yet Another Edison Getting Started - with the Breakout Board. Also note you will have to solder header pins onto the SI1145 sensor as well. See SparkFun's step-by-step soldering tutorial for more info.
Attach the SI1145 Light Sensor
Turn the power to your Edison OFF for this step!! Using four board jumper cables, connect the Adafruit SI1145 sensor to the Edison. The SI1145 uses the I2C protocol, which means there will be a wire for data transmission and a separate wire for syncing the sensor to the Edison. There are also two wires for power; one for ground and one for the "live" wire. Since we are only connecting one sensor you can use the 3.3V power output pins directly on the Edison breakout board. If you need to reference the pinout map for the breakout board, please see the schematic section of my Yet Another Edison Getting Started - with the Breakout Board tutorial.
My wire color code choices:
- BLUE = SCL
- GREEN = SDA
- RED = ground
- ORANGE = "hot" wire
We will be using the SDA, SCL, 3Vo, and GND connections on the SI1145. The other connections will be unused. The I2C data connection are labeled SDA (for data), and SCL (for clock sync) on the SI1145 pins. There are two I2C busses available on the Edison, and I chose to use bus 1 for this project. (The other bus is called bus 6.) This is important because for this particular sensor you have to define in your code which bus you are connected to.
Connect the SI1145 SDA pin to I2C-1 SDA pin located at J18-6 on the breakout board. Also connect the SI1145 SCL to I2C-1 SCL pin located at J17-8.
Now connect the power wires. As good practice, always connect the ground wire first before connecting the live wire. The ground wire connects to J19-3 and the live wire connects to J20-2.
Here's what the finished wiring should look like:
For more information on the Adafruit SI1145 sensor:
Install the AWS SDK and AWS IoT SDK
Since this tutorial assumes you have already configured your Edison to allow ssh connections over your wifi, we will login using the Edison's IP address. and the password you would have given your Edison in my Yet Another Edison Getting Started - with the Breakout Board tutorial.
Once logged in to the Edison command line, install the AWS SDK as well as the AWS IoT SDK. Luckily the Node.js npm already is aware of the sdk's and can grab them automatically without us having to download them first.
1. Check to make sure the repository is up-to-date.
2. Install the AWS SDK
npm install aws-sdk
3. Install the AWS IoT SDK
npm install aws-iot-device-sdk
4. To make sure the Edison knows how to talk to the sensor, we need to verify the sensor's libraries are installed. The libraries for the SI1145 (as SI114x) are already installed with the OS version (25.5-15). But, in the past I have found they are not installed on the 05-15 OS, for example. You can check to see if the SI114x libraries are installed by typing the command:
npm list -g jsupm_si114x
and the package should be listed as installed in /usr/lib.
For more information on how to use npm, see the npm documentation.
Before we start coding or setting up the AWS services, its a good idea to first configure IFTTT to talk to our Hue. The reason for this is we will need to have the event name for our Maker Channel recipe. We need this name on hand when we configure AWS Lambda so Lambda knows where to push messages (event name is the receiving end of messages sent by Lambda.)
1. After you register with IFTTT, select "Recipes" from the menu bar at the top of the page. Select the "Create a Recipe" button. You will then be asked to choose the trigger channel.
2. Subscribe to the IFTTT Maker channel and Hue channel. The maker channel can be used for sending messages to IFTTT from IoT devices via a web service. To use the Maker channel, you first have to generate a unique user key.
3. Select "Recipes" from the menu bar at the top of the page.
4. Select the "Create a Recipe" button. You will then be asked to choose the trigger channel. Click on the big blue "this".
5. Search for "maker" and select the Maker channel from the list.
6. Once you've selected to subscribe to the Maker channel, follow the instructions to create a user key for your channel.
9. Click on the "Receive a web request" option.
10. Create an "Event Name". The event name will be used as a tag by the AWS Lambda function to send messages from Lambda to IFTTT.
11. Click on the big blue "that".
12. Search for "hue" and select the hue channel. Follow the prompts to configure your Hue with IFTTT.
13. After the configuration, select "Turn on lights" as the Hue action.
14. Choose which light you would like to turn on and create the action.
11. This is what a finished recipe should look like. You can turn it on and off and go back and edit too.
IFTTT is now ready to accept messages from For more information on how to use IFTTT, see The Ultimate IFTTT Guide.
Understanding The Big Picture
The best way to think about AWS is like building blocks. Each services is like a different sized block and used for different purposes. This gives quite a bit of flexibility in building an infrastructure, but also can be overly confusing if you don't have a clear goal in mind.
This project requires the following AWS services in our architecture:
- AWS Lambda
- AWS SNS
- AWS IAM
- AWS IoT
As a disclaimer, I've described how to setup AWS configurations in an order I believe is easiest to follow for this project. However, you can choose to do some of the steps in a different order based on which services you use and their dependency on other services.
With that in mind, I found it made the most sense to work backwards from Hue and IFTTT to Lambda rather than from the Edison end. The reasoning here is you can then test each AWS configuration independently. For example, my Hue light should turn on when I test Lambda with some dummy code; even when IoT and SNS aren't configured yet.
AWS Lambda operates like a traffic controller. Triggers you define for Lambda can automatically execute code you put into a Lambda function. In this project, we use Lambda to send a message to IFTTT over the Maker channel. SNS triggers Lambda when IoT sends a message through an SNS topic.
1. Select Lambda from the AWS console. Then select the "Create a Lambda function" button. Copy and past the Lambda code found in the Code section of this tutorial into the field under the Lambda "Code" tab.
2. Modify the IFTTT event name and user key to match the ones you setup in your IFTTT account.
3. Select the "Configuration" tab and allow Lambda to auto-generate the Role. The role will be created as lambda_basic_execution appear in the list of roles under the IAM service.
We're now done with the Lambda console config. The "Endpoint" value will be automatically generated in the next section.
AWS SNS is just a message delivery service. In this tutorial, IoT delivers the value of uv_visible to a topic. Lambda is listening to the topic for new messages, and passes the uv_visible message to the IFTTT maker channel listening to it's event name (IFTTTevent) on the other end. Since turning a light on or off with Hue is a binary action, we don't care what the value of uv_visible is because we've already filtered values 400 and below when AWS IoT receives the value from Edison.
1. Create an SNS topic.
2. Lambda needs to know where to listen for messages coming from IoT. Subscribe to the SNS topic you created by clicking "Subscriptions" from the left-hand menu. Then select the "Create Subscription" button.
By selecting the Lambda function you created from the "Endpoint" dropdown, an entry for the SNS topic as a Lambda event source will automatically be created.
AWS Identity Access Management (IAM) is the keeper of all permissions for all AWS services. It's essentially your hub for granting access between AWS services as well as out to the internet. You will use IAM roles in this tutorial to allow IoT and Lambda to send information over SNS. Of the two roles needed for this project, you already created the Lambda role.
1. Create the SNS role by navigating to IAM from the AWS console. Select the "Roles" link from the menu on the left.
2. Click the "Create New Role" button and give it a name. I used the name "aws_iot_sns".
3. In the newly created role, click the "Create Role Policy" button under the "Inline Policies" section.
4. In the wizard, choose the "Custom Policy" radio button. Cut and paste the AWS SNS policy text found in the Code section of this tutorial. Be sure to modify the "Resource" to match your SNS ARN.
AWS IoT has several unique features: secure communication as well as virtual instances of devices (called shadows). I will only be making use of the secure communication feature in this tutorial. To explore how shadows work, please read the AWS documentation. The following diagram illustrates how AWS IoT should be set up for this tutorial, where the orange numbers 1-5 are the order for setting up each component.
1. CERTIFICATE: Create a certificate and download the public key, private key, and certificate files by selecting the "1-Click certificate create" button.
2. POLICY: SNS needs to know it's ok for IoT to publish to the hue-Office-topic. To do this we create a policy in IoT.
a. Click on the "+ Create Resource" button at the top of the page.
b. Select the "Policy" item.
c. In the "Action" field type "iot:*" and copy and paste your SNS topic ARN into the "Resource" field. This will allow IoT to perform all of its actions on only the hue-office-topic.
d. Check the "Allow" box and then add the statement by selecting the "Add Statement" button.
e. Click the "Create" button to finish creating the policy.
3. THING SHADOW: (device) Create a virtual representation of your Edison device (a.k.a. thing). I called mine "Hue-Office". You only have to give your device a name, attributes are optional.
4. RULE: Click on the big "View Thing" button. Alternatively click on the name of your device inside of the newly created device box.
a. In the device's details panel that will pop up on the right side of the page, select the "Create a Rule" button
b. Give your rule a name and fill out the query statement fields. If you wanted to allow all messages on all topics being transmitted by the device, you would use the query string:
SELECT * FROM '#'
Where " * " is a wildcard meaning "all messages" and the " # " means all devices.
c. For this project though, we want to only accept uv_visible from the messages sent over hue-Office-topic. We also only want to accept values of uv_visible that are below 400. The SQL query for this looks like:
SELECT uv_visible FROM 'hue-office-topic' WHERE uv_visible < 400
Note that you can edit this query at any time in the Rule's details window. I used a very specific query to show how granular you can get when accepting data from IoT devices, even individually.
d. We also need to tell IoT what to do with the uv_visible message once we ingest it. In the Action dropdown, select "Send a message as a push notification (SNS)".
e. The dropdown that appears should be populated with SNS topics and subscriptions you have created. From the SNS Target dropdown, select the topic you created for this project. In the SNS section of this tutorial, I named by topic "hue-office-topic".
f. In the Role field, select the role you created in the IAM section of this tutorial. I named my role "aws-iot-sns" during the IAM step.
g. Click the "Add Action" button and then click the "Create" button to finish creating the rule.
5. The last step is to connect the device and policy to the certificate.
a. Click on the certificate string (i.e. cd41290.....). Also make sure the square radio button for the certificate is selected. This will enable the "Actions" dropdown right above it and slightly to the right.
b. First, activate the certificate by selecting "Activate" from the list. Your certificate should now show as activated.
c. Now select "Attach a policy" from the list. Enter the name of the IoT policy you created, mine is called "hue-office-allow".
d. Again from the "Actions" menu, select "Attach a thing" and enter the name of the device you created. Mine is named "HueOffice"
Your certificate details window on the right should now look something like this:
The Edison's code is minimal and for a reason. All the code does is take an ambient light measurement and pass that value to IoT. All decisions for what to do based on the reading is kept on AWS. This allows the Edison to "stay in the field" if you want to update the decision logic later without collecting the physical device.
This tutorial assumes you have already completed the steps to connect to the Intel XDK. This means attaching the Edison by IP to the XDK. If you need instructions for this, see my tutorial Yet Another Edison Getting Started - with the Breakout Board.
*The complete node.js code file is included in the "Code" section of the tutorial.
1. Configure the libraries that will be used by this app. I also like to include the "os" and "fs" libraries (operating system and file system) in case I need them.
2. Define a variable to keep the hostname (used in the optional debugging code), and a variable for the SI1145. Don't forget to use the correct I2C bus number.
3. Configure the information needed to allow the Edison to talk securely to AWS IoT.
a. First, upload the xyz.pem.crt, xyz-private.pem.key, that you created during the IoT certificate creation step. Also create a new file and copy/paste the root-CA.crt certificate from this link. I suggest putting the three files in a directory called awsCerts under /home/root. Where ever your directory is, remember its path, and the contents should like something like this:
b. Use the paths to the certificate files, the name of the AWS region of your IoT architecture, and the name you gave to your AWS IoT device to fill in the device attributes:
3. Fill in the IoT connection attributes to tell Edison to publish to the SNS topic "hue-office-topic", and run a test message on successful connect.
4. The periodicActivity function is the bit of code that keeps looping infinitely at an interval you set. It's also where you read in sensor data and dispatch messages to SNS.
5. Upload and run your code on the Edison.
Now when the Edison senses the ambient light level drops below 400 lux, your Hue light should turn on!