デバイス管理の開始 (.NET)

バックエンド アプリでは、Azure IoT Hub プリミティブ (デバイス ツインダイレクト メソッドなど) を使用して、デバイス上のデバイス管理アクションをリモートで開始および監視できます。 この記事では、バックエンド アプリとデバイス アプリをどのように連携させると、IoT Hub を使用してデバイスの再起動をリモートで開始して監視できるかについて示します。

Note

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

ダイレクト メソッドを使用して、クラウド内のバックエンド アプリケーションからデバイス管理操作 (再起動、出荷時の設定に戻す、ファームウェアの更新など) を開始します。 デバイスは次の操作を担当します。

  • IoT Hub から送信されたメソッド要求の処理。

  • デバイスでの対応するデバイス固有の操作の開始。

  • "報告されるプロパティ" を介した IoT Hub への状態更新の提供。

クラウドでバックエンド アプリを使用してデバイス ツインのクエリを実行することで、デバイス管理操作の進行状況を報告できます。

この記事では、次のものを作成する方法について説明します。

  • SimulateManagedDevice: デバイスを再起動し、最後の再起動時刻を報告するダイレクト メソッドを含むシミュレートされたデバイス アプリ。 ダイレクト メソッドは、クラウドから呼び出されます。

  • TriggerReboot: シミュレートされたデバイス アプリのダイレクト メソッドを IoT Hub から呼び出す .NET コンソール アプリ。 応答と更新されて報告されたプロパティを表示します。

前提条件

  • 見ることができます。

  • Azure サブスクリプション内の IoT ハブ。 ハブがまだない場合は、「IoT ハブの作成」の手順に従うことができます。

  • お使いの IoT ハブに登録されているデバイス。 IoT ハブにデバイスがない場合は、「デバイスを登録する」の手順に従います。

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

ダイレクト メソッドを使用してデバイス アプリを作成する

このセクションでは、次の作業を行います。

  • クラウドによって呼び出されたダイレクト メソッドに応答する .NET コンソール アプリを作成します。

  • シミュレート対象デバイスの再起動をトリガーします。

  • 報告されるプロパティを使用して、デバイス ツイン クエリで、デバイスとデバイスの最後の再起動時間を識別できるようにします。

シミュレートされたデバイス アプリを作成するには、次の手順を実行します。

  1. Visual Studio を開き、[新しいプロジェクトの作成] を選んでから、[コンソール アプリ (.NET Framework)] プロジェクト テンプレートを見つけて選んで、[次へ] を選びます。

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

    Visual Studio で新しいプロジェクトを名づける方法を示すスクリーンショット。 

  3. 既定の .NET Framework のバージョンをそのまま使って、[作成] を選びます。

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

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

    Microsoft.Azure.Devices. パッケージ をインストールする方法を示すスクリーンショット。

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

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

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

    static string DeviceConnectionString = "{device connection string}";
    static DeviceClient Client = null;
    
  8. デバイスにダイレクト メソッドを実装するために以下を追加します。

    static Task<MethodResponse> onReboot(MethodRequest methodRequest, object userContext)
    {
        // In a production device, you would trigger a reboot 
        //   scheduled to start after this method returns.
        // For this sample, we simulate the reboot by writing to the console
        //   and updating the reported properties.
        try
        {
            Console.WriteLine("Rebooting!");
    
            // Update device twin with reboot time. 
            TwinCollection reportedProperties, reboot, lastReboot;
            lastReboot = new TwinCollection();
            reboot = new TwinCollection();
            reportedProperties = new TwinCollection();
            lastReboot["lastReboot"] = DateTime.Now;
            reboot["reboot"] = lastReboot;
            reportedProperties["iothubDM"] = reboot;
            Client.UpdateReportedPropertiesAsync(reportedProperties).Wait();
        }
        catch (Exception ex)
        {
            Console.WriteLine();
            Console.WriteLine("Error in sample: {0}", ex.Message);
        }
    
        string result = @"{""result"":""Reboot started.""}";
        return Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(result), 200));
    }
    
  9. 最後に、IoT ハブへの接続を開いてメソッド リスナーを初期化する次のコードを Main メソッドに追加します。

    try
    {
        Console.WriteLine("Connecting to hub");
        Client = DeviceClient.CreateFromConnectionString(DeviceConnectionString, 
          TransportType.Mqtt);
    
        // setup callback for "reboot" method
        Client.SetMethodHandlerAsync("reboot", onReboot, null).Wait();
        Console.WriteLine("Waiting for reboot method\n Press enter to exit.");
        Console.ReadLine();
    
        Console.WriteLine("Exiting...");
    
        // as a good practice, remove the "reboot" handler
        Client.SetMethodHandlerAsync("reboot", null, null).Wait();
        Client.CloseAsync().Wait();
    }
    catch (Exception ex)
    {
        Console.WriteLine();
        Console.WriteLine("Error in sample: {0}", ex.Message);
    }
    
  10. ソリューション エクスプローラーで、ソリューションを右クリックし、 [スタートアップ プロジェクトの設定] を選択します。

  11. [共通プロパティ]>[スタートアップ プロジェクト][シングル スタートアップ プロジェクト] を選択し、SimulateManagedDevice プロジェクトを選択します。 [OK] を選択して変更を保存します。

  12. [ビルド]>[ビルドするソリューション] を選択します。

