次の方法で共有


デバイス ツインを使ってみる

Azure IoT Hub デバイス SDK とサービス SDK を使用して、一般的なデバイス ツイン タスクを処理するアプリケーションを開発します。 デバイス ツインは、デバイスに関する情報 (メタデータ、構成、状態など) を格納する JSON ドキュメントです。 IoT Hub は、IoT Hub に接続する各デバイスにデバイス ツインを保持します。

デバイス ツインを使用すると、次のことができます。

  • ソリューション バックエンドからデバイス メタデータを格納する
  • デバイス アプリで利用できる機能や状態 (たとえば、使用される接続方法) などの現在の状態に関する情報をレポートする
  • デバイス アプリとバックエンド アプリの間で実行時間の長いワークフロー (ファームウェアや構成の更新など) の状態を同期する
  • デバイス メタデータ、構成、または状態のクエリを実行する

デバイス ツインを使用するタイミングなど、デバイス ツインの詳細については、「IoT Hub のデバイス ツインの理解と使用」を参照してください。

Note

この記事で説明されている機能は、Standard レベルの IoT Hub でのみ使用できます。 Basic および Standard または Free レベルの IoT Hub の詳細については、ソリューションに適した IoT Hub のレベルの選択に関するページを参照してください。

この記事では、次の 2 種類のアプリケーションを開発する方法について説明します。

  • デバイス アプリは、必要なプロパティを更新する要求を処理し、報告されたプロパティへの変更を応答として返すことができます。
  • サービス アプリは、デバイス ツイン タグを更新し、新しい必要なプロパティを設定し、デバイス ツインの値に基づいてデバイスのクエリを実行できます。

Note

この記事は、この記事内から参照される Azure IoT SDK サンプルを補完するためのものです。 SDK ツールを使用して、デバイス アプリケーションとバックエンド アプリケーションの両方を構築できます。

前提条件

  • IoT ハブ SDK の一部の呼び出しでは、IoT Hub のプライマリ接続文字列が必要であるため、接続文字列を記録しておきます。

  • 登録済みのデバイス。 SDK の一部の呼び出しでは、デバイスのプライマリ接続文字列が必要であるため、接続文字列を記録しておきます。

  • アプリケーションが MQTT プロトコルを使用している場合は、必ずファイアウォールのポート 8883 を開きます。 MQTT プロトコルはポート 8883 経由で通信します。 このポートは、企業や教育用のネットワーク環境によってはブロックされている場合があります。 この問題の詳細と対処方法については、「IoT Hub への接続 (MQTT)」を参照してください。

  • 言語 SDK の要件:

    • .NET SDK - Visual Studio が必要です。
    • Python SDK - Python バージョン 3.7 以降をお勧めします。 必ず、セットアップに必要な 32 ビットまたは 64 ビットのインストールを使用してください。 インストール中に求められた場合は、プラットフォーム固有の環境変数に Python を追加します。
    • Java - Java SE Development Kit 8 が必要です。 必ず「長期サポート」の「Java 8」を選択して JDK 8 のダウンロードに移動します。
    • Node.js - Node.js バージョン 10.0.x 以降が必要です。

概要

この記事では、Azure IoT SDK for .NET を使用して、デバイス ツイン用のデバイスおよびバックエンド サービス アプリケーション コードを作成する方法について説明します。

デバイス アプリケーションを作成する

デバイス アプリケーションは、ツインの報告されたプロパティの読み取りと書き込みを行うことができます。また、バックエンド アプリケーションまたは IoT Hub によって設定された必要なツインのプロパティの変更について通知を受け取ることができます。

このセクションでは、デバイス アプリケーション コードを使用して次のことを行う方法について説明します。

  • デバイス ツインを取得し、報告されたプロパティを確認する
  • 報告されたデバイス ツインのプロパティを更新する
  • 必要なプロパティ更新コールバック ハンドラーを作成する

重要

この記事では、Shared Access Signature (対称キー認証とも呼ばれます) を使用してデバイスを接続する手順について説明します。 この認証方法はテストと評価には便利ですが、X.509 証明書を使用してデバイスを認証する方が安全なアプローチです。 詳細については、「セキュリティのベスト プラクティス」>「接続のセキュリティ」をご覧ください。

デバイス NuGet パッケージを追加する

C# で記述されたデバイス クライアント アプリケーションには、Microsoft.Azure.Devices.Client NuGet パッケージが必要です。

デバイスへの接続

DeviceClient クラスは、デバイスからデバイス ツインとやりとりするために必要なすべてのメソッドを公開しています。

CreateFromConnectionString メソッドと共にデバイス接続文字列と接続トランスポート プロトコルを使用してデバイスに接続します。

CreateFromConnectionStringTransportType トランスポート プロトコル パラメーターは、次のトランスポート プロトコルをサポートしています。

  • 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 を呼び出して、現在のデバイス ツインのプロパティを取得します。 PropertiesStatusTagsVersion など、Twin JSON データの特定の領域にアクセスするために使用できる Twin オブジェクトのプロパティは多数あります。

この例では、デバイス ツインのプロパティを取得し、ツインの値を 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 オブジェクト内の報告されたプロパティを 1 つ以上更新します
  3. UpdateReportedPropertiesAsync を使用して、報告されたプロパティの変更を IoT Hub サービスにプッシュします

次に例を示します。

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 Hub 経由でデバイスに接続します。また、デバイスから報告されたプロパティと必要なプロパティを読み取り、デバイスの必要なプロパティを書き込み、デバイス クエリを実行することができます。

このセクションでは、次のことを行うバックエンド アプリケーション コードを作成する方法について説明します。

  • デバイス ツイン フィールドの読み取りと更新
  • デバイス ツイン クエリを作成する

RegistryManager クラスは、サービスからデバイス ツインと対話するバックエンド アプリケーションを作成するために必要なすべてのメソッドを公開しています。

サービス NuGet パッケージを追加する

バックエンド サービス アプリケーションには、Microsoft.Azure.Devices NuGet パッケージが必要です。

IoT Hub に接続する

次の方法を使用して、バックエンド サービスを IoT Hub に接続できます。

  • 共有アクセス ポリシー
  • Microsoft Entra

重要

この記事では、Shared Access Signature を使用してサービスに接続する手順について説明しています。 この認証方法はテストと評価には便利ですが、サービスに対する認証方法としては、Microsoft Entra ID またはマネージド ID を使用する方が安全です。 詳細については、「セキュリティのベスト プラクティス」の「クラウドのセキュリティ」 を参照してください。>

共有アクセス ポリシーを使用して接続する

CreateFromConnectionString を使用して、バックエンド アプリケーションをデバイスに接続します。 そのアプリケーションには、必要なデバイス ツインのプロパティを変更するためのサービス接続アクセス許可と、ID レジストリに対してクエリを実行するためのレジストリ読み取りアクセス許可が必要となります。 その 2 つのアクセス許可だけを含んだ既定の共有アクセス ポリシーは存在しないため、存在しない場合には共有アクセス ポリシーを作成する必要があります。 この共有アクセス ポリシー接続文字列を、fromConnectionString のパラメーターとして指定します。 共有アクセス ポリシーの詳細については、「Shared Access Signature を使用して IoT Hub へのアクセスを制御する」を参照してください。

using Microsoft.Azure.Devices;
static RegistryManager registryManager;
static string connectionString = "{Shared access policy connection string}";
registryManager = RegistryManager.CreateFromConnectionString(connectionString);

Microsoft Entra を使用して接続する

Microsoft Entra を使用するバックエンド アプリは、IoT Hub に接続する前に、認証に成功してセキュリティ トークンの資格情報を取得する必要があります。 このトークンは、IoT Hub 接続メソッドに渡されます。 IoT Hub 用の Microsoft Entra の設定と使用に関する一般的な情報については、「Microsoft Entra ID を使用した IoT Hub へのアクセス制御」を参照してください。

Microsoft Entra アプリを構成する

優先する認証資格情報用に構成された Microsoft Entra アプリを設定する必要があります。 このアプリには、バックエンド アプリケーションで認証に使用されるクライアント シークレットなどのパラメーターが含まれています。 使用可能なアプリ認証構成は次のとおりです。

  • クライアント シークレット
  • [証明書]
  • フェデレーション ID 資格情報

Microsoft Entra アプリでは、実行される操作に応じて、特定のロールのアクセス許可が必要になる場合があります。 たとえば、IoT Hub デバイスとモジュール ツインへの読み取りと書き込みアクセスを有効にするには、IoT Hub ツイン共同作成者が必要です。 詳細については、「Azure RBAC ロールの割り当てを使用して IoT Hub へのアクセスを管理する」を参照してください。

Microsoft Entra アプリの設定の詳細については、「クイック スタート: Microsoft ID プラットフォームにアプリケーションを登録する」を参照してください。

DefaultAzureCredential を使用して認証する

Microsoft Entra を使用してバックエンド アプリケーションを認証する最も簡単な方法は、DefaultAzureCredential を使用することですが、特定の TokenCredential や削減された ChainedTokenCredential など、運用環境では別の方法を使用することをお勧めします。 わかりやすくするために、このセクションでは、 DefaultAzureCredential とクライアント シークレットを使用した認証について説明します。 DefaultAzureCredential を使用する長所と短所の詳細については、「DefaultAzureCredential の使用ガイダンス」を参照してください。

DefaultAzureCredential では、さまざまな認証メカニズムがサポートされ、実行されている環境に基づいて適切な資格情報の種類が決まります。 有効な資格情報が見つかるまで、複数の種類の資格情報の使用を順番に試みます。

Microsoft Entra には、次の NuGet パッケージと、対応する using ステートメントが必要です。

  • Azure.Core
  • Azure.Identity
using Azure.Core;
using Azure.Identity;

この例では、Microsoft Entra アプリ登録のクライアント シークレット、クライアント ID、テナント ID が環境変数に追加されます。 これらの環境変数は、アプリケーションを認証するために DefaultAzureCredential で使用されます。 Microsoft Entra 認証が成功した結果、セキュリティ トークン資格情報が IoT Hub 接続メソッドに渡されます。

string clientSecretValue = "xxxxxxxxxxxxxxx";
string clientID = "xxxxxxxxxxxxxx";
string tenantID = "xxxxxxxxxxxxx";

