Sintaxis de las consultas de enrutamiento de mensajes de IoT Hub

El enrutamiento de mensajes permite a los usuarios enrutar diferentes tipos de datos, incluidos mensajes de telemetría de dispositivos, eventos de ciclo de vida de dispositivos y eventos de cambio de dispositivos gemelos a varios puntos de conexión. También puede aplicar consultas enriquecidas a estos datos antes de enrutarlos para recibir los datos que le interesan. En este artículo se describe el lenguaje de consulta de enrutamiento de mensajes de IoT Hub, y se proporcionan algunos patrones de consulta comunes.

Nota

Algunas de las características que se mencionan en este artículo, como la mensajería de la nube al dispositivo, los dispositivos gemelos y la administración de dispositivos, solo están disponibles en el nivel estándar de IoT Hub. Para obtener más información sobre los niveles Básico y Estándar o Gratis de IoT Hub, consulte Elección del nivel adecuado de IoT Hub para la solución.

El enrutamiento de mensajes le permite realizar consultas sobre las propiedades de los mensajes y el cuerpo del mensaje, así como las etiquetas del dispositivo gemelo y las propiedades del dispositivo gemelo. Si el cuerpo del mensaje no está en formato JSON, el enrutamiento de mensajes todavía puede enrutar el mensaje, pero no se pueden aplicar consultas al cuerpo del mensaje. Las consultas se describen como expresiones booleanas donde, si es true, la consulta se realiza correctamente y enruta todos los datos de entrada; de lo contrario, se produce un error en la consulta y no se enrutan los datos de entrada. Si la expresión se evalúa como nula o como un valor indefinido, se trata como un valor booleano false y genera un error en los registros de recursos de rutas de IoT Hub. La sintaxis de consulta debe ser correcta para que la ruta se guarde y evalúe.

Consulta basada en las propiedades del mensaje

IoT Hub define un formato común para todos los mensajes del dispositivo a la nube a fin de generar interoperabilidad entre protocolos. IoT Hub da por supuesto la siguiente representación JSON del mensaje. Las propiedades del sistema se agregan para todos los usuarios e identifican el contenido del mensaje. Los usuarios pueden agregar propiedades de aplicación al mensaje de forma selectiva. Se recomienda utilizar nombres de propiedades únicos porque la mensajería del dispositivo a la nube de IoT Hub no distingue mayúsculas de minúsculas. Por ejemplo, si tiene varias propiedades con el mismo nombre, IoT Hub solo enviará una de las propiedades.

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

Propiedades del sistema

Las propiedades del sistema ayudan a identificar el contenido y el origen de los mensajes, algunos de los cuales se describen en la tabla siguiente.

Propiedad Tipo Descripción
contentType string El usuario especifica el tipo de contenido del mensaje. Para permitir la consulta en el cuerpo del mensaje, este valor debe establecerse en application/JSON.
contentEncoding string El usuario especifica el tipo de codificación del mensaje. Si la propiedad contentType se establece en application/JSON, los valores permitidos son UTF-8, UTF-16 y UTF-32.
iothub-connection-device-id string Este valor se establece mediante IoT Hub e identifica el identificador del dispositivo. Para realizar la consulta, use $connectionDeviceId.
iothub-connection-module-id string Este valor se establece mediante IoT Hub e identifica el identificador del módulo perimetral. Para realizar la consulta, use $connectionModuleId.
iothub-enqueuedtime string Este valor lo establece IoT Hub y representa la hora real en UTC de espera en cola del mensaje. Para realizar la consulta, use $enqueuedTime.
dt-dataschema string IoT Hub establece este valor en mensajes del dispositivo a la nube. Contiene el id. de modelo del dispositivo establecido en la conexión del dispositivo. Para realizar la consulta, use $dt-dataschema.
dt-subject string Nombre del componente que envía los mensajes del dispositivo a la nube. Para realizar la consulta, use $dt-subject.

Para más información sobre las otras propiedades del sistema disponibles, consulte Creación y lectura de mensajes de IoT Hub.

Propiedades de la aplicación

Las propiedades de la aplicación son cadenas definidas por el usuario que se pueden agregar al mensaje. Estos campos son opcionales.

Expresiones de consulta de propiedades de mensaje

Una consulta sobre las propiedades del sistema de mensajes debe tener como prefijo el símbolo $. Las consultas a las propiedades de aplicación se realizan con el nombre y no deben tener como prefijo el símbolo $. Si el nombre de una propiedad de la aplicación comienza por $, IoT Hub la buscará primero en las propiedades del sistema y, si no la encuentra, la buscará luego en las propiedades de la aplicación. En los ejemplos siguientes se muestra cómo consultar las propiedades del sistema y las propiedades de la aplicación.

