24
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

デバイスシャドウ/デバイスツインを活用した実装のベストプラクティス (2018年末)

Last updated at Posted at 2019-01-01

デバイスシャドウ、デバイスツインは、デバイスの状態に関する情報 (メタデータ、構成、状態など) を格納する ことを目的としています。
詳しくは AWS IoT Core の Device Shadow や Microsoft Azure の Device Twin を読んでください。
(以下、AWS IoT Core を対象にし、名称はシャドウで統一します)

ここではシャドウの実装に関するベストプラクティスを紹介します。

2019年1月2日追記: Wio LTE を対象とした実装を公開しました

実装すべき内容3点

実装すべきは以下3点です。便宜上 reporter updater restore とします。1

  • Reporter
    • デバイス自身の状態を取得し、取得できた内容を /update へ送信する
  • updater
    • /update/delta から得られた内容を基にデバイス自身の状態を更新する
  • restore
    • /get に問い合わせをして、返ってきた内容を基にデバイス自身の状態を更新する

Reporter

デバイス自身の状態を取得し、取得できた内容を /update へ送信します。
Reporter の実装は必須です。

image.png

送信時の JSON ですが、例えば Digital I/O の D38 番の状態を 0 もしくは 1 で表現するなら、以下の通りです。(d38とか、値は自由に設定できます)

{
  "state": {
    "reported": {
      "d38": 1
    },
    "desired": null
  }
}

詳しくは AWS IoT Core であれば シャドウの更新 を見てください。

Reporter の実行は任意ですが、 デバイスへの更新が発生した時には必ず実行してください
そうしないと、デバイスとシャドウが同期しなくなり、シャドウの中身が役に立たなくなります。

例えば後述する Updater や Restore を実行した結果、デバイスの状態が変化したら無論 Reporter を実行する必要がありますが、実世界上からの干渉によってデバイスの状態が変化したときも Reporter を実行してください。(例えば、実世界でボタンが押された、等)

image.png

desired を「空」にする

deltastate が更新された毎に算出され、必要があれば出力されます。
これは desired を送った際にはあたりまえの動作となりますが、見落としがちなのが reported を送った時にも delta が計算されるということです。
結論から言えば、 reported 送付時に desired を「空」(実装レベルで言えば null) にする必要があります。

さもないと、以下のような問題が発生します。(後日記載します)

Updater

/update/delta から得られた内容を基にデバイス自身の状態を更新します。
Updater の実装は任意です。AWS IoT Core からの状態更新要求を受け取らないのであれば実装しなくても問題ありません。

image.png

Reporter のところでも解説しましたが、 Device に反映したら Reporter を起動するようにします。

Restore

/get に問い合わせをして、返ってきた内容を基にデバイス自身の状態を更新します。
Restore の実装は任意です。ここで解説する挙動が不要であれば実装しなくても問題ありません。

image.png

AWS IoT Core の場合 /get に空文字 (例えば {}) を Publish すると /get/accpeted に以下のような JSON が返ります。

/get/accepted
{
  "state": {
    "desired":{"d38":1},
    "reported":{"d38":0},
    "delta":{"d38":1}
  },
  "metadata":{...}
}

この中で重要なのは reporteddelta です。

state.reported には後述する reporter が送信した "状態" が入っています。この内容を参照しながらデバイスを構成することで「復元」ができます。

state.delta には、オフライン中に発生した要求で、かつデバイスが適用すべき要求が入っています。この内容を参照しながらデバイスを構成することで「オフラインへの対応」ができます。

それぞれ実行するか否かは任意です。
たとえば状態復元しないのであれば reported は無視すれば良いわけです。

また「定期実行」と書いてありますが、定期的に sync することもお勧めです。

Updater との実装共有について

「デバイスの状態を更新する」という関数/メソッドを作る際、/get/accpeted/update/delta では JSON の階層が違うため、ちょっと工夫が必要です。

/get/accpeted
{"state":{"delta":{"d38":1}...}
/update/delta
{"state":{"d38":1}}

以上のようにトピックに応じて state の下の階層を掘り出してから使ってください。

全部を実装した場合のシーケンス

image.png

その他に実装すべきこと

接続を維持する方法

シャドウはステートフル・プロトコル、すなわちセッションを維持する必要があるため、セッション切断時における再接続も実装が必要です。

再接続の必要性判定&処理は Publish 直前に入れるのが良いでしょう。疑似コードで解説します。

def publish(topic, payload) {
  if (!MQTT.is_connected) {
    MQTT.connect()
  }
  MQTT.publish(topic, payload)
}

ここで解説した Restore/get へのpublishが含まれているため、Restore を定期的に実行することで自動的に再接続判定&処理がなされるという事になります。

Device ID

デバイスの ID をデバイスに埋め込むと、生産や交換が大変です。これを
(記載中: TODO)

Appendix

シーケンス図は PlantUML で記述しました。(レンダリングには PlantUML previewer を使いました)

Reporter
participant Device
participant "AWS IoT Core"

Device -> Device: Device の状態を取得
Device -> "AWS IoT Core": `{state: {reported: ...}} ` を `/update` に Publish
Updater
participant Device
participant "AWS IoT Core"

group 起動時
  Device --> "AWS IoT Core": Subscribe to `/update/delta`
end

group `/update/delta` 着信時のコールバック
  Device <- "AWS IoT Core": `{state: {...}}` が返ってくる
  Device -> Device: `state` の内容を Device に反映
  Device -> "AWS IoT Core": **Reporter**
end
Restore
participant Device
participant "AWS IoT Core"

group 起動時
  Device --> "AWS IoT Core": Subscribe to `/get/accepted`
end

group 起動時 もしくは 定期実行
  Device -> "AWS IoT Core": `/get` に Publush
  Device <- "AWS IoT Core": `{state: {...}}` が返ってくる
  Device -> Device: `state.reported` の内容を Device に反映
  note right: 最後にデバイス自身が報告した状態を復元する
  Device -> Device: `state.delta` の内容を Device に反映
  note right: オフライン中に発生した要求を反映するため
  Device -> "AWS IoT Core": **Reporter**
end

あとがき

新年からこんなことやってます。

  1. センスがないのは許してください

24
16
4

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
24
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?