Environment.SetEnvironmentVariable("AZURE_CLIENT_SECRET", clientSecretValue);
Environment.SetEnvironmentVariable("AZURE_CLIENT_ID", clientID);
Environment.SetEnvironmentVariable("AZURE_TENANT_ID", tenantID);

TokenCredential tokenCredential = new DefaultAzureCredential();

結果として得られる TokenCredential は、Microsoft Entra 資格情報を受け入れる SDK クライアントの IoT Hub メソッドに接続するために渡すことができます。

次の例では、ServiceClient 接続オブジェクトを作成するために、TokenCredentialServiceClient.Create に渡されます。

string hostname = "xxxxxxxxxx.azure-devices.net";
using var serviceClient = ServiceClient.Create(hostname, tokenCredential, TransportType.Amqp);

次の例では、RegistryManager オブジェクトを作成するために、TokenCredentialRegistryManager.Create に渡されます。

string hostname = "xxxxxxxxxx.azure-devices.net";
registryManager = RegistryManager.Create(hostname, tokenCredential);
コード サンプル

Microsoft Entra サービス認証の作業サンプルについては、ロール ベースの認証のサンプルのページを参照してください。

デバイス ツイン フィールドの読み取りと更新

GetTwinAsync を呼び出すことで、現在のデバイス ツイン フィールドを Twin オブジェクトに取得できます。

Twin クラスには、デバイス ツインの各セクションに対応するプロパティが含まれています。 デバイス ツイン フィールドを表示および更新するには、Twin クラスのプロパティを使用します。 UpdateTwinAsync を使用してデバイスに更新を書き込む前に、Twin オブジェクトのプロパティを使用して複数のツイン フィールドを更新できます。

ツイン フィールドを更新した後、UpdateTwinAsync を呼び出して、Twin オブジェクト フィールドの更新をデバイスに書き込みます。 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 Hub はそれを解析して適用します。

この例では、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 メソッドを使用して、ツインの更新を適用することもできます。

  • デバイス ツイン全体を置き換えるには、ReplaceTwinAsync を呼び出します。
  • システム内で以前に作成されたツインの一覧を更新するには、UpdateTwins2Async を呼び出します。

デバイス ツイン クエリを作成する

このセクションでは、2 つのデバイス ツイン クエリを示します。 デバイス ツイン クエリは、デバイス ツインの結果セットを返す SQL のようなクエリです。

デバイス ツイン クエリを作成するには、CreateQuery を呼び出してツイン SQL クエリを送信し、IQuery インターフェイスを取得します。 必要に応じて、2 つ目のパラメーターを指定して CreateQuery を呼び出し、ページごとの最大項目数を指定できます。

次に、必要な回数だけ GetNextAsTwinAsync または GetNextAsJsonAsync メソッドを呼び出し、すべてのツインの結果を取得します。

  • GetNextAsTwinAsync で、次のページングされた結果を Twin オブジェクトとして取得します。
  • GetNextAsJsonAsync で、次のページングされた結果を JSON 文字列として取得します。

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 Hub によって設定された必要なツインのプロパティの変更について通知を受け取ることができます。

このセクションでは、次のことを行うデバイス アプリケーション コードを作成する方法について説明します。

  • デバイス ツインの取得と表示
  • 報告されたデバイス ツインのプロパティを更新する
  • 必要なプロパティの変更をサブスクライブする

DeviceClient クラスは、デバイスからデバイス ツインとやりとりするのに必要なすべてのメソッドを公開しています。

重要

この記事では、Shared Access Signature (対称キー認証とも呼ばれます) を使用してデバイスを接続する手順について説明します。 この認証方法はテストと評価には便利ですが、X.509 証明書を使用してデバイスを認証する方が安全なアプローチです。 詳細については、「セキュリティのベスト プラクティス」>「接続のセキュリティ」をご覧ください。

デバイス インポート ステートメント

次のデバイス インポート ステートメントを使用して、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 Hub に接続します。 クライアントが既に開いている場合、メソッドは何も行いません。

    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 には、この記事で説明されているデバイス アプリの概念をテストするための動作するサンプルが含まれています。 詳細については、デバイス ツインのサンプルのページを参照してください。

バックエンド アプリケーションを作成する

このセクションでは、次のようなバックエンド アプリケーションを作成する方法について説明します。

  • デバイス ツイン タグを更新する
  • タグとプロパティにフィルターを使用してデバイスのクエリを実行する

ServiceClientDeviceTwin クラスには、サービスがデバイス ツインにアクセスするために使用できるメソッドが含まれています。

サービス インポート ステートメント

次のサービス インポート ステートメントを使用して、Azure IoT SDK for Java にアクセスします。

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

IoT ハブに接続します

次の方法を使用して、バックエンド サービスを IoT Hub に接続できます。

  • 共有アクセス ポリシー
  • Microsoft Entra

重要

この記事では、Shared Access Signature を使用してサービスに接続する手順について説明しています。 この認証方法はテストと評価には便利ですが、サービスに対する認証方法としては、Microsoft Entra ID またはマネージド ID を使用する方が安全です。 詳細については、「セキュリティのベスト プラクティス」の「クラウドのセキュリティ」 を参照してください。>

共有アクセス ポリシーを使用して接続する

DeviceTwin コンストラクターを使用して、IoT Hub への接続を作成します。 DeviceTwin オブジェクトは、IoT Hub との通信を処理します。

そのアプリケーションには、必要なデバイス ツインのプロパティを変更するためのサービス接続アクセス許可と、ID レジストリに対してクエリを実行するためのレジストリ読み取りアクセス許可が必要となります。 その 2 つのアクセス許可だけを含んだ既定の共有アクセス ポリシーは存在しないため、存在しない場合には共有アクセス ポリシーを作成する必要があります。 この共有アクセス ポリシー接続文字列を、fromConnectionString のパラメーターとして指定します。 共有アクセス ポリシーの詳細については、「Shared Access Signature を使用して IoT Hub へのアクセスを制御する」を参照してください。

DeviceTwinDevice オブジェクトは、プロパティとタグを使用してデバイス ツインを表現します。

次に例を示します。

public static final String iotHubConnectionString = "{Shared access policy 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
DeviceTwin twinClient = new DeviceTwin(iotHubConnectionString);
DeviceTwinDevice device = new DeviceTwinDevice(deviceId);

Microsoft Entra を使用して接続する

Microsoft Entra を使用するバックエンド アプリは、IoT Hub に接続する前に、認証に成功してセキュリティ トークンの資格情報を取得する必要があります。 このトークンは、IoT Hub 接続メソッドに渡されます。 IoT Hub 用の Microsoft Entra の設定と使用に関する一般的な情報については、「Microsoft Entra ID を使用した IoT Hub へのアクセス制御」を参照してください。

Java SDK 認証の概要については、「Java と Azure ID を使用した Azure 認証」を参照してください。

わかりやすくするために、このセクションでは、クライアント シークレットを使用した認証について説明します。

Microsoft Entra アプリを構成する

優先する認証資格情報用に構成された Microsoft Entra アプリを設定する必要があります。 このアプリには、バックエンド アプリケーションで認証に使用されるクライアント シークレットなどのパラメーターが含まれています。 使用可能なアプリ認証構成は次のとおりです。

  • クライアント シークレット
  • [証明書]
  • フェデレーション ID 資格情報

Microsoft Entra アプリでは、実行される操作に応じて、特定のロールのアクセス許可が必要になる場合があります。 たとえば、IoT Hub デバイスとモジュール ツインへの読み取りと書き込みアクセスを有効にするには、IoT Hub ツイン共同作成者が必要です。 詳細については、「Azure RBAC ロールの割り当てを使用して IoT Hub へのアクセスを管理する」を参照してください。

Microsoft Entra アプリの設定の詳細については、「クイック スタート: Microsoft ID プラットフォームにアプリケーションを登録する」を参照してください。

DefaultAzureCredential を使用して認証する

Microsoft Entra を使用してバックエンド アプリケーションを認証する最も簡単な方法は、DefaultAzureCredential を使用することですが、特定の TokenCredential や削減された ChainedTokenCredential など、運用環境では別の方法を使用することをお勧めします。 DefaultAzureCredential を使用する長所と短所の詳細については、「Java 用 Azure ID クライアント ライブラリの資格情報チェーン」を参照してください。

DefaultAzureCredential では、さまざまな認証メカニズムがサポートされ、実行されている環境に基づいて適切な資格情報の種類が決まります。 有効な資格情報が見つかるまで、複数の種類の資格情報の使用を順番に試みます。

Microsoft Entra アプリの資格情報は、DefaultAzureCredentialBuilder を使用して認証できます。 クライアント シークレット tenantID、clientID、クライアント シークレットの値などの接続パラメーターを環境変数として保存します。 TokenCredential が作成されたら、それを 'credential' パラメーターとして ServiceClient またはその他のビルダーに渡します。

この例では、DefaultAzureCredentialBuilder は、DefaultAzureCredential で説明されている一覧から接続の認証を試みます。 Microsoft Entra 認証が成功した結果として、セキュリティ トークン資格情報が ServiceClient などのコンストラクターに渡されます。

TokenCredential defaultAzureCredential = new DefaultAzureCredentialBuilder().build();
ClientSecretCredentialBuilder を使用して認証する

クライアント シークレット情報を使用して資格情報を作成するには、ClientSecretCredentialBuilder を使用できます。 成功した場合、このメソッドは ServiceClient またはその他のビルダーに 'credential' パラメーターとして渡すことができる TokenCredential を返します。

この例では、Microsoft Entra アプリ登録のクライアント シークレット、クライアント ID、テナント ID の値が環境変数に追加されました。 これらの環境変数は、資格情報を構築するために ClientSecretCredentialBuilder によって使用されます。

string clientSecretValue = System.getenv("AZURE_CLIENT_SECRET");
string clientID = System.getenv("AZURE_CLIENT_ID");
string tenantID = System.getenv("AZURE_TENANT_ID");

TokenCredential credential =
     new ClientSecretCredentialBuilder()
          .tenantId(tenantID)
          .clientId(clientID)
          .clientSecret(clientSecretValue)
          .build();
その他の認証クラス

Java SDK には、Microsoft Entra でバックエンド アプリを認証する次のクラスも含まれています。

コード サンプル

Microsoft Entra サービス認証の作業サンプルについては、「ロール ベースの認証のサンプルのページを参照してください。

デバイス ツインのフィールドを更新する

デバイス ツイン フィールドを更新するには:

  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);
    

デバイス ツイン クエリを作成する

このセクションでは、2 つのデバイス ツイン クエリを示します。 デバイス ツイン クエリは、デバイス ツインの結果セットを返す SQL のようなクエリです。

Query クラスには、IoT Hub に対してツイン、ジョブ、デバイス ジョブ、または生データに関する 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 Hub によって設定された必要なツインのプロパティの変更について通知を受け取ることができます。

IoTHubDeviceClient クラスには、デバイス ツインを操作するために使用できるメソッドが含まれています。

このセクションでは、次のようなデバイス アプリケーション コードを作成する方法について説明します。

  • デバイス ツインを取得し、報告されたプロパティを確認する
  • 報告されたデバイス ツインのプロパティにパッチを適用する

重要

この記事では、Shared Access Signature (対称キー認証とも呼ばれます) を使用してデバイスを接続する手順について説明します。 この認証方法はテストと評価には便利ですが、X.509 証明書を使用してデバイスを認証する方が安全なアプローチです。 詳細については、「セキュリティのベスト プラクティス」>「接続のセキュリティ」をご覧ください。

デバイスへの接続

このセクションでは、共有アクセス キーを含むデバイスの主キーを使用してアプリケーションをデバイスに接続する方法を示します。

アプリケーションをデバイスに接続するには:

  1. create_from_connection_string を呼び出して、デバイスの接続文字列を追加します
  2. connect を呼び出して、デバイス クライアントを Azure IoT Hub に接続します
# 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 portal でデバイスについて表示できるデバイス ツインの JSON 形式のデータと一致します。

get_twin を呼び出して、Azure IoT Hub サービスからデバイス ツインを取得します。 ツイン情報は、出力または確認できる変数に配置されます。

この例では、デバイス ツインを取得し、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 を呼び出して、ツインの必要なプロパティ パッチを受信したときに呼び出されるハンドラー関数またはコルーチンを作成します。 このハンドラーは引数を 1 つ受け取ります。これは、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 Hub 経由でデバイスに接続します。また、デバイスから報告されたプロパティと必要なプロパティを読み取り、デバイスの必要なプロパティを書き込み、デバイス クエリを実行することができます。

このセクションでは、次のことを行うバックエンド アプリケーションを作成する方法について説明します。

  • ツイン タグと必要なプロパティを更新する
  • タグとプロパティにフィルターを使用してデバイスのクエリを実行する

IoTHubRegistryManager クラスは、サービスからデバイス ツインと対話するバックエンド アプリケーションを作成するために必要なすべてのメソッドを公開しています。

IoT Hub に接続する

次の方法を使用して、バックエンド サービスを IoT Hub に接続できます。

  • 共有アクセス ポリシー
  • Microsoft Entra

重要

この記事では、Shared Access Signature を使用してサービスに接続する手順について説明しています。 この認証方法はテストと評価には便利ですが、サービスに対する認証方法としては、Microsoft Entra ID またはマネージド ID を使用する方が安全です。 詳細については、「セキュリティのベスト プラクティス」の「クラウドのセキュリティ」 を参照してください。>

共有アクセス ポリシーを使用して接続する

from_connection_string を使用して、IoT Hub に接続します。 そのアプリケーションには、必要なデバイス ツインのプロパティを変更するためのサービス接続アクセス許可と、ID レジストリに対してクエリを実行するためのレジストリ読み取りアクセス許可が必要となります。 その 2 つのアクセス許可だけを含んだ既定の共有アクセス ポリシーは存在しないため、存在しない場合には共有アクセス ポリシーを作成する必要があります。 この共有アクセス ポリシー接続文字列を、fromConnectionString のパラメーターとして指定します。 共有アクセス ポリシーの詳細については、「Shared Access Signature を使用して IoT Hub へのアクセスを制御する」を参照してください。

次に例を示します。

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)

Microsoft Entra を使用して接続する

Microsoft Entra を使用するバックエンド アプリは、IoT Hub に接続する前に、認証に成功してセキュリティ トークンの資格情報を取得する必要があります。 このトークンは、IoT Hub 接続メソッドに渡されます。 IoT Hub 用の Microsoft Entra の設定と使用に関する一般的な情報については、「Microsoft Entra ID を使用した IoT Hub へのアクセス制御」を参照してください。

Python SDK 認証の概要については、「Azure SDK for Python を使用して Azure サービスに対して Python アプリを認証する方法」を参照してください

Microsoft Entra アプリを構成する

優先する認証資格情報用に構成された Microsoft Entra アプリを設定する必要があります。 このアプリには、バックエンド アプリケーションで認証に使用されるクライアント シークレットなどのパラメーターが含まれています。 使用可能なアプリ認証構成は次のとおりです。

  • クライアント シークレット
  • [証明書]
  • フェデレーション ID 資格情報

Microsoft Entra アプリでは、実行される操作に応じて、特定のロールのアクセス許可が必要になる場合があります。 たとえば、IoT Hub デバイスとモジュール ツインへの読み取りと書き込みアクセスを有効にするには、IoT Hub ツイン共同作成者が必要です。 詳細については、「Azure RBAC ロールの割り当てを使用して IoT Hub へのアクセスを管理する」を参照してください。

