分享方式:


開始使用攣生裝置

使用 Azure IoT 中樞裝置 SDK 和服務 SDK 來開發可處理常見裝置對應項工作的應用程式。 裝置對應項是存放裝置狀態資訊的 JSON 文件,包括中繼資料、組態和條件。 IoT 中樞會為其連線的每個裝置保存裝置對應項。

您可以使用裝置對應項來執行下列作業:

  • 從解決方案後端儲存裝置中繼資料
  • 從裝置應用程式報告目前狀態資訊,例如可用功能和狀況 (例如,使用的連線方法)
  • 同步處理裝置應用程式與後端應用程式之間,長時間執行的工作流程狀態 (例如韌體和設定更新)
  • 查詢裝置中繼資料、設定或狀態

如需裝置對應項的詳細資訊,包括何時使用裝置對應項,請參閱了解和使用 IoT 中樞的裝置對應項

注意

本文中所述的功能僅適用於 IoT 中樞的標準層。 如需有關基本和標準/免費 IoT 中樞服務層級的詳細資訊,請參閱為您的解決方案選擇適合的 IoT 中樞層 (部分機器翻譯)。

本文說明如何開發兩種類型的應用程式:

  • 裝置應用程式可以處理更新所需屬性的要求,並回應報告屬性的變更。
  • 服務應用程式可以更新裝置對應項標籤、設定新的所需屬性,以及根據裝置對應項值查詢裝置。

注意

本文旨在補充本文中參考的 Azure IoT SDK 範例。 您可以使用 SDK 工具來建置裝置應用程式和後端應用程式。

必要條件

  • IoT 中樞。 某些 SDK 呼叫需要使用 IoT 中樞主要連接字串,因此請記下該連接字串。

  • 已註冊的裝置。 某些 SDK 呼叫需要使用裝置主要連接字串,因此請記下該連接字串。

  • IoT 中樞服務連接字串

    在本文中,您會建立後端服務,其會將所需的屬性新增至裝置對應項,然後查詢身分識別登錄,以尋找具有所報告屬性且已分別更新的所有裝置。 服務需要有服務連線權限,才能修改裝置對應項的所需屬性,也需要有登錄讀取權限才能查詢身分識別登錄。 沒有任何預設的共用存取原則只包含這兩項權限,所以必須自己建立一個。

    若要建立共用存取原則,其會授與服務連線登錄讀取權限,並取得此原則的連接字串,請遵循下列步驟:

    1. Azure 入口網站,中選取 [資源群組]。 選取中樞所在的資源群組,然後從資源清單選取中樞。

    2. 在中樞的左側窗格上,選取 [共用存取原則]

    3. 從原則清單上方的頂端功能表中,選取 [新增共用存取原則]

    4. 在右側的 [新增共用存取原則] 窗格中,輸入原則的描述性名稱,例如 "serviceAndRegistryRead"。 在 [權限] 底下選取 [登錄讀取] 和 [服務連線],然後選取 [新增]

    5. 從原則清單中選取新原則。

    6. 選取 [主要連接字串] 的複製圖示,然後儲存值。

    如需 IoT 中樞共用存取原則和權限的詳細資訊,請參閱使用共用存取簽章來控制 IoT 中樞的存取權

  • 如果您的應用程式使用 MQTT 通訊協定,請確定防火牆中已開啟連接埠 8883。 MQTT 通訊協定會透過連接埠 8883 進行通訊。 某些公司和教育網路環境可能會封鎖此連接埠。 如需此問題的詳細資訊和解決方法,請參閱連線至 IoT 中樞 (MQTT)

  • 語言 SDK 需求:

    • .NET SDK - 需要 Visual Studio。
    • Python SDK - 建議使用 Python 3.7 版或更新版本。 請務必使用安裝程式所需的 32 位元或 64 位元安裝。 在安裝期間出現系統提示時,務必將 Python 新增至平台特有的環境變數。
    • Java - 需要 Java SE 開發套件 8。 請務必選取 [長期支援] 下的 [Java 8],以瀏覽至 JDK 8 的下載。
    • Node.js - 需要 Node.js 10.0.x 版或更新版本。

概觀

本文說明如何使用 Azure IoT SDK for .NET 來建立裝置對應項的裝置和後端服務應用程式碼。

建立裝置應用程式

裝置應用程式可以讀取和寫入對應項報告屬性,並針對後端應用程式或 IoT 中樞所設定的所需對應項屬性變更接收其通知。

本節說明如何使用裝置應用程式碼來執行下列作業:

  • 擷取裝置對應項並檢查報告屬性
  • 更新報告的裝置對應項屬性
  • 建立所需的屬性更新回呼處理常式

新增裝置 NuGet 套件

以 C# 撰寫的裝置用戶端應用程式需要 Microsoft.Azure.Devices.Client NuGet 套件。

連線到裝置

DeviceClient 類別會公開從裝置與裝置對應項進行互動時所需的所有方法。

使用 CreateFromConnectionString 方法以及裝置連接字串和連線傳輸通訊協定來連線到裝置。

CreateFromConnectionString TransportType 傳輸通訊協定參數支援下列傳輸通訊協定:

  • Mqtt
  • Mqtt_WebSocket_Only
  • Mqtt_Tcp_Only
  • Amqp
  • Amqp_WebSocket_Only
  • Amqp_Tcp_Only

裝置對應項更新不支援 Http1 通訊協定。

此範例會使用 Mqtt 傳輸通訊協定連線到裝置。

