デバイス ツインの使用 (.NET)

デバイス ツインは、デバイスに関する情報 (メタデータ、構成、状態など) を格納する JSON ドキュメントです。 IoT Hub は、IoT Hub に接続する各デバイスにデバイス ツインを保持します。

Note

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

次の場合にデバイス ツインを使用します。

  • ソリューション バックエンドからデバイス メタデータを格納する。

  • デバイス アプリで利用できる機能や状態 (たとえば、使用される接続方法) などの現在の状態に関する情報をレポートする。

  • デバイス アプリとバックエンド アプリの間で実行時間の長いワークフロー (ファームウェアや構成の更新など) の状態を同期する。

  • デバイス メタデータ、構成、または状態を照会する。

デバイス ツインは、同期のほか、デバイスの構成と状態の照会に対応しています。 デバイス ツインの使用方法など、デバイス ツインの詳細については、デバイス ツインの理解に関するページを参照してください。

IoT ハブには、次の要素を含むデバイス ツインが格納されます。

  • タグ。 ソリューション バックエンドからのみアクセスできるデバイス メタデータです。

  • 必要なプロパティ。 ソリューション バックエンドから変更でき、デバイス アプリから監視できる JSON オブジェクトです。

  • 報告されるプロパティ。 デバイス アプリから変更でき、ソリューション バックエンドから読み取り可能な JSON オブジェクトです。

タグとプロパティには配列を含めることはできませんが、入れ子になったオブジェクトを含めることができます。

次の図は、デバイス ツイン組織を示しています。

デバイス ツインの概念図のスクリーンショット。

さらに、ソリューション バックエンドは、上記のすべてのデータに基づいてデバイス ツインに対してクエリを実行できます。 デバイス ツインの詳細については、デバイス ツインの理解に関するページを参照してください。 クエリ実行の詳細については、IoT Hub クエリ言語に関するページを参照してください。

この記事で取り上げるテクニック:

  • シミュレートされたデバイス アプリを使用して、その接続チャネルをデバイス ツインで報告されたプロパティとして報告します。

  • 以前に作成したタグとプロパティのフィルターを使用して、バックエンド アプリからデバイスに対してクエリを実行します。

この記事では、次の 2 つの .NET コンソール アプリを作成します。

  • AddTagsAndQuery: タグの追加とデバイス ツインのクエリを実行するバックエンド アプリ。

  • ReportConnectivity: IoT ハブに接続してその接続状態を報告するシミュレートされたデバイス アプリ。

Note

デバイスとバックエンド アプリの両方の構築に使用できる SDK ツールに関する詳細については、「Azure IoT Hub SDK」を参照してください。

前提条件

  • 見ることができます。

  • IoT Hub。 CLI または Azure portal を使って作成します。

  • 登録済みのデバイス。 Azure portal に登録してください。

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

IoT ハブ接続文字列を取得する

この記事では、デバイス ツインに必要なプロパティを追加した後、ID レジストリに対してクエリを実行し、適切に更新された報告されるプロパティを持つデバイスをすべて検索するバックエンド サービスを作成します。 そのサービスには、必要なデバイス ツインのプロパティを変更するためのサービス接続アクセス許可と、ID レジストリに対してクエリを実行するためのレジストリ読み取りアクセス許可が必要となります。 その 2 つのアクセス許可だけを含んだ既定の共有アクセス ポリシーは存在しないため、共有アクセス ポリシーを独自に作成する必要があります。

サービス接続レジストリ読み取りのアクセス許可を付与する共有アクセス ポリシーを作成し、そのポリシーの接続文字列を取得するには、次の手順を実行します。

  1. Azure portal で、 [リソース グループ] を選択します。 ハブが配置されているリソース グループを選択し、リソースの一覧からハブを選択します。

  2. ハブの左側のウィンドウで、 [共有アクセス ポリシー] を選択します。

  3. ポリシー一覧の上にある最初のメニューから、[共有アクセス ポリシーの追加] を選びます。

  4. 右側の [共有アクセス ポリシーの追加] ウィンドウで、serviceAndRegistryRead などのポリシーのわかりやすい名前を入力します。 [アクセス許可][レジストリ読み取り][サービス接続] を選び、[追加] を選びます。

    新しい共有アクセス ポリシーを追加する方法を示すスクリーン キャプチャ。

  5. ポリシーの一覧から、新しいポリシーを選択します。

  6. [プライマリ接続文字列] のコピー アイコンを選び、その値を保存します。

    接続文字列を取得する方法を示すスクリーン キャプチャ。