Para consultar la propiedad del sistema contentEncoding:

$contentEncoding = 'UTF-8'

Para consultar la propiedad de la aplicación processingPath:

processingPath = 'hot'

Para combinar estas consultas, se pueden usar funciones y expresiones booleanas:

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

Se proporciona una lista completa de operadores y funciones compatibles en la sección Expresiones y condiciones de Lenguaje de consulta de IoT Hub para dispositivos y módulos gemelos, trabajos y enrutamiento de mensajes.

Consulta basada en el cuerpo del mensaje

Para habilitar la consulta en el cuerpo de un mensaje, este debe estar en el formato JSON y codificado en UTF-8, UTF-16 o UTF-32. La propiedad del sistema contentType debe ser application/JSON. La propiedad del sistema contentEncoding debe ser uno de los valores de codificación UTF admitidos por esa propiedad del sistema. Si no se especifican estas propiedades del sistema, IoT Hub no evaluará la expresión de consulta en el cuerpo del mensaje.

En el ejemplo de JavaScript siguiente se muestra cómo crear un mensaje con un cuerpo JSON codificado y formado correctamente:

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

Para obtener un ejemplo de codificación de mensajes en C#, consulte el ejemplo HubRoutingSample proporcionado en el SDK de Microsoft Azure IoT para .NET. Este es el mismo ejemplo que se utilizó en el tutorial de enrutamiento de mensajes El archivo Program.cs también tiene un método denominado ReadOneRowFromFile, que lee uno de los archivos codificados, lo descodifica y lo vuelve a escribir como ASCII para que pueda leerlo.

Expresiones de consulta del cuerpo del mensaje

Una consulta en un cuerpo del mensaje debe tener el prefijo $body. Puede usar una referencia al cuerpo, una referencia a la matriz del cuerpo o varias referencias al cuerpo en la expresión de consulta. La expresión de consulta también puede combinar una referencia al cuerpo con una referencia a las propiedades del sistema de mensajes o una referencia a las propiedades de la aplicación de mensajes. Por ejemplo, todos los ejemplos siguientes son unas expresiones de consulta válidas:

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

Solo puede ejecutar consultas y funciones en las propiedades de referencia del cuerpo. No puede ejecutar consultas o funciones en toda la referencia del cuerpo. Por ejemplo, la siguiente consulta no se admite y devuelve undefined:

$body[0] = 'Feb'

Para filtrar una carga de notificación gemela en función de lo que ha cambiado, ejecute la consulta en el cuerpo del mensaje. Por ejemplo, para filtrar cuando haya un cambio de propiedad deseado en sendFrequency y el valor sea superior a 10:

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

Para filtrar los mensajes que contienen un cambio de propiedad, independientemente del valor de la propiedad, puede usar la función is_defined() (cuando el valor es un tipo primitivo):

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

Consulta basada en dispositivos o módulos gemelos

El enrutamiento de mensajes le permite consultar en etiquetas y propiedades de dispositivos gemelos o módulo gemelo, que son objetos JSON. En el ejemplo siguiente se muestra un dispositivo gemelo con etiquetas y propiedades.

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

Los módulos no heredan las etiquetas gemelas de sus dispositivos correspondientes. Las consultas gemelas para los mensajes que se originan en los módulos de dispositivo (por ejemplo, de los módulos IoT Edge) se consultan en el módulo gemelo y no en el dispositivo gemelo correspondiente.

Expresiones de consulta de gemelos

Una consulta sobre un dispositivo gemelo o un módulo gemelo debe tener el prefijo $twin. La expresión de consulta también puede combinar referencias a las propiedades o etiquetas de dispositivo gemelo con referencias al cuerpo del mensaje, a las propiedades del sistema de mensajes o a las propiedades de la aplicación de mensajes. Se recomienda usar nombres únicos en las etiquetas y propiedades porque la consulta no distingue mayúsculas de minúsculas. Esta recomendación se aplica tanto a los dispositivos gemelos como a los módulos gemelos. También se recomienda evitar el uso de twin, $twin, body o $body como nombres de propiedad. Por ejemplo, todos los ejemplos siguientes son unas expresiones de consulta válidas:

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

Limitaciones

Las consultas de enrutamiento no admiten el uso de espacios en blanco ni ninguno de los siguientes caracteres en los nombres de propiedad, la ruta de acceso del cuerpo del mensaje o la ruta de acceso del dispositivo o módulo gemelo: ()<>@,;:\"/?={}.

Pasos siguientes