MQTT - 使用Amazon AWS IoT Shadow 服務

材料準備

範例說明

介紹

Amazon AWS IoT 提供可用於實施 IoT 解決方案的雲服務和設備支持。 AWS 提供許多雲服務來支持基於物聯網的應用程序。
AWS IoT Core 提供將您的 IoT 設備連接到 AWS 雲的服務,以便其他雲服務和應用程序可以與您的聯網設備進行交互。

1

(圖片來自 http://docs.aws.amazon.com/iot/latest/developerguide/aws-iot-how-it-works.html )

在該結構中,Ameba屬於左上角的“Things”。 將在“Things”和MQTT Message Broker之間建立一個TLS安全通道。 接著,“Things”和“Message Broker”通過此安全通道使用MQTT協議進行通信。 在“Message Broker”後面,“Thing Shadows”在Ameba離線時暫時保留消息,並在下次連接時將控制消息發送給Ameba。 通過“Rules Engine”,您可以限制事物的行為或將事物連接到Amazon的其他服務。

AWS管理控制台

首先,創建一個帳戶並註冊AWS IoT服務:https://aws.amazon.com/iot-core/
然後,登錄到Amazon 管理控制台,然後單擊services -> Internet of Things下的 “IoT Core”。

選擇附近的區域。 這是一份教學在線文檔,可供詳細參考。 請注意,需要完成以下步驟。
• 創建thing。 使用“ameba”作為thing名稱。 添加“attribute”,使用“led”作為名稱,“0”作為值。
• 創建policy。 使用“amebaPolicy”作為名稱,“iot:*”作為操作,“*”作為資源 ARN。
• 創建TLS憑證。 記錄“public keys”、“private key”、“certificate”和“root CA”。
• 啟用後,附加Policy和Thing。

查找用於設置 Amazon Alexa 的 Rest API Endpoint 資訊:
• REST API endpoint:
o 例如 “https://a1a7oo4baosgyy.iot.us-east-1.amazonaws.com/things/ameba/shadow”,“a1a7oo4baosgyy.iot.us-east-1.amazonaws.com” 為 MQTT Broker 服務器的地址。
• MQTT topic:
o 例如 “$aws/things/ameba/shadow/update” 表示我們將在AWS IoT Shadow服務中使用的MQTT主題(如果僅使用MQTT,而沒有AWS IoT Shadow服務,則可以指定其他主題名稱)。 建議使用”$aws/things/ameba/shadow/update”。

Ameba 設定

打開 “File” -> “Examples” -> “AmebaMQTTClient” -> “Amazon_AWS_IoT_Basic”

在範例代碼中,
• 設置WiFi 網絡SSID 和密碼。
• “Thing_Name”設置為“ameba”。
• “mqttServer”設置為之前在AWS IoT 中找到的MQTT 代理服務器地址。
• “rootCABuff”設置為記錄的“root CA”。
• “certificate”。 填寫紀錄的憑證(即客戶端憑證),通常其文件名以“-certificate.pem.crt”結尾(例如“efae24a533-certificate.pem.crt”)。 使用文字編輯器打開憑證,並如下調整其格式:
– 在每行末尾添加新的行字元“\n”。
– 在每行的開頭和結尾處添加雙引號。
– 要將每行連接為字串,請在每行末尾添加“\”。
– 最後一行以分號結尾。
• “privateKeyBuff”。 以相同的方式調整private key的格式。

編譯並執行

上傳程式碼並在上傳完成後按Ameba上的重置按鈕。
在Arduino IDE中打開串行端口,觀察Ameba連接到AWS IoT服務器的情況。
1

備擇方案

Ameba還可以從AWS shadow中檢索當前的LED狀態。 通過向“shadow/get”主題發送消息來完成此操作。 有關更多信息,請參閱Amazon_AWS_IoT_with_ACK範例代碼。

程式碼說明

更改led狀態:
在這個例子中,我們使用GPIO接口來控制led。 在範例代碼中,我們默認將led_pin設置為10,將led_state設置為1。

pinMode(led_pin, OUTPUT);
digitalWrite(led_pin, led_state);

設置憑證:
注意我們是使用wifiClient的WiFiSSLClient類型。

WiFiSSLClient wifiClient;

WiFiSSLClient繼承Client,因此可以將其作為PubSubClient構造函數的參數進行傳遞。
接下來,設置連接所需的TLS憑證。

wifiClient.setRootCA((unsigned char*)rootCABuff);
wifiClient.setClientCertificate((unsigned char*)certificateBuff, (unsigned char*)privateKeyBuff);

配置MQTT Broker服務器
然後,MQTT PubClient將MQTT Broker服務器設置成連接

client.setServer(mqttServer, 8883);
client.setCallback(callback);

連接到MQTT Broker服務器:
在loop()中,調用reconnect()函數並嘗試連接到MQTT Broker服務器並進行憑證驗證。

while (!client.connected()) {

訂閱並發布
接下來,訂閱主題。

for (int i=0; i<5; i++) {
client.subscribe(subscribeTopic[i]);
}

有一些共同的主題:
“$aws/things/ameba/shadow/update/accepted”,
“$aws/things/ameba/shadow/update/rejected”,
“$aws/things/ameba/shadow/update/delta”,
“$aws/things/ameba/shadow/get/accepted”,
“$aws/things/ameba/shadow/get/rejected”
相關文件:
http://docs.aws.amazon.com/iot/latest/developerguide/thing-shadow-data-flow.html
然後發布當前狀態:

sprintf(publishPayload, "{\"state\":{\"reported\":{\"led\":%d}},\"clientToken\":\"%s\"}", led_state, clientId);
client.publish(publishTopic, publishPayload);

檢查主題並做出回應:
在回調函數中,我們檢查5個訂閱的主題,並檢查是否有“/shadow/get/accepted”消息:

if (strstr(topic, "/shadow/get/accepted") != NULL) {

如果存在,則消息來自控制端。 如果消息中的屬性狀態不同於當前狀態,請發布新狀態。

updateLedState(desired_led_state);
請先確認已安裝QQ通訊軟體