IoT 中樞訊息路由查詢語法
訊息路由可讓使用者將不同的資料類型路由傳送至各種端點,包括裝置遙測訊息、裝置生命週期事件和裝置對應項變更事件。 您也可以在路由此資料之前先套用豐富查詢,以僅接收對您最重要的資料。 此文會說明 IoT 中樞訊息路由查詢語言,並提供一些常見的查詢模式。
注意
本文中提及的某些功能 (例如雲端對裝置傳訊、裝置對應項和裝置管理) 僅適用於 IoT 中樞的標準層。 如需基本和標準/免費IoT 中樞層的詳細資訊,請參閱為您的解決方案選擇正確的IoT 中樞層。
訊息路由可讓您對訊息屬性和訊息本文,以及裝置對應項標記和裝置對應項屬性進行查詢。 如果訊息本文不是 JSON 格式,訊息路由仍然可以路由傳送訊息,但無法將查詢套用至訊息本文。 查詢會描述為布林運算式,如果為 true,則查詢會成功並路由傳送所有傳入資料;否則,查詢會失敗,而且不會路由傳送傳入資料。 如果運算式評估為 null 或未定義的值,則會將其視為布林值 false 值,並在IoT 中樞路由資源記錄中產生錯誤。 查詢語法必須正確以儲存並評估路由。
根據訊息屬性進行查詢
IoT 中樞會針對所有裝置到雲端訊息定義常見格式,以在通訊協定之間提供互通性。 IoT 中樞會針對訊息假設下列 JSON 表示法。 系統會針對訊息的所有使用者和身分識別內容新增系統屬性。 使用者可以選擇性地將應用程式屬性新增至訊息。 建議您使用唯一的屬性名稱,因為IoT 中樞裝置到雲端傳訊不會區分大小寫。 例如,如果您有多個具相同名稱的屬性,IoT 中樞將只會傳送其中一個屬性。
{
"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 | 字串 | 使用者會指定訊息的內容類型。 若要允許對訊息本文進行查詢,此值應該設定為 application/JSON 。 |
contentEncoding | 字串 | 使用者會指定訊息的編碼類型。 如果 contentType 屬性設定為 application/JSON ,則允許的值為 UTF-8 、 UTF-16 和 UTF-32 。 |
iothub-connection-device-id | 字串 | 此值是由 IoT 中樞設定,並能識別裝置的識別碼。 若要查詢,請使用 $connectionDeviceId 。 |
iothub-connection-module-id | 字串 | 此值由 IoT 中樞設定,且能識別邊緣模組的識別碼。 若要查詢,請使用 $connectionModuleId 。 |
iothub-enqueuedtime | 字串 | 此值是由 IoT 中樞設定,並代表將訊息加入佇列的實際時間 (以 UTC 表示)。 若要查詢,請使用 $enqueuedTime 。 |
dt-dataschema | 字串 | 此值由 IoT 中樞在裝置到雲端訊息上所設定。 其包含裝置連線中所設定的裝置模型識別碼。 若要查詢,請使用 $dt-dataschema 。 |
dt-subject | 字串 | 傳送裝置到雲端訊息的元件名稱。 若要查詢,請使用 $dt-subject 。 |
如需其他可用系統屬性的詳細資訊,請參閱建立和讀取IoT 中樞訊息。
應用程式屬性
應用程式屬性為可新增至訊息的使用者定義字串。 這些欄位為選擇性。
訊息屬性查詢運算式
訊息系統屬性的查詢前面必須加上 $
符號。 應用程式屬性的查詢會以其名稱存取,且不應加上符號的 $
前置詞。 如果應用程式屬性名稱開頭為 $
,則IoT 中樞先在系統屬性中搜尋它,如果找不到,則會在應用程式屬性中搜尋它。 下列範例示範如何查詢系統屬性和應用程式屬性。
若要查詢系統屬性 contentEncoding:
$contentEncoding = 'UTF-8'
若要查詢應用程式屬性 processingPath:
processingPath = 'hot'
若要結合這些查詢,您可以使用布林運算式和函式:
$contentEncoding = 'UTF-8' AND processingPath = 'hot'
在裝置和模組對應項、作業和訊息路由IoT 中樞查詢語言的運算式和條件一節中提供了支援運算子和函式的完整清單。
根據訊息本文進行查詢
若要啟用訊息本文的查詢,訊息應採用 JSON 格式,並以 UTF-8、UTF-16 或 UTF-32 編碼。 contentType
系統屬性必須是 application/JSON
。 contentEncoding
系統屬性必須是該系統屬性所支援的其中一個 UTF 編碼值。 如果未指定這些系統屬性,IoT 中樞將不會評估訊息本文上的查詢運算式。
下列 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
的方法,它會讀取其中一個編碼的檔案、解碼,並將它寫回 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
、 $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
限制
路由查詢不支援在屬性名稱、訊息內文路徑或裝置/模組對應項路徑中使用空白字元或下列任何字元:()<>@,;:\"/?={}
。