アプリケーションが IoT デバイスにコマンドを送信するときに使用するメカニズムは主に 2 つで、1 つは "cloud-to-device メッセージング"、もう 1 つは "ダイレクト メソッド" です。
アプリケーションは、cloud-to-device メッセージを、IoT プラットフォーム上のデバイス固有のメッセージ キューに送信して、デバイスが接続されているときにそのデバイスで読み取れるようにします。 メッセージを読み取るタイミングはデバイスが決めます。
アプリケーションは、専用 IoT デバイス エンドポイントの対する要求 - 応答パターンを使用して、接続されているデバイスで直接ダイレクト メソッドを呼び出します。
この記事では、cloud-to-device メッセージングおよびダイレクト メソッドの特性について説明します。 この記事では、プロトコル ゲートウェイと接続されたスタンバイ デバイスでのダイレクト メソッドの使用方法についても説明します。
クラウドからデバイスへのメッセージ
特定のデバイスに対する cloud-to-device コマンド メッセージが、アプリケーションによって Azure IoT Hub に送信され、デバイス固有のキューに格納されます。 メッセージは、デバイスが接続されているかどうかに関係なく、IoT Hub によりデバイス固有のキューに配信されます。
cloud-to-device メッセージングを使用する場合は、次の点を考慮してください。
- メッセージ キューはデバイスのメールボックスとして効果的に機能し、接続されているデバイスは、メッセージ キューで新しいメッセージのポーリングを担当します。
- デバイスは先入れ先出し方式でメッセージを受信するため、メッセージを順番に読み取って処理するには cloud-to-device メッセージングが最適です。
- メッセージの有効期限は構成可能です。したがって未読メッセージは最終的にはデバイスのメッセージ キューから削除できます。
- ステートフル通信の場合は、アプリケーションがフィードバック レシーバー を使って、メッセージの配信と受信確認を監視できます。 アプリケーションは単一のフィードバック レシーバーを使用して、すべてのデバイスのすべてのメッセージ キューを監視できます。
ダイレクト メソッド
ダイレクト メソッドは、接続された IoT デバイス上でアプリケーションによって直接呼び出されます。アプリケーションは、メソッドがデバイスによって実行され IoT Hub に登録されることを想定しています。 IoT Hub は、接続されたデバイス上で直接チャネルを介してダイレクト メソッドを呼び出します。デバイスは関数を実行し、すぐに結果を返す必要があります。
ダイレクト メソッドを使用するときは、次の点を考慮してください。
- ダイレクト メソッドは、メソッドが完了する前に IoT Hub とデバイスの間の接続が切断されると失敗します。 アプリケーションはエラーをキャッチして処理し、コマンドを再試行できます。
- キューが存在しないため、メソッド呼び出しのシーケンスの管理は、ダイレクト メソッドのシーケンスを必要とするアプリケーションが行う必要があり、前のメソッドが完了すると、次のメソッドが呼び出されます。
- ダイレクト メソッドを呼び出すと、アプリケーションで 2 つのタイムアウトを設定できます。 1 つは、デバイスが接続するまでの IoT Hub の待ち時間を指定するタイムアウトで、この時間が経過すると待機が中止されます。もう 1 つは、メソッドが完了して応答するまでの呼び出し元の待ち時間を指定するタイムアウトで、この時間が経過すると待機が中止されます。
プロトコル ゲートウェイを使用したダイレクト メソッド
プロトコル ゲートウェイ が使用されている IoT アプリケーションは、接続の強制と、ダイレクト メソッドの要求 - 応答モデルの利点を活用できます。 クラウド ゲートウェイまたはプロトコル ゲートウェイは、デバイスの代わりに動作してカスタム プロトコル通信を仲介することで、既存の多様なデバイスを IoT Hub に接続できます。 同様に、プロトコル ゲートウェイは、メソッドをデバイス対応プロトコル メッセージにシリアル化して、ダイレクト メソッド モデルを抽象化することもできます。
- アプリケーションが、プロトコル ゲートウェイでデバイスに代わってダイレクト メソッドを呼び出します。
- メソッド実装については、ゲートウェイがメソッドをデバイス固有のプロトコルに変換し、メッセージをデバイスに送信します。 デバイスは、クラウド実装に対する変更を認識しません。
- デバイスがメッセージを完了して応答すると、ゲートウェイはデバイス固有の状態をメソッドの応答に変換します。
- IoT Hub は呼び出し元のメソッドの結果を設定することで、ダイレクト メソッドを完了します。
Azure プロトコル ゲートウェイ オープン ソース プロジェクトは、ダイレクト メソッドを MQTT プロトコル メッセージにネイティブに変換し、簡単に拡張できます。また、他のプロトコル アダプター用のこのプログラミング モデルを示します。
コネクト スタンバイ デバイス
IoT コマンドのシナリオには、アクティブでない低電力アイドル状態のコネクト スタンバイ デバイスが含まれる場合があります。 モバイル ショート メッセージ サービス (SMS) などのメカニズムを使用すると、スリープ解除シグナルを送信して、これらのデバイスを完全に動作可能な状態に切り替えることができます。
- アプリケーションは、ServiceClient API を使用してコマンドをデバイスに送信します。 ServiceClient の 1 つのインスタンスが、複数のデバイスに対してメッセージを送信し、メソッドを呼び出すことができます。
- また、アプリケーションは、モバイル プロバイダーの SMS ゲートウェイを使用して、スタンバイ デバイスに SMS スリープ解除呼び出しを送信します。
- スリープ解除時に、スタンバイ デバイスは DeviceClient API を使用して IoT Hub に接続し、コマンドを受信します。 DeviceClient の 1 つのインスタンスが、IoT Hub に接続された 1 つのデバイスを表します。
ダイレクト メソッドを使用してデバイスの接続状態を確認する
SMS ゲートウェイを介した不要なスリープ解除メッセージの送信にはコストがかかります。 実際のコマンドをデバイスに送信する前に、接続とメソッドのタイムアウトを使用して、デバイスが接続されているかどうかを確認し、必要な場合はスリープ解除を送信します。
TimeSpan connTimeOut = FromSeconds(0); // Period to wait for device to connect.
TimeSpan funcTimeOut = FromSeconds(30); // Period to wait for method to execute.
while (true) {
// Send the command via direct method. Initially use a timeout of zero
// for the connection, which determines whether the device is connected to
// IoT Hub or needs an SMS wakeup sent to it.
var method = new CloudToDeviceMethod("RemoteCommand", funcTimeOut, connTimeOut);
methodInvocation1.SetPayloadJson(CommandPayload);
var response = await serviceClient.InvokeDeviceMethodAsync(deviceId, method);
// [DeviceNotConnected] represents a return value from the CloudToDeviceMethod
// method. That method is not implemented in this sample.
if (response == [DeviceNotConnected] && connTimeOut == 0) {
// The device is not currently connected and needs an SMS wakeup. This
// device should wake up within a period of < 30 seconds. Send the wakeup
// and retry the method request with a 30 second timeout on waiting for
// the device to connect.
connTimeOut = FromSeconds(30); // Set a 30 second connection timeout.
SendAsyncSMSWakeUpToDevice(); // Send SMS wakeup through mobile gateway.
continue; // Retry with new connection timeout.
} else {
// The method either succeeded or failed.
ActOnMethodResult(var);
break;
}
}
接続を確認するだけの場合は、接続タイムアウト ゼロの空のメソッドを使用して、単純な ping を実装します。 次に例を示します。
var method = new CloudToDeviceMethod("Ping", 0, 0);
共同作成者
この記事は、Microsoft によって保守されています。 当初の寄稿者は以下のとおりです。
プリンシパル作成者:
- ジェイソン・ワズワース | プリンシパル ソフトウェア エンジニア
次の手順
- 「cloud-to-device 通信に関するガイダンス」は、cloud-to-device メッセージまたはダイレクト メソッドの使用に関するシナリオ ベースのガイダンスです。