using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Shared;
using Newtonsoft.Json;

static string DeviceConnectionString = "{IoT hub device connection string}";
static _deviceClient = null;
_deviceClient = DeviceClient.CreateFromConnectionString(DeviceConnectionString, 
   TransportType.Mqtt);

擷取裝置對應項並檢查屬性

呼叫 GetTwinAsync 以擷取目前的裝置對應項屬性。 有許多 Twin 物件屬性可用來存取 Twin JSON 資料的特定區域,包括 PropertiesStatusTagsVersion

此範例會擷取裝置對應項屬性,並以 JSON 格式列印對應項值。

Console.WriteLine("Retrieving twin...");
Twin twin = await _deviceClient.GetTwinAsync();
Console.WriteLine("\tInitial twin value received:");
Console.WriteLine($"\t{twin.ToJson()}");

更新報告的裝置對應項屬性

若要更新對應項的報告屬性,請執行下列動作:

  1. 為報告屬性更新建立 TwinCollection 物件
  2. 更新 TwinCollection 物件內的一或多個報告屬性
  3. 使用 UpdateReportedPropertiesAsync 將報告屬性變更推送至 IoT 中樞服務

例如:

try
{
Console.WriteLine("Sending sample start time as reported property");
TwinCollection reportedProperties = new TwinCollection();
reportedProperties["DateTimeLastAppLaunch"] = DateTime.UtcNow;
await _deviceClient.UpdateReportedPropertiesAsync(reportedProperties);
}
catch (Exception ex)
{
   Console.WriteLine();
   Console.WriteLine("Error in sample: {0}", ex.Message);
}

建立所需的屬性更新回呼處理常式

透過將回呼處理常式方法名稱傳遞至 SetDesiredPropertyUpdateCallbackAsync,建立在裝置對應項中變更所需屬性時執行的所需屬性更新回呼處理常式。

例如,此呼叫會設定系統,以在變更所需屬性時通知名為 OnDesiredPropertyChangedAsync 的方法。

await _deviceClient.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertyChangedAsync, null);

對應項屬性會以 TwinCollection 的形式傳遞至回呼方法,並且可以作為 KeyValuePair 結構進行檢查。

此範例會接收所需屬性更新作為 TwinCollection,然後循環檢查並列印 KeyValuePair 集合更新。 循環檢查 KeyValuePair 集合之後,程式碼會呼叫 UpdateReportedPropertiesAsync 以更新 DateTimeLastDesiredPropertyChangeReceived 報告屬性,使上次更新時間保持在最新狀態。

private async Task OnDesiredPropertyChangedAsync(TwinCollection desiredProperties, object userContext)
{
   var reportedProperties = new TwinCollection();

   Console.WriteLine("\tDesired properties requested:");
   Console.WriteLine($"\t{desiredProperties.ToJson()}");

   // For the purpose of this sample, we'll blindly accept all twin property write requests.
   foreach (KeyValuePair<string, object> desiredProperty in desiredProperties)
   {
         Console.WriteLine($"Setting {desiredProperty.Key} to {desiredProperty.Value}.");
         reportedProperties[desiredProperty.Key] = desiredProperty.Value;
   }

   Console.WriteLine("\tAlso setting current time as reported property");
   reportedProperties["DateTimeLastDesiredPropertyChangeReceived"] = DateTime.UtcNow;

   await _deviceClient.UpdateReportedPropertiesAsync(reportedProperties);
}

SDK 裝置範例

Azure IoT SDK for .NET 提供可處理裝置對應項工作的裝置應用程式工作範例。 如需詳細資訊,請參閱 TwinSample

建立後端應用程式

後端應用程式:

  • 透過 IoT 中樞連線到裝置
  • 可以讀取裝置報告屬性和所需屬性、寫入裝置所需屬性,以及執行裝置查詢

RegistryManager 類別會公開建立後端應用程式以從服務與裝置對應項進行互動時所需的所有方法。

本節說明如何建立後端應用程式碼來執行下列作業:

  • 讀取和更新裝置對應項欄位
  • 建立裝置對應項查詢

新增服務 NuGet 套件

後端服務應用程式需要 Microsoft.Azure.Devices NuGet 套件。

連線至 IoT 中樞

使用 CreateFromConnectionString 將後端應用程式連線到裝置。 提供您在<必要條件>一節中建立的 IoT 中樞服務連接字串作為參數。

using Microsoft.Azure.Devices;
static RegistryManager registryManager;
static string connectionString = "{IoT hub service connection string}";
registryManager = RegistryManager.CreateFromConnectionString(connectionString);

讀取和更新裝置對應項欄位

您可以呼叫 GetTwinAsync,將目前的裝置對應項欄位擷取至 Twin 物件。

Twin 類別包含對應至每個裝置對應項區段的屬性。 使用 Twin 類別屬性可檢視和更新裝置對應項欄位。 您可以使用 Twin 物件屬性來更新多個對應項欄位,再使用 UpdateTwinAsync 將更新寫入裝置。

進行對應項欄位更新之後,請呼叫 UpdateTwinAsyncTwin 物件欄位更新寫回裝置。 使用 trycatch 邏輯與錯誤處理常式結合,從 UpdateTwinAsync 中攔截格式不正確的修補檔錯誤。

讀取和更新裝置對應項標籤

使用裝置對應項 Tags 屬性可讀取和寫入裝置標籤資訊。

使用對應項物件更新標籤

