AWS IoT Device Shadowを使ってみた!(Part1)
備忘録です。
本記事は、最終目標である遠隔からDevice Shadow機能を使ってIoT Device制御をまとめたものです。 なお、4つの記事の中で今回は 下記の「 Part1 」です
主な全体記事の流れです。
■ Part1 : API Gatewayから起動するLambda関数の作成
■ Part3 : AWS IoT Deviceとshadow作成
■ Part4 : iPhoneアプリ作成 と 遠隔Camera起動確認
以前の記事からの変更追加
「 AWS API Gateway/Lambda Functionを使用してIoT Coreへメッセージを送信してみた!」の記事がベースで以下が変更と追加になります。
・Camera ON/OFFのAPI Gatewayパラメータ化
・AWS IoT Device Shadow機能でCameraの状態管理
・IoT Deviceで遠隔指示の差分を検知しカメラの起動/停止
・ Camera ON/OFFするiPhoneアプリの作成
一番難航したところ
API Gatewayのパラメータ化は、他サイトを参考にしてすIoT Coreのshadowメッセージを受信・更新までいけました。
しかし、最初IoT Device(Raspberry Pi)からIoT Coreで管理しているshadow差分が検出できず苦労しました。
期待動作しなかったのは、Part3の記事にあるRaspberry Piソースコードの「clientId 」と「thingName」変数の値を同じ文字列で実行するとダメでした。。。
AWS構成図
赤点線で囲んだ箇所を今回作成します。
IoT Device Shadowとは
主にDeviceの状態を管理するための機能として使われますが、遠隔からDeviceだけの状態だけではなく、個々の機能についても状態管理ができます。
Device(今回ではRaspberry Pi)とアプリケーション(今回ではiPhone)のそれぞれDeviceの状態情報をAWS IoT Coreに状態をUpdate送信し、AWS IoT Coreがその内容を管理することで実現しています。
状態は、デバイスが報告するアイテムを「reported」とアプリケーション操作アイテムを「desired」とし、それぞれreporedとdesiredの各内容に差分があるときは、「 delta 」というアイテムがあり、その差分情報有無で処理を実行することになります。
“reported”: デバイス自身がどういった状態なのかを示すのに使用します。この状態を変更するのは基本的にはデバイス自身です。
”desired”: アプリケーションとして期待する状態を示すのに使用します。アプリケーションで状態の変更要求を出す場合は、この状態を更新します。
Lambda function作成
Lambdaコンソールを起動します。
「 関数の作成 」ボタンをクリックします。
関数はPythonを使用します。
「 関数名 : cameraAPI 」 、「 ランタイム:Python3.7 、「 実行ロール:基本的なLambdaアクセス権限で新しいロールを作成 」を設定します。
最後に「 関数の作成 」ボタンをクリックし関数を作成します。
作成が完了すると、画面の下の方に関数コードがありますので、そちらに下記ソースコードをコピぺしてください。
最初にlambda_functionのタブのソースコード内容を消して、貼り付けしてください。
次に「 File 」-> 「 save 」し、最後に「 デプロイ」ボタンをクリックすることで変更内容が反映されます。
ソースコードは下記です。
6行目「cameraState = event['camera'] 」は、API GatewayからURLの「camera」変数に保持されてる値を取得します。
下記URLの場合は「camera=0」になっているので「event[camera]変数に0(数字ではなく文字列)が入っているイメージ」
https://xxxxxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/"test?camera=0"
19〜20行目「response = client.update_thing_shadow........」は、IoT Coreへ「desired」の「camera」の状態変更を Update Shadowを使用してメッセージを送信します。
import boto3 import json def lambda_handler(event, context): cameraState = event['camera'] # Camera ON ? if cameraState == "1": # send message state = 1 set state=1 else: # send message state = 0 set state=0 # iot Core Accsess Instance client = boto3.client('iot-data') # Iot Core shadow Update Send response = client.update_thing_shadow( thingName='RaspberryPi_Test',payload=json.dumps({"state":{"desired": {"camera": state}}}) )
ランタイム設定のハンドラは
「 lambda_function .py」ファイルの「 def lambda_handler () 」を示しており、API GaytewayからLambda functionが起動すると、「lambda_handler」関数 が動作するイメージです。
ここでLambda functionが作成しましたが、まだ「 Lambdaのロールアタッチ 」と、「 IoT Coreに送信するポリシー登録 」するまで完了していません。
それでは「Lambdaのロールアタッチ 」と「ポリシー登録」します。
Lambdaのロールアタッチとポリシー登録
Lambda function作成時に自動でロールが作成されています。Lambda function画面の「 アクセス権限 」タブを選択し、「ロール名」をクリックしてください。
IAMコンソールが起動します。
左メニューから「 ポリシー 」を選択し、「 ポリシーの作成 」ボタンをクリックします。 ここで作成するポリシーは、IoT Coreへ送信するための登録です。
ポリシーの作成画面の遷移し、サービスで「 IoT 」選択します。
アクションは「 shadow」を入力し、表示された4ポリシーにチェックボックスをクリックします。
リソースは「 すべてのリソース 」のラジオボタンをクリックし、「 ポリシーの確認 」ボタンをクリックします。
ポリシーの画面確認で名前を入力し、「 ポリシーの作成 」ボタンをクリックします。。ここでは「cameraAPI_policy」としています
作成完了後の画面です。
「 ロール 」の画面に移動し、ロール名検索で「 camera」を入力し、該当するロール名をクリックします。
「 ポリシーをアタッチします 」ボタンをクリックします。
ポリシーフィルタの検索で「camera 」を入力し、該当するポリシー名のチェックボックスにチェックを入れて、「 ポリシーのアタッチ 」ボタンをクリックします。
該当ロールに「cameraAPI-policy」がアタッチできたことが表示されます。
Lambda functionコンソールに戻り「 アクセス権限 」タブのリソース概要に「 IoT Core 」が関連付けされていることが確認できます。
これでLambda function 登録が完了です!!