Atom's tech blog

AWS IoT Device Shadowを使ってみた!(Part1)

f:id:iAtom:20201218174003j:plain


備忘録です。

本記事は、最終目標である遠隔からDevice Shadow機能を使ってIoT Device制御をまとめたものです。 なお、4つの記事の中で今回は 下記の「 Part1 」です

主な全体記事の流れです。

■ Part1 : API Gatewayから起動するLambda関数の作成

■ Part2:API GatewayAPI作成

■ 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構成図

赤点線で囲んだ箇所を今回作成します。


f:id:iAtom:20201217154234j:plain

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コンソールを起動します。


f:id:iAtom:20201207202403j:plain


関数の作成 」ボタンをクリックします。


f:id:iAtom:20201207202723j:plain


関数はPythonを使用します。

関数名 : cameraAPI 」 、「 ランタイム:Python3.7 、「 実行ロール:基本的なLambdaアクセス権限で新しいロールを作成 」を設定します。


f:id:iAtom:20201216111522j:plain


最後に「 関数の作成 」ボタンをクリックし関数を作成します。


f:id:iAtom:20201207203812j:plain


作成が完了すると、画面の下の方に関数コードがありますので、そちらに下記ソースコードをコピぺしてください。


f:id:iAtom:20201216111918j:plain

最初にlambda_functionのタブのソースコード内容を消して、貼り付けしてください。

次に「 File 」-> 「 save 」し、最後に「 デプロイ」ボタンをクリックすることで変更内容が反映されます。

f:id:iAtom:20201216112720j:plain

ソースコードは下記です。

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」関数 が動作するイメージです。


f:id:iAtom:20201207205805j:plain


ここでLambda functionが作成しましたが、まだ「 Lambdaのロールアタッチ 」と、「 IoT Coreに送信するポリシー登録 」するまで完了していません。

それでは「Lambdaのロールアタッチ 」と「ポリシー登録」します。

Lambdaのロールアタッチとポリシー登録

Lambda function作成時に自動でロールが作成されています。Lambda function画面の「 アクセス権限 」タブを選択し、「ロール名」をクリックしてください。


f:id:iAtom:20201216114843j:plain

IAMコンソールが起動します。

左メニューから「 ポリシー 」を選択し、「 ポリシーの作成 」ボタンをクリックします。 ここで作成するポリシーは、IoT Coreへ送信するための登録です。


f:id:iAtom:20201207210807j:plain


ポリシーの作成画面の遷移し、サービスで「 IoT 」選択します。


f:id:iAtom:20201207211113j:plain


アクションは「 shadow」を入力し、表示された4ポリシーにチェックボックスをクリックします。


f:id:iAtom:20201216120201j:plain


リソースは「 すべてのリソース 」のラジオボタンをクリックし、「 ポリシーの確認 」ボタンをクリックします。


f:id:iAtom:20201216120302j:plain


ポリシーの画面確認で名前を入力し、「 ポリシーの作成 」ボタンをクリックします。。ここでは「cameraAPI_policy」としています


f:id:iAtom:20201216120918j:plain


作成完了後の画面です。


f:id:iAtom:20201216130326p:plain


ロール 」の画面に移動し、ロール名検索で「 camera」を入力し、該当するロール名をクリックします。


f:id:iAtom:20201216130838j:plain


「 ポリシーをアタッチします 」ボタンをクリックします。


f:id:iAtom:20201216131250j:plain


ポリシーフィルタの検索で「camera 」を入力し、該当するポリシー名のチェックボックスにチェックを入れて、「 ポリシーのアタッチ 」ボタンをクリックします。


f:id:iAtom:20201216132201j:plain


該当ロールに「cameraAPI-policy」がアタッチできたことが表示されます。


f:id:iAtom:20201216132540j:plain


Lambda functionコンソールに戻り「 アクセス権限 」タブのリソース概要に「 IoT Core 」が関連付けされていることが確認できます。


f:id:iAtom:20201216132850j:plain

これでLambda function 登録が完了です!!

次はAWS API Gatewayに新しいAPIを作成します。