此範例會建立 location 標籤修補檔,使用 Tags 屬性將其指派給 Twin 物件,然後使用 UpdateTwinAsync 套用該修補檔。

// Retrieve the device twin
var twin = await registryManager.GetTwinAsync("myDeviceId");

// Create the tag patch
var tagspatch =
   @"{
   tags: {
         location: {
            region: 'US',
            plant: 'Redmond43'
         }
   }
}";

// Assign the patch to the Twin object
twin.Tags["location"] = tagspatch;

// Apply the patch to update the device twin tags section
try
{
   await registryManager.UpdateTwinAsync(twin.DeviceId, patch, twin.ETag);
}
catch (Exception e)
{
   console.WriteLine("Twin update failed.", e.Message);
}
使用 JSON 字串更新標籤

您可以建立並套用 JSON 格式的裝置對應項資訊更新修補檔。 如果修補檔的格式正確,IoT 中樞會剖析並套用該修補檔。

此範例會呼叫 GetTwinAsync,將目前的裝置對應項欄位擷取至 Twin 物件,建立包含區域和工廠位置資訊的 JSON 格式 tag 修補檔,然後呼叫 UpdateTwinAsync 以套用該修補檔來更新裝置對應項。 如果 UpdateTwinAsync 失敗,系統就會顯示錯誤訊息。

// Retrieve the device twin
var twin = await registryManager.GetTwinAsync("myDeviceId");

// Create the JSON tags patch
var patch =
   @"{
      tags: {
            location: {
               region: 'US',
               plant: 'Redmond43'
            }
      }
   }";
// Apply the patch to update the device twin tags
try
{
   await registryManager.UpdateTwinAsync(twin.DeviceId, patch, twin.ETag);
}
catch (Exception e)
{
   console.WriteLine("Twin update failed.", e.Message);
}

檢視和更新對應項所需屬性

使用裝置對應項 TwinProperties.Desired 屬性可讀取和寫入裝置所需屬性資訊。 請使用 JSON 格式的修補檔來更新對應項 Desired 屬性。

此範例會呼叫 GetTwinAsync,將目前的裝置對應項欄位擷取至 Twin 物件,更新對應項 speed 所需屬性,然後呼叫 UpdateTwinAsync 以套用 Twin 物件來更新裝置對應項。

// Retrieve the device twin
var twin = await registryManager.GetTwinAsync("myDeviceId");

twin.Properties.Desired["speed"] = "type: '5G'";
await registryManager.UpdateTwinAsync(twin.DeviceId, twin, twin.ETag);

其他對應項更新方法

您也可以使用這些 SDK 方法來套用對應項更新:

建立裝置對應項查詢

本節示範兩個裝置對應項查詢。 裝置對應項查詢是類似 SQL 的查詢,可傳回裝置對應項的結果集。

若要建立裝置對應項查詢,請呼叫 CreateQuery 以提交對應項 SQL 查詢,並取得 IQuery 介面。 您可以選擇使用第二個參數呼叫 CreateQuery,以指定每個頁面的項目數上限。

接下來視需要多次呼叫 GetNextAsTwinAsyncGetNextAsJsonAsync 方法,以擷取所有對應項結果。

IQuery 介面包含 HasMoreResults 布林值屬性,該屬性可用來檢查是否有更多要擷取的對應項結果。

此範例查詢只會選取 Redmond43 工廠中所含裝置的裝置對應項。

var query = registryManager.CreateQuery(
"SELECT * FROM devices WHERE tags.location.plant = 'Redmond43'", 100);
var twinsInRedmond43 = await query.GetNextAsTwinAsync();
Console.WriteLine("Devices in Redmond43: {0}", 
string.Join(", ", twinsInRedmond43.Select(t => t.DeviceId)));

此範例查詢會重新調整第一個查詢,只選取也透過行動電話通訊網路連線的裝置。

query = registryManager.CreateQuery("SELECT * FROM devices WHERE tags.location.plant = 'Redmond43' AND properties.reported.connectivity.type = 'cellular'", 100);
var twinsInRedmond43UsingCellular = await query.GetNextAsTwinAsync();
Console.WriteLine("Devices in Redmond43 using cellular network: {0}", 
string.Join(", ", twinsInRedmond43UsingCellular.Select(t => t.DeviceId)));

SDK 服務範例

Azure IoT SDK for .NET 提供可處理裝置對應項工作的服務應用程式工作範例。 如需詳細資訊,請參閱登錄管理員範例

概觀

本文說明如何使用 Azure IoT SDK for Java 來建立裝置對應項的裝置和後端服務應用程式碼。

建立裝置應用程式

裝置應用程式可以讀取和寫入對應項報告屬性,並針對後端應用程式或 IoT 中樞所設定的所需對應項屬性變更接收其通知。

本節說明如何建立裝置應用程式碼來執行下列作業:

  • 擷取和檢視裝置對應項
  • 更新報告的裝置對應項屬性
  • 訂閱所需屬性變更

DeviceClient 類別會公開從裝置與裝置對應項進行互動時所需的所有方法。

裝置 import 陳述式

使用下列裝置 import 陳述式來存取 Azure IoT SDK for Java。

import com.microsoft.azure.sdk.iot.device.*;
import com.microsoft.azure.sdk.iot.device.DeviceTwin.*;

連線到裝置

若要連線到裝置,請執行下列動作:

  1. 使用 IotHubClientProtocol 來選擇傳輸通訊協定。 例如:

    IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;
    
  2. 使用 DeviceClient 建構函式來新增裝置主要連接字串和通訊協定。

    String connString = "{IoT hub device connection string}";
    DeviceClient client = new DeviceClient(connString, protocol);
    
  3. 使用 open 將裝置連線到 IoT 中樞。 如果用戶端已經開啟,方法就不會執行任何動作。

    client.open(true);
    

擷取和檢視裝置對應項

開啟用戶端連線之後,呼叫 getTwin 將目前的對應項屬性擷取至 Twin 物件。

例如:

private static Twin twin;
System.out.println("Getting current twin");
twin = client.getTwin();
System.out.println("Received current twin:");
System.out.println(twin);

更新裝置對應項的報告屬性

擷取目前的對應項之後,您就可以開始進行報告屬性更新。 只要擁有正確的報告屬性版本,您也可以進行報告屬性更新,而不需要取得目前的對應項。 如果您傳送報告屬性並收到「先決條件失敗」錯誤,則表示報告屬性版本已過期。 在此情況下,請再次呼叫 getTwin 以取得最新版本。

若要更新報告屬性,請執行下列動作:

  1. 呼叫 getReportedProperties 將對應項報告屬性擷取至 TwinCollection 物件。

  2. 使用 put 以更新 TwinCollection 物件內的報告屬性。 針對每個報告屬性更新呼叫 put

  3. 使用 updateReportedProperties 以套用使用 put 方法更新的報告屬性群組。

例如:

TwinCollection reportedProperties = twin.getReportedProperties();

int newTemperature = new Random().nextInt(80);
reportedProperties.put("HomeTemp(F)", newTemperature);
System.out.println("Updating reported property \"HomeTemp(F)\" to value " + newTemperature);

ReportedPropertiesUpdateResponse response = client.updateReportedProperties(reportedProperties);
System.out.println("Successfully set property \"HomeTemp(F)\" to value " + newTemperature);

訂閱所需屬性變更

呼叫 subscribeToDesiredProperties 以訂閱所需屬性變更。 每次更新所需屬性時,此用戶端都會收到含有 Twin 物件的回呼。 視所需屬性的變更方式而定,該回呼包含完整的所需屬性集,或只包含更新的所需屬性。

此範例會訂閱所需屬性變更。 任何所需屬性變更都會傳遞至名為 DesiredPropertiesUpdatedHandler 的處理常式。

client.subscribeToDesiredProperties(new DesiredPropertiesUpdatedHandler(), null);

在此範例中,DesiredPropertiesUpdatedHandler 所需屬性變更回呼處理常式會呼叫 getDesiredProperties 以擷取屬性變更,然後列印更新的對應項屬性。

  private static class DesiredPropertiesUpdatedHandler implements DesiredPropertiesCallback
  {
      @Override
      public void onDesiredPropertiesUpdated(Twin desiredPropertyUpdateTwin, Object context)
      {
          if (twin == null)
          {
              // No need to care about this update because these properties will be present in the twin retrieved by getTwin.
              System.out.println("Received desired properties update before getting current twin. Ignoring this update.");
              return;
          }

          // desiredPropertyUpdateTwin.getDesiredProperties() contains all the newly updated desired properties as well as the new version of the desired properties
          twin.getDesiredProperties().putAll(desiredPropertyUpdateTwin.getDesiredProperties());
          twin.getDesiredProperties().setVersion(desiredPropertyUpdateTwin.getDesiredProperties().getVersion());
          System.out.println("Received desired property update. Current twin:");
          System.out.println(twin);
      }
  }

SDK 裝置範例

Azure IoT SDK for Java 包含可測試本文所述裝置應用程式概念的工作範例。 如需詳細資訊,請參閱裝置對應項範例

建立後端應用程式

本節說明如何建立執行下列作業的後端應用程式:

  • 更新裝置對應項標籤
  • 使用標籤和屬性的篩選條件來查詢裝置

ServiceClient DeviceTwin 類別包含服務可用來存取裝置對應項的方法。

服務 import 陳述式

使用下列服務 import 陳述式來存取 Azure IoT SDK for Java。

import com.microsoft.azure.sdk.iot.service.devicetwin.*;
import com.microsoft.azure.sdk.iot.service.exceptions.IotHubException;

連線到 IoT 中樞服務用戶端

若要連線到 IoT 中樞以檢視和更新裝置對應項資訊,請執行下列動作:

  1. 建立 DeviceTwinClientOptions 物件。 設定應用程式所需的任何選項。 這些選項會傳遞至 DeviceTwin 物件。
  2. 使用 DeviceTwin 建構函式以建立 IoT 中樞的連線。 DeviceTwin 物件會處理與 IoT 中樞的通訊。 提供您在<必要條件>一節中建立的 IoT 中樞服務連接字串以及 DeviceTwinClientOptions 物件作為參數。
  3. DeviceTwinDevice 物件會以其屬性和標籤代表裝置對應項。

例如:

public static final String iotHubConnectionString = "{IoT hub service connection string}";
public static final String deviceId = "myDeviceId";
public static final String region = "US";
public static final String plant = "Redmond43";

// Get the DeviceTwin and DeviceTwinDevice objects
DeviceTwinClientOptions twinOptions = new DeviceTwinClientOptions();
DeviceTwin twinClient = new DeviceTwin(iotHubConnectionString,twinOptions);
DeviceTwinDevice device = new DeviceTwinDevice(deviceId);

更新裝置對應項欄位

