次の方法で共有


IoT Hub メッセージ ルーティングのクエリ構文

メッセージ ルーティングを使用すると、ユーザーは種類の異なるデータ (デバイス テレメトリ メッセージ、デバイス ライフサイクル イベント、デバイス ツイン変更イベントなど) を、さまざまなエンドポイントにルーティングできます。 さらにルーティング前には、お客様にとって重要なデータを受け取れるよう、上記のデータに高度なクエリを適用することもできます。 この記事では、IoT Hub メッセージ ルーティングのクエリ言語について説明するほか、一般的なクエリ パターンをいくつか紹介します。

この記事で言及されている一部の機能 (cloud-to-device メッセージング、デバイス ツイン、デバイス管理など) は、IoT Hub の Standard レベルだけで使用することができます。 Basic および Standard/Free IoT Hub レベルの詳細については、「ソリューションに適した IoT Hub レベルとサイズを選択する」を参照してください。

メッセージ ルーティングでは、メッセージ プロパティとメッセージ本文に基づいてクエリを実行できるほか、デバイス ツインのタグとプロパティに基づいてクエリを実行することもできます。 メッセージ本文が JSON 形式でない場合でも、メッセージ ルーティングでメッセージをルーティングできますが、メッセージ本文にクエリを適用することはできません。 クエリはブール式として記述されます。true の場合、クエリは成功し、すべての受信データがルーティングされます。それ以外の場合、クエリは失敗し、受信データはルーティングされません。 式が null または未定義の値に評価された場合、式はブール false 値として扱われ、IoT Hub ルーティング リソース ログにエラーが生成されます。 ルートが保存および評価されるようにするには、正しいクエリ構文を使用する必要があります。

メッセージ プロパティに基づいたクエリ

IoT Hub では、各種プロトコルにおける相互運用性を確保するためにすべての device-to-cloud メッセージ用の共通形式が定義されています。 IoT Hub では、次の JSON 表現のメッセージが想定されます。 すべてのユーザーのシステム プロパティが追加され、メッセージのコンテンツが特定されます。 ユーザーは、アプリケーション プロパティをメッセージに選択的に追加できます。 IoT Hub の device-to-cloud メッセージでは大文字と小文字が区別されないため、一意のプロパティ名を使用することをお勧めします。 たとえば、名前が同じプロパティが複数ある場合は、いずれか 1 つのプロパティのみが IoT Hub によって送信されます。

{ 
  "message": { 
    "systemProperties": { 
      "contentType": "application/json", 
      "contentEncoding": "UTF-8", 
      "iothub-message-source": "deviceMessages", 
      "iothub-enqueuedtime": "2017-05-08T18:55:31.8514657Z" 
    }, 
    "appProperties": { 
      "processingPath": "{cold | warm | hot}", 
      "verbose": "{true, false}", 
      "severity": 1-5, 
      "testDevice": "{true | false}" 
    }, 
    "body": "{\"Weather\":{\"Temperature\":50}}" 
  } 
} 

システム プロパティ

システム プロパティは、メッセージの内容とソースを識別するのに役立ちます。その一部を次の表に示します。

プロパティ 種類 説明
コンテンツタイプ 文字列 ユーザーはメッセージのコンテンツの種類を指定します。 メッセージ本文に基づいてクエリを実行するには、この値を application/JSON に設定する必要があります。
コンテンツエンコーディング 文字列 ユーザーはメッセージのエンコードの種類を指定します。 contentType プロパティが application/JSON に設定されている場合に使用できる値は、UTF-8UTF-16UTF-32 です。
iothub-コネクション-デバイス-ID 文字列 IoT Hub は、デバイスの ID を識別するこの値を設定します。 クエリを実行するには、$connectionDeviceId を使用します。
iothub-connection-module-id 文字列 IoT Hub は、エッジ モジュールの ID を識別するこの値を設定します。 クエリを実行するには、$connectionModuleId を使用します。
iothub-enqueuedtime 文字列 IoT Hub は、この値を設定します。これは、メッセージをキューに入れる実際の時刻を UTC で表します。 クエリを実行するには、$enqueuedTime を使用します。
dt-dataschema 文字列 IoT Hub は、デバイスからクラウドへのメッセージにこの値を設定します。 デバイス接続で設定されたデバイス モデル ID が含まれます。 クエリを実行するには、$dt-dataschema を使用します。
dt-subject 文字列 device-to-cloud メッセージを送信しているコンポーネントの名前。 クエリを実行するには、$dt-subject を使用します。

