AWS IoT Device Shadow 示範應用程式 - FreeRTOS

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

AWS IoT Device Shadow 示範應用程式

重要

這是 FreeRTOS 使用者指南的封存版本,適用於 FreeRTOS 版本 202210.00。如需本文件的最新版本,請參閱 FreeRTOS 使用者指南

簡介

此示範示範如何使用 AWS IoT Device Shadow 程式庫連線至 AWS Device Shadow 服務。它使用 coreMQTT 程式庫 建立與 MQTT 代理程式和 coreJSON 程式庫剖析器的 TLS (相互身分驗證) 的 AWS IoT MQTT 連線,以剖析從 AWS Shadow 服務收到的陰影文件。示範顯示基本的陰影操作,例如如何更新陰影文件,以及如何刪除陰影文件。示範也會示範如何向 coreMQTT 程式庫註冊回呼函數,以處理陰影等訊息,/update以及從 AWS IoT Device Shadow 服務傳送/update/delta的訊息。

此示範僅供學習練習使用,因為更新影子文件 (狀態) 的請求和更新回應是由相同的應用程式完成。在逼真的生產案例中,外部應用程式會請求遠端更新裝置的狀態,即使裝置目前未連線。裝置會在連線時確認更新請求。

注意

若要設定和執行 FreeRTOS 示範,請遵循中的步驟FreeRTOS 入門

功能

示範會建立單一應用程式任務,逐一查看一組範例,示範陰影/update和回/update/delta呼,以模擬切換遠端裝置的狀態。它會傳送具有新desired狀態的陰影更新,並等待裝置變更其reported狀態以回應新desired狀態。此外,陰影回/update呼會用來列印變更的陰影狀態。此示範也會使用安全 MQTT 連線至 AWS IoT MQTT 代理程式,並假設裝置影子中有一個powerOn狀態。

示範會執行下列操作:

  1. 使用 中的協助程式函數建立 MQTT 連線shadow_demo_helpers.c

  2. 使用 AWS IoT Device Shadow 程式庫定義的巨集,為裝置影子操作組合 MQTT 主題字串。

  3. 發佈至用於刪除裝置影子的 MQTT 主題,以刪除任何現有的裝置影子。

  4. 訂閱 的 MQTT 主題/update/delta/update/accepted並在 /update/rejected中使用協助程式函數shadow_demo_helpers.c

  5. 在 中使用powerOn協助程式函數發佈所需的狀態shadow_demo_helpers.c。這會導致/update/delta訊息傳送到裝置。

  6. 在 中處理傳入 MQTT 訊息prvEventCallback,並使用 Device Shadow 程式庫 () 定義的函數,判斷訊息是否與 AWS IoT 裝置影子相關Shadow_MatchTopic。如果訊息是裝置影子/update/delta訊息,則主要示範函數會發佈第二則訊息,將報告狀態更新為 powerOn。如果收到/update/accepted訊息,請確認訊息與先前在更新訊息中發佈的訊息clientToken相同。這會標記示範的結尾。

shadow 示範終端機輸出

您可以在 檔案freertos/demos/device_shadow_for_aws/shadow_demo_main.c GitHub 中找到示範。

下列螢幕擷取畫面顯示示範成功時的預期輸出。

shadow demo 終端機輸出顯示成功

連線至 AWS IoT MQTT 代理程式

若要連線至 AWS IoT MQTT 代理程式,我們使用與 MQTT_Connect() 相同的方法coreMQTT 相互身分驗證示範

刪除影子文件

若要刪除影子文件,請使用 AWS IoT Device Shadow 程式庫定義的巨集,xPublishToTopic以空白訊息呼叫 。這會使用 MQTT_Publish來發佈至 /delete 主題。下列程式碼區段顯示如何在函數 中完成此操作prvShadowDemoTask