若要更新裝置對應項欄位,請執行下列動作:

  1. 使用 getTwin 以擷取目前的裝置對應項欄位

    此範例會擷取並列印裝置對應項欄位:

    // Get the device twin from IoT Hub
    System.out.println("Device twin before update:");
    twinClient.getTwin(device);
    System.out.println(device);
    
  2. 使用 HashSet 物件以 add (新增) 一組對應項標籤配對

  3. 使用 setTags 將一組標籤配對從 tags 物件新增至 DeviceTwinDevice 物件

  4. 使用 updateTwin 以更新 IoT 中樞內的對應項

    此範例會更新裝置對應項的區域和工廠裝置對應項標籤:

    // Update device twin tags if they are different
    // from the existing values
    String currentTags = device.tagsToString();
    if ((!currentTags.contains("region=" + region) && !currentTags.contains("plant=" + plant))) {
    
    // Create the tags and attach them to the DeviceTwinDevice object
    Set<Pair> tags = new HashSet<Pair>();
    tags.add(new Pair("region", region));
    tags.add(new Pair("plant", plant));
    device.setTags(tags);
    
    // Update the device twin in IoT Hub
    System.out.println("Updating device twin");
    twinClient.updateTwin(device);
    }
    
    // Retrieve and display the device twin with the tag values from IoT Hub
    System.out.println("Device twin after update:");
    twinClient.getTwin(device);
    System.out.println(device);
    

建立裝置對應項查詢

本節示範兩個裝置對應項查詢。 裝置對應項查詢是類似 SQL 的查詢,可傳回裝置對應項的結果集。

Query 類別包含一些方法,可用來為對應項、作業、裝置作業或未經處理資料建立 IoT 中樞的 SQL 樣式查詢。

若要建立裝置查詢,請執行下列動作:

  1. 使用 createSqlQuery 以建置對應項 SQL 查詢

  2. 使用 queryTwin 以執行查詢

  3. 使用 hasNextDeviceTwin 以檢查結果集中是否有另一個裝置對應項

  4. 使用 getNextDeviceTwin 以從結果集中擷取下一個裝置對應項

下列範例查詢最多傳回 100 個裝置。

此範例查詢只會選取 Redmond43 工廠中所含裝置的裝置對應項。

// Query the device twins in IoT Hub
System.out.println("Devices in Redmond:");

// Construct the query
SqlQuery sqlQuery = SqlQuery.createSqlQuery("*", SqlQuery.FromType.DEVICES, "tags.plant='Redmond43'", null);

// Run the query, returning a maximum of 100 devices
Query twinQuery = twinClient.queryTwin(sqlQuery.getQuery(), 100);
while (twinClient.hasNextDeviceTwin(twinQuery)) {
  DeviceTwinDevice d = twinClient.getNextDeviceTwin(twinQuery);
  System.out.println(d.getDeviceId());
}

此範例查詢會重新調整第一個查詢,只選取也透過行動電話通訊網路連線的裝置。

System.out.println("Devices in Redmond using a cellular network:");

// Construct the query
sqlQuery = SqlQuery.createSqlQuery("*", SqlQuery.FromType.DEVICES, "tags.plant='Redmond43' AND properties.reported.connectivityType = 'cellular'", null);

// Run the query, returning a maximum of 100 devices
twinQuery = twinClient.queryTwin(sqlQuery.getQuery(), 3);
while (twinClient.hasNextDeviceTwin(twinQuery)) {
  DeviceTwinDevice d = twinClient.getNextDeviceTwin(twinQuery);
  System.out.println(d.getDeviceId());
}

SDK 服務範例

Azure IoT SDK for Java 提供可處理裝置對應項工作的服務應用程式工作範例。 如需詳細資訊,請參閱裝置對應項範例

概觀

本文說明如何使用 Azure IoT SDK for Python 來建立裝置對應項的裝置和後端服務應用程式碼。

建立裝置應用程式

裝置應用程式可以讀取和寫入對應項報告屬性,並針對後端應用程式或 IoT 中樞所設定的所需對應項屬性變更接收其通知。

IoTHubDeviceClient 類別包含可用來處理裝置對應項的方法。

本節說明如何建立執行下列作業的裝置應用程式碼:

  • 擷取裝置對應項並檢查報告屬性
  • 修補更新報告的裝置對應項屬性

連線到裝置

本節說明如何使用包含共用存取金鑰的裝置主索引鍵,將應用程式連線到裝置。

若要將應用程式連線到裝置,請執行下列動作:

  1. 呼叫 create_from_connection_string 以新增裝置連接字串
  2. 呼叫 connect 將裝置用戶端連線到 Azure IoT 中樞
# import the device client library
import asyncio
from azure.iot.device.aio import IoTHubDeviceClient

# substitute the device connection string in conn_str
# and add it to the IoTHubDeviceClient object
conn_str = "{IOT hub device connection string}"
device_client = IoTHubDeviceClient.create_from_connection_string(conn_str)

# connect the application to the device
await device_client.connect()

擷取裝置對應項並檢查報告屬性

您可以擷取並檢查裝置對應項資訊,包括標籤和屬性。 擷取的裝置對應項資訊與您可以在 Azure 入口網站中針對裝置檢視的裝置對應項 JSON 格式資料相符。

呼叫 get_twin 以從 Azure IoT 中樞服務取得裝置對應項。 該對應項資訊會放入可列印或檢查的變數中。

此範例會擷取裝置對應項,並使用 print 命令來檢視 JSON 格式的裝置對應項。