その他の使用可能なシステム プロパティの詳細については、「IoT Hub メッセージの作成と読み取り」を参照してください。

アプリケーション プロパティ

アプリケーション プロパティは、メッセージに追加できるユーザー定義の文字列です。 これらのフィールドは省略可能です。

メッセージ プロパティのクエリ式

メッセージ システム プロパティに基づくクエリには、前に $ 記号を付ける必要があります。 アプリケーション プロパティに基づくクエリは、それらの名前を使用してアクセスされるので、前に $ 記号を付ける必要がありません。 アプリケーション プロパティ名が $ で始まる場合、IoT Hub によって、まずシステム プロパティ内でその名前が検索されます。見つからない場合は、次にアプリケーション プロパティ内で検索されます。 次の例は、システム プロパティとアプリケーション プロパティに対してクエリを実行する方法を示しています。

システム プロパティ contentEncoding に基づいてクエリを実行するには、次を行います。

$contentEncoding = 'UTF-8'

アプリケーション プロパティ processingPath に基づいてクエリを実行するには、次を行います。

processingPath = 'hot'

これらのクエリを結合するには、ブール式と関数を使用することができます。

$contentEncoding = 'UTF-8' AND processingPath = 'hot'

サポートされている演算子と関数の完全な一覧は、デバイス ツイン、モジュール ツイン、ジョブ、メッセージ ルーティングに関する IoT Hub クエリ言語の式と条件に関するセクションで提供されています。

メッセージ本文に基づいたクエリ

メッセージ本文に基づいてクエリを実行するには、メッセージが UTF-8、UTF-16、UTF-32 のいずれかでエンコードされた JSON 形式である必要があります。 contentType システム プロパティは application/JSON である必要があります。 contentEncoding システム プロパティは、そのシステム プロパティでサポートされている UTF エンコード値のいずれかである必要があります。 これらのシステム プロパティが指定されていない場合、IoT Hub は、メッセージ本文のクエリ式を評価しません。

次の JavaScript 例では、正しい形式でエンコードされた JSON 本文を持つメッセージを作成する方法を示します。

var messageBody = JSON.stringify(Object.assign({}, {
    "Weather": {
        "Temperature": 50,
        "Time": "2017-03-09T00:00:00.000Z",
        "PrevTemperatures": [
            20,
            30,
            40
        ],
        "IsEnabled": true,
        "Location": {
            "Street": "One Microsoft Way",
            "City": "Redmond",
            "State": "WA"
        },
        "HistoricalData": [
            {
                "Month": "Feb",
                "Temperature": 40
            },
            {
                "Month": "Jan",
                "Temperature": 30
            }
        ]
    }
}));

// Encode message body using UTF-8  
var messageBytes = Buffer.from(messageBody, "utf8");

var message = new Message(messageBytes);

// Set message body type and content encoding 
message.contentEncoding = "utf-8";
message.contentType = "application/json";

// Add other custom application properties   
message.properties.add("Status", "Active");

deviceClient.sendEvent(message, (err, res) => {
    if (err) console.log('error: ' + err.toString());
    if (res) console.log('status: ' + res.constructor.name);
});

C# のメッセージ エンコード サンプルについては、Microsoft Azure IoT SDK for .NET で提供されている HubRoutingSample を参照してください。 このサンプルは、 メッセージ ルーティング チュートリアルで使用されるサンプルと同じです。 Program.cs ファイルには、ReadOneRowFromFile という名前のメソッドもあります。これは、エンコードされたファイルの 1 つを読み取り、デコードし、読み取ることができるように ASCII として書き戻します。

