Sintassi query per il routing dei messaggi di hub IoT

Il routing dei messaggi consente agli utenti di instradare diversi tipi di dati, inclusi i messaggi di telemetria del dispositivo, gli eventi del ciclo di vita del dispositivo e gli eventi di modifica dei dispositivi gemelli a vari endpoint. È inoltre possibile applicare query complesse per ai dati prima del routing in modo da ricevere i dati rilevanti. Questo articolo descrive il linguaggio di query per il routing dei messaggi dell'hub IoT e indica alcuni modelli di query comuni.

Nota

Alcune delle funzionalità indicate in questo articolo, come la messaggistica da cloud a dispositivo, i dispositivi gemelli e la gestione dei dispositivi, sono disponibili solo nel livello Standard dell'hub IoT. Per altre informazioni sui livelli di hub IoT di base e standard/gratuiti, vedere Scegliere il livello di hub IoT appropriato per la soluzione.

Il routing dei messaggi consente di eseguire query sulle proprietà dei messaggi e sul corpo del messaggio, nonché sui tag e sulle proprietà del dispositivo gemello. Se il corpo del messaggio non è in formato JSON, il routing dei messaggi può comunque instradare il messaggio, ma le query non possono essere applicate al corpo del messaggio. Le query vengono descritte come espressioni booleane in cui, se true, la query ha esito positivo e instrada tutti i dati in ingresso; in caso contrario, la query ha esito negativo e i dati in ingresso non vengono indirizzati. Se l'espressione restituisce un valore null o non definito, viene considerato come valore false booleano e genera un errore nei log delle risorse hub IoT route. La sintassi di query deve essere corretta per la route per essere salvata e valutata.

Eseguire query in base alle proprietà del messaggio

hub IoT definisce un formato comune per tutta la messaggistica da dispositivo a cloud per l'interoperabilità tra protocolli. hub IoT presuppone la rappresentazione JSON seguente del messaggio. Le proprietà di sistema vengono aggiunte per tutti gli utenti e identificano il contenuto del messaggio. Gli utenti possono aggiungere al messaggio le proprietà dell'applicazione in modo selettivo. È consigliabile usare nomi di proprietà univoci perché hub IoT messaggistica da dispositivo a cloud non è distinzione tra maiuscole e minuscole. Ad esempio, se si hanno più proprietà con lo stesso nome, l'hub IoT invierà solo una delle proprietà.

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

Proprietà di sistema

Le proprietà di sistema consentono di identificare il contenuto e l'origine dei messaggi, alcuni dei quali sono descritti nella tabella seguente:

Proprietà Type Descrizione
contentType string L'utente specifica il tipo di contenuto del messaggio. Per consentire la query sul corpo del messaggio, questo valore deve essere impostato su application/JSON.
contentEncoding string L'utente specifica il tipo di codifica del messaggio. Se la proprietà contentType è impostata su application/JSON, i valori consentiti sono UTF-8, UTF-16e UTF-32.
iothub-connection-device-id string Questo valore viene impostato dall'hub IoT e identifica l'ID del dispositivo. Per la query, usare $connectionDeviceId.
iothub-connection-module-id string Questo valore viene impostato da hub IoT e identifica l'ID del modulo perimetrale. Per la query, usare $connectionModuleId.
iothub-enqueuedtime string Questo valore viene impostato dall'hub IoT e rappresenta l'ora effettiva di inserimento in coda del messaggio in UTC. Per la query, usare $enqueuedTime.
dt-dataschema string Questo valore viene impostato da hub IoT nei messaggi da dispositivo a cloud. Contiene l'ID modello di dispositivo impostato nella connessione del dispositivo. Per la query, usare $dt-dataschema.
dt-subject string Nome del componente che invia i messaggi da dispositivo a cloud. Per la query, usare $dt-subject.

Per altre informazioni sulle altre proprietà di sistema disponibili, vedere Creare e leggere hub IoT messaggi.

Proprietà dell'applicazione

Le proprietà dell'applicazione sono stringhe definite dall'utente che è possibile aggiungere al messaggio. Questi campi sono facoltativi.

Espressioni di query sulle proprietà del messaggio

Una query sulle proprietà del $ sistema dei messaggi deve essere preceduta dal simbolo. Le query sulle proprietà dell'applicazione vengono accessibili con il $nome e non devono essere precedute dal simbolo. Se un nome della proprietà dell'applicazione inizia con $, hub IoT prima cercarlo nelle proprietà di sistema e, se non viene trovato, cercarlo nelle proprietà dell'applicazione. Negli esempi seguenti viene illustrato come eseguire query sulle proprietà di sistema e sulle proprietà dell'applicazione.