/* First of all, try to delete any Shadow document in the cloud. */ returnStatus = PublishToTopic( SHADOW_TOPIC_STRING_DELETE( THING_NAME ), SHADOW_TOPIC_LENGTH_DELETE( THING_NAME_LENGTH ), pcUpdateDocument, 0U );

訂閱陰影主題

訂閱 Device Shadow 主題,以接收代理 AWS IoT 程式有關陰影變更的通知。Device Shadow 主題由 Device Shadow 程式庫中定義的巨集組合。下列程式碼區段顯示如何在 prvShadowDemoTask函數中完成此操作。

/* Then try to subscribe shadow topics. */ if( returnStatus == EXIT_SUCCESS ) { returnStatus = SubscribeToTopic( SHADOW_TOPIC_STRING_UPDATE_DELTA( THING_NAME ), SHADOW_TOPIC_LENGTH_UPDATE_DELTA( THING_NAME_LENGTH ) ); } if( returnStatus == EXIT_SUCCESS ) { returnStatus = SubscribeToTopic( SHADOW_TOPIC_STRING_UPDATE_ACCEPTED( THING_NAME ), SHADOW_TOPIC_LENGTH_UPDATE_ACCEPTED( THING_NAME_LENGTH ) ); } if( returnStatus == EXIT_SUCCESS ) { returnStatus = SubscribeToTopic( SHADOW_TOPIC_STRING_UPDATE_REJECTED( THING_NAME ), SHADOW_TOPIC_LENGTH_UPDATE_REJECTED( THING_NAME_LENGTH ) ); }

傳送陰影更新

若要傳送影子更新,示範會使用 Device Shadow 程式庫定義的巨集,xPublishToTopic呼叫 JSON 格式的訊息。這會使用 MQTT_Publish來發佈至 /delete 主題。下列程式碼區段顯示如何在 prvShadowDemoTask函數中完成此操作。

#define SHADOW_REPORTED_JSON \ "{" \ "\"state\":{" \ "\"reported\":{" \ "\"powerOn\":%01d" \ "}" \ "}," \ "\"clientToken\":\"%06lu\"" \ "}" snprintf( pcUpdateDocument, SHADOW_REPORTED_JSON_LENGTH + 1, SHADOW_REPORTED_JSON, ( int ) ulCurrentPowerOnState, ( long unsigned ) ulClientToken ); xPublishToTopic( SHADOW_TOPIC_STRING_UPDATE( THING_NAME ), SHADOW_TOPIC_LENGTH_UPDATE( THING_NAME_LENGTH ), pcUpdateDocument, ( SHADOW_DESIRED_JSON_LENGTH + 1 ) );

處理陰影差異訊息和陰影更新訊息

使用 函數向 coreMQTT Client Library 註冊的使用者回呼MQTT_Init函數,將通知我們傳入的封包事件。請參閱 GitHub 上的回呼函數 prvEventCallback

回呼函數會確認傳入封包的類型為 MQTT_PACKET_TYPE_PUBLISH,並使用 Device Shadow Library API Shadow_MatchTopic來確認傳入訊息是陰影訊息。

如果傳入訊息是類型為 的陰影訊息ShadowMessageTypeUpdateDelta,則我們呼叫 prvUpdateDeltaHandler 來處理此訊息。處理常式prvUpdateDeltaHandler使用 coreJSON 程式庫剖析訊息以取得 powerOn 狀態的差異值,並將此值與本機維護的目前裝置狀態進行比較。如果這些不同,則會更新本機裝置狀態,以反映陰影文件中powerOn狀態的新值。

如果傳入訊息是類型為 的陰影訊息ShadowMessageTypeUpdateAccepted,則我們呼叫 prvUpdateAcceptedHandler 來處理此訊息。處理常式會使用 coreJSON prvUpdateAcceptedHandler 程式庫剖析訊息,clientToken從訊息中取得 。此處理常式函數會檢查來自 JSON 訊息的用戶端字符是否符合應用程式使用的用戶端字符。如果不相符,函數會記錄警告訊息。