Microsoft Entra アプリの設定の詳細については、「クイック スタート: Microsoft ID プラットフォームにアプリケーションを登録する」を参照してください。

DefaultAzureCredential を使用して認証する

Microsoft Entra を使用してバックエンド アプリケーションを認証する最も簡単な方法は、DefaultAzureCredential を使用することですが、特定の TokenCredential や削減された ChainedTokenCredential など、運用環境では別の方法を使用することをお勧めします。 わかりやすくするために、このセクションでは、 DefaultAzureCredential とクライアント シークレットを使用した認証について説明します。 DefaultAzureCredential を使用する長所と短所の詳細については、「Python 用 Azure ID クライアント ライブラリの資格情報チェーン」を参照してください。

DefaultAzureCredential では、さまざまな認証メカニズムがサポートされ、実行されている環境に基づいて適切な資格情報の種類が決まります。 有効な資格情報が見つかるまで、複数の種類の資格情報の使用を順番に試みます。

Microsoft Entra には、次の Import パッケージと、対応する import ステートメントが必要です。

pip install azure-identity
from azure.identity import DefaultAzureCredential

この例では、Microsoft Entra アプリ登録のクライアント シークレット、クライアント ID、テナント ID が環境変数に追加されました。 これらの環境変数は、アプリケーションを認証するために DefaultAzureCredential で使用されます。 Microsoft Entra 認証が成功した結果、セキュリティ トークン資格情報が IoT Hub 接続メソッドに渡されます。

from azure.identity import DefaultAzureCredential
credential = DefaultAzureCredential()

結果として得られる AccessToken は、Microsoft Entra 資格情報を受け入れる SDK クライアントの IoT Hub に接続するために from_token_credential に渡すことができます。

from_token_credential には、次の 2 つのパラメーターが必要です。

  • Azure サービス URL - Azure サービスの URL は、https:// プレフィックスのない {Your Entra domain URL}.azure-devices.net 形式にする必要があります。 たとえば、MyAzureDomain.azure-devices.net のようにします。
  • Azure 資格情報トークン

次の例では、Azure 資格情報は DefaultAzureCredential を使用して取得されます。 その後、Azure サービスの URL と資格情報が IoTHubRegistryManager.from_token_credential に指定され、IoT Hub への接続が作成されます。

import sys
import os

from azure.identity import DefaultAzureCredential
from azure.iot.hub import IoTHubRegistryManager

# Define the client secret values
clientSecretValue = 'xxxxxxxxxxxxxxx'
clientID = 'xxxxxxxxxxxxxx'
tenantID = 'xxxxxxxxxxxxx'

# Set environment variables
os.environ['AZURE_CLIENT_SECRET'] = clientSecretValue
os.environ['AZURE_CLIENT_ID'] = clientID
os.environ['AZURE_TENANT_ID'] = tenantID

# Acquire a credential object
credential = DefaultAzureCredential()

# Use Entra to authorize IoT Hub service
print("Connecting to IoTHubRegistryManager...")
iothub_registry_manager = IoTHubRegistryManager.from_token_credential(
url="MyAzureDomain.azure-devices.net",
token_credential=credential)
コード サンプル

Microsoft Entra サービス認証の作業サンプルについては、「Python 用 Microsoft 認証ライブラリ (MSAL)」を参照してください。

ツイン タグと必要なプロパティを更新する

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 を使用して IoTHub にクエリを実行し、SQL のようなクエリ仕様を使用してデバイス ツイン情報を取得します。

この例では 2 つのクエリを実行します。 1 つ目を使用して Redmond43 工場にあるデバイスのデバイス ツインのみを選択し、2 つ目を使用して移動体通信ネットワーク経由でも接続しているデバイスのみを選択するようにクエリを改良します。 結果は各クエリの後に出力されます。

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 Hub によって設定された必要なツインのプロパティの変更について通知を受け取ることができます。

このセクションでは、Azure IoT SDK for Node.js の azure-iot-device パッケージを使用して、次のことを行うデバイス アプリケーションを作成する方法について説明します。

  • デバイス ツインを取得し、報告されたプロパティを確認する
  • 報告されたデバイス ツインのプロパティを更新する
  • 必要なプロパティ変更の通知を受け取る

重要

この記事では、Shared Access Signature (対称キー認証とも呼ばれます) を使用してデバイスを接続する手順について説明します。 この認証方法はテストと評価には便利ですが、X.509 証明書を使用してデバイスを認証する方が安全なアプローチです。 詳細については、「セキュリティのベスト プラクティス」>「接続のセキュリティ」をご覧ください。

SDK パッケージをインストールする

次のコマンドを実行して、開発マシンに azure-iot-device デバイス SDK をインストールします。

npm install azure-iot-device --save

azure-iot-device パッケージには、IoT デバイスとやり取りするオブジェクトが含まれています。 Twin クラスには、ツイン固有のオブジェクトが含まれています。 このセクションでは、デバイス ツイン データの読み取りと書き込みに使用される Client クラス コードについて説明します。

トランスポート プロトコルを選択する

Client オブジェクトでは、次のプロトコルがサポートされます。

  • Amqp
  • Http - Http を使用する場合、Client インスタンスは IoT Hub からのメッセージを頻繁にはチェックしません (少なくとも 25 分ごと)。
  • Mqtt
  • MqttWs
  • AmqpWs

必要なトランスポート プロトコルを開発マシンにインストールします。

たとえば、次のコマンドを使用すると、Mqtt プロトコルをインストールできます。

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

MQTT、AMQP、および HTTPS のサポートの相違点の詳細については、「cloud-to-device 通信に関するガイダンス」と「通信プロトコルの選択」を参照してください。

クライアント モジュールを作成する

インストールされたパッケージを使用して Client モジュールを作成します。

次に例を示します。

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

プロトコル モジュールを作成する

インストールされたトランスポート パッケージを使用して Protocol モジュールを作成します。

この例では、MQTT プロトコルを割り当てます。

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

デバイスの接続文字列とトランスポート プロトコルを追加する

fromConnectionString を呼び出して、デバイス接続パラメーターを指定します。

  • connStr - IoT ハブの "デバイス接続" アクセス許可をカプセル化する接続文字列。 接続文字列には、ホスト名、デバイス ID、共有アクセス キーが次の形式で含まれます: "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 Hub への接続を開く

open メソッドを使用して、IoT デバイスと IoT Hub の間の接続を開きます。 .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 形式のパッチを 1 つ目のパラメーターとして、関数実行状態のコールバック メソッドを 2 つ目のパラメーターとしてメソッドに含めます。

この例では、JSON 形式のデバイス ツイン パッチが patch 変数に格納されます。 パッチには、デバイス ツイン connectivity の更新値 cellular が含まれています。 パッチとエラー ハンドラーは 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 に渡して、デバイス内で必要なプロパティが変更されたときに実行される必要なプロパティ更新イベント リスナーを作成します。

必要なプロパティ イベント リスナーは、次のいずれかの形式を受け取ることができます。

  • 1 つのイベント ハンドラーですべてのパッチを受信する
  • プロパティ グループで何か変更があった場合にイベントを受信する
  • 1 つのプロパティ変更のイベントを受信する

1 つのイベント ハンドラーですべてのパッチを受信する

必要なプロパティの変更を受け取るリスナーを作成できます。

このコード例は、サービスから受信したプロパティを出力します。

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);
        }
    });
    

1 つのプロパティ変更のイベントを受信する

1 つのプロパティ変更に対してリスナーを設定できます。 この例では、このイベントのコードは、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);
      });
    

Device SDK のサンプル

Azure IoT SDK for Node.js には、次の 2 つのデバイス ツイン サンプルが含まれています。

バックエンド アプリケーションを作成する

バックエンド アプリケーションは、IoT Hub 経由でデバイスに接続します。また、デバイスから報告されたプロパティと必要なプロパティを読み取り、デバイスの必要なプロパティを書き込み、デバイス クエリを実行することができます。

このセクションでは、次のようなバックエンド アプリケーションを作成する方法について説明します。

  • デバイス ツインの取得と更新
  • デバイス ツイン クエリを作成する

サービス SDK パッケージをインストールする

次のコマンドを実行して、開発マシンに azure-iothub をインストールします。

npm install azure-iothub --save

Registry クラスは、バックエンド アプリケーションからデバイス ツインと対話するために必要なすべてのメソッドを公開しています。

IoT Hub に接続する

次の方法を使用して、バックエンド サービスを IoT Hub に接続できます。

  • 共有アクセス ポリシー
  • Microsoft Entra

重要

この記事では、Shared Access Signature を使用してサービスに接続する手順について説明しています。 この認証方法はテストと評価には便利ですが、サービスに対する認証方法としては、Microsoft Entra ID またはマネージド ID を使用する方が安全です。 詳細については、「セキュリティのベスト プラクティス」の「クラウドのセキュリティ」 を参照してください。>

共有アクセス ポリシーを使用して接続する

fromConnectionString を使用して IoT Hub に接続します。 そのアプリケーションには、必要なデバイス ツインのプロパティを変更するためのサービス接続アクセス許可と、ID レジストリに対してクエリを実行するためのレジストリ読み取りアクセス許可が必要となります。 その 2 つのアクセス許可だけを含んだ既定の共有アクセス ポリシーは存在しないため、存在しない場合には共有アクセス ポリシーを作成する必要があります。 この共有アクセス ポリシー接続文字列を、fromConnectionString のパラメーターとして指定します。 共有アクセス ポリシーの詳細については、「Shared Access Signature を使用して IoT Hub へのアクセスを制御する」を参照してください。

'use strict';
var iothub = require('azure-iothub');
var connectionString = '{Shared access policy connection string}';
var registry = iothub.Registry.fromConnectionString(connectionString);

Microsoft Entra を使用して接続する

Microsoft Entra を使用するバックエンド アプリは、IoT Hub に接続する前に、認証に成功してセキュリティ トークンの資格情報を取得する必要があります。 このトークンは、IoT Hub 接続メソッドに渡されます。 IoT Hub 用の Microsoft Entra の設定と使用に関する一般的な情報については、「Microsoft Entra ID を使用した IoT Hub へのアクセス制御」を参照してください。

Node.js SDK 認証の概要については、次を参照してください。

Microsoft Entra アプリを構成する

優先する認証資格情報用に構成された Microsoft Entra アプリを設定する必要があります。 このアプリには、バックエンド アプリケーションで認証に使用されるクライアント シークレットなどのパラメーターが含まれています。 使用可能なアプリ認証構成は次のとおりです。

  • クライアント シークレット
  • [証明書]
  • フェデレーション ID 資格情報

Microsoft Entra アプリでは、実行される操作に応じて、特定のロールのアクセス許可が必要になる場合があります。 たとえば、IoT Hub デバイスとモジュール ツインへの読み取りと書き込みアクセスを有効にするには、IoT Hub ツイン共同作成者が必要です。 詳細については、「Azure RBAC ロールの割り当てを使用して IoT Hub へのアクセスを管理する」を参照してください。

Microsoft Entra アプリの設定の詳細については、「クイック スタート: Microsoft ID プラットフォームにアプリケーションを登録する」を参照してください。

DefaultAzureCredential を使用して認証する

Microsoft Entra を使用してバックエンド アプリケーションを認証する最も簡単な方法は、DefaultAzureCredential を使用することですが、特定の TokenCredential や削減された ChainedTokenCredential など、運用環境では別の方法を使用することをお勧めします。 わかりやすくするために、このセクションでは、 DefaultAzureCredential とクライアント シークレットを使用した認証について説明します。 DefaultAzureCredential を使用する長所と短所の詳細については、「JavaScript 用 Azure ID クライアント ライブラリの資格情報チェーン」を参照してください

DefaultAzureCredential では、さまざまな認証メカニズムがサポートされ、実行されている環境に基づいて適切な資格情報の種類が決まります。 有効な資格情報が見つかるまで、複数の種類の資格情報の使用を順番に試みます。

Microsoft Entra には、次のパッケージが必要です。

npm install --save @azure/identity

この例では、Microsoft Entra アプリ登録のクライアント シークレット、クライアント ID、テナント ID が環境変数に追加されました。 これらの環境変数は、アプリケーションを認証するために DefaultAzureCredential で使用されます。 Microsoft Entra 認証が成功した結果、セキュリティ トークン資格情報が IoT Hub 接続メソッドに渡されます。

import { DefaultAzureCredential } from "@azure/identity";

// Azure SDK clients accept the credential as a parameter
const credential = new DefaultAzureCredential();

結果として得られる資格情報トークンは、Microsoft Entra 資格情報を受け入れる SDK クライアントの IoT Hub に接続するために fromTokenCredential に渡すことができます。

fromTokenCredential には、次の 2 つのパラメーターが必要です。

  • Azure サービス URL - Azure サービスの URL は、https:// プレフィックスのない {Your Entra domain URL}.azure-devices.net 形式にする必要があります。 たとえば、MyAzureDomain.azure-devices.net のようにします。
  • Azure 資格情報トークン

次の例では、Azure 資格情報は DefaultAzureCredential を使用して取得されます。 その後、Azure ドメインの URL と資格情報が Registry.fromTokenCredential に指定され、IoT Hub への接続が作成されます。

const { DefaultAzureCredential } = require("@azure/identity");

let Registry = require('azure-iothub').Registry;

// Define the client secret values
clientSecretValue = 'xxxxxxxxxxxxxxx'
clientID = 'xxxxxxxxxxxxxx'
tenantID = 'xxxxxxxxxxxxx'

// Set environment variables
process.env['AZURE_CLIENT_SECRET'] = clientSecretValue;
process.env['AZURE_CLIENT_ID'] = clientID;
process.env['AZURE_TENANT_ID'] = tenantID;

// Acquire a credential object
const credential = new DefaultAzureCredential()

// Create an instance of the IoTHub registry
hostName = 'MyAzureDomain.azure-devices.net';
let registry = Registry.fromTokenCredential(hostName,credential);
コード サンプル

Microsoft Entra サービス認証の作業サンプルについては、 Azure ID の例に関するページを参照してください。

デバイス ツインの取得と更新

デバイス ツインのタグと必要なプロパティの更新を含むパッチを作成できます。

デバイス ツインを更新するには:

  1. getTwin を呼び出して、デバイス ツイン オブジェクトを取得します。
  • デバイス ツインの更新を含むパッチの書式を設定します。 「Twin クラス」で説明されているように、パッチは JSON 形式です。 バックエンド サービス パッチには、タグと必要なプロパティの更新を含めることができます。 パッチ形式の詳細については、「タグやプロパティの形式」を参照してください。
  1. update を呼び出して、デバイス ツインをパッチで更新します。

この例では、myDeviceId のデバイス ツインが取得され、その後、region: 'US', plant: 'Redmond43'location タグ更新を含むパッチがツインに適用されます。

     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 Hub インスタンス上で実行してデバイスまたはジョブに関する情報を検索できるクエリを作成します。

createQuery には 2 つのパラメーターがあります。

  • 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(','));
    }
});
};

Service SDK のサンプル

Azure IoT SDK for Node.js には、デバイス ツイン タスクを処理するサービス アプリの動作するサンプルが用意されています。 詳細については、「デバイス ツイン バックエンド サービス」を参照してください。このプロジェクトは、特定のデバイスのデバイス ツイン パッチ更新を送信するために使用されます。