Note

わかりやすくするために、この記事では再試行ポリシーは実装しません。 運用コードでは、「一時的な障害の処理」で推奨されているように、再試行ポリシー (エクスポネンシャル バックオフなど) を実装してください。

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

この記事では、デバイス上で直接メソッドを呼び出すバックエンド サービスを作成します。 IoT Hub を介してデバイス上で直接メソッドを呼び出すには、サービスにサービス接続アクセス許可が必要です。 既定では、どの IoT Hub も、このアクセス許可を付与する service という名前の共有アクセス ポリシーがある状態で作成されます。

サービス ポリシーの IoT Hub 接続文字列を取得するには、次の手順を実行します。

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

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

  3. ポリシーの一覧から、サービス ポリシーを選択します。

  4. [プライマリ接続文字列] をコピーし、値を保存します。

Azure portal で IoT ハブから接続文字列を取得する方法を示すスクリーンショット。

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

再起動をトリガーするサービス アプリを作成する

このセクションでは、ダイレクト メソッドを使用してデバイスでのリモート再起動を開始する .NET コンソール アプリケーションを C# を使用して作成します。 このアプリは、デバイス ツイン クエリを使用して、そのデバイスの前回の再起動時刻を検出します。

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

  2. [新しいプロジェクトの作成] で、 [コンソール アプリ (.NET Framework)] プロジェクト テンプレートを探して選択し、 [次へ] を選択します。

  3. [新しいプロジェクトの構成] で、プロジェクトに トリガーして再起動 という名前を付けて、[次へ] を選択します。

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

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

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

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

    Microsoft.Azure.Devices. パッケージ をインストールする方法を示すスクリーンショット。

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

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

    using Microsoft.Azure.Devices;
    using Microsoft.Azure.Devices.Shared;
    
  8. Program クラスに次のフィールドを追加します。 {iot hub connection string} プレースホルダーの値を、先ほど「IoT ハブ接続文字列を取得する」でコピーした IoT Hub 接続文字列に置き換えます。

    static RegistryManager registryManager;
    static string connString = "{iot hub connection string}";
    static ServiceClient client;
    static string targetDevice = "myDeviceId";
    
  9. Program クラスに次のメソッドを追加します。 このコードは、再起動中のデバイスのデバイス ツインを取得し、報告されるプロパティを出力します。

    public static async Task QueryTwinRebootReported()
    {
        Twin twin = await registryManager.GetTwinAsync(targetDevice);
        Console.WriteLine(twin.Properties.Reported.ToJson());
    }
    
  10. Program クラスに次のメソッドを追加します。 このコードは、ダイレクト メソッドを使用してデバイスの再起動をトリガーします。

    public static async Task StartReboot()
    {
        client = ServiceClient.CreateFromConnectionString(connString);
        CloudToDeviceMethod method = new CloudToDeviceMethod("reboot");
        method.ResponseTimeout = TimeSpan.FromSeconds(30);
    
        CloudToDeviceMethodResult result = await 
          client.InvokeDeviceMethodAsync(targetDevice, method);
    
        Console.WriteLine("Invoked firmware update on device.");
    }
    
  11. 最後に、Main メソッドに次の行を追加します。

    registryManager = RegistryManager.CreateFromConnectionString(connString);
    StartReboot().Wait();
    QueryTwinRebootReported().Wait();
    Console.WriteLine("Press ENTER to exit.");
    Console.ReadLine();
    
  12. [ビルド]>[ビルドするソリューション] を選択します。

