IoT Hub メッセージ ルーティングのクエリ構文
メッセージ ルーティングを使用すると、ユーザーは種類の異なるデータ (デバイス テレメトリ メッセージ、デバイス ライフサイクル イベント、デバイス ツイン変更イベントなど) を、さまざまなエンドポイントにルーティングできます。 さらにルーティング前には、お客様にとって重要なデータを受け取れるよう、上記のデータに高度なクエリを適用することもできます。 この記事では、IoT Hub メッセージ ルーティングのクエリ言語について説明するほか、一般的なクエリ パターンをいくつか紹介します。
Note
この記事で言及されている一部の機能 (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}}"
}
}
システム プロパティ
システム プロパティは、メッセージの内容とソースを識別するのに役立ちます。その一部を次の表に示します。
プロパティ | タイプ | 説明 |
---|---|---|
contentType | string | ユーザーはメッセージのコンテンツの種類を指定します。 メッセージ本文に基づいてクエリを実行するには、この値を application/JSON に設定する必要があります。 |
contentEncoding | string | ユーザーはメッセージのエンコードの種類を指定します。 contentType プロパティが application/JSON に設定されている場合に使用できる値は、UTF-8 、UTF-16 、UTF-32 です。 |
iothub-connection-device-id | string | この値は IoT Hub によって設定され、デバイスの ID を示します。 クエリを実行するには、$connectionDeviceId を使用します。 |
iothub-connection-module-id | string | この値は IoT Hub によって設定され、エッジ モジュールの ID を示します。 クエリを実行するには、$connectionModuleId を使用します。 |
iothub-enqueuedtime | string | この値は IoT Hub によって設定されます。この値によって、メッセージがエンキューされた実際の時刻が UTC で表されます。 クエリを実行するには、$enqueuedTime を使用します。 |
dt-dataschema | string | この値は、IoT Hub で、device-to-cloud メッセージに対して設定されます。 デバイス接続で設定されたデバイス モデル ID が含まれます。 クエリを実行するには、$dt-dataschema を使用します。 |
dt-subject | string | device-to-cloud メッセージを送信しているコンポーネントの名前。 クエリを実行するには、$dt-subject を使用します。 |
その他の使用可能なシステム プロパティの詳細については、「IoT Hub メッセージの作成と読み取り」を参照してください。
Application properties
アプリケーション プロパティは、メッセージに追加できるユーザー定義の文字列です。 これらのフィールドは省略可能です。
メッセージ プロパティのクエリ式
メッセージ システム プロパティに基づくクエリには、前に $
記号を付ける必要があります。 アプリケーション プロパティに基づくクエリは、それらの名前を使用してアクセスされるので、前に $
記号を付ける必要がありません。 アプリケーション プロパティ名が $
で始まる場合、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
}
}
}
Note
モジュールは、対応するデバイスからツインのタグを継承しません。 デバイス モジュールから (たとえば、IoT Edge モジュールから) 送信されたメッセージのツイン クエリは、対応するデバイス ツインではなく、モジュール ツインに対して実行されます。
ツイン クエリ式
デバイス ツインまたはモジュール ツインに基づくクエリには、前に $twin
を付ける必要があります。 さらにクエリ式では、ツインのタグまたはプロパティの参照を、本文の参照、メッセージ システム プロパティの参照、メッセージ アプリケーション プロパティの参照と組み合わせることもできます。 クエリでは大文字と小文字が区別されないため、タグとプロパティには一意の名前を使用することをお勧めします。 この推奨事項は、デバイス ツインとモジュール ツインの両方に適用されます。 また、twin
、$twin
、body
、$body
をプロパティ名として使用しないようにすることをお勧めします。 たとえば、以下の例はすべて有効なクエリ式です。
$twin.properties.desired.telemetryConfig.sendFrequency = '5m'
$body.Weather.Temperature = 50 AND $twin.properties.desired.telemetryConfig.sendFrequency = '5m'
$twin.tags.deploymentLocation.floor = 1
制限事項
ルーティング クエリでは、プロパティ名、メッセージ本文パス、またはデバイス/モジュール ツイン パスで空白または次の文字を使用することはできません: ()<>@,;:\"/?={}
。
次のステップ
- メッセージ ルーティングについて確認する。
- メッセージ ルーティングのチュートリアルを試す。