AWS IoT Device Shadow デモアプリケーション
重要
このデモは、非推奨の Amazon-FreeRTOS リポジトリでホストされています。新しいプロジェクトを作成するときは、ここから始めることをお勧めします。現在非推奨の Amazon-FreeRTOS リポジトリをベースにした既存の FreeRTOS プロジェクトが既にある場合は、「Amazon FreeRTOS Github リポジトリ移行ガイド」を参照してください。
序章
このデモでは、AWS IoT Device Shadow ライブラリを使って AWS Device Shadow サービスに接続する方法を説明しています。coreMQTT ライブラリ を使用して、AWS IoT MQTT ブローカーと coreJSON ライブラリパーサーへの TLS (相互認証) MQTT 接続を確立し、AWS Shadow サービスから受信したシャドウドキュメントを解析します。デモでは、シャドウドキュメントの更新方法やシャドウドキュメントの削除方法など、基本的なシャドウオペレーションについて説明します。また、AWS IoT Device Shadow サービスから送信されるメッセージ (シャドウ /update や /update/delta メッセージなど) を処理するために coreMQTT ライブラリを使ってコールバック関数を登録する方法も示します。
このデモは、シャドウドキュメント (状態) の更新要求と更新レスポンスが同じアプリケーションによって行われるため、学習演習としてのみ意図されています。現実的な本番シナリオでは、デバイスが現在接続されていない場合でも、外部アプリケーションによってデバイスの状態の更新がリモートで要求されます。デバイスは、接続時に更新要求を承認します。
注記
FreeRTOS デモをセットアップして実行するには、FreeRTOS の開始方法 の手順に従います。
機能
デモでは、シャドウ /update と /update/delta コールバックを示す一連の例をループする 1 つのアプリケーションタスクを作成して、リモートデバイスの状態を切り替えます。新しい desired 状態のシャドウアップデートを送信し、デバイスが新しい desired 状態に応答して reported を変更するまで待ちます。さらに、シャドウ /update コールバックは、変化するシャドウの状態を出力するために使用されます。また、AWS IoT MQTT ブローカーへの安全な MQTT 接続を使用し、デバイスシャドウが powerOn の状態であると想定します。
このデモでは以下のオペレーションを実行します。
-
shadow_demo_helpers.cのヘルパー関数を使用して MQTT 接続を確立します。 -
AWS IoT Device Shadow ライブラリで定義されたマクロを使用して、デバイスシャドウオペレーションの MQTT トピック文字列を組み立てます。
-
デバイスシャドウの削除用に使用する MQTT トピックに公開して、既存のデバイスシャドウを削除します。
-
shadow_demo_helpers.cのヘルパー関数を使って、/update/delta、/update/accepted、/update/rejectedの MQTT トピックをサブスクライブします。 -
shadow_demo_helpers.cのヘルパー関数を使ってpowerOnの望ましい状態を公開します。これにより、デバイスに/update/deltaメッセージが送信されます。 -
prvEventCallbackで受信 MQTT メッセージを処理し、AWS IoT Device Shadow ライブラリ (Shadow_MatchTopic) で定義される関数を使ってそのメッセージがデバイスシャドウに関連しているかどうかを判断します。メッセージがデバイスシャドウ/update/deltaメッセージの場合、メインのデモ関数が 2 つ目のメッセージを発行して、報告された状態をpowerOnに更新します。/update/acceptedメッセージを受信した場合、以前更新メッセージで発行されたものとclientTokenが同じか確認します。これでデモは終了です。
デモはファイル または GitHubfreertos/demos/device_shadow_for_aws/shadow_demo_main.c
次のスクリーンショットは、デモが成功したときに予想される出力です。
AWS IoT MQTT ブローカーに接続する
AWS IoT MQTT ブローカーに接続するには、coreMQTT Mutual Authentication デモ の MQTT_Connect() と同じ方法を使用します。
シャドウキュメントを削除する
シャドウドキュメントを削除するには、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 ライブラリで定義されるマクロを使用して、JSON 形式のメッセージ付きの xPublishToTopic を呼び出します。これは 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 ) );
シャドウデルタメッセージとシャドウ更新メッセージを処理する
ユーザーコールバック関数は MQTT_Init 関数を使って coreMQTT クライアントライブラリ
コールバック関数は受信パケットが MQTT_PACKET_TYPE_PUBLISH のタイプであることを確認し、Device Shadow ライブラリ API Shadow_MatchTopic を使用して、受信メッセージがシャドウメッセージであることを確認します。
受信メッセージが ShadowMessageTypeUpdateDelta タイプのシャドウメッセージである場合、prvUpdateDeltaHandlerprvUpdateDeltaHandler が coreJSON ライブラリを使用してメッセージを解析し、powerOn 状態のデルタ値を取得し、これをローカルで保持されているデバイスの現在の状態と比較します。これらが異なる場合、シャドウドキュメントの powerOn 状態の新しい値を反映するようにローカルデバイスの状態が更新されます。
受信メッセージが ShadowMessageTypeUpdateAccepted タイプのシャドウメッセージである場合、prvUpdateAcceptedHandlerprvUpdateAcceptedHandler は coreJSON ライブラリを使用してメッセージを解析し、メッセージから clientToken を取得します。このハンドラ関数は、JSON メッセージのクライアントトークンが、アプリケーションで使用されるクライアントトークンと一致するかチェックします。一致しない場合、関数は警告メッセージをログに記録します。