IoT プラグ アンド プレイ規則

IoT プラグ アンド プレイ デバイスは、IoT ハブとメッセージを交換するとき、一連の規則に従う必要があります。 IoT プラグ アンド プレイ デバイスは、MQTT プロトコルを使用して IoT Hub と通信します。 IoT Hub では、一部の IoT デバイス SDK で使用できる AMQP プロトコルもサポートされています。

デバイスにはモジュールを含めるか、IoT Edge ランタイムによってホストされる IoT Edge モジュール内にデバイスを実装できます。

IoT プラグ アンド プレイ デバイスが実装するテレメトリ、プロパティ、コマンドを、Digital Twins Definition Language (DTDL)モデルで記述します。 この記事では、次の 2 種類のモデルを参照します。

  • コンポーネントなし - コンポーネントのないモデル。 このモデルでは、テレメトリ、プロパティ、およびコマンドを、メイン インターフェイスのコンテンツ セクションで最上位レベルの要素として宣言します。 Azure IoT エクスプローラー ツールでは、このモデルは 1 つの既定のコンポーネントとして表示されます。
  • 複数のコンポーネント - 2 つ以上のインターフェイスで構成されるモデル。 テレメトリ、プロパティ、およびコマンドを持つ既定のコンポーネントとして表示されるメイン インターフェイス。 追加のテレメトリ、プロパティ、およびコマンドを備えたコンポーネントとして宣言された 1 つ以上のインターフェイス。

詳細については、「IoT プラグ アンド プレイ モデリング ガイド」を参照してください。

モデルを識別する

実装するモデルをアナウンスするために、IoT プラグ アンド プレイ デバイスまたはモジュールでは、USERNAME フィールドに model-id を追加することにより、MQTT 接続パケットにモデル ID を含めます。

デバイスまたはモジュールに実装されるモデルを識別するには、サービスを使用して以下でモデル ID を取得できます。

  • デバイス ツインの modelId フィールド。
  • デジタル ツインの $metadata.$model フィールド。
  • デジタル ツインの変更通知

テレメトリ

  • コンポーネントのないデバイスから送信されたテレメトリは、追加のメタデータが必要ありません。 システムによって dt-dataschema プロパティが追加されます。
  • コンポーネントを使用してデバイスから送信されたテレメトリのメッセージには、コンポーネント名が追加されている必要があります。
  • MQTT を使用している場合、$.sub プロパティをコンポーネント名と共にテレメトリ トピックに追加すると、システムによって dt-subject プロパティが追加されます。
  • AMQP を使用している場合は、dt-subject プロパティをコンポーネント名と共にメッセージ注釈として追加します。

Note

コンポーネントからのテレメトリには、コンポーネントごとに 1 つのメッセージが必要です。

テレメトリの例については、「ペイロード > テレメトリ」を参照してください。

読み取り専用プロパティ

デバイスは、読み取り専用プロパティを設定し、バックエンド アプリケーションに報告します。

コンポーネントなしの読み取り専用プロパティのサンプル

デバイスまたはモジュールからは、DTDL の規則に従う有効な JSON を送信できます。

インターフェイスのプロパティを定義する DTDL:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:example: Thermostat;1",
  "@type": "Interface",
  "contents": [
    {
      "@type": "Property",
      "name": "temperature",
      "schema": "double"
    }
  ]
}

reported プロパティのペイロードの例:

"reported" :
{
  "temperature" : 21.3
}

複数のコンポーネントの読み取り専用プロパティのサンプル

この要素からコンポーネントを参照していることを示すために、デバイスまたはモジュールは {"__t": "c"} マーカーを追加する必要があります。

コンポーネントを参照する DTDL:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:com:example:TemperatureController;1",
  "@type": "Interface",
  "displayName": "Temperature Controller",
  "contents": [
    {
      "@type" : "Component",
      "schema": "dtmi:com:example:Thermostat;1",
      "name": "thermostat1"
    }
  ]
}

コンポーネントを定義する DTDL:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:com:example:Thermostat;1",
  "@type": "Interface",
  "contents": [
    {
      "@type": "Property",
      "name": "temperature",
      "schema": "double"
    }
  ]
}

reported プロパティのペイロードの例:

"reported": {
  "thermostat1": {
    "__t": "c",
    "temperature": 21.3
  }
}

読み取り専用プロパティのその他の例については、「ペイロード > プロパティ」ページを参照してください。

書き込み可能なプロパティ

バックエンド アプリケーションは、IoT Hub がデバイスに送信する書き込み可能なプロパティを設定します。

デバイスまたはモジュールでは、reported プロパティを送信することで、プロパティを受け取ったことを確認する必要があります。 報告されたプロパティには次のものが含まれます。

  • value - プロパティの実際の値 (通常は受信した値。ただし、デバイスは別の値を報告するように決定できます)。
  • ac - HTTP 状態コードを使用する受信確認コード。
  • av - 目的のプロパティの $version を参照する確認バージョン。 この値は、必要なプロパティの JSON ペイロードで見つけることができます。
  • ad - 省略可能な受信確認の説明。

受信確認応答

書き込み可能なプロパティをレポートする場合、デバイスは、次の表に示すように、前のリストの 4 つのフィールドを使用して、実際のデバイスの状態を示す受信確認メッセージを作成する必要があります

Status(ac) Version(av) Value(value) Description(av)
200 目的のバージョン 必要な値 受け入れられる必要なプロパティ値
202 目的のバージョン デバイスで受け入れられる値 受け入れられた必要なプロパティ値、進行中の更新 (200 で終了する必要があります)
203 0 デバイスによって設定された値 必要なプロパティが反映されない、デバイスから設定されたプロパティ
400 目的のバージョン デバイスで使用される実際の値 受け入れられない必要なプロパティ値
500 目的のバージョン デバイスで使用される実際の値 プロパティを適用するときの例外

デバイスが起動すると、そのデバイスは、デバイス ツインを要求し、書き込み可能なプロパティの更新があるかどうかを確認する必要があります。 デバイスがオフラインの間に書き込み可能なプロパティのバージョンが追加された場合、デバイスは reported プロパティ応答を送信して、更新を受け取ったことを確認する必要があります。

デバイスが必要な初期プロパティを IoT ハブから受け取っていない場合は、そのデバイスは初回起動時に reported プロパティの初期値を送信できます。 この場合、デバイスは既定値 av0 に、ac203 に送信できます。 次に例を示します。

"reported": {
  "targetTemperature": {
    "value": 20.0,
    "ac": 203,
    "av": 0,
    "ad": "initialize"
  }
}

デバイスは、reported プロパティを使用して、ハブに他の情報を提供できます。 たとえば、デバイスは次のような一連の進行中メッセージを使用して応答できます。

"reported": {
  "targetTemperature": {
    "value": 35.0,
    "ac": 202,
    "av": 3,
    "ad": "In-progress - reporting current temperature"
  }
}

デバイスが目標温度に達すると、次のメッセージが送信されます。

"reported": {
  "targetTemperature": {
    "value": 20.0,
    "ac": 200,
    "av": 4,
    "ad": "Reached target temperature"
  }
}

デバイスは次のようなエラーを報告できます。

"reported": {
  "targetTemperature": {
    "value": 120.0,
    "ac": 500,
    "av": 3,
    "ad": "Target temperature out of range. Valid range is 10 to 99."
  }
}

オブジェクトの種類

書き込み可能なプロパティがオブジェクトとして定義されている場合、サービスでは完全なオブジェクトをデバイスに送信する必要があります。 デバイスでは、デバイスが更新に対してどのように動作したかをサービスが認識できるように、サービスに十分な情報を返送して、更新を受信確認する必要があります。 この応答には次のものが含まれる可能性があります。

  • オブジェクト全体。
  • デバイスが更新したフィールドだけ。
  • フィールドのサブセット。

大きなオブジェクトの場合、受信確認に含めるオブジェクトのサイズを最小限に抑えることを検討してください。

次の例は、4 つのフィールドがある Object として定義された書き込み可能プロパティを示しています。

DTDL:

{
  "@type": "Property",
  "name": "samplingRange",
  "schema": {
    "@type": "Object",
    "fields": [
      {
        "name": "startTime",
        "schema": "dateTime"
      },
      {
        "name": "lastTime",
        "schema": "dateTime"
      },
      {
        "name": "count",
        "schema": "integer"
      },
      {
        "name": "errorCount",
        "schema": "integer"
      }
    ]
  },
  "displayName": "Sampling range"
  "writable": true
}

この書き込み可能プロパティを更新するには、サービスから次の例のように見える完全なオブジェクトを送信します。

{
  "samplingRange": {
    "startTime": "2021-08-17T12:53:00.000Z",
    "lastTime": "2021-08-17T14:54:00.000Z",
    "count": 100,
    "errorCount": 5
  }
}

デバイスは、次の例のように見える受信確認で応答します。

{
  "samplingRange": {
    "ac": 200,
    "av": 5,
    "ad": "Weighing status updated",
    "value": {
      "startTime": "2021-08-17T12:53:00.000Z",
      "lastTime": "2021-08-17T14:54:00.000Z",
      "count": 100,
      "errorCount": 5
    }
  }
}

コンポーネントなしの書き込み可能プロパティのサンプル

デバイスでは、1 つのペイロードで複数の必要なプロパティを受け取ると、reported プロパティ応答を複数のペイロードに送信するか、または応答を 1 つのペイロードに結合することができます。

デバイスまたはモジュールからは、DTDL の規則に従う有効な JSON を送信できます。

DTDL:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:example: Thermostat;1",
  "@type": "Interface",
  "contents": [
    {
      "@type": "Property",
      "name": "targetTemperature",
      "schema": "double",
      "writable": true
    },
    {
      "@type": "Property",
      "name": "targetHumidity",
      "schema": "double",
      "writable": true
    }
  ]
}

必要なプロパティのペイロードの例:

"desired" :
{
  "targetTemperature" : 21.3,
  "targetHumidity" : 80,
  "$version" : 3
}

reported プロパティの最初のペイロードの例:

"reported": {
  "targetTemperature": {
    "value": 21.3,
    "ac": 200,
    "av": 3,
    "ad": "complete"
  }
}

reported プロパティの 2 番目のペイロードの例:

"reported": {
  "targetHumidity": {
    "value": 80,
    "ac": 200,
    "av": 3,
    "ad": "complete"
  }
}

Note

これら 2 つの reported プロパティ ペイロードを 1 つのペイロードに結合するように選択することもできます。

複数のコンポーネントの書き込み可能プロパティのサンプル

この要素からコンポーネントを参照していることを示すために、デバイスまたはモジュールは {"__t": "c"} マーカーを追加する必要があります。

マーカーは、コンポーネントで定義されたプロパティの更新についてのみ送信されます。 既定のコンポーネントで定義されているプロパティの更新には、マーカーは含まれません。コンポーネントなしの書き込み可能プロパティのサンプルを参照してください。

デバイスでは、1 つのペイロードで複数の reported プロパティを受け取ると、複数のペイロードで reported プロパティ応答を送信するか、または応答を 1 つのペイロードに組み合わせることができます。

デバイスまたはモジュールでは、reported プロパティを送信することで、プロパティを受け取ったことを確認する必要があります。

コンポーネントを参照する DTDL:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:com:example:TemperatureController;1",
  "@type": "Interface",
  "displayName": "Temperature Controller",
  "contents": [
    {
      "@type" : "Component",
      "schema": "dtmi:com:example:Thermostat;1",
      "name": "thermostat1"
    }
  ]
}

コンポーネントを定義する DTDL:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:com:example:Thermostat;1",
  "@type": "Interface",
  "contents": [
    {
      "@type": "Property",
      "name": "targetTemperature",
      "schema": "double",
      "writable": true
    }
  ]
}

必要なプロパティのペイロードの例:

"desired": {
  "thermostat1": {
    "__t": "c",
    "targetTemperature": 21.3,
    "targetHumidity": 80,
    "$version" : 3
  }
}

reported プロパティの最初のペイロードの例:

"reported": {
  "thermostat1": {
    "__t": "c",
    "targetTemperature": {
      "value": 23,
      "ac": 200,
      "av": 3,
      "ad": "complete"
    }
  }
}

reported プロパティの 2 番目のペイロードの例:

"reported": {
  "thermostat1": {
    "__t": "c",
    "targetHumidity": {
      "value": 80,
      "ac": 200,
      "av": 3,
      "ad": "complete"
    }
  }
}

Note

これら 2 つの reported プロパティ ペイロードを 1 つのペイロードに結合するように選択することもできます。

書き込み可能プロパティのその他の例については、「ペイロード > プロパティ」を参照してください。

コマンド

プレフィックスなしでコマンド名を使用するコンポーネント インターフェイスはありません。

デバイスまたはモジュールでは、複数のコンポーネント インターフェイスで、componentName*commandName という形式のコマンド名を使用します。

コマンドの例については、「ペイロード > コマンド」を参照してください。

ヒント

IoT Central には、実行時間の長いコマンドオフライン コマンドを実装するための独自の規則があります。

次のステップ

IoT プラグ アンド プレイ規則について学習したので、いくつかの他のリソースを次に示します。