Reading Nodemcu IoT Data with Alexa

This is the final post in a series aimed at connecting Alexa to a Nodemcu that is collecting temperature and humidity data.





Overview

I recommend reviewing my first post in this series, so you can understand the game plan... but here's the short version. We will create and configure three separate services in AWS. An Alexa Skill for voice commands, a AWS Lambda function that will act as a middle man, and AWS IoT for storing the current state of the Nodemcu sensors.





DISCLAIMER: This guide uses a work around to allow Nodemcu to communicate directly with AWS IoT. The work around uses API keys that will be written in cleartext on the Nodemcu. Proceed at your own discretion.

Goals

Create a AWS Lambda function that will collect the Nodemcu data that was sent to AWS IoT This will be written in Python Create an Alexa Skill to read data gathered by the Lambda function Setup a security policy to provide Lambda access to Thing Shadow state in AWS IoT Prep

I considered showing how to setup the appropriate accounts on AWS and Amazon Developer, but it seems there are plenty of good resources to show how to do that. Put your google-fu skills to work or take a wild stab at it.



A Nodemcu sending data to AWS IoT Thing Shadow Part 2 - AWS IoT An AWS Account from creating Lambda functions (free tier allows 1M messages a month) This would have been setup to complete Part 2 An Amazon Developer account for creating Alexa Skills (Optional) Echo Dot - http://amzn.to/2EeGNaP You can test everything using the Alexa Skills Kit or Echosim.io if you don't have an Echo Dot

You can find the parts and components I used to build the sensor in Part 2 - AWS IoT

Steps - Alexa Skill In the previous post , we configured our Nodemcu to send temperature and humidity data to an AWS IoT Thing Shadow. Our next step is to get that data to a web service that Alexa can access and read it. Amazon recommends using AWS Lambda.

Creating the Skill > Alexa > Alexa Skills Kit - Get Started Open the Developer Console at https://developer.amazon.com

Add a New Skill > Ensure Custom Interaction Model is selected

Create a Skill Name such as Sensor Reader

Note that if you intend on releasing a skill for public use this Name will be search-able by other Alexa users.

Create an Invocation Name such as sensor reader

The Invocation Name is how you will trigger the Skill when giving commands to Alexa such as "Alexa, ask sensor reader what the temperature is in the office"





Select Save and copy the Application Id to your text editor for use in later steps

Select Next

The Interaction Model

I want the skill to tell me the temperature and humidity of a specific room. To do this we need to build an Interaction Model that tells the Skill how to respond.

If you would like a better understanding of how Interaction Models work, an in depth reference is found at https://developer.amazon.com/docs/custom-skills/custom-interaction-model-reference.html

Here is a simple explanation of the parts in the Interaction Model: Utterance: The words you speak to Alexa "Alexa, ask Sensor Reader what is the temperature in Office" Intent: The Alexa Skill that Alexa determines will fulfill your request/utterance Slot Type: Essentially the Key in a key : value pair



Creating the Intent Schema

Paste the following JSON into the Intent Schema field



{ "intents": [ { "intent": "AMAZON.CancelIntent" }, { "intent": "AMAZON.HelpIntent" }, { "intent": "AMAZON.StopIntent" }, { "slots": [ { "name": "room", "type": "LIST_OF_ROOMS" } ], "intent": "getTemperature" }, { "slots": [ { "name": "room", "type": "LIST_OF_ROOMS" } ], "intent": "getHumidity" } ] }

Creating Slot Types

In my example I have Nodemcu's in 3 rooms. If you are using just one Nodemcu you can change to values below to fit your needs. Select Add Slot Type and enter the following

Creating Sample Utterances

The utterance determines which intent will be triggered. In simple terms, the utterance will determine whether Alexa will read the temperature or the humidity. In the Sample Utterances field enter the following Copy the Skill ID found at under your Skill name, to your text editor

Leave this web tab open. We need to open AWS IAM to setup a user for Lambda

Steps - Lambda User





Open IAM from the AWS Console > Policies > Create Policy

Service: IoT



Actions: GetThingShadow



Resources : All resources



If you have one Thing you can set the policy to allow access to only that Thing



Select Review Policy



Name the policy



I used lambda_getAllThingShadows



Create policy Now go to Users

Add User > Name the User > Select Programmatic Access > Next: Permissions Lambda will require an account to authenticate and interact with the IoT Thing Shadow. I will set the policy to allow the Lambda function to access the Shadow state of all my Things in IoT.

Attach existing policies directly

Search for your policy > Check the box next the policy > Next: Preview

Create User

Copy the the Access key ID and Secret access key to your text editor

Steps - AWS Lambda

I will be honest, coming from a data center infrastructure background, AWS Lambda is blowing my mind! The concept of server-less and container-less programs is amazing.

Alright, let's create a some Lambda functions in Python to read the state of the Nodemcu Thing Shadow. Open the AWS Console https://console.aws.amazon.com/

Search Lambda and select Lambda

Select Create Function > Author from Scratch (because that's how we roll)

Enter a Name, I used getNodemcuData

In Runtime select Python 3.6

In the Role section, select Create a custom role

IAM Role: lambda_basic_execution



Policy Name: Create a new Role Policy



Allow

You will be redirected back to Author from scratch

Role: should be set to Choose an existing role



Existing Role: lambda_basic_execution

Create function

Copy the function ARN (Amazon Resource Name) to your text editor

In the Designer, assign Alexa Skills Kit as the trigger

In the Configure triggers pane, paste the Skill ID from the Alexa Skill we created.

Select Add

Select Save

Scroll down to Environment variables

Input the secret key id and access key that you copied from the User you created in IAM

Key: SECRET_KEY | Value: secret key



Key: ACCESS_KEY | Value: your access key id

Select Save

Lambda - Python Code





Paste the following into the Lamba programming pane



import boto3 import os import json def lambda_handler(event, context): # Determine which Thing Shadow to read room = event["request"]["intent"]["slots"]["room"]["value"] if room == "bedroom": thingShadow = "node_bedroom" elif room == "kitchen": thingShadow = "node_kitchen" elif room == "office": thingShadow = "node_office" # Connect to AWS IoT REST API client = boto3.client( 'iot-data', region_name='us-east-1', aws_access_key_id=os.environ['ACCESS_KEY'], aws_secret_access_key=os.environ['SECRET_KEY'] ) # Read the current data in the Thing Shadow shadowState = client.get_thing_shadow(thingName=thingShadow) streamingBody = shadowState["payload"] shadowJSON = json.loads(streamingBody.read()) # Determine temperature or humidity intent = event["request"]["intent"]["name"] if intent == "getTemperature": dataType = "temperature" description = " degrees" elif intent == "getHumidity": dataType = "humidity" description = " percent" # Create the response that will be sent to Alexa alexaString = str(shadowJSON["state"]["reported"][dataType]) + description # Send the response back to Alexa return { "version": "1.0", "response": { "outputSpeech": { "type": "PlainText", "text": alexaString } } } We will use the AWS boto3 Python module. Boto3 has a simple client function to allow a connection to the AWS IoT Thing Shadow(s). We will also use Lambda's built in key/value encryption feature to securely add your API access key and access secret.Paste the following into the Lamba programming pane

Steps - Final Alexa Configuration

Its about to get real! We need to connect this Skill to the Lambda function we created.

Go back to the Alexa Skill Kit... you should still have that tab open right?

In Configuration, select AWS Lambda ARN

In Default, paste the Lambda ARN

The remaining settings can be left as defaults

Select Next

Testing

Okay. That was not too bad. Let's see the fruits of our labor.





You should have the Test screen up

Set Testing to Enabled for you account





In Service Simulator you should see the Lambda ARN you setup in Configuration

Now we can simulate speaking to Alexa and triggering our Lambda function

If all goes well, this is what you should see





The tests are successful. Try asking for the humidity also.

Alexa Setup for your Echo Dot

Open the Alexa App on your smart phone/device

Go to Skills > Your Skills

Now press on the Dev Skill tab you should see the Skill you created If the skill is there you are ready to interact with your Echo device









Bada Bing... Bada Boom.

Result