返回文章列表

樹莓派打造根據AWSIoT平臺訊息傳遞系統

本文闡述如何利用 AWS IoT 平臺和 MQTT 協定,打造一個 Raspberry Pi 訊息傳遞系統。文章涵蓋了建立 IoT 事物、取得安全憑證、撰寫 Python 程式碼、傳送與接收 MQTT 訊息等關鍵步驟,並提供程式碼範例和流程圖,引導讀者逐步建構完整的 IoT 系統。

物聯網 雲端服務

透過 AWS IoT 平臺與 MQTT 協定,我們可以建構一個功能完善的 Raspberry Pi 訊息傳遞系統。首先,需在 AWS IoT 平臺上建立一個 IoT 事物,並取得對應的安全憑證,以便後續 Raspberry Pi 與 AWS IoT Core 進行安全連線。接著,在 Raspberry Pi 上撰寫 Python 程式碼,利用 AWSIoTPythonSDK 建立 MQTT 客戶端,並訂閱指定的 MQTT 主題,以便接收來自 AWS IoT Core 的訊息。設定完成後,即可透過 AWS IoT Core 的 MQTT 測試客戶端傳送訊息至 Raspberry Pi,驗證訊息傳遞功能的正常運作。

網站回應

網站會以 JSON 格式回應,內容如下:

{
    "number": 10,
    "people": [
        {
            "craft": "ISS",
            "name": "Mark Vande Hei"
        },
        {
            "craft": "ISS",
            "name": "Pyotr Dubrov"
        },
        {
            "craft": "ISS",
            "name": "Megan McArthur"
        },
        {
            "craft": "Shenzhou 13",
            "name": "Ye Guangfu"
        }
    ]
}

圖表翻譯:

內容解密:

以上程式碼定義了一個 Handler,負責處理「getAstronauts」Intent。當使用者要求太空人數量時,Handler 會先發出進階回應,然後取得網站資料並解析 JSON 格式的回應。最後,Handler 會根據解析的資料回應使用者。

進階回應 - 存取網際網路

在本章中,我們將探討如何使用 asyncioasync/await 關鍵字來等待網頁回應的資料。首先,我們需要從 JSON 回應中提取人數,使用 jsonResponse.get('number')

使用 asyncio 和 async/await 等待網頁回應

為了等待網頁資源回應其資料,我們使用了協程(coroutine)。協程是一個可以暫停其執行的函式,以等待另一個操作完成。在程式碼中,我們使用 asyncio.run() 函式來執行 get(url) 協程。

import asyncio

async def get(url):
    #...

asyncio.run(get(url))

在這裡,我們使用 async def get(url) 來建立一個協程,並使用 await resp.text() 來暫停程式碼的執行,直到網頁回應完成。注意,await 命令只能在 async 函式內使用。

在呼叫協程之前,我們呼叫進階回應處理器,使用 get_progressive_response(handler_input)

建立樹莓派 IoT 事物

介紹

現在我們知道如何建立和顯示 Alexa 技能後,我們可以轉移到硬體部分。在本章中,我們將建立一個 AWS IoT 事物並取得安全憑證,以啟用 MQTT 發布/訂閱訊息。我們將為 Pi 撰寫程式碼,使其傾聽來自 AWS 主控臺的訊息。我們將從 AWS 主控臺傳送訊息並在 Pi 事物上接收它們。

建立樹莓派 IoT

建立 IoT 的步驟如下:

  1. 建立物聯網(IoT)和其憑證和政策。
  2. 在 Pi 上建立和執行 Python 程式碼。
  3. 向 Pi 傳送 MQTT 訊息。
  4. 建立 Alexa 主機技能並測試它與 Pi。
  5. 嘗試從 Alexa 裝置使用它。

前置條件:我使用的是 Raspberry Pi 4 和 Raspberry Pi OS Buster(Debian 10)作為作業系統。最新版本是 Debian 11(bullseye),它也應該可以工作。我的 Pi 有一個 explorer HAT I/O 板,控制一個 Pimoroni 機器人,但你不需要它,你可以簡單地切換一個 LED 開關。