Per eseguire query sul contenuto della proprietà di sistemaEncoding:

$contentEncoding = 'UTF-8'

Per eseguire query sul percorso di elaborazione delle proprietà dell'applicazione:

processingPath = 'hot'

Per combinare queste query, è possibile usare funzioni ed espressioni booleane:

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

Un elenco completo di operatori e funzioni supportati viene fornito nella sezione espressioni e condizioni di hub IoT linguaggio di query per dispositivi e moduli gemelli, processi e routing dei messaggi.

Query basata sul corpo del messaggio

Per abilitare la query su un corpo del messaggio, il messaggio deve essere in un formato JSON e codificato in UTF-8, UTF-16 o UTF-32. La contentType proprietà di sistema deve essere application/JSON. La contentEncoding proprietà di sistema deve essere uno dei valori di codifica UTF supportati da tale proprietà di sistema. Se queste proprietà di sistema non sono specificate, hub IoT non valuterà l'espressione di query nel corpo del messaggio.

Nell'esempio JavaScript seguente viene illustrato come creare un messaggio con un corpo JSON formato e codificato correttamente:

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

Per un esempio di codifica dei messaggi in C#, vedere HubRoutingSample fornito in Microsoft Azure IoT SDK per .NET. Questo esempio è lo stesso usato nell'esercitazione sul routing dei messaggi. Il file Program.cs include anche un metodo denominato ReadOneRowFromFile, che legge uno dei file codificati, lo decodifica e lo scrive come ASCII in modo da poterlo leggere.

Espressioni di query del corpo del messaggio

Una query su un corpo del messaggio deve essere preceduta da $body. Nell'espressione di query è possibile usare un riferimento al corpo, un riferimento a una matrice del corpo o riferimenti multipli al corpo. L'espressione di query può anche combinare un riferimento al corpo con un riferimento alle proprietà del sistema di messaggi o a un riferimento alle proprietà dell'applicazione di messaggi. Ad esempio, gli esempi seguenti sono tutte espressioni di query valide:

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

È possibile eseguire query e funzioni solo sulle proprietà nel riferimento al corpo. Non è possibile eseguire query o funzioni sull'intero riferimento al corpo. Ad esempio, la query seguente non è supportata e restituisce undefined:

$body[0] = 'Feb'

Per filtrare un payload di notifica gemello in base a ciò che è stato modificato, eseguire la query nel corpo del messaggio. Ad esempio, per filtrare quando è presente una modifica sendFrequency di proprietà desiderata e il valore è maggiore di 10:

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

Per filtrare i messaggi che contengono una modifica della proprietà, indipendentemente dal valore della proprietà, è possibile usare la is_defined() funzione (quando il valore è un tipo primitivo):

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

Query basata su dispositivo o modulo gemello

Il routing dei messaggi consente di eseguire query su tag e proprietà gemelli del dispositivo gemello del dispositivogemello , ovvero oggetti JSON. L'esempio seguente illustra un dispositivo gemello con tag e proprietà:

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

Nota

I moduli non ereditano tag gemelli dai propri dispositivi corrispondenti. Query gemelle per i messaggi provenienti da moduli di dispositivo ,ad esempio da moduli di IoT Edge, query sul modulo gemello e non sul dispositivo gemello corrispondente.

Espressioni di query gemelle

Una query su un dispositivo gemello o un modulo gemello deve essere preceduta da $twin. L'espressione di query può anche combinare un riferimento a un tag gemello o a un riferimento alla proprietà del corpo, a un riferimento alle proprietà del sistema di messaggi o a un riferimento alle proprietà dell'applicazione di messaggio. È consigliabile usare nomi univoci in tag e proprietà perché la query non è distinzione tra maiuscole e minuscole. Questa raccomandazione si applica sia ai dispositivi gemelli che ai gemelli del modulo. È anche consigliabile evitare di usare twin, $twin, bodyo $body come nomi delle proprietà. Ad esempio, gli esempi seguenti sono tutte espressioni di query valide:

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

Limitazioni

Il routing delle query non supporta l'uso di spazi vuoti o di uno dei caratteri seguenti nei nomi delle proprietà, nel percorso del corpo del messaggio o nel percorso del dispositivo/modulo gemello: ()<>@,;:\"/?={}.

Passaggi successivi