IoT Hub の共有アクセス ポリシーとアクセス許可の詳細については、「アクセス制御とアクセス許可」を参照してください。

報告されたプロパティを更新するデバイス アプリを作成する

このセクションでは、myDeviceId としてハブに接続される .NET コンソール アプリを作成し、その報告されたプロパティを更新して、接続に携帯ネットワークが使用されていることを確認します。

  1. Visual Studio を開き、[新しいプロジェクトの作成] を選びます。

  2. [コンソール アプリ (.NET Framework)] を選び、[次へ] を選びます。

  3. [新しいプロジェクトの構成] で、プロジェクトに ReportConnectivity という名前を付け、[次へ] を選びます。

  4. ソリューション エクスプローラーで ReportConnectivity プロジェクトを右クリックし、 [NuGet パッケージの管理] を選択します。

  5. 既定の .NET Framework をそのまま使い、[作成] を選んでプロジェクトを作成します。

  6. [参照] を選択し、Microsoft.Azure.Devices.Client を探して選択します。 [インストール] を選択します。

    この手順により、パッケージのダウンロードとインストールが実行され、Azure IoT device SDK NuGet パッケージへの参照とその依存関係が追加されます。

  7. Program.cs ファイルの先頭に次の using ステートメントを追加します。

    using Microsoft.Azure.Devices.Client;
    using Microsoft.Azure.Devices.Shared;
    using Newtonsoft.Json;
    
  8. Program クラスに次のフィールドを追加します。 {device connection string} を、IoT Hub にデバイスを登録した時に表示されたデバイス接続文字列に置き換えます。

    static string DeviceConnectionString = "HostName=<yourIotHubName>.azure-devices.net;DeviceId=<yourIotDeviceName>;SharedAccessKey=<yourIotDeviceAccessKey>";
    static DeviceClient Client = null;
    
  9. Program クラスに次のメソッドを追加します。

    public static async void InitClient()
    {
        try
        {
            Console.WriteLine("Connecting to hub");
            Client = DeviceClient.CreateFromConnectionString(DeviceConnectionString, 
              TransportType.Mqtt);
            Console.WriteLine("Retrieving twin");
            await Client.GetTwinAsync();
        }
        catch (Exception ex)
        {
            Console.WriteLine();
            Console.WriteLine("Error in sample: {0}", ex.Message);
        }
    }
    

    Client オブジェクトに、デバイスからデバイス ツインとやりとりするのに必要なすべてのメソッドが表示されます。 上記のコードでは、クライアント オブジェクトが初期化された後、myDeviceId のデバイス ツインが取得されます。

  10. Program クラスに次のメソッドを追加します。

    public static async void ReportConnectivity()
    {
        try
        {
            Console.WriteLine("Sending connectivity data as reported property");
    
            TwinCollection reportedProperties, connectivity;
            reportedProperties = new TwinCollection();
            connectivity = new TwinCollection();
            connectivity["type"] = "cellular";
            reportedProperties["connectivity"] = connectivity;
            await Client.UpdateReportedPropertiesAsync(reportedProperties);
        }
        catch (Exception ex)
        {
            Console.WriteLine();
            Console.WriteLine("Error in sample: {0}", ex.Message);
        }
    }
    

    上記のコードでは、myDeviceId の報告されるプロパティが接続情報で更新されます。

  11. 最後に、Main メソッドに次の行を追加します。

    try
    {
        InitClient();
        ReportConnectivity();
    }
    catch (Exception ex)
    {
        Console.WriteLine();
        Console.WriteLine("Error in sample: {0}", ex.Message);
    }
    Console.WriteLine("Press Enter to exit.");
    Console.ReadLine();
    
  12. ソリューション エクスプローラーでソリューションを右クリックし、 [スタートアップ プロジェクトの設定] を選択します。

  13. [共通プロパティ]>[スタートアップ プロジェクト] で、 [マルチ スタートアップ プロジェクト] を選択します。 ReportConnectivity では、 [アクション] として [開始] を選択します。 [OK] を選択して変更を保存します。

  14. ReportConnectivity プロジェクトを右クリックし、 [デバッグ] を選択してから、 [新しいインスタンスを開始] を選択して、このアプリを実行します。 アプリでツインの情報が取得された後、接続性が "報告されるプロパティ" として送信される様子が見られます。

    デバイス アプリを実行して接続性を報告

    デバイスの接続情報が報告された後、両方のクエリで表示されるようになります。

  15. AddTagsAndQuery プロジェクトを右クリックし、 [デバッグ]>[新しいインスタンスを開始] を選択して、クエリを再実行します。 今回は、myDeviceId が両方のクエリ結果に表示されるはずです。

    デバイスの接続性が正常に報告される