使用 US(East Virginia)作為 AWS 伺服器。你需要一個 AWS 帳戶。Pi 將訂閱並傾聽透過我們的 Alexa 語音命令傳送的訊息,這將執行一些 Python lambda 程式碼,該程式碼發布(傳送)訊息(例如,移動)。

內容解密:

  • 我們使用 asyncioasync/await 關鍵字來等待網頁回應的資料。
  • 建立 IoT 的步驟包括建立物聯網、取得安全憑證、建立 Python 程式碼、傳送 MQTT 訊息、建立 Alexa 主機技能和測試它與 Pi。
  • 我們使用 Plantuml 圖表來視覺化建立 IoT 的流程。

圖表翻譯:

此圖表顯示了建立 IoT 的流程。首先,我們建立 IoT 事物,然後取得安全憑證。接下來,我們建立 Python 程式碼,然後傳送 MQTT 訊息。最後,我們建立 Alexa 主機技能並測試它與 Pi。這個流程展示瞭如何使用 AWS IoT 和 Alexa 建立一個完整的 IoT 系統。

建立 Raspberry Pi IoT 物件

在本章中,我們將學習如何建立一個 Raspberry Pi IoT 物件,並將其連線到 AWS IoT 平臺。這個過程涉及建立一個物件、產生憑證、設定 MQTT 通訊協定等步驟。

建立物件和憑證

首先,登入 AWS IoT 平臺,點選「Create things」按鈕,然後選擇「Create a single thing」。命名您的物件(例如 MyThing),然後忽略「Additional Configurations」部分,將「Device Shadow」設為「No shadow」。點選「Next」按鈕,然後您將看到「Attach policies to certificate」的頁面。

點選「Create policy」按鈕,然後命名您的政策(例如 MyThingPolicy)。為了給予 IoT 存取您的物件的許可權,新增「iot:」動作,資源 ARN 為「」,並勾選「Allow」。您可以透過點選 JSON 標籤並複製和貼上以下內容來完成此操作:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:*"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}

點選「Create」按鈕,傳回到之前的視窗,選擇政策並點選「Create Thing」按鈕。現在,您的憑證已經顯示出來。下載並儲存這些憑證,它們將用於驗證您的物件與 AWS IoT 的身份。

取得物件端點

為了讓您的技能與您的物件進行通訊,您需要知道物件的端點地址。點選 IoT > Settings,然後點選設定按鈕。您將看到一個通知,告訴您如何複製端點地址。MQTT 客戶端和 AWS IoT Device SDK 使用此端點地址。

傳輸憑證到 Raspberry Pi

建立一個目錄在您的 Raspberry Pi 上(例如 MyThing),然後在該目錄中建立一個名為「certs」的子目錄。將憑證檔案傳輸到您的 Raspberry Pi 的 MyThing/certs 目錄中。我使用 WinSCP 來完成此操作。

重新命名 xx.private.pem.key 檔案為 MyThing-private.pem.key,重新命名 xx.certificate.pem.crt 檔案為 MyThing-certificate.pem.crt,並使用 AmazonRootCA1.pem。如果您這樣做,您就不需要在程式中更改它們。您的目錄內容應該如下所示:

建立和執行 Python 程式碼

在您的 Raspberry Pi 上安裝 AWSIoTPythonSDK 檔案,使用以下命令:

sudo pip install AWSIoTPythonSDK

我們需要一個監聽程式,這個程式將在終端上列印「hello」當收到「hello」作為 payload[‘directive’] 的 /myPi 主題(稍後會解釋)。輸入程式碼並將其儲存在 MyThing 目錄中,以 listener.py 命名。軟體部分來自第 12.1 節。

重要部分是:

# 建立 MQTT 客戶端和連線

內容解密:

在這個程式碼中,我們建立了一個 MQTT 客戶端和連線到 AWS IoT 平臺。這個程式將監聽 /myPi 主題,並在收到「hello」作為 payload[‘directive’] 時列印「hello」。

圖表翻譯:

以下是 MQTT 通訊協定的簡化流程圖:

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title 樹莓派打造根據AWSIoT平臺訊息傳遞系統