# get the twin
twin = await device_client.get_twin()
print("Twin document:")
print("{}".format(twin))

修補更新報告的裝置對應項屬性

您可以套用修補檔來更新 JSON 格式的裝置報告屬性。

若要套用修補檔以更新報告屬性,請執行下列動作:

  1. 將報告屬性 JSON 修補檔指派給變數。
  2. 呼叫 patch_twin_reported_properties 將 JSON 修補檔套用至報告屬性。 這是同步呼叫,表示在修補檔傳送至服務並經認可之前,不會傳回此函式。

如果 patch_twin_reported_properties 傳回錯誤,此函式會引發對應的錯誤。

# create the reported properties patch
reported_properties = {"temperature": random.randint(320, 800) / 10}
print("Setting reported temperature to {}".format(reported_properties["temperature"]))
# update the reported properties and wait for the result
await device_client.patch_twin_reported_properties(reported_properties)

您也可以呼叫這些方法來更新裝置對應項:

  • 呼叫 replace_twin 以取代裝置對應項標籤和所需屬性。
  • 呼叫 update_twin 以更新裝置對應項標籤和所需屬性。

傳入的所需屬性修補檔處理常式

呼叫 on_twin_desired_properties_patch_received 以建立接收對應項所需屬性修補檔時所呼叫的處理常式函式或協同程式。 處理常式會採用一個引數,該引數是 JSON 字典物件形式的對應項修補檔。

此範例會設定名為 twin_patch_handler 的所需屬性修補檔處理常式。

例如:

try:
    # Set handlers on the client
    device_client.on_twin_desired_properties_patch_received = twin_patch_handler
except:
    # Clean up in the event of failure
    client.shutdown()

twin_patch_handler 會接收並列印 JSON 所需屬性更新。

    # Define behavior for receiving twin desired property patches
    def twin_patch_handler(twin_patch):
        print("Twin patch received:")
        print(twin_patch)

SDK 裝置範例

Azure IoT SDK for Python 包含下列範例:

建立後端應用程式

後端應用程式會透過 IoT 中樞連線到裝置,並可讀取裝置報告屬性和所需屬性、寫入裝置所需屬性,以及執行裝置查詢。

本節說明如何建立後端應用程式以執行下列作業:

  • 更新對應項標籤和所需屬性
  • 使用標籤和屬性的篩選條件來查詢裝置

IoTHubRegistryManager 類別會公開建立後端應用程式以從服務與裝置對應項進行互動時所需的所有方法。

連線至 IoT 中樞

使用 from_connection_string 連線到 IoT 中樞。 提供您在<必要條件>一節中建立的 IoT 中樞服務連接字串作為參數。

例如:

import sys
from time import sleep
from azure.iot.hub import IoTHubRegistryManager
from azure.iot.hub.models import Twin, TwinProperties, QuerySpecification, QueryResult

# Connect to IoT hub
IOTHUB_CONNECTION_STRING = "{IoT hub service connection string}"
iothub_registry_manager = IoTHubRegistryManager.from_connection_string(IOTHUB_CONNECTION_STRING)

更新對應項標籤和所需屬性

您可以使用 update_twin 同時從後端應用程式更新裝置對應項標籤和所需屬性。

  1. 呼叫 get_twin 以取得裝置對應項的目前版本
  2. 使用 Twin 類別以 JSON 格式新增標籤和屬性。
  3. 呼叫 update_twin 將修補檔套用至裝置對應項。 您也可以使用 replace_twin 來取代裝置對應項的所需屬性和標籤。

此範例會更新 regionplant 標籤資訊,並將 power_level 所需屬性設定為 1

new_tags = {
        'location' : {
            'region' : 'US',
            'plant' : 'Redmond43'
        }
    }

DEVICE_ID = "[Device Id]"
twin = iothub_registry_manager.get_twin(DEVICE_ID)
twin_patch = Twin(tags=new_tags, properties= TwinProperties(desired={'power_level' : 1}))
twin = iothub_registry_manager.update_twin(DEVICE_ID, twin_patch, twin.etag)

建立裝置對應項查詢

您可以使用裝置對應項查詢來查詢裝置對應項資訊。 裝置對應項查詢是類似 SQL 的查詢,可傳回裝置對應項的結果集。

若要使用裝置對應項查詢,請執行下列動作:

  1. 使用 QuerySpecification 物件來定義類似 SQL 的查詢要求。

  2. 使用 query_iot_hub 以查詢 IoT 中樞,並使用類似 SQL 的查詢規格擷取裝置對應項資訊。

此範例會執行兩個查詢。 第一個只選取 Redmond43 工廠所含裝置的裝置對應項,第二個會重新調整查詢,只選取也透過行動電話通訊網路連線的裝置。 系統會在每個查詢之後列印結果。

query_spec = QuerySpecification(query="SELECT * FROM devices WHERE tags.location.plant = 'Redmond43'")
query_result = iothub_registry_manager.query_iot_hub(query_spec, None, 100)
print("Devices in Redmond43 plant: {}".format(', '.join([twin.device_id for twin in query_result.items])))

print()

query_spec = QuerySpecification(query="SELECT * FROM devices WHERE tags.location.plant = 'Redmond43' AND properties.reported.connectivity = 'cellular'")
query_result = iothub_registry_manager.query_iot_hub(query_spec, None, 100)
print("Devices in Redmond43 plant using cellular network: {}".format(', '.join([twin.device_id for twin in query_result.items])))

