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 Basic e Standard/Gratuito dell'hub IoT, vedere Scegliere il livello appropriato dell'hub IoT 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 instradati. Se l'espressione restituisce un valore null o non definito, viene considerato come valore booleano false e genera un errore nei log delle risorse dell'hub IoT. La sintassi di query deve essere corretta per la route per essere salvata e valutata.

Query basata sulle proprietà del messaggio

L'hub IoT definisce un formato comune per tutta la messaggistica da dispositivo a cloud per l'interoperabilità tra i protocolli. L’hub IoT presuppone la seguente rappresentazione JSON 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 delle proprietà univoci, in quanto l'hub IoT di messaggistica da dispositivo a cloud non fa distinzione tra maiuscole e minuscole. Ad esempio, se si hanno più proprietà con lo stesso nome, l'hub IoT invia 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 l'esecuzione di 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-16 e 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 dall'hub IoT e identifica l'ID del dispositivo. 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 è impostato dall'hub IoT sui 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 i messaggi dell'hub IoT.

Proprietà dell'applicazione

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

Espressioni di query delle proprietà del messaggio

Una query sulle proprietà di sistema del messaggio richiede come prefisso il simbolo $. Viene eseguito l'accesso alle query sulle proprietà dell'applicazione con il relativo nome e non devono essere precedute dal simbolo $. Se il nome di una proprietà dell'applicazione inizia con $, l'hub IoT cerca prima di tutto nelle proprietà di sistema e, se non viene trovato, lo cerca nelle proprietà dell'applicazione. Negli esempi seguenti viene illustrato come eseguire query sulle proprietà di sistema e sulle proprietà dell'applicazione.

Per eseguire una query su una proprietà di sistema contentEncoding:

$contentEncoding = 'UTF-8'

Per eseguire una query una proprietà di applicazione processingPath:

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 è disponibile nella sezione Espressione e condizioni di Linguaggio di query dell'hub IoT per dispositivi e moduli gemelli, processi e routing di messaggi.

Query basata sul corpo del messaggio

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

L'esempio JavaScript seguente mostra come creare un messaggio con un corpo JSON correttamente formattato e codificato:

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 Routing 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 nel corpo di un 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 dei messaggi o un riferimento alle proprietà dell'applicazione del messaggio. Ad esempio, gli esempi di seguito riportano tutte le 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 quanto modificato, eseguire la query sul corpo del messaggio. Ad esempio, per filtrare quando è presente una modifica sendFrequency della 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 funzione is_defined() (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 dispositivo gemello o modulo gemello, che sono 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 dispositivi corrispondenti. Query dei dispositivi gemelli per i messaggi provenienti da moduli del dispositivo (ad esempio, dai moduli IoT Edge) su un modulo gemello e non sul dispositivo gemello corrispondente.

Espressioni query gemelli

Una query su un dispositivo gemello o un modulo gemello deve essere preceduta da $twin. L'espressione di query può anche combinare un tag gemello o un riferimento a una proprietà con un riferimento al corpo,un riferimento alle proprietà del sistema di messaggi o un riferimento alle proprietà dell'applicazione del messaggio. È consigliabile usare nomi univoci per tag e proprietà, poiché la query non fa distinzione tra maiuscole e minuscole. Questa raccomandazione si applica sia ai dispositivi gemelli che ai moduli gemelli. È anche consigliabile evitare di usare twin, $twin, body o $body come nomi di proprietà. Ad esempio, gli esempi di seguito riportano tutte le 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 

Limiti

Le query di routing non supportano 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