LoginSignup
5
4

More than 3 years have passed since last update.

AWS IoT Core の シャドウ機能についての調査まとめ

Posted at

シャドウ概要

AWS IoT Coreでは、ラズパイなどのエッジ端末をモノ(Thing)として登録し、その状態を保持する機能を持っています。この「状態(state)」がシャドウ(shadow)です。

アプリケーションでは、この状態の変更を通してデバイスを操作します。
image.png

状態には”reported””desired”の2つの要素が存在します。

  • ”desired”: アプリケーションとして期待する状態を示すのに使用します。アプリケーションで状態の変更要求を出す場合は、この状態を更新します。
  • “reported”: デバイス自身がどういった状態なのかを示すのに使用します。この状態を変更するのは基本的にはデバイス自身です。

image.png

具体例

下記例は、AWSコンソールからシャドウを追加し、シャドウの内容を確認した結果です。

  1. IoT Core > [モノ]タブ > 表示されたモノを選択 > [シャドウ]タブ > シャドウを追加するボタン押下
    image.png

  2. シャドウ名の入力欄が表示されるので、任意(今回は「test」)で入力し、シャドウを追加する。

  3. 追加されたシャドウを選択する。
    image.png

  4. 下記の通り、前述したdesired、reportedの状態が表示されている。
    image.png

  5. アプリケーションからの状態変更があったと想定して、コンソールでdesired側の"welcome"の値を"aiueo"変更すると、シャドウステータスが下記のように変化する。

deltaとは、状態に差異がある箇所を抽出し、表示してくれるもの

    {
      "desired": {
        "welcome": "aiueo"
      },
      "reported": {
        "welcome": "aws-iot"
      },
      "delta": {
        "welcome": "aiueo"
      }
    }
  1. 次にエッジから状態変更があったと想定して、コンソールでreportedの"welcome"の値を"oeuia"変更すると、シャドウステータスが下記のように変化する。

まだ状態が一致していないため、deltaは表示されたままとなる。

   {
     "desired": {
       "welcome": "aiueo"
     },
     "reported": {
       "welcome": "oeiua"
     },
     "delta": {
       "welcome": "aiueo"
     }
   }
  1. 最後に、コンソールでreportedの"welcome"の値を"aiueo"変更し状態を一致させると、シャドウステータスが下記のように変化する。

状態が一致するとdeltaが消える。

   {
     "desired": {
       "welcome": "aiueo"
     },
     "reported": {
       "welcome": "aiueo"
     }
   }

状態はjson形式で管理されるため、例えば下記のように、複数の情報を持つことができ、また配列なども保持することが可能。

そのため、例えば、1つのシャドウで1つのエッジにぶら下がっている複数のデバイス(照明やエアコンなど)の複数の状態(電源ON/OFF、温度など)を管理することも可能です。
(複数のシャドウで管理することも可能ですが、1つのシャドウで管理することもできます。という意味です。)

  "desired": {
    "welcome": "aws-iot",
    "device": [
      {
        "type": "light",
        "id": "1",
        "connect": true,
        "power": "on"
      },
      {
        "type": "aircon",
        "id": "2",
        "connect": true,
        "ondo": "20"
      }
    ]
  },

シャドウの種類

名前なしシャドウ

前述の例では、シャドウに名前を決めていたが、名前なしでシャドウを作ることもできる。

AWSコンソールで作成する場合、前述の例の名前決定箇所で名前を入力しなければ生成される。

公式サイトによると、あらかじめ1つしかシャドウを利用しないことが決まっているのであれば、名前なしシャドウを利用すると良いらしいが、既に複数のシャドウを使用する可能性があるのであれば、後述する名前付きシャドウを利用した方が良いとのこと。

拡張性を考えるなら、名前付きシャドウを使う方が良いとの理解。

[メリット]

  • 名前が無いため、利用する側(エッジやLambda)が名前を知らなくてもアクセスできる。(単純)

[デメリット]

  • 名前がないため、1つしか作ることができない。

名前付きシャドウ

前述の例で記載した通り、名前を指定したシャドウ。

[メリット]

  • シャドウ内で複数の状態(例えば、電源ON/OFF、温度など)を管理することもできるが、複数の名前付きシャドウを作成し、個々に管理することが可能。

[デメリット]

  • 基本的(*)にはエッジ端末が直接IoT Coreからシャドウの一覧を取得することはできないため、あらかじめ名前は決めておく必要がある。

(*)Sigv4(IAMユーザのアクセスキーとシークレットキーがあれば、取得可能だが、クライアント証明書では取得することができなかった)

シャドウへのアクセス方法

シャドウへの制御は、名前付きシャドウ と 名前なしシャドウでそれぞれ異なり、それぞれで、

GET、UPDATE、DELETEの3種類の制御が可能。

  • GETは、指定したシャドウの状態を取得

  • UPDATEは、指定したシャドウの状態を更新(desired、reportedのどちらを更新するか選択できる)

  • DELETEは、指定したシャドウの削除

エッジ側からのアクセス方法

<余談>AWS のnodejsのサンプルコードにシャドウに関するサンプルはなかったため、pythonのサンプルを元にnodejsに実装して確認してみた。
前述の通り、シャドウの制御は3つしかないので比較的簡単に実装できる。

AWS SDKの"aws-iot-device-sdk-v2"をインポートするとiotshadowというオブジェクトがある。

そのオブジェクトの提供関数に、シャドウの名前付き、名前なしでそれぞれGET、UPDATE、DELETEの関数が提供されているため、それを用いる。

なお、指定したシャドウの状態が変化した場合にコールバック関数を登録できる関数もある。

//シャドウクライアント生成。connectionはMQTTのコネクションオブジェクト
let shadow = new iotshadow.IotShadowClient(this.connection);

// GET関数コール
const getNamShadow: iotshadow.model.GetNamedShadowRequest = {
thingName: client_id,                               //モノの名前
shadowName: shadowName,                             //シャドウの名前
};
await shadow.publishGetNamedShadow(getNamShadow, mqtt.QoS.AtLeastOnce);

AWS側からのアクセス方法

Lambda経由でIoT CoreにMQTTメッセージを送信することで行う。

IoT CoreへMQTTメッセージを送信するSDK(boto3)が提供されているため、それを用いる。

GET、UPDATE、DELETE制御は、それぞれTopicを指定し行う。

名前付きシャドウの場合、下記のようにTopicにモノの名前、シャドウ名を含めMQTTメッセージを送信し、受信を待つ。

iot = boto3.client('iot-data')
topic = f'$aws/things/{thingName}/shadow/name/{shadowName}/update'
response = iot.get_thing_shadow(thingName=thingName, shadowName=shadowName)

Topicについては、公式サイト参照

補足

シャドウをあらかじめ生成していなくても、UPDATE時になければ新規生成される。

最後に

シャドウの状態は、AWS IoT Coreで管理されるため、例えばエッジの電源が落ちていても状態は残り続けます。
そのため、エッジ端末が起動していなかったとしても、シャドウの更新をしておけば、エッジ起動時にシャドウの状態に合わせて、更新後の状態にエッジを動作させる。といったことが可能になります。
シャドウが無いとエッジの状態を管理するための状態をストレージに持つ必要があるので、シャドウはとても便利に思いました。

参考URL

・概要

・シャドウ動かしてみた

・シャドウサンプル

・公式サイト

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4