[アップデート]IoT Coreで名前付きシャドウが利用できるようになりました

IoT案件におけるコスト削減やセキュリティレベル向上が期待できるアップデートです
2020.07.10

CX事業本部@大阪の岩田です。 AWS IoT Coreで新機能「名前付きシャドウ」が利用できるようになりました。この新機能について簡単に紹介させて頂きます。

名前付きシャドウとは?

AWS IoT Coreには元々「デバイスシャドウ」という機能がありました。デバイスシャドウはデバイスの状態をクラウド側から管理するためのデータストアとして設計されており

  • デバイスのあるべき状態を格納するdesired
  • デバイスから報告された実際の状態を格納するreported
  • desiredとreportedの差分を格納するdelta

3つのプロパティから構成されています。データの構造は以下のようなイメージです

{
  "desired": {
    "led": {
      "color": "green"
    }
  },
  "reported": {
    "led": {
      "color": "red"
    }
  },
  "delta": {
    "led": {
      "color": "green"
    }
  }
}

このデバイスシャドウはIoT Coreで管理するモノに対して1:1で紐づいていましたが、今回追加された新機能名前付きシャドウを利用することで、1つのモノに対してN個のシャドウを紐づけることが可能になりました。

なお、名前付きシャドウに対して旧来のデバイスシャドウは「クラシックシャドウ」と呼ばれるようです。

何が嬉しいの?

これまではデバイスに紐づくシャドウを1つしか持てなかったため、あらゆる状態データが1つのシャドウに格納されていました。本来状態データにアクセスする必要のあるユーザーやアクセス頻度はデータの特性によって異なりますが、1つのモノに1つのシャドウしか持てないという制約から、全てのユーザーが全ての状態データにアクセスするような管理方法を取らざるを得ませんでした。そのため

  • 適切な権限分離ができない
  • デバイスシャドウのサイズが肥大化し、シャドウサイズの制限に達する
  • AWS <-> エッジ間でのNW転送量が最適化できずに、レイテンシやコストに悪影響を及ぼす

といった課題を抱えていました。

今後は名前付きシャドウを利用して状態データの特性ごとにシャドウを分割することで、これらの課題を改善できるようになりました。

やってみる

実際に名前付きシャドウの機能を利用してみます。

マネコンから名前付きシャドウを作成してみる

まずは適当にモノを作成します。名前は「myThing」としました。

モノを作成したら詳細を表示してみます。以前からUIが変わっていることが分かりますね。モノの作成直後はデフォルトで「Classic Shadow」というシャドウが作成されています。これが旧来のデバイスシャドウです。

名前付きシャドウを作成してみましょう。「シャドウを追加する」のリンクをクリックするとシャドウの名前を指定するためのポップアップが表示されるので、適当な名前を設定して「追加」をクリックします。

登録完了後の画面です。

1つのモノに対して

  • クラシックシャドウ
  • switchという名前付きシャドウ

2つのシャドウが紐づいているのが分かります。

AWS CLIからシャドウを取得してみる

AWS CLIからクラシックシャドウを取得してみます。これは旧来の方法が利用できます。

$ aws iot-data get-thing-shadow --thing-name myThing  /dev/stdout | jq .
{
  "state": {
    "desired": {
      "welcome": "aws-iot"
    },
    "reported": {
      "welcome": "aws-iot"
    }
  },
  "metadata": {
    "desired": {
      "welcome": {
        "timestamp": 1594339836
      }
    },
    "reported": {
      "welcome": {
        "timestamp": 1594339836
      }
    }
  },
  "version": 11,
  "timestamp": 1594340449
}

続いて名前付きシャドウの取得です。--shadow-name というパラメータでシャドウの名前を指定します。ここでは名前付きシャドウ作成時に指定したswitchという名前を指定しています。

$ aws iot-data get-thing-shadow --thing-name myThing --shadow-name switch /dev/stdout | jq .
{
  "state": {
    "desired": {
      "welcome": "aws-iot"
    },
    "reported": {
      "welcome": "aws-iot"
    }
  },
  "metadata": {
    "desired": {
      "welcome": {
        "timestamp": 1594339915
      }
    },
    "reported": {
      "welcome": {
        "timestamp": 1594339915
      }
    }
  },
  "version": 1,
  "timestamp": 1594340545
}

取得できました。先程取得したクラシックシャドウとは諸々のtimestampが異なっていることが分かります。

名前付きシャドウ用のトピックをSubscribeしてみる

名前付きシャドウの機能追加によってデバイスシャドウ関連の予約済みトピックはどうなるのでしょうか?こちらの記事にまとめられているように、デバイスシャドウ関連に関する諸々のイベントが発生すると、$aws/things/<モノの名前>/shadow/という予約済みトピックに関連するイベントデータが流れてきます。

クラシックシャドウに関しては今後も$aws/things/<モノの名前>/shadow/のトピックが利用でき、名前付きシャドウに関しては$aws/things/<モノの名前>/shadow/name/<シャドウの名前>というトピックが利用可能です。

シャドウトピック

こちらもマネコンから試してみましょう。

先ほど作成した名前付きシャドウの更新を検知するために$aws/things/myThing/shadow/name/switch/#をSubscribeしてみます。

この状態でクラシックシャドウを更新してみます。

MQTTクライアントの方には特に何も情報が流れてきません。

今度は名前付きシャドウを更新してみます。

今度はMQTTクライアントにデータが流れてきました。想定通りに動作しているようです。

まとめ

実際にIoT案件をやっていると、エッジ側のハードウェアのパワー不足や通信回線のコストの問題で、少しでもAWS <-> エッジ間の通信量を削減したい という要望を頂くことが少なくありません。名前付きシャドウを活用することで、こういったユースケースにも柔軟に対応することが可能になりました。現在クラシックシャドウを利用している環境も名前付きシャドウへの移行を検討してみても良いかもしれませんね。

参考