Skip to content

Device Shadow

Device Shadowは、EMQX Fleetsがクラウドの意図とデバイスの現実を同期させるために使用する仕組みです。デバイスがオフラインでも常に利用可能な、デバイスの状態を永続的かつバージョン管理された形で表現します。

3つの状態モデル

各Thingは、3つの状態を含む1つのシャドウドキュメントを持ちます。

状態所有者意味
Reportedデバイスデバイス自身が最後に報告した実際の現在の状態
Desiredクラウドクラウドがデバイスに到達してほしい目標状態
DeltaFleetsによる計算DesiredとReportedの差分、つまりデバイスがまだ適用すべき内容

クラウドがDesired状態を書き込むと、FleetsがDeltaを計算してデバイスにプッシュします。デバイスはDeltaを適用し、新しい状態を報告します。Fleetsはシャドウを更新し、Deltaを再計算します(DesiredとReportedが一致するとDeltaは空になります)。

text
クラウドがDesiredを書き込む  →  FleetsがDeltaを計算  →  デバイスがDeltaを受信

クラウドがReportedを読み取る  ←  FleetsがReportedを保存  ←  デバイスが状態を報告

シャドウのバージョニング

各シャドウドキュメントには単調増加するバージョン番号があります。DesiredまたはReportedの状態が変わるたびにバージョンがインクリメントされます。デバイスはこのバージョンを使って古い更新を検出し、順序が逆の変更を適用しないようにできます。

コンソールでシャドウを確認する

  1. Fleetsのデプロイメントで、左メニューのShadow Syncに移動します。
  2. 左側のリストからThingを選択します。各エントリにはThing名とそのMQTTクライアントIDが表示されます。
  3. 右側のパネルには以下が表示されます:
    • Thing IDThing Type、現在のVersion、およびUpdated Atのタイムスタンプ
    • Current state (Reported):デバイスが最後に報告した状態
    • Target state (Desired):クラウドがデバイスに到達してほしい状態

デバイスがまだ状態を報告していない場合、Reportedパネルには「Device has not reported any state yet.」と表示されます。

最新のシャドウデータを再読み込みするには、Refresh(リフレッシュアイコン)をクリックしてください。

shadow_sync

Desired状態を更新する

デバイスにDesired状態の変更をプッシュするには:

  1. Shadow Syncに移動し、Thingを選択します。
  2. **Target state (Desired)**パネルにJSONオブジェクト形式でDesired状態を入力します:
    json
    {
      "targetTemperature": 22,
      "mode": "cooling"
    }
  3. Update Desiredをクリックします。

FleetsはDesired状態を保存し、Deltaを計算してMQTT経由でデバイスにパブリッシュします。

REST APIを使ってプログラムからDesired状態を更新することも可能です:

text
PATCH /api/v1/things/{id}/shadow

デバイスが状態変更を受け取る方法

クラウドがDesired状態を更新すると、Fleetsは2つのMQTTトピックにパブリッシュします:

トピック内容
$emqx/things/{thingName}/shadow/updateDesired状態の全ペイロード
$emqx/things/{thingName}/shadow/update/deltaReportedと異なるフィールドのみ

デバイスはDeltaトピックをサブスクライブし、異なるフィールドのみを適用してから更新された状態を報告するべきです。

デバイスがDesired状態更新時にオフラインの場合、Deltaはデバイスが再接続してトピックをサブスクライブした際に配信されます(永続的なMQTTセッションを使用)。

デバイスが状態を報告する方法

デバイスは現在の状態を以下のトピックにパブリッシュして報告します:

text
$emqx/things/{thingName}/shadow/update

ペイロード例:

json
{
  "state": {
    "reported": {
      "temperature": 21.5,
      "targetTemperature": 22,
      "mode": "cooling"
    }
  },
  "clientToken": "optional-correlation-id",
  "version": 3
}

EMQXはこのメッセージをFleetsにルーティングし、Fleetsは以下を行います:

  1. GreptimeDB(時系列履歴)とPostgreSQL(最新コピー)にReported状態を保存
  2. Deltaを再計算
  3. シャドウのバージョンを更新

また、デバイスはHTTPS経由で状態を報告することも可能です:

text
POST /api/v1/thing-datas/shadow/reported

プロトコルの詳細はMQTT IntegrationまたはHTTPS Integrationを参照してください。

Desired状態をクリアする

Desired状態を削除するには(例えばデバイスが収束した後):

  1. Shadow Syncに移動し、Thingを選択します。
  2. Clear Desired(リフレッシュボタンの隣のアイコン)をクリックします。

REST APIを使う場合は以下を実行します:

text
DELETE /api/v1/things/{id}/shadow

シャドウ履歴

Reported状態はGreptimeDBに時系列データとして保存されます。過去のシャドウ値はDevice Queryの時系列フィルターでtsFromtsTotsFieldNameパラメータを使ってクエリ可能です。

次のステップ