package "安全架構" {
    package "網路安全" {
        component [防火牆] as firewall
        component [WAF] as waf
        component [DDoS 防護] as ddos
    }

    package "身份認證" {
        component [OAuth 2.0] as oauth
        component [JWT Token] as jwt
        component [MFA] as mfa
    }

    package "資料安全" {
        component [加密傳輸 TLS] as tls
        component [資料加密] as encrypt
        component [金鑰管理] as kms
    }

    package "監控審計" {
        component [日誌收集] as log
        component [威脅偵測] as threat
        component [合規審計] as audit
    }
}

firewall --> waf : 過濾流量
waf --> oauth : 驗證身份
oauth --> jwt : 簽發憑證
jwt --> tls : 加密傳輸
tls --> encrypt : 資料保護
log --> threat : 異常分析
threat --> audit : 報告生成

@enduml

這個流程圖展示了 MQTT 客戶端如何連線到 AWS IoT 平臺,監聽 /myPi 主題,並在收到「hello」作為 payload[‘directive’] 時列印「hello」。

建立 Raspberry Pi 的 IoT 連線

要建立 Raspberry Pi 的 IoT 連線,我們需要使用 AWS IoT Core 服務。首先,讓我們建立一個 MQTT 客戶端,連線到 AWS IoT Core。

import AWSIoTPyMQTT

# 建立 MQTT 客戶端
createMQTTClient = AWSIoTPyMQTT.AWSIoTMQTTClient("MyThing")

# 設定連線引數
createMQTTClient.configureEndpoint("你的端點", 443)

# 設定憑證
createMQTTClient.configureCredentials(
    "/home/pi/MyThing/certs/MyThing-certificate.pem.crt",
    "/home/pi/MyThing/certs/MyThing-private.pem.key",
    "/home/pi/MyThing/certs/MyThing-certificate.pem.crt"
)

# 訂閱主題
createMQTTClient.subscribe("/myPi", 1, driveCallback)

print("Listening on /myPi")

接下來,我們需要定義 driveCallback 函式,處理收到的 MQTT 訊息。

import json

def driveCallback(client, userdata, message):
    print(f"Received {message.payload} from {message.topic}")

    # 解析 JSON 訊息
    payload = json.loads(message.payload)

    # 取得指令
    command = payload['directive']

    print(f"Processing command: {command}")

    if command == "hello":
        print("hello")
    else:
        print("Command not found")

現在,你可以使用 AWS IoT Core 的 MQTT 測試客戶端傳送訊息給你的 Raspberry Pi。

傳送 MQTT 訊息給 Raspberry Pi

  1. 登入 AWS 管理主控臺,前往 IoT Core > 測試 > 裝置顧問 > MQTT 測試客戶端。
  2. 訂閱主題 /myPi
  3. 選擇「釋出到主題」,輸入以下 JSON 訊息到訊息Payload欄位:
{
    "directive": "hello"
}
  1. 確保你的 Raspberry Pi 還在等待訊息,然後點選「釋出」。

如果一切順利,你的 Raspberry Pi 應該會收到訊息並執行指令。

建立一個 Raspberry Pi IoT 裝置

在本章中,我們將探討如何建立一個 Raspberry Pi IoT 訊息傳遞系統。首先,讓我們確保您已經成功地將訊息傳遞給您的 Raspberry Pi。

從技術架構視角來看,本章節闡述了構建根據AWS IoT平臺與Raspberry Pi的物聯網訊息傳遞系統的關鍵步驟。透過MQTT協定,實作了雲端與裝置間的雙向通訊。我們深入剖析了從建立IoT事物、取得安全憑證、撰寫Python程式碼到傳送與接收MQTT訊息的完整流程,並輔以流程圖和程式碼範例,有效降低了讀者理解門檻。然而,系統的安全性仍需考量,例如憑證的儲存方式以及MQTT訊息的加密傳輸。此外,程式碼的錯誤處理機制也需強化,以提升系統的穩定性。展望未來,整合更多感測器與致動器,並結合機器學習技術,將能賦予此係統更豐富的應用場景,例如智慧家庭控制、環境監控等。對於想要入門物聯網開發的讀者,建議深入研究AWS IoT平臺提供的安全機制與進階功能,並探索更多根據MQTT協定的應用案例。玄貓認為,此架構展現了物聯網技術的應用潛力,值得開發者深入學習與實踐。