メッセージ本文のクエリ式

メッセージ本文に基づくクエリには、前に $body を付ける必要があります。 クエリ式では、本文の参照、本文配列の参照、または複数の本文の参照を使用できます。 さらにクエリ式では、本文の参照を、メッセージ システム プロパティの参照またはメッセージ アプリケーション プロパティの参照と組み合わせることもできます。 たとえば、以下の例はすべて有効なクエリ式です。

$body.Weather.HistoricalData[0].Month = 'Feb' 
$body.Weather.Temperature = 50 AND $body.Weather.IsEnabled 
length($body.Weather.Location.State) = 2 
$body.Weather.Temperature = 50 AND processingPath = 'hot'

クエリおよび関数は、本文参照のプロパティでのみ実行できます。 本文参照全体でクエリまたは関数を実行することはできません。 たとえば、次のクエリはサポートされて "おらず"、 が返されます。undefined

$body[0] = 'Feb'

ツイン通知のペイロードを変更内容に基づいてフィルター処理するには、メッセージ本文に対して次のクエリを実行します。 たとえば、sendFrequency で必要なプロパティの変更があり、値が 10 より大きい場合にフィルター処理するには、次のようにします。

$body.properties.desired.telemetryConfig.sendFrequency > 10

プロパティ変更を含むメッセージをフィルター処理するには、プロパティの値に関係なく、is_defined() 関数を使用できます (値がプリミティブ型である場合)。

is_defined($body.properties.desired.telemetryConfig.sendFrequency)

デバイスまたはモジュール ツインに基づいたクエリ

メッセージ ルーティングでは、JSON オブジェクトであるデバイス ツインまたはモジュール ツインのタグとプロパティに対してクエリを実行できます。 次の例では、デバイス ツインを、タグとプロパティと共に示しています。

{
    "tags": { 
        "deploymentLocation": { 
            "building": "43", 
            "floor": "1" 
        } 
    }, 
    "properties": { 
        "desired": { 
            "telemetryConfig": { 
                "sendFrequency": "5m" 
            }, 
            "$metadata" : {...}, 
            "$version": 1 
        }, 
        "reported": { 
            "telemetryConfig": { 
                "sendFrequency": "5m", 
                "status": "success" 
            },
            "batteryLevel": 55, 
            "$metadata" : {...}, 
            "$version": 4 
        } 
    } 
} 

モジュールは、対応するデバイスからツイン タグを継承しません。 デバイス モジュールから (たとえば、IoT Edge モジュールから) 送信されたメッセージのツイン クエリは、対応するデバイス ツインではなく、モジュール ツインに対して実行されます。

ツイン クエリ式

デバイス ツインまたはモジュール ツインに基づくクエリには、前に $twin を付ける必要があります。 さらにクエリ式では、ツインのタグまたはプロパティの参照を、本文の参照、メッセージ システム プロパティの参照、メッセージ アプリケーション プロパティの参照と組み合わせることもできます。 クエリでは大文字と小文字が区別されないため、タグとプロパティには一意の名前を使用することをお勧めします。 この推奨事項は、デバイス ツインとモジュール ツインの両方に適用されます。 また、twin$twinbody$body をプロパティ名として使用しないようにすることをお勧めします。 たとえば、以下の例はすべて有効なクエリ式です。

$twin.properties.desired.telemetryConfig.sendFrequency = '5m'
$body.Weather.Temperature = 50 AND $twin.properties.desired.telemetryConfig.sendFrequency = '5m'
$twin.tags.deploymentLocation.floor = 1 

制限事項

ルーティング クエリでは、プロパティ名、メッセージ本文パス、またはデバイス/モジュール ツイン パスで空白または次の文字を使用することはできません: ()<>@,;:\"/?={}

次のステップ