IoT 隨插即用 模型化指南

IoT 隨插即用 的核心是一種裝置模型,可描述 IoT 隨插即用 啟用應用程式之裝置的功能。 此模型會結構化為一組可定義下列項目的介面:

  • 屬性 ,表示裝置或其他實體的唯讀或可寫入狀態。 例如,裝置序號可能是唯讀屬性,而控溫器上的目標溫度可能是可寫入屬性。
  • 定義裝置所發出數據的遙測 欄位,不論數據是感測器讀數的一般數據流、偶爾的錯誤或資訊訊息。
  • 描述 可在裝置上完成之函式或作業的命令。 例如,命令可以重新啟動閘道或使用遠端相機拍照。

若要深入瞭解 IoT 隨插即用 如何使用裝置型號,請參閱 IoT 隨插即用 裝置開發人員指南IoT 隨插即用 服務開發人員指南

若要定義模型,您可以使用 Digital Twins 定義語言 (DTDL)。 DTDL 使用稱為 JSON-LD 的 JSON 變體。 下列代碼段顯示控溫器裝置的模型:

  • 具有唯一的模型標識碼: dtmi:com:example:Thermostat;1
  • 傳送溫度遙測資料。
  • 具有可寫入屬性可設定目標溫度。
  • 具有唯讀屬性,可報告自上次重新啟動以來的最高溫度。
  • 回應一段時間內要求最高、最小值和平均溫度的命令。
{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:com:example:Thermostat;1",
  "@type": "Interface",
  "displayName": "Thermostat",
  "description": "Reports current temperature and provides desired temperature control.",
  "contents": [
    {
      "@type": [
        "Telemetry",
        "Temperature"
      ],
      "name": "temperature",
      "displayName": "Temperature",
      "description": "Temperature in degrees Celsius.",
      "schema": "double",
      "unit": "degreeCelsius"
    },
    {
      "@type": [
        "Property",
        "Temperature"
      ],
      "name": "targetTemperature",
      "schema": "double",
      "displayName": "Target Temperature",
      "description": "Allows to remotely specify the desired target temperature.",
      "unit": "degreeCelsius",
      "writable": true
    },
    {
      "@type": [
        "Property",
        "Temperature"
      ],
      "name": "maxTempSinceLastReboot",
      "schema": "double",
      "unit": "degreeCelsius",
      "displayName": "Max temperature since last reboot.",
      "description": "Returns the max temperature since last device reboot."
    },
    {
      "@type": "Command",
      "name": "getMaxMinReport",
      "displayName": "Get Max-Min report.",
      "description": "This command returns the max, min and average temperature from the specified time to the current time.",
      "request": {
        "name": "since",
        "displayName": "Since",
        "description": "Period to return the max-min report.",
        "schema": "dateTime"
      },
      "response": {
        "name": "tempReport",
        "displayName": "Temperature Report",
        "schema": {
          "@type": "Object",
          "fields": [
            {
              "name": "maxTemp",
              "displayName": "Max temperature",
              "schema": "double"
            },
            {
              "name": "minTemp",
              "displayName": "Min temperature",
              "schema": "double"
            },
            {
              "name": "avgTemp",
              "displayName": "Average Temperature",
              "schema": "double"
            },
            {
              "name": "startTime",
              "displayName": "Start Time",
              "schema": "dateTime"
            },
            {
              "name": "endTime",
              "displayName": "End Time",
              "schema": "dateTime"
            }
          ]
        }
      }
    }
  ]
}

控溫器模型具有單一介面。 本文稍後的範例顯示使用元件和繼承的更複雜的模型。

本文說明如何設計和撰寫您自己的模型,並涵蓋數據類型、模型結構和工具等主題。

若要深入瞭解,請參閱 Digital Twins 定義語言 規格。

注意

IoT Central 目前支援具有 IoT Central 擴充功能的 DTDL v2。

模型結構

屬性、遙測和命令會分組為介面。 本節說明如何使用介面,透過元件和繼承來描述簡單和複雜的模型。

模型標識碼

每個介面都有唯一的數字對應項模型標識碼(DTMI)。 複雜的模型會使用 DTMIs 來識別元件。 應用程式可以使用裝置傳送的 DTMIs,在存放庫中尋找模型定義。

DTMIS 應該使用下列命名慣例:

  • DTMI 前置詞為 dtmi:
  • DTMI 後綴是模型的版本號碼,例如 ;2
  • DTMI 的主體會對應至儲存模型之模型存放庫中的資料夾和檔案。 版本號碼是檔名的一部分。

例如,DTMI 所識別的模型會儲存在 dtmidtmi:com:Example:Thermostat;2/com/example/thermostat-2.json 檔案中。

下列代碼段顯示介面定義的大綱及其唯一 DTMI:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:com:example:Thermostat;2",
  "@type": "Interface",
  "displayName": "Thermostat",
  "description": "Reports current temperature and provides desired temperature control.",
  "contents": [
    ...
  ]
}

沒有元件

簡單的模型,例如先前顯示的控溫器,不會使用內嵌或串聯的元件。 遙測、屬性和命令定義於 contents 介面的節點中。

下列範例顯示不使用元件的簡單模型的一部分:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:com:example:Thermostat;1",
  "@type": "Interface",
  "displayName": "Thermostat",
  "description": "Reports current temperature and provides desired temperature control.",
  "contents": [
    {
      "@type": [
        "Telemetry",
        "Temperature"
      ],
      "name": "temperature",
      "displayName": "Temperature",
      "description": "Temperature in degrees Celsius.",
      "schema": "double",
      "unit": "degreeCelsius"
    },
    {
      "@type": [
        "Property",
...

Azure IoT Explorer 和 IoT Central 裝置範本設計工具等工具會將獨立介面加上標籤,例如控溫器作為 預設元件

下列螢幕快照顯示模型在 Azure IoT Explorer 工具中的顯示方式:

顯示 Azure IoT 總管工具中預設元件的螢幕快照。

下列螢幕快照顯示模型在IoT Central裝置範本設計工具中顯示為預設元件的方式。 選取 [ 檢視身分 識別] 以查看模型的 DTMI:

顯示 IoT Central 裝置範本設計工具中控溫器模型的螢幕快照。

模型標識符會儲存在裝置對應項屬性中,如下列螢幕快照所示:

Azure IoT Explorer 工具的螢幕快照,其中顯示數位對應項屬性中的模型標識符。

不含元件的 DTDL 模型,對於具有單一遙測、屬性和命令的裝置或 IoT Edge 模組而言,是有用的簡化。 不使用元件的模型可讓您輕鬆地將現有的裝置或模組移轉為 IoT 隨插即用 裝置或模組 - 您建立 DTDL 模型來描述實際裝置或模組,而不需要定義任何元件。

提示

模組可以是裝置 模組IoT Edge模組

重複使用

有兩種方式可以重複使用介面定義。

  • 在模型中使用多個元件來參考其他介面定義。
  • 使用繼承來擴充現有的介面定義。

多個元件

元件可讓您建置模型介面做為其他介面的元件。

例如, 控溫器 介面會定義為模型。 當您定義 溫度控制器模型時,您可以將此介面併入為一或多個元件。 在下列範例中,這些元件稱為 thermostat1thermostat2

對於具有多個元件的 DTDL 模型,有兩個以上的元件區段。 每個區段都 @type 已設定為 Component 並明確參考架構,如下列代碼段所示:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:com:example:TemperatureController;1",
  "@type": "Interface",
  "displayName": "Temperature Controller",
  "description": "Device with two thermostats and remote reboot.",
  "contents": [
    {
      "@type": [
        "Telemetry",
        "DataSize"
      ],
      "name": "workingSet",
      "displayName": "Working Set",
      "description": "Current working set of the device memory in KiB.",
      "schema": "double",
      "unit": "kibibyte"
    },
    {
      "@type": "Property",
      "name": "serialNumber",
      "displayName": "Serial Number",
      "description": "Serial number of the device.",
      "schema": "string"
    },
    {
      "@type": "Command",
      "name": "reboot",
      "displayName": "Reboot",
      "description": "Reboots the device after waiting the number of seconds specified.",
      "request": {
        "name": "delay",
        "displayName": "Delay",
        "description": "Number of seconds to wait before rebooting the device.",
        "schema": "integer"
      }
    },
    {
      "@type" : "Component",
      "schema": "dtmi:com:example:Thermostat;1",
      "name": "thermostat1",
      "displayName": "Thermostat One",
      "description": "Thermostat One of Two."
    },
    {
      "@type" : "Component",
      "schema": "dtmi:com:example:Thermostat;1",
      "name": "thermostat2",
      "displayName": "Thermostat Two",
      "description": "Thermostat Two of Two."
    },
    {
      "@type": "Component",
      "schema": "dtmi:azure:DeviceManagement:DeviceInformation;1",
      "name": "deviceInformation",
      "displayName": "Device Information interface",
      "description": "Optional interface with basic device hardware information."
    }
  ]
}

此模型在contents區段中定義了三個元件 - 兩 Thermostat 個元件和一個 DeviceInformation 元件。 contents 區段也包含屬性、遙測和命令定義。

下列螢幕快照顯示此模型在IoT Central中的顯示方式。 溫度控制器中的屬性、遙測和命令定義會出現在最上層 預設元件中。 每個控溫器的屬性、遙測和命令定義會出現在元件定義中:

顯示 IoT Central 中溫度控制器裝置範本的螢幕快照。

此螢幕快照顯示IoT Central 中溫度控制器裝置範本中的控溫器元件。

若要瞭解如何撰寫與元件互動的裝置程序代碼,請參閱 IoT 隨插即用 裝置開發人員指南

若要瞭解如何撰寫與裝置上元件互動的服務程序代碼,請參閱 IoT 隨插即用 服務開發人員指南

繼承

繼承可讓您重複使用基底介面中的功能,以擴充介面的功能。 例如,數個裝置型號可以共用常見的功能,例如序號:

顯示裝置模型中繼承範例的圖表。控溫器介面和流量控制器介面都會從基底介面共用功能。

下列代碼段顯示 DTML 模型,該模型會使用 extends 關鍵詞來定義上圖中顯示的繼承關聯性:

[
  {
    "@context": "dtmi:dtdl:context;2",
    "@id": "dtmi:com:example:Thermostat;1",
    "@type": "Interface",
    "contents": [
      {
        "@type": "Telemetry",
        "name": "temperature",
        "schema": "double",
        "unit": "degreeCelsius"
      },
      {
        "@type": "Property",
        "name": "targetTemperature",
        "schema": "double",
        "unit": "degreeCelsius",
        "writable": true
      }
    ],
    "extends": [
      "dtmi:com:example:baseDevice;1"
    ]
  },
  {
    "@context": "dtmi:dtdl:context;2",
    "@id": "dtmi:com:example:baseDevice;1",
    "@type": "Interface",
    "contents": [
      {
        "@type": "Property",
        "name": "SerialNumber",
        "schema": "double",
        "writable": false
      }
    ]
  }
]

下列螢幕快照顯示IoT Central裝置範本環境中的此模型:

顯示IoT Central中介面繼承的螢幕快照。

當您撰寫裝置或服務端程式代碼時,程式代碼不需要執行任何特殊動作來處理繼承的介面。 在本節所示的範例中,您的裝置程式代碼會報告序號,就像是控溫器介面的一部分一樣。

提示

您可以在建立模型時結合元件和繼承。 下圖顯示 thermostat 繼承自介面的 baseDevice 模型。 介面 baseDevice 具有元件,其本身繼承自另一個介面:

此圖顯示同時使用元件和繼承的模型。

下列代碼段顯示 DTML 模型,其使用 extendscomponent 關鍵字來定義上圖中顯示的繼承關聯性和元件使用方式:

[
  {
    "@context": "dtmi:dtdl:context;2",
    "@id": "dtmi:com:example:Thermostat;1",
    "@type": "Interface",
    "contents": [
      {
        "@type": "Telemetry",
        "name": "temperature",
        "schema": "double",
        "unit": "degreeCelsius"
      },
      {
        "@type": "Property",
        "name": "targetTemperature",
        "schema": "double",
        "unit": "degreeCelsius",
        "writable": true
      }
    ],
    "extends": [
      "dtmi:com:example:baseDevice;1"
    ]
  },
  {
    "@context": "dtmi:dtdl:context;2",
    "@id": "dtmi:com:example:baseDevice;1",
    "@type": "Interface",
    "contents": [
      {
        "@type": "Property",
        "name": "SerialNumber",
        "schema": "double",
        "writable": false
      },
      {
        "@type" : "Component",
        "schema": "dtmi:com:example:baseComponent;1",
        "name": "baseComponent"
      }
    ]
  }
]

資料類型

使用數據類型來定義遙測、屬性和命令參數。 數據類型可以是基本類型或複雜類型。 複雜數據類型使用基本類型或其他複雜類型。 複雜類型的深度上限為五個層級。

基本類型

下表顯示您可以使用的基本類型集合:

基本型別 描述
boolean 布爾值
date RFC 3339 第 5.6 節中所 定義的完整日期
dateTime RFC 3339 中所 定義的日期時間
double IEEE 8 位元組浮點數
duration ISO 8601 格式的持續時間
float IEEE 4 位元組浮點數
integer 帶正負號的 4 位元組整數
long 帶正負號的8位元組整數
string UTF8 字串
time RFC 3339 第 5.6 節中所 定義的全職

下列代碼段顯示使用 double 欄位中類型的 schema 範例遙測定義:

{
  "@type": "Telemetry",
  "name": "temperature",
  "displayName": "Temperature",
  "schema": "double"
}

複雜的資料類型

複雜數據類型是其中一個陣列、列舉地圖物件或其中一個地理空間類型。

陣列

數位是可編製索引的數據類型,其中所有元素都是相同的類型。 項目類型可以是基本類型或複雜類型。

下列代碼段顯示使用 Array 欄位中類型的 schema 範例遙測定義。 陣列的元素是布林值:

{
  "@type": "Telemetry",
  "name": "ledState",
  "schema": {
    "@type": "Array",
    "elementSchema": "boolean"
  }
}

列舉

列舉描述類型,其中包含一組對應至值的具名標籤。 這些值可以是整數或字串,但標籤一律為字串。

下列代碼段顯示使用 Enum 欄位中類型的 schema 範例遙測定義。 列舉中的值為整數:

{
  "@type": "Telemetry",
  "name": "state",
  "schema": {
    "@type": "Enum",
    "valueSchema": "integer",
    "enumValues": [
      {
        "name": "offline",
        "displayName": "Offline",
        "enumValue": 1
      },
      {
        "name": "online",
        "displayName": "Online",
        "enumValue": 2
      }
    ]
  }
}

地圖

對應是索引鍵/值組的類型,其中值全都有相同的類型。 對應中的索引鍵必須是字串。 對應中的值可以是任何類型,包括另一個複雜類型。

下列代碼段顯示使用 Map 欄位中類型的 schema 範例屬性定義。 對應中的值為字串:

{
  "@type": "Property",
  "name": "modules",
  "writable": true,
  "schema": {
    "@type": "Map",
    "mapKey": {
      "name": "moduleName",
      "schema": "string"
    },
    "mapValue": {
      "name": "moduleState",
      "schema": "string"
    }
  }
}

物件

物件類型是由具名字段所組成。 對象對應中的欄位類型可以是基本類型或複雜類型。

下列代碼段顯示使用 Object 欄位中類型的 schema 範例遙測定義。 物件中的欄位為 dateTimedurationstring 類型:

{
  "@type": "Telemetry",
  "name": "monitor",
  "schema": {
    "@type": "Object",
    "fields": [
      {
        "name": "start",
        "schema": "dateTime"
      },
      {
        "name": "interval",
        "schema": "duration"
      },
      {
        "name": "status",
        "schema": "string"
      }
    ]
  }
}

地理空間類型

DTDL 提供一組以 GeoJSON 為基礎的地理空間類型,用於模型化地理數據結構:pointmultiPoint、、lineStringmultiLineStringpolygonmultiPolygon 這些類型是陣列、物件和列舉的預先定義巢狀結構。

下列代碼段顯示使用 point 欄位中類型的 schema 範例遙測定義:

{
  "@type": "Telemetry",
  "name": "location",
  "schema": "point"
}

由於地理空間類型是以數位為基礎,因此目前無法在屬性定義中使用。

語意類型

屬性或遙測定義的數據類型會指定裝置與服務交換的數據格式。 語意類型提供應用程式可用來判斷如何處理或顯示值之遙測和屬性的相關信息。 每個語意類型都有一或多個相關聯的單位。 例如,攝氏和華氏是溫度語意類型的單位。 IoT Central 儀錶板和分析可以使用語意類型資訊來判斷如何繪製遙測或屬性值和顯示單位。 若要瞭解如何使用模型剖析器來讀取語意類型,請參閱 瞭解數字對應項模型剖析器

下列代碼段顯示包含語意類型資訊的範例遙測定義。 語意類型 Temperature 會新增至 @type 陣列,而 unitdegreeCelsius 則是語意類型的有效單位之一:

{
  "@type": [
    "Telemetry",
    "Temperature"
  ],
  "name": "temperature",
  "schema": "double",
  "unit": "degreeCelsius"
}

當地語系化

IoT Central 之類的應用程式會使用模型中的資訊,以動態方式建置與 IoT 隨插即用 裝置交換之數據周圍的UI。 例如,儀錶板上的圖格可以顯示遙測、屬性和命令的名稱和描述。

模型中的選擇性 descriptiondisplayName 欄位會保存要用於UI的字串。 這些欄位可以保存應用程式可用來轉譯本地化 UI 的當地語系化字串。

下列代碼段顯示包含本地化字串的範例溫度遙測定義:

{
  "@type": [
    "Telemetry",
    "Temperature"
  ],
  "description": {
    "en": "Temperature in degrees Celsius.",
    "it": "Temperatura in gradi Celsius."
  },
  "displayName": {
    "en": "Temperature",
    "it": "Temperatura"
  },
  "name": "temperature",
  "schema": "double",
  "unit": "degreeCelsius"
}

新增本地化字串是選擇性的。 下列範例只有單一的預設語言:

{
  "@type": [
    "Telemetry",
    "Temperature"
  ],
  "description": "Temperature in degrees Celsius.",
  "displayName": "Temperature",
  "name": "temperature",
  "schema": "double",
  "unit": "degreeCelsius"
}

生命週期和工具

裝置模型的四個生命週期階段是 作者發佈使用版本

作者

DTML 裝置模型是可在文本編輯器中建立的 JSON 檔。 不過,在IoT Central中,您可以使用裝置範本 GUI 環境來建立 DTML 模型。 在 IoT Central 中,您可以:

  • 建立可定義屬性、遙測和命令的介面。
  • 使用元件將多個介面組合在一起。
  • 定義介面之間的繼承關聯性。
  • 匯入和匯出 DTML 模型檔案。

若要深入瞭解,請參閱 在 Azure IoT Central 應用程式中定義新的 IoT 裝置類型。

VS Code 有 DTDL 撰寫延伸模組。

若要安裝 VS Code 的 DTDL 擴充功能,請移至 Visual Studio Code 的 DTDL 編輯器。 您也可以在 VS Code 的 [延伸模組] 檢視中搜尋 DTDL

當您安裝擴充功能時,請使用它來協助您在 VS Code 中撰寫 DTDL 模型檔案:

  • 此延伸模組會在 DTDL 模型檔案中提供語法驗證,並醒目提示錯誤,如下列螢幕快照所示:

    顯示 VS Code 中 DTDL 模型驗證的螢幕快照。

  • 當您編輯 DTDL 模型時,請使用 intellisense 和自動完成:

    顯示 VS Code 中 DTDL 模型的 Intellisense 螢幕快照。

  • 建立新的 DTDL 介面。 DTDL:Create Interface 命令會使用新的介面建立 JSON 檔案。 介面包含範例遙測、屬性和命令定義。

使用

IoT Central 等應用程式會使用裝置型號。 在IoT Central中,模型是描述裝置功能的裝置範本的一部分。 IoT Central 會使用裝置範本來動態建置裝置的 UI,包括儀錶板和分析。

注意

IoT Central 會定義 DTDL 語言的一些延伸模組。 若要深入瞭解,請參閱 IoT Central擴充功能

自定義解決方案可以使用 數位對應項模型剖析器 來了解實作模型的裝置功能。 若要深入瞭解,請參閱在IoT解決方案中使用 IoT 隨插即用模型。

版本

為了確保使用模型的裝置和伺服器端解決方案能夠繼續運作,已發佈的模型是不可變的。

DTMI 包含可用來建立模型多個版本的版本號碼。 裝置和伺服器端解決方案可以使用其設計來使用的特定版本。

IoT Central 會針對裝置模型實作更多版本控制規則。 如果您在 IoT Central 中建立裝置範本及其型號的版本,您可以將裝置從舊版移轉至更新版本。 不過,移轉的裝置無法在沒有韌體升級的情況下使用新功能。 若要深入瞭解,請參閱 編輯裝置範本

發行

自 2024 年 2 月起,Azure 認證裝置計劃已淘汰。 因此,Microsoft 不再接受將 DTDL 模型提交至Azure IoT 隨插即用模型 存放庫。

如果您想要設定自己的模型存放庫,您可以使用 Azure IoT 隨插即用模型工具 存放庫。 此存放庫包含 CLI 工具的程式碼 dmr-client ,可驗證、匯入和展開 DTDL 模型。 此工具也可讓您編製遵循裝置模型存放庫慣例的模型存放庫索引。

限制和條件約束

下列清單摘要說明模型的某些主要條件約束和限制:

  • 目前,陣列、地圖和物件的深度上限為五個層級。
  • 您無法在屬性定義中使用陣列。
  • 您可以將介面延伸至 10 個層級的深度。
  • 介面最多可以擴充兩個其他介面。
  • 元件不能包含另一個元件。

下一步

既然您已了解裝置模型化,以下是一些更多資源: