IoT 隨插即用慣例

當裝置與 IoT 中樞交換訊息時,IoT 隨插即用裝置應該遵循一組慣例。 IoT 隨插即用裝置使用 MQTT 通訊協定來與IoT 中樞通訊,某些裝置 SDK 支援IOT 中樞且可在某些裝置 SDK 中使用 AMQP。

裝置可以包含模組,或實作在由IoT Edge執行時間裝載的IoT Edge模組中。

您會描述IoT 隨插即用裝置使用Digital Twins Definition Language v2 (DTDL) 模型實作的遙測、屬性和命令。 本文中提及的模型有兩種類型:

  • 無元件 - 沒有元件的模型。 模型會將遙測、屬性和命令宣告為主要介面內容區段中的最上層屬性。 在Azure IoT總管工具中,此模型會顯示為單一預設元件
  • 多個元件 - 由兩個或多個介面組成的模型。 主要介面,其會顯示為 預設元件,其中包含遙測、屬性和命令。 宣告為具有其他遙測、屬性和命令之元件的一或多個介面。

如需詳細資訊,請參閱IoT 隨插即用模型化指南

識別模型

若要宣告其實作的模型,IoT 隨插即用裝置或模組會藉由將 新增 model-idUSERNAME 欄位,在 MQTT 連線封包中包含模型識別碼。

若要識別裝置或模組所實作的模型,服務可以從下列來源取得模型識別碼:

  • 裝置對應項 modelId 欄位。
  • 數位對應項 $metadata.$model 欄位。
  • 數位對應項變更通知。

遙測

  • 從任何元件裝置傳送的遙測不需要任何額外的中繼資料。 系統會新增 dt-dataschema 屬性。
  • 使用元件從裝置傳送的遙測必須將元件名稱新增至遙測訊息。
  • 使用 MQTT 將 $.sub 具有元件名稱的屬性新增至遙測主題時,系統會新增 dt-subject 屬性。
  • 使用 AMQP 時,請將 dt-subject 具有元件名稱的屬性新增為訊息批註。

注意

來自元件的遙測需要每個元件的一則訊息。

唯讀屬性

取樣無元件唯讀屬性

裝置或模組可以傳送任何遵循 DTDL v2 規則的有效 JSON。

DTDL:

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

報告屬性承載範例:

"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": {
  "thermostat1": {
    "__t": "c",
    "temperature": 21.3
  }
}

可寫入的屬性

裝置或模組應該藉由傳送報告屬性來確認它已接收屬性。 報告的屬性應該包括:

  • value - 屬性的實際值 (通常接收的值,但裝置可能會決定報告不同的值) 。
  • ac - 使用 HTTP 狀態碼的通知代碼。
  • av - 參考 $version 所需屬性之 的通知版本。 您可以在所需的屬性 JSON 承載中找到此值。
  • ad - 選擇性通知描述。

通知回應

當報告可寫入屬性時,裝置應該使用上述四個欄位來撰寫通知訊息,以指出實際的裝置狀態,如下表所述

狀態 (ac) 版本 (av) 值 (值) 描述 (av)
200 所需的版本 所需的值 已接受所需的屬性值
202 所需的版本 裝置接受的值 已接受所需的屬性值,進行中更新 (應該會完成 200)
203 0 裝置所設定的值 從裝置設定的屬性,不會反映任何所需的屬性
400 所需的版本 裝置所使用的實際值 不接受所需的屬性值
500 所需的版本 裝置所使用的實際值 套用 屬性時的例外狀況

當裝置啟動時,它應該要求裝置對應項,並檢查是否有任何可寫入的屬性更新。 如果在裝置離線時增加可寫入屬性的版本,裝置應該傳送報告的屬性回應,以確認它已收到更新。

當裝置第一次啟動時,如果未從中樞收到初始所需的屬性,它可以傳送報告屬性的初始值。 在此情況下,裝置可以使用 將 的 av 預設值傳送至 0203ac 。 例如:

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

裝置可以使用報告屬性,將其他資訊提供給中樞。 例如,裝置可能會回應一系列進行中的訊息,例如:

"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."
  }
}

物件類型

如果可寫入的屬性定義為物件,服務必須將完整物件傳送至裝置。 裝置應該藉由將足夠的資訊傳回服務來認可更新,以瞭解裝置在更新上的運作方式。 此回應可能包括:

  • 整個 物件。
  • 只有裝置更新的欄位。
  • 欄位的子集。

對於大型物件,請考慮將您包含在通知中的物件大小降至最低。

下列範例顯示定義為 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
    }
  }
}

範例無元件可寫入屬性

當裝置在單一承載中收到多個所需的屬性時,它可以跨多個承載傳送報告的屬性回應,或將回應合併成單一承載。

裝置或模組可以傳送任何遵循 DTDL v2 規則的有效 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": {
  "targetTemperature": {
    "value": 21.3,
    "ac": 200,
    "av": 3,
    "ad": "complete"
  }
}

報告屬性第二個承載的範例:

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

注意

您可以選擇將這兩個報告的屬性承載合併成單一承載。

範例多個元件可寫入屬性

裝置或模組必須新增 {"__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": "targetTemperature",
      "schema": "double",
      "writable": true
    }
  ]
}

範例所需的屬性承載:

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

範例報告屬性第一個承載:

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

報告屬性第二個承載的範例:

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

注意

您可以選擇將這兩個報告的屬性承載合併成單一承載。

命令

沒有元件介面會使用沒有前置詞的命令名稱。

在裝置或模組上,多個元件介面會使用具有下列格式的命令名稱: componentName*commandName

後續步驟

現在您已瞭解IoT 隨插即用慣例,以下是一些額外的資源: