開發用到的環境與工具
4.IAM(權限金鑰管理)
7.Linux PC or box


功能連接說明
1.透過Alexa Skill Testing Tool 發出指令
2.Alexa收到指令後,解析內容,將內容送到AWS Lambda
3.AWS Lambda會根據內容(intent),更新AWS IoT Shadow service
4.若Client Device 有連接上AWS IoT Shadow service,就會將訊息秀出來



架設步驟
1.Device 環境開發安裝
2.註冊Alexa開發帳號
3.設定Alexa Skills Kit
4.設定AWS Lambda
5.IAM建立存取AWS Lambda權限
6.設定AWS IoT Things
7.AWS IoT SDK安裝
8.測試

1.Device 環境開發安裝

安裝nodejs
sudo apt-get update
sudo apt-get install nodejs

更新至v7.x以上
sudo curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -
sudo apt-get install -y nodejs

測試是否安裝成功
node --version

npm --version

2.註冊Alexa開發帳號
至Alexa的開發網頁,建立skill

選擇ALEXA裡的Alexa Skills Kit

點選Add New Skill

3.設定Alexa Skills Kit

Skill Information
1. Skill Type選擇Custom Interaction Model
2. Language選擇English(U.S)
3. Name為你的Skill名稱,類似APP名稱,可隨意命名
4. Invocation Name: 這個名稱是要給Alexa辨識用的,這邊塡light controller

Interaction Model
intents 設定
在Intent Schema 貼上以下資料

{
"intents": [
{
"intent": "ControlLight",
"slots": [
{
"name": "LightState",
"type": "LIGHT_STATE"
}
]
}
]
}

這邊的Enter Type填入LIGH_STATE,Values 填入on/off

Sample Utterances,填入以下文字
ControlLight Turn {LightState} the light
ControlLight Turn the light {LightState}
到這邊先暫停skill設定,因為接下來需要一個server來連接skill,此次我們選擇利用AWS Lambda連接。

4.設定AWS Lambda
建立 AWS Lambda Function

登入AWS Lambda
點選Create a Lambda function

AWS Lambda本身有提供一些使用範例,你可以根據你需要的語言與功能的篩選,去取得你要的sample code,
這邊我們選擇Blank Function

Configure triggers設定選擇Alexa Skills Kit
進入Configure function後,填寫以下欄位

Name為function名稱,填選ControlLight
Description為說明function用途,可選擇不填
Runtime你要使用的語言與版本,這邊選擇目前AWS支援最新的nodejs v6.10版本

下載js code貼到下方框框裡




接下來,開始設定Lambda function Role的權限,保留Handler預設值


5.IAM建立存取AWS Lambda權限
建立自訂Role
點選Create a custom role
將Role Name命名為control_light,並點選View Policy Document
將以下文字貼到欄位
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": ["iot:*"],
"Resource": "arn:aws:iot:*:*:*"
}
]
}


完成後選擇剛剛建立的Role,選擇剛剛建立的Role,基本上就完成function的建立了。

再來將右上角的文字,貼到Alexa Skills kit 的Service Endpoint Type

Alexa Skills kit


6.設定AWS IoT Things
登入AWS IoT

建立Thing

至Things頁面,會看到右上角有一個Create按鈕。
點擊Create按鈕

輸入名稱,這邊我們輸入TestLight,按下Create thing,系統會導到Detail頁面。

建立Attributes
進入 Detail頁面後,在Attributes那一列上,點選Edit


Attribute Key欄位填入led,Value填入0,按下Update。
此attribute的值是用來更新電燈開關的狀態,當我們命令Alexa開燈,我們建立的Lambda function 會去更新這個attribute的值。
建立Certificates與policy
1.Certificates,讓Client device可以有權限存取這個thing的資料
2.Policy可以限制或開放thing的使用Protocal、port、topic等,有興趣可參考下列網址
在Security裡,點擊Create certificate,系統會自動建立 certificate

下載所有的download,存在你的Client device裡,這邊就是Linux PC


再來得點擊Activate按鈕,成功後會顯示Deactivate字樣

再來點擊Attach a Policy
1.Name為Policy名稱,可隨意填寫
2.Action填寫iot:*,允許存取所有action,有興趣可以參考
3.Resource填寫*
4.勾選Allow


完成後,需要再回 certificate attach剛剛建立的policy。

回到thing的Security,點擊Certificates

點選Policies
點選Actions > Attach policy

勾選剛剛建立的policy就完成policy attach

7.AWS IoT SDK安裝
完成AWS 上的服務設定後,就可以開始安裝aws-iot-sdk環境。

建立一個資料夾,將剛剛下載的certificate放入該資料夾,接著輸入以下指令
npm install aws-iot-device-sdk

安裝完成後
建立一個myIot.js file,將以下程式碼貼上

//app deps
const awsIot = require('aws-iot-device-sdk');

//begin module

function processTest() {

//
// The thing module exports the thing class through which we
// can register and unregister interest in thing shadows, perform
// update/get/delete operations on them, and receive delta updates
// when the cloud state differs from the device state.
//
const thingShadows = awsIot.thingShadow({
keyPath: 'TestLight.private.key',
certPath: 'TestLight.cert.pem',
caPath: 'root-CA.crt',
clientId: 'us-east-1:391121664623',
region: 'us-east-1',
baseReconnectTimeMs: 4000,
keepalive: 30,
protocol: 'mqtts',
host: 'ap5hjvtrkgx5w.iot.us-east-1.amazonaws.com',
debug: false
});
//
// Register a thing name and listen for deltas. Whatever we receive on delta
// is echoed via thing shadow updates.
//
thingShadows.register('TestLight', {
persistentSubscribe: true
});

thingShadows
.on('error', function(error) {
console.log('error', error);
});

thingShadows
.on('delta', function(thingName, stateObject) {
console.log('received delta on ' + thingName + ': ' + JSON.stringify(stateObject));
thingShadows.update(thingName, {
state: {
reported: stateObject.state
}
});
});

thingShadows
.on('timeout', function(thingName, clientToken) {
console.warn('timeout: ' + thingName + ', clientToken=' + clientToken);
});
}

processTest();

輸入
node myIot.js


8.測試
打開 Alexa Skill Testing Tool,對著麥克風說
Alexa, ask light Controller

Alexa會回答
Welcome to the light Controller example. Please tell me next action by saying, turn on the light

接著說
turn on the light

client device就可以收到訊息了


參考資料: