IoT Hub-frågesyntaxen för meddelandedirigering

Meddelanderoutning gör det möjligt för användare att dirigera olika datatyper, inklusive enhetstelemetrimeddelanden, enhetslivscykelhändelser och enhetstvillingens ändringshändelser, till olika slutpunkter. Du kan också tillämpa omfattande frågor på dessa data innan du dirigerar dem för att ta emot de data som är viktiga för dig. Den här artikeln beskriver frågespråket IoT Hub meddelanderoutning och innehåller några vanliga frågemönster.

Anteckning

Några av de funktioner som nämns i den här artikeln, t.ex. moln till enhet-meddelanden, enhetstvillingar och enhetshantering, är bara tillgängliga på IoT Hubs standardnivå. Mer information om nivåerna grundläggande och standard/kostnadsfri IoT Hub finns i Välj rätt IoT Hub nivå för din lösning.

Med meddelanderoutning kan du fråga efter meddelandeegenskaper och meddelandetext samt enhetstvillingtaggar och egenskaper för enhetstvillingar. Om meddelandetexten inte är i JSON-format kan meddelanderoutning fortfarande dirigera meddelandet, men frågor kan inte tillämpas på meddelandetexten. Frågor beskrivs som booleska uttryck där, om det är sant, frågan lyckas och dirigerar alla inkommande data. Annars misslyckas frågan och inkommande data dirigeras inte. Om uttrycket utvärderas till ett null- eller odefinierat värde behandlas det som ett booleskt falskt värde och genererar ett fel i IoT Hub dirigerar resursloggar. Frågesyntaxen måste vara korrekt för att vägen ska sparas och utvärderas.

Fråga baserat på meddelandeegenskaper

IoT Hub definierar ett gemensamt format för alla enhets-till-moln-meddelanden för samverkan mellan protokoll. IoT Hub förutsätter följande JSON-representation av meddelandet. Systemegenskaper läggs till för alla användare och identifierar innehållet i meddelandet. Användare kan selektivt lägga till programegenskaper i meddelandet. Vi rekommenderar att du använder unika egenskapsnamn eftersom IoT Hub meddelanden från enhet till moln inte är skiftlägeskänsliga. Om du till exempel har flera egenskaper med samma namn skickar IoT Hub bara en av egenskaperna.

{ 
  "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}}" 
  } 
} 

Systemegenskaper

Systemegenskaper hjälper dig att identifiera innehållet och källan för meddelandena, av vilka några beskrivs i följande tabell:

Egenskap Typ Description
Contenttype sträng Användaren anger meddelandets innehållstyp. Om du vill tillåta frågor i meddelandetexten ska det här värdet anges till application/JSON.
contentEncoding sträng Användaren anger kodningstypen för meddelandet. Om egenskapen contentType är inställd på application/JSONär UTF-8tillåtna värden , UTF-16, och UTF-32.
iothub-connection-device-id sträng Det här värdet anges av IoT Hub och identifierar enhetens ID. Om du vill fråga använder du $connectionDeviceId.
iothub-connection-module-id sträng Det här värdet anges av IoT Hub och identifierar ID:t för edge-modulen. Om du vill fråga använder du $connectionModuleId.
iothub-enqueuedtime sträng Det här värdet anges av IoT Hub och representerar den faktiska tiden för att ange meddelandet i UTC. Om du vill fråga använder du $enqueuedTime.
dt-dataschema sträng Det här värdet anges av IoT Hub på meddelanden från enhet till moln. Den innehåller enhetsmodell-ID:t som angetts i enhetsanslutningen. Om du vill fråga använder du $dt-dataschema.
dt-subject sträng Namnet på komponenten som skickar meddelanden från enheten till molnet. Om du vill fråga använder du $dt-subject.

Mer information om andra tillgängliga systemegenskaper finns i Skapa och läsa IoT Hub meddelanden.

Egenskaper för program

Programegenskaper är användardefinierade strängar som kan läggas till i meddelandet. De här fälten är valfria.

Frågeuttryck för meddelandeegenskaper

En fråga om egenskaper för meddelandesystemet måste föregås av symbolen $ . Frågor om programegenskaper används med deras namn och bör inte föregås av symbolen $. Om ett programegenskapsnamn börjar med $söker IoT Hub först efter det i systemegenskaperna, och om det inte hittas söker du efter det i programegenskaperna. I följande exempel visas hur du frågar efter systemegenskaper och programegenskaper.

Så här frågar du efter systemegenskapens innehållKodning:

$contentEncoding = 'UTF-8'

Så här frågar du på application property processingPath:

processingPath = 'hot'

Om du vill kombinera dessa frågor kan du använda booleska uttryck och funktioner:

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

En fullständig lista över operatorer och funktioner som stöds finns i avsnittet uttryck och villkor i IoT Hub frågespråk för enhets- och modultvillingar, jobb och meddelanderoutning.

Fråga baserat på meddelandetext

Om du vill aktivera frågor i en meddelandetext ska meddelandet vara i JSON-format och kodas i UTF-8, UTF-16 eller UTF-32. Systemegenskapen contentType måste vara application/JSON. Systemegenskapen contentEncoding måste vara ett av UTF-kodningsvärdena som stöds av den systemegenskapen. Om dessa systemegenskaper inte anges utvärderar IoT Hub inte frågeuttrycket i meddelandetexten.

Följande JavaScript-exempel visar hur du skapar ett meddelande med en korrekt utformad och kodad JSON-brödtext:

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);
});

Ett exempel på meddelandekodning i C#finns i HubRoutingSample som finns i Microsoft Azure IoT SDK för .NET. Det här exemplet är samma som används i självstudien Meddelanderoutning. Filen Program.cs har också en metod med namnet ReadOneRowFromFile, som läser en av de kodade filerna, avkodar den och skriver tillbaka den som ASCII så att du kan läsa den.

Frågeuttryck för meddelandetext

En fråga i en meddelandetext måste vara prefix med $body. Du kan använda en brödtextreferens, en brödtextmatrisreferens eller flera brödtextreferenser i frågeuttrycket. Frågeuttrycket kan också kombinera en brödtextreferens med en referens för meddelandesystemegenskaper eller en referens för egenskaper för meddelandeprogrammet. Följande exempel är till exempel alla giltiga frågeuttryck:

$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'

Du kan bara köra frågor och funktioner på egenskaper i brödtextreferensen. Du kan inte köra frågor eller funktioner på hela brödtextreferensen. Följande fråga stöds till exempel inte och returnerar undefined:

$body[0] = 'Feb'

Om du vill filtrera en nyttolast för tvillingmeddelanden baserat på vad som har ändrats kör du frågan i meddelandetexten. Om du till exempel vill filtrera när en önskad egenskap ändras sendFrequency och värdet är större än 10:

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

Om du vill filtrera meddelanden som innehåller en egenskapsändring, oavsett värdet för egenskapen, kan du använda is_defined() funktionen (när värdet är en primitiv typ):

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

Fråga baserat på enhets- eller modultvilling

Med meddelanderoutning kan du fråga efter taggar och egenskaper för enhetstvillingar eller modultvillingar , som är JSON-objekt. Följande exempel illustrerar en enhetstvilling med taggar och egenskaper:

{
    "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 
        } 
    } 
} 

Anteckning

Moduler ärver inte tvillingtaggar från motsvarande enheter. Tvillingfrågor för meddelanden från enhetsmoduler (till exempel från IoT Edge moduler) frågar mot modultvillingen och inte motsvarande enhetstvilling.

Tvillingfrågeuttryck

En fråga på en enhetstvilling eller modultvilling måste föregås av $twin. Frågeuttrycket kan också kombinera en tvillingtagg eller egenskapsreferens med en brödtextreferens, en referens för meddelandesystemets egenskaper eller en referens för egenskaper för meddelandeprogrammet. Vi rekommenderar att du använder unika namn i taggar och egenskaper eftersom frågan inte är skiftlägeskänslig. Den här rekommendationen gäller både enhetstvillingar och modultvillingar. Vi rekommenderar också att du undviker att använda twin, $twin, bodyeller $body som egenskapsnamn. Följande exempel är till exempel alla giltiga frågeuttryck:

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

Begränsningar

Routningsfrågor stöder inte användning av blanksteg eller något av följande tecken i egenskapsnamn, sökvägen till meddelandetexten eller enhets-/modultvillingens sökväg: ()<>@,;:\"/?={}.

Nästa steg