print()

SDK 服務範例

Azure IoT SDK for Python 提供可處理裝置對應項工作的服務應用程式工作範例。 如需詳細資訊,請參閱登錄管理員查詢範例

概觀

本文說明如何使用 Azure IoT SDK for Node.js 來建立裝置對應項的裝置和後端服務應用程式碼。

建立裝置應用程式

裝置應用程式可以讀取和寫入對應項報告屬性,並針對後端應用程式或 IoT 中樞所設定的所需對應項屬性變更接收其通知。

本節說明如何在 Azure IoT SDK for Node.js 中使用 azure-iot-device 套件來建立裝置應用程式以執下列作業:

  • 擷取裝置對應項並檢查報告屬性
  • 更新報告的裝置對應項屬性
  • 接收所需屬性變更的通知

安裝 SDK 套件

執行此命令,在開發電腦上安裝 azure-iot-device 裝置 SDK:

npm install azure-iot-device --save

azure-iot-device 套件 包含與 IoT 裝置互動的物件。 Twin 類別包含對應項特有物件。 本節說明用來讀取和寫入裝置對應項資料的 Client 類別代碼。

選擇傳輸通訊協定

Client 物件支援這些通訊協定:

  • Amqp
  • Http - 使用 Http 時,Client 執行個體會不常檢查來自 IoT 中樞的訊息 (至少每25分鐘)。
  • Mqtt
  • MqttWs
  • AmqpWs

在開發電腦上安裝所需的傳輸通訊協定。

例如,此命令會安裝 Mqtt 通訊協定:

npm install azure-iot-device-mqtt --save

如需 MQTT、AMQP 和 HTTPS 支援之間差異的詳細資訊,請參閱雲端到裝置的通訊指引選擇通訊協定

建立用戶端模組

使用已安裝的套件建立 Client 模組。

例如:

const Client = require('azure-iot-device').Client;

建立通訊協定模組

使用已安裝的傳輸套件建立 Protocol 模組。

此範例會指派 MQTT 通訊協定:

const Protocol = require('azure-iot-device-mqtt').Mqtt;

新增裝置連接字串和傳輸通訊協定

呼叫 fromConnectionString 以提供裝置連線參數:

  • connStr - 連接字串,可封裝 IoT 中樞的「裝置連線」權限。 連接字串包含主機名稱、裝置識別碼和共用存取金鑰,格式如下:HostName=<iothub_host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>。
  • transportCtor - 傳輸通訊協定。

此範例會使用 Mqtt 傳輸通訊協定:

const deviceConnectionString = "{IoT hub device connection string}"
const Protocol = require('azure-iot-device-mqtt').Mqtt;
let client = Client.fromConnectionString(deviceConnectionString, Protocol);

開啟連線到 IoT 中樞

使用 open 方法來開啟 IoT 裝置與 IoT 中樞之間的連線。 使用 .catch(err) 來攔截錯誤並執行處理常式程式碼。

例如:

client.open()  //open the connection
.catch((err) => {
  console.error('Could not connect: ' + err.message);
});

擷取裝置對應項並檢查報告屬性

呼叫 getTwin 將目前的裝置對應項資訊擷取到 Twin 物件。

例如:

client.getTwin(function(err, twin))
if (err)
    console.error('could not get twin');

更新報告的裝置對應項屬性

使用 update 來更新裝置報告屬性。 包含 JSON 格式的修補檔作為第一個參數,並包含函式執行狀態回呼方法作為方法的第二個參數。

在此範例中,JSON 格式的裝置對應項修補檔會儲存在 patch 變數中。 修補檔包含 cellular 的裝置對應項 connectivity 更新值。 修補檔和錯誤處理常式會傳遞至 update 方法。 如果發生錯誤,則系統會顯示主控台錯誤訊息。

var patch = {
    connectivity: {
        type: 'cellular'
    }
}
twin.properties.reported.update(patch, function(err)
  {
    if (err)
      {
        console.error('could not update twin');
      } 
    else
      {
        console.log('twin state reported');
        process.exit();
      }
  });

接收所需屬性變更的通知

透過將回呼處理常式方法名稱傳遞至 twin.on,建立在裝置中變更所需屬性時執行的所需屬性更新事件接聽程式。

所需屬性事件接聽程式可以採用下列其中一種形式:

  • 使用單一事件處理常式接收所有修補檔
  • 屬性群組下有任何變更時接收事件
  • 接收單一屬性變更的事件

使用單一事件處理常式接收所有修補檔

您可以建立接聽程式來接收任何所需屬性變更。

此範例程式碼會輸出從服務接收的任何屬性。

twin.on('properties.desired', function (delta) {
    console.log('new desired properties received:');
    console.log(JSON.stringify(delta));
});

屬性群組下有任何變更時接收事件

如果屬性群組下有任何變更,您可以建立接聽程式來接收事件。

例如:

  1. minTemperaturemaxTemperature 屬性位於名為 properties.desired.climate changes 的屬性群組之下。

  2. 後端服務應用程式會套用此修補檔來更新 minTemperaturemaxTemperature 所需屬性:

    const twinPatch1 = {
    properties: {
       desired: {
        climate: { minTemperature: 68, maxTemperature: 76, },
        },
      },
     };
    
  3. 此程式碼可設定所需屬性變更事件接聽程式,以觸發 properties.desired.climate 屬性群組內的任何變更。 如果此群組內有所需屬性變更,則系統會在主控台上顯示最小和最大溫度變更訊息:

    twin.on('properties.desired.climate', function (delta) {
        if (delta.minTemperature || delta.maxTemperature) {
            console.log('updating desired temp:');
            console.log('min temp = ' + twin.properties.desired.climate.minTemperature);
            console.log('max temp = ' + twin.properties.desired.climate.maxTemperature);
        }
    });
    

接收單一屬性變更的事件

您可以為單一屬性變更設定接聽程式。 在此範例中,只有當 fanOn 布林值是修補檔的一部分時,才會執行此事件的程式碼。 每當服務更新時,程式碼就會輸出新的所需 fanOn 狀態。

  1. 後端應用程式會套用這個所需屬性修補檔:

     const twinPatch2 = {
      properties: {
        desired: {
          climate: {
            hvac: {
              systemControl: { fanOn: true, },
            },
          },
        },
      },
    };
    
  2. 只有在 fanOn 屬性變更時,才會觸發接聽程式:

     twin.on('properties.desired.climate.hvac.systemControl', function (fanOn) {
         console.log('setting fan state to ' + fanOn);
      });
    

裝置 SDK 範例

Azure IoT SDK for Node.js 包含兩個裝置對應項範例:

建立後端應用程式

後端應用程式會透過 IoT 中樞連線到裝置,並可讀取裝置報告屬性和所需屬性、寫入裝置所需屬性,以及執行裝置查詢。

本節說明如何建立執行下列作業的後端應用程式:

  • 擷取和更新裝置對應項
  • 建立裝置對應項查詢

安裝服務 SDK 套件

執行此命令,在開發電腦上安裝 azure-iothub

npm install azure-iothub --save

Registry 類別會公開從後端應用程式與裝置對應項進行互動時所需的所有方法。

連線至 IoT 中樞

使用 fromConnectionString 連線到 IoT 中樞。 提供您在<必要條件>一節中建立的 IoT 中樞服務連接字串作為參數。

'use strict';
var iothub = require('azure-iothub');
var connectionString = '{Iot Hub service connection string}';
var registry = iothub.Registry.fromConnectionString(connectionString);

擷取和更新裝置對應項

您可以建立修補檔,其中包含裝置對應項的標籤和所需屬性更新。

若要更新裝置對應項,請執行下列動作:

  1. 呼叫 getTwin 以擷取裝置對應項物件。
  • 將包含裝置對應項更新的修補檔格式化。 如 Twin 類別中所述,修補檔的格式為 JSON。 後端服務修補檔可以包含標籤和所需屬性更新。 如需更多修補檔格式資訊,請參閱標籤和屬性格式
  1. 呼叫 update 以修補檔更新裝置對應項。

在此範例中,系統會針對 myDeviceId 擷取裝置對應項,然後將修補檔套用至包含 location 標籤更新為 region: 'US', plant: 'Redmond43' 的對應項。

     registry.getTwin('myDeviceId', function(err, twin){
         if (err) {
             console.error(err.constructor.name + ': ' + err.message);
         } else {
             var patch = {
                 tags: {
                     location: {
                         region: 'US',
                         plant: 'Redmond43'
                   }
                 }
             };

             twin.update(patch, function(err) {
               if (err) {
                 console.error('Could not update twin: ' + err.constructor.name + ': ' + err.message);
               } else {
                 console.log(twin.deviceId + ' twin updated successfully');
                 queryTwins();
               }
             });
         }
     });

建立裝置對應項查詢

您可以建立類似 SQL 的裝置查詢,以從裝置對應項收集資訊。

使用 createQuery 建立可在 IoT 中樞執行個體上執行的查詢,以尋找裝置或作業的相關資訊。

createQuery 包含兩個參數:

  • sqlQuery - 以 SQL 字串形式寫入的查詢。
  • pageSize - 每頁所需的結果數 (選用。預設值:1000,最大值:10000)。

如果指定了 pageSize 參數,則查詢物件會包含 hasMoreResults 布林值屬性,您可以檢查該屬性並使用 nextAsTwin 方法視需要多次取得下一個對應項結果頁面,以擷取所有結果。 有一個稱為 next 的方法,其適用於非裝置對應項的結果,例如彙總查詢的結果。

此範例查詢只會選取 Redmond43 工廠中所含裝置的裝置對應項。

var queryTwins = function() {
var query = registry.createQuery("SELECT * FROM devices WHERE tags.location.plant = 'Redmond43'", 100);
query.nextAsTwin(function(err, results) {
    if (err) {
        console.error('Failed to fetch the results: ' + err.message);
    } else {
        console.log("Devices in Redmond43: " + results.map(function(twin) {return twin.deviceId}).join(','));
    }
});

此範例查詢會重新調整第一個查詢,只選取也透過行動電話通訊網路連線的裝置。

query = registry.createQuery("SELECT * FROM devices WHERE tags.location.plant = 'Redmond43' AND properties.reported.connectivity.type = 'cellular'", 100);
query.nextAsTwin(function(err, results) {
    if (err) {
        console.error('Failed to fetch the results: ' + err.message);
    } else {
        console.log("Devices in Redmond43 using cellular network: " + results.map(function(twin) {return twin.deviceId}).join(','));
    }
});
};

服務 SDK 範例

Azure IoT SDK for Node.js 提供可處理裝置對應項工作的服務應用程式工作範例。 如需詳細資訊,請參閱裝置對應項後端服務。此專案可用來傳送特定裝置的裝置對應項修補檔更新。