Note

このアーティクルでは、デバイスでレポートされるプロパティに対して 1 つのクエリのみを実行します。 運用環境のコードでは、レポートされるプロパティの変化を検出するために、ポーリング処理をお勧めします。

アプリの実行

これで、アプリを実行する準備が整いました。

  1. .Net デバイス アプリ SimulateManagedDevice を実行するには、ソリューション エクスプローラーで SimulateManagedDevice プロジェクトを右クリックし、 [デバッグ] を選択し、 [新しいインスタンスを開始] を選択します。 アプリで IoT ハブからメソッド呼び出しのリッスンが開始されます。

  2. デバイスが接続され、メソッドの呼び出しを待ってから、TriggerReboot プロジェクトを右クリックし、 [デバッグ][新しいインスタンスを開始] の順に選択します。

    Rebooting (再起動中) というメッセージが SimulatedManagedDevice コンソールに出力されます。また、デバイスのレポートされたプロパティ (最終再起動時間など) が TriggerReboot コンソールに出力されます。

    サービスとデバイス アプリの実行

デバイス管理操作のカスタマイズと拡張を行う

IoT ソリューションでは、定義された一連のデバイス管理パターンを拡張したり、デバイス ツインと cloud-to-device メソッド プリミティブを使用してカスタム パターンを作成したりできます。 デバイス管理操作の他の例には、出荷時の設定への復帰、ファームウェアの更新、ソフトウェアの更新、電源管理、ネットワークと接続の管理、データの暗号化などがあります。

デバイスのメンテナンス期間

通常、デバイスは、中断やダウンタイムを最小限に抑えることができる時間に操作を実行するように構成します。 デバイスのメンテナンス期間は、デバイスがその構成を更新する必要がある時間を定義する一般的に使用されるパターンです。 バックエンド ソリューションは、デバイス ツインの必要なプロパティを使用して、メンテナンス期間を可能にするデバイスのポリシーを定義してアクティブにすることができます。 デバイスは、メンテナンス期間ポリシーを受信したときに、デバイス ツインの報告されたプロパティを使用してポリシーの状態を報告することができます。 その後、バックエンド アプリケーションは、デバイス ツインのクエリを使用して、デバイスが各ポリシーに対応していることを確認できます。

次のステップ

この記事では、ダイレクト メソッドを使用して、デバイスのリモート再起動をトリガーしました。 報告されるプロパティを使用してデバイスの最後の再起動時間を報告し、デバイス ツインのクエリを実行してクラウドからデバイスの最後の再起動時間を検出しました。

Raspberry Pi 3 B+ 参照イメージを使用した Azure IoT Hub のデバイス アップデートのアーティクル」でエンドツーエンドのイメージベースの更新など、IoT Hub とデバイス管理パターンの使用を続けます。

IoT ソリューションの拡張と複数のデバイスでのメソッドの呼び出しをスケジュールする方法については、ジョブのスケジュールとブロードキャストに関するページを参照してください。