目的のプロパティおよびクエリ ツインを更新するサービス アプリを作成する

このセクションでは、myDeviceId に関連付けられたデバイス ツインに場所のメタデータを追加する .NET コンソール アプリを C# を使用して作成します。 このアプリは、IoT ハブで米国内にあるデバイスのクエリを実行した後、携帯ネットワーク接続を報告しているデバイスのクエリを実行します。

  1. Visual Studio で、[ファイル] > [新規作成] > [プロジェクト] の順に選びます。 [新しいプロジェクトの作成] で、 [コンソール アプリ (.NET Framework)] を選択してから、 [次へ] を選択します。

  2. [新しいプロジェクトの構成] で、プロジェクトに AddTagsAndQuery という名前を付け、[次へ] を選びます。

    新しい Visual Studio プロジェクトを作成する方法のスクリーンショット。

  3. .NET Framework の既定のバージョンをそのまま使用し、[作成] を選択してプロジェクトを作成します。

  4. ソリューション エクスプローラーで AddTagsAndQuery プロジェクトを右クリックし、 [NuGet パッケージの管理] を選択します。

  5. [参照] を選択し、Microsoft.Azure.Devices を探して選択します。 [インストール] を選択します。

    NuGet Package Manager window

    この手順により、パッケージのダウンロードとインストールが実行され、Azure IoT service SDK NuGet パッケージへの参照とその依存関係が追加されます。

  6. Program.cs ファイルの先頭に次の using ステートメントを追加します。

    using Microsoft.Azure.Devices;
    
  7. Program クラスに次のフィールドを追加します。 {iot hub connection string} を、「IoT ハブ接続文字列を取得する」でコピーしておいた IoT ハブ接続文字列に置き換えてください。

    static RegistryManager registryManager;
    static string connectionString = "{iot hub connection string}";
    
  8. Program クラスに次のメソッドを追加します。

    public static async Task AddTagsAndQuery()
    {
        var twin = await registryManager.GetTwinAsync("myDeviceId");
        var patch =
            @"{
                tags: {
                    location: {
                        region: 'US',
                        plant: 'Redmond43'
                    }
                }
            }";
        await registryManager.UpdateTwinAsync(twin.DeviceId, patch, twin.ETag);
    
        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)));
    }
    

    RegistryManager クラスに、サービスからデバイス ツインとやりとりするのに必要なすべてのメソッドが表示されます。 前のコードでは、まず registryManager オブジェクトを初期化し、myDeviceId のデバイス ツインを取得して、最後にタグを目的の位置情報で更新します。

    更新後、2 つのクエリを実行します。1 番目のクエリでは、Redmond43 工場にあるデバイスのデバイス ツインのみを選択し、2 番目のクエリでは携帯ネットワーク経由で接続しているデバイスのみを選択します。

    前のコードでは、query オブジェクトの作成時に、返されるドキュメントの最大数を指定します。 query オブジェクトには、GetNextAsTwinAsync メソッドを複数回呼び出してすべての結果を取得する際に使用できる HasMoreResults のブール型プロパティが含まれます。 GetNextAsJson というメソッドは、集計クエリの結果など、デバイス ツインではない結果に使用できます。

  9. 最後に、Main メソッドに次の行を追加します。

    registryManager = RegistryManager.CreateFromConnectionString(connectionString);
    AddTagsAndQuery().Wait();
    Console.WriteLine("Press Enter to exit.");
    Console.ReadLine();
    
  10. AddTagsAndQuery プロジェクトを右クリックし、 [デバッグ] を選択してから、 [新しいインスタンスを開始] を選択して、このアプリケーションを実行します。 Redmond43 にあるすべてのデバイスを照会するクエリの結果には、1 件のデバイスが表示され、携帯ネットワークを使用するデバイスに絞り込んだ結果には 0 件のデバイスが表示されます。

    ウィンドウに表示されたクエリの結果

この記事では、次の内容について説明します。

  • バックエンド アプリからタグとしてデバイス メタデータを追加しました
  • デバイス ツインでデバイス接続情報を報告しました
  • SQL に似た IoT Hub クエリ言語を使用して、デバイス ツイン情報のクエリを実行しました

次のステップ

参照: