Syntaxe des requêtes pour le routage des messages IoT Hub

Le routage de messages permet aux utilisateurs d’acheminer différents types de données (notamment des messages de télémétrie des appareils, des événements de cycle de vie des appareils et des événements de modification des jumeaux d’appareil) vers différents points de terminaison. Vous pouvez également appliquer des requêtes élaborées à ces données avant de les router, afin de recevoir les données qui vous intéressent. Cet article décrit le langage des requêtes du routage de messages IoT Hub, et fournit quelques modèles courants de requête.

Notes

Certaines des fonctionnalités mentionnées dans cet article, comme la messagerie cloud-à-appareil, les jumeaux d’appareil et la gestion des appareils, sont disponibles uniquement dans le niveau Standard d’IoT Hub. Pour plus d’informations sur les niveaux de base et standard/gratuit d’IoT Hub, consultez Choisir le niveau IoT Hub correspondant à votre solution.

Le routage de messages vous permet d’interroger les propriétés et le corps d’un message, ainsi que les étiquettes et les propriétés d’un jumeau d’appareil. Si le corps du message n’est pas écrit au format JSON, le routage des messages peut acheminer le message, mais les requêtes ne sont pas applicables au corps du message. Les requêtes sont décrites comme des expressions booléennes : si leur valeur est true, la requête réussit et achemine toutes les données entrantes ; dans le cas contraire, la requête échoue, et les données entrantes ne sont pas routées. Si l’expression prend la valeur « null » ou une valeur non définie, celle-ci est considérée comme une valeur booléenne « false » et génère une erreur dans les journaux de ressources des itinéraires d’IoT Hub. La syntaxe des requêtes doit être correcte pour que l’itinéraire soit enregistré et évalué.

Requête basée sur les propriétés de message

IoT Hub définit un format commun pour tous les envois de messages appareil-à-cloud à des fins d'interopérabilité entre les protocoles. IoT Hub suppose la représentation JSON suivante du message. Les propriétés système sont ajoutées pour tous les utilisateurs et identifient le contenu du message. Les utilisateurs peuvent ajouter de façon sélective des propriétés de l’application au message. Les messages appareil-à-cloud IoT Hub ne respectant pas la casse, nous recommandons d’utiliser des noms de propriété uniques. Par exemple, si vous avez plusieurs propriétés portant le même nom, IoT Hub n’envoie qu’une seule de ces propriétés.

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

Propriétés système

Les propriétés système permettent d’identifier le contenu et la source des messages, dont certains sont décrits dans le tableau suivant :

Propriété Type Description
contentType string L’utilisateur spécifie le type de contenu du message. Pour autoriser l’interrogation sur le corps du message, cette valeur doit être définie sur application/JSON.
contentEncoding string L’utilisateur spécifie le type d’encodage du message. Si la propriété contentType est définie sur application/JSON, les valeurs autorisées sont UTF-8, UTF-16 et UTF-32.
iothub-connection-device-id string Cette valeur est définie par IoT Hub et identifie l’ID de l’appareil. Pour interroger, utilisez $connectionDeviceId.
iothub-connection-module-id string Cette valeur est définie par IoT Hub et identifie l’ID du module Edge. Pour interroger, utilisez $connectionModuleId.
iothub-enqueuedtime string Cette valeur est définie par IoT Hub et représente l’heure (UTC) réelle de la mise en file d’attente du message. Pour interroger, utilisez $enqueuedTime.
dt-dataschema string Cette valeur est définie par IoT Hub sur les messages appareil-à-cloud. Elle contient l’ID du modèle d’appareil défini dans la connexion de l’appareil. Pour interroger, utilisez $dt-dataschema.
dt-subject string Nom du composant qui envoie les messages appareil-à-cloud. Pour interroger, utilisez $dt-subject.

Pour plus d’informations sur les autres propriétés système disponibles, consultez Création et lecture des messages IoT Hub.

Propriétés de l’application

Les propriétés de l’application sont des chaînes définies par l’utilisateur qui peuvent être ajoutées au message. Ces champs sont facultatifs.

Expressions de requête des propriétés de message

Une requête sur les propriétés système d’un message doit avoir pour préfixe le symbole $. Les requêtes sur les propriétés de l’application sont accessibles par leur nom, qui ne doit pas comporter le préfixe $. Si le nom d’une propriété de l’application commence par $, IoT Hub commence par rechercher ce nom dans les propriétés système. S’il y est introuvable, IoT Hub le cherche ensuite dans les propriétés de l’application. Les exemples suivants montrent comment interroger les propriétés système et les propriétés de l’application.

Pour interroger la propriété système contentEncoding, procédez comme suit :

$contentEncoding = 'UTF-8'

Pour interroger la propriété de l’application processingPath, procédez comme suit :

processingPath = 'hot'

Pour combiner ces requêtes, vous pouvez utiliser des fonctions et des expressions booléennes :

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

La liste complète des opérateurs et fonctions pris en charge figure dans la section Expression et conditions de Langage de requête IoT Hub pour les appareils et les jumeaux de module, les travaux et le routage des messages.

Requête basée sur le corps du message

Pour permettre l’interrogation d’un corps de message, le message doit être au format JSON et encodé en UTF-8, UTF-16 ou UTF-32. La propriété système contentType doit être application/JSON. La propriété système contentEncoding doit être l’une des valeurs d’encodage UTF prises en charge par cette propriété système. Si ces propriétés système ne sont pas spécifiées, IoT Hub n’évalue pas l’expression de requête sur le corps de message.

L’exemple de JavaScript suivant montre comment créer un message avec un corps JSON correctement formé et encodé :

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

Pour obtenir un exemple d’encodage de message en C#, consultez hubRoutingSample fourni dans le kit de développement logiciel (SDK) Microsoft Azure IoT pour .NET. Cet exemple est le même que celui utilisé dans l’article Tutoriel sur le routage des messages : Le fichier Program.cs comporte également une méthode nommée ReadOneRowFromFile, qui lit l’un des fichiers encodés, le décode et le réécrit au format ASCII pour que vous puissiez le lire.

Expressions de requête de corps de message

Une requête sur le corps de message doit avoir pour préfixe $body. Vous pouvez utiliser une référence au corps, une référence au tableau du corps ou plusieurs références au corps dans l’expression de requête. Votre expression de requête peut également combiner une référence au corps avec une référence aux propriétés système du message ou aux propriétés de l’application de message. Par exemple, les exemples suivants constituent tous des expressions de requête valides :

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

Vous pouvez exécuter des requêtes et des fonctions uniquement sur les propriétés dans la référence de corps. Vous ne pouvez pas exécuter de requêtes ou de fonctions sur l’ensemble de la référence de corps. Par exemple, la requête suivante n’est pas prise en charge et renvoie undefined :

$body[0] = 'Feb'

Pour filtrer une charge utile de notification de jumeau numérique sur la base de ce qui a été modifié, exécutez votre requête sur le corps du message. Par exemple, pour filtrer les résultats en cas de modification de la propriété souhaitée sur sendFrequency avec une valeur supérieure à 10, procédez ainsi :

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

Pour filtrer les messages qui contiennent une modification de propriété, quelle que soit la valeur de la propriété, vous pouvez utiliser la fonction is_defined() (quand la valeur est un type primitif) :

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

Requête basée sur un jumeau d’appareil ou de module

Le routage de messages vous permet d’interroger les étiquettes et les propriétés et balises de jumeau d’appareil ou de jumeau de module, qui sont des objets JSON. L’exemple suivant illustre un jumeau d’appareil avec les balises et les propriétés :

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

Notes

Les modules n’héritent pas des étiquettes de jumeau de leurs appareils correspondants. Les requêtes de jumeau relatives aux messages provenant de modules d’appareil (par exemple de modules IoT Edge) portent sur le jumeau de module et non sur le jumeau d’appareil correspondant.

Expressions de requête de jumeau

Une requête établie sur un jumeau d’appareil ou de module doit être précédée de $twin. Votre expression de requête peut également combiner une référence à une étiquette ou à une propriété de jumeau avec une référence au corps, aux propriétés système du message ou aux propriétés de l’application de message. La requête ne respectant pas la casse, nous recommandons d’utiliser des noms uniques dans les balises et les propriétés. Cette recommandation s’applique aux jumeaux d’appareil ainsi qu’aux jumeaux de module. Nous vous conseillons également d’éviter d’utiliser les noms de propriétés twin, $twin, body et $body. Par exemple, les exemples suivants constituent tous des expressions de requête valides :

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

Limites

Les requêtes de routage ne prennent pas en charge l’utilisation d’espaces blancs ou d’un des caractères suivants dans les noms des propriétés, le chemin du corps du message ou le chemin du jumeau d’appareil/module : ()<>@,;:\"/?={}.

Étapes suivantes