Tutorial Steps
This tutorial explains steps to port Amazon* Alexa Voice Service* onto the Intel® NUC with Wind River Linux* operating system. This tutorial assumes you have already done some basic setup on an Intel® IoT Gateway and are familiar with its operation.
Setup Arduino 101* and Firmata
Clone the GitHub* repository onto your Intel® IoT Gateway by logging into the gateway and running: git clone https://github.com/SSG-DRD-IOT/Alexa-on-Intel-NUC
Wire up the sensors
Connect Grove* button to pin D8, one LED to pin D3 and other one to Pin D4 as shown in the following picture using the cables from the Grove* starter sensor kit box.
Sensor | Pin Connection |
Grove - Red LED | D3 |
Grove - Blue LED | D4 |
Grove - Button | D8 |
Grove - LCD RGB Backlight | I2C |
Set Up Firmata* on Arduino 101*
- Download Arduino* IDE: https://www.arduino.cc/en/Main/Software
- Connect Arduino 101* (branded Genuino 101* outside the U.S.) to a host computer via USB
- Launch Arduino IDE
- Open boards manager:
- Search for "Arduino 101" and install the board definition:
- Select "Arduino/Genuino 101" from the Boards menu and the correct port. If you are unsure which port to use disconnect the Arduino 101 and see which port disappears.
- Load StandardFirmata Sketch:
- Click Upload and wait for "Sketch will execute about 5 seconds"
Setup Intel® IoT Gateway as Echo
- SSH onto the Intel® IoT Gateway: ssh root@IP.OF.GATE.WAY
Where IP.OF.GATE.WAY is the IP address of your gateway
Use "root" as the password
- CD into the Repo:
cd ~/Alexa-on-Intel-NUC
- Run setup.sh: chmod +x ./setup.sh
./setup.sh
The script will ask you for confirmation to install a number of packages, enter "y" and hit enter for all.
The setup script will install the dependencies needed for the project and will take around 5 minutes to finish.
Reboot the Intel® IoT Gateway
Generate SSL Key for Intel® NUC
- Run these commands:
openssl genrsa -out /root/privkey.pem 2048
openssl req -new -x509 -days 365 -key
/root/privkey.pem -out /root/cert.pem
Fill out your information for the SSL certificate.
Create an AWS Account
Follow the instructions at this link to create an Amazon Web Services (AWS)* account and security profile: https://github.com/alexa/alexa-avs-sample-app/wiki/Linux
Security profile setup for Intel® NUC on Amazon* Developer console
- Login to Amazon Developer Portal - developer.amazon.com
- Go to APPS & SERVICES -> Security Profile
- Click Web setting tab
- Click Edit button on Web settings tab.
- Get IP address of your Intel® NUC using "ifconfig" command.
- Add the URL in the form https://ip_address_for_NUC:5000/code to Allowed Return URLs
- e.g. https://192.168.1.197:5000/code
Add Your Credentials to Creds.py
- Navigate to the General tab on the Security Profile Management page:
- Open creds.py using vi with: vi creds.py
- Hit "a" to enter insert mode
- Enter your information into ProductID, Client_ID, etc.
- Hit "esc", type ":wq", and hit enter to save the file
Create an AWS IoT Device
In order for the gateway to communicate with the AWS* cloud we will create an AWS IoT Device to act as a bridge. Alexa* Voice Services will then push updates to the device shadow (a virtual persistent state) and the gateway will get updates from the device shadow.
- Create an AWS account: https://console.aws.amazon.com
- From Services select AWS IoT:
Make sure that your region is selected as N. Virginia (us-east-1). The AWS services are not yet online for all regions.
The dashboard should look like this:
- Go to: Registry -> Things and click "Create" to the right of the search bar. Follow the screens to create AWS IoT device.
- On the device page navigate to Interact and click on "Connect a Device"
- Choose your platform – Linux*/OSX* or Windows*, and choose Python*.
- Click "Getting Started" and download the connection kit for your selected OS. This package will contain a private key and certificate which we will use to connect the gateway to the AWS IoT service. It also contains a start.sh script which will run a basic connection test, install the SDK, and download the rootCA.crt.
- Transfer the zip file to the gateway using FTP from the command line, or FileZilla:
- Go to https://filezilla-project.org/ to download and install the FileZilla client
- Open Filezilla and connect to the IP of your gateway using "root" as username, "root" as password, and 22 as the port:
- When asked about unknown host key hit OK
- Navigate to the zip file on the left panel and the Alexa-on-Intel-NUC repository folder on the right panel. Double click the zip file to transfer it.
Edit main.py
Main.py contains code for both sending voice commands to Alexa* and connecting to AWS IoT. Now that you have created a device you can add its connection details to main.py.
- Using VI open main.py and replace AWS_IOT_ARN with the Thing arn from the Details section of the AWS IoT device console:
- Replace REST_API_ENDPOINT with the Rest API Endpoint under the HTTPS section of the Interact section of the AWS IoT Console:
Create a Lambda Function
The lambda function is a function that runs in a virtual run time environment in AWS. We will use it to do two things: set up a handler for requests coming from Alexa* Voice Services, and setup a connection to AWS IoT to update the gateway device shadow.
The Github* repository contains /lambda/index.js which you will have to edit in order to connect to your AWS IoT Device.
- On line 4 of index.js replace REST_API_ENDPOINT with the endpoint of your IoT Device. The endpoint can be found in the AWS IoT device console under Interact
- Once you have edited index.js make a zip file containing index.js and /lambda/node_modules. You will upload this to Lambda later on.
- Navigate to the AWS Lambda service: https://console.aws.amazon.com/lambda/
- Click ‘Create Function’ use the Blank Function blueprint:
- Select "Alexa Skills Kit" as the trigger:
- Give your function a name and description and choose "Upload a .ZIP file"
- Click Upload and select the zip file you made earlier.
- Enter index.handler for the Handler – this is the default handler for Lambda
- Choose "Create new role form template"
- Select "Simple Microservice Permissions" from "Policy Templates"
- Leave everything else as default and click next.
- Review the function on the next page and click "Create Function"
Configure IAM access policy
- Navigate to AWS IAM console: https://console.aws.amazon.com/iam
- Navigate to the Roles list form the left side menu:
- Select the role policy you created for your Lambda function
- Select "Attach Policy"
- Select "AWSIoTFullAccess" and click Attach Policy:
Configure Custom Alexa Skill
Finally, we will create a custom Alexa skill that will pass events to the handler running in the Lambda function.
- Navigate to the Alexa developer portal: https://developer.amazon.com/edw/home.html#/ and select "Get Started" under Alexa Skills Kit
- Select "Add a New Skill". On the following screen add a name for your skill and an invocation name. The invocation name is how you will call the skill from Alexa e.g "Alexa tell gateway to turn on blue LED" where "gateway" is the invocation name.
- Click "Next"
- On the next screen, we will configure the Intent Schema, add custom Slots, and set the utterance. The Intent Schema describes the events that are sent to Lambda and the slots associated with each. Slots can be thought of as variables for the device state, e.g. "blue led off" is a slot that describes the intended state of our gateway. The utterance is what people say to interact with your skill.
- In Custom_Skill/Intent_Schema you will find the intent schema that we will use for this project. This schema describes an intent called "DeviceStateIntent" with Slots called "DeviceState" of Type "Device_States". Note that DeviceStateIntent is the event name used in the handler lambda function for switching the state of the gateway – if you rename the event name in the handler function you must also rename it in the intent schema. There are also some default helper intents in the schema that send events to the handler function when the user says things like "help".
- Device States is not a standard slot type so we will have to define them. Select Add Slot Type, enter Device States as the type and add the values separated by line, i.e. hit enter between each value. These values are the different cases passes to the DeviceStateIntent handler function. On line 56 of the lambda function you can see case "all on": which defines what the function does when "all on" is passed by the DeviceStateIntent event. We will use "all on", "all off", "blue led on", "blue led off", "red led on", "red led off". You may add your own, but you must define what slot does in the lambda handler function.
- Finally add a Sample Utterance. The first term in the sample utterance defines which intent to tie the utterance to, i.e. the user does not say "DeviceStateIntent turn on blue led", only "turn blue led on" and then "blue led on" is passed as the slot for DeviceStateIntent. Any terms in curly braces are slot names defined in the intent schma. Use the simplest form for now "Device StateIntent turn {DeviceState}" Note: Alexa is clever enough to substitute "turn" with "switch" and other contextual terms, no need to explicitly define it.
- Much more info on intent schema setup can be found here: https://developer.amazon.com/public/solutions/alexa/alexa-skillskit/docs/defining-the-voice-interface#The Sample Utterances File
- Click next to continue to the configuration.
- Here select AWS Lambda ARN (Amazon Resource Name) as the endpoint type, and enter the ARN found in your Lambda Function Dashboard in the upper right:
- Click next to go to test your new skill:
- Enter an utterance like "turn blue led on" and click Ask. IF everything is working correctly you should see the lambda request and response with "Turn Blue LED on" as the output speech.
Run the program
- You are now ready to run the program. Launch "Python main.py" from the root folder of the repository.
- Wait 15 seconds for everything to initialize.
- Click the button, say "Tell gateway to turn blue led on"
- The Blue LED should turn on and Alexa will respond with "Blue LED on"