Sintaxe de consulta do roteamento de mensagens do Hub IoT

O roteamento de mensagens permite aos usuários rotear diferentes tipos de dados, incluindo mensagens de telemetria de dispositivo, eventos de ciclo de vida do dispositivo e eventos de alteração de dispositivo gêmeo para vários pontos de extremidade. Também é possível aplicar consultas avançadas a esses dados antes de roteá-los para receber os dados mais importantes para você. Este artigo descreve a linguagem de consulta de roteamento de mensagens do Hub IoT e fornece alguns padrões comuns de consulta.

Observação

Alguns dos recursos mencionados neste artigo, como mensagens de nuvem para dispositivo, dispositivos gêmeos e gerenciamento de dispositivo estão disponíveis somente na camada Standard do Hub IoT. Para obter mais informações sobre as camadas básica e padrão/gratuita do Hub IoT, confira Escolher a camada certa do Hub IoT para sua solução.

O roteamento de mensagens permite consultar as propriedades da mensagem e o corpo da mensagem, bem como as marcas do dispositivo gêmeo e as propriedades do dispositivo gêmeo. Se o corpo da mensagem não estiver no formato JSON, o roteamento de mensagens ainda poderá rotear a mensagem, mas as consultas não poderão ser aplicadas ao corpo da mensagem. Consultas são descritas como expressões boolianas e, se verdadeira, a consulta será bem-sucedida e roteará todos os dados recebidos, caso contrário, a consulta falhará e os dados recebidos não serão roteados. Se a expressão for avaliada como um valor nulo ou indefinido, ela será tratada como um valor booliano false e um erro será gerado nos logs do recurso de rotas do Hub IoT. A sintaxe de consulta deve estar correta para a rota ser salva e avaliada.

Consulta com base nas propriedades da mensagem

O Hub IoT define um formato comum para todas as mensagens de dispositivo para nuvem que permite a interoperabilidade entre protocolos. O Hub IoT pressupõe a seguinte representação JSON da mensagem. As propriedades do sistema são adicionadas para todos os usuários e identificam o conteúdo da mensagem. Os usuários seletivamente podem adicionar propriedades do aplicativo para a mensagem. É recomendável usar nomes de propriedades exclusivos porque as mensagens de dispositivo para nuvem do Hub IoT não diferenciam maiúsculas de minúsculas. Por exemplo, se você tiver várias propriedades com o mesmo nome, o Hub IoT somente enviará uma das propriedades.

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

Propriedades do sistema

As propriedades do sistema ajudam a identificar o conteúdo e a origem das mensagens. Veja algumas delas descritas na seguinte tabela:

Propriedade Tipo Descrição
contentType string O usuário especifica o tipo de conteúdo da mensagem. Para permitir a consulta no corpo da mensagem, esse valor deve ser definido como application/JSON.
contentEncoding string O usuário especifica o tipo de codificação da mensagem. Se a propriedade contentType estiver definida como application/JSON, os valores permitidos serão UTF-8, UTF-16 e UTF-32.
iothub-connection-device-id string Esse valor é definido pelo Hub IoT e identifica a ID do dispositivo. Para consultar, use $connectionDeviceId.
iothub-connection-module-id string Esse valor é definido pelo Hub IoT e identifica a ID do módulo de borda. Para consultar, use $connectionModuleId.
iothub-enqueuedtime string Esse valor é definido pelo Hub IoT e representa a hora real de enfileiramento da mensagem em UTC. Para consultar, use $enqueuedTime.
dt-dataschema string Esse valor é definido pelo Hub IoT em mensagens do dispositivo para a nuvem. Ele contém a ID do modelo do dispositivo definida na conexão do dispositivo. Para consultar, use $dt-dataschema.
dt-subject string O nome do componente que está enviando as mensagens do dispositivo para a nuvem. Para consultar, use $dt-subject.

Para obter mais informações sobre as outras propriedades do sistema disponíveis, consulte Criar e ler mensagens do Hub IoT.

Propriedades do aplicativo

Propriedades do aplicativo são cadeias de caracteres definidas pelo usuário que podem ser adicionadas à mensagem. Esses campos são opcionais.

Expressões de consulta de propriedades de mensagem

Uma consulta nas propriedades do sistema de mensagens deverá ser prefixada com o símbolo $. As consultas nas propriedades do aplicativo serão acessadas com o nome e não deverão ser prefixadas com o símbolo $. Se o nome de uma propriedade do aplicativo começar com $, o Hub IoT primeiro pesquisará nas propriedades do sistema e, se não localizá-lo, pesquisará nas propriedades do aplicativo. Os seguintes exemplos mostram como consultar as propriedades do sistema e as propriedades do aplicativo.

Para consultar a propriedade do sistema contentEncoding:

$contentEncoding = 'UTF-8'

Para consultar a propriedade do aplicativo processingPath:

processingPath = 'hot'

Para combinar essas consultas, é possível usar expressões e funções boolianas:

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

Uma lista completa de operadores e funções com suporte é fornecida na seção Expressão e condições da Linguagem de consulta do Hub IoT para dispositivos e módulos gêmeos, trabalhos e roteamento de mensagens.

Consulta com base no corpo da mensagem

Para habilitar a consulta no corpo de uma mensagem, a mensagem deverá estar em um formato JSON e codificada em UTF-8, UTF-16 ou UTF-32. A propriedade do sistema contentType precisa ser definida como application/JSON. A propriedade do sistema contentEncoding precisa ser definida como um dos valores de codificação UTF com suporte nessa propriedade do sistema. Se essas propriedades do sistema não forem especificadas, o Hub IoT não avaliará a expressão de consulta no corpo da mensagem.

O exemplo JavaScript a seguir mostra como criar uma mensagem com um corpo JSON formado e codificado corretamente:

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 obter um exemplo de codificação de mensagens C#, confira HubRoutingSample fornecido no SDK do IoT do Microsoft Azure para .NET. Este exemplo é o mesmo que foi usado no tutorial Roteamento de mensagem. O arquivo Program.cs também possui um método nomeado ReadOneRowFromFile, que lê um dos arquivos codificados, decodifica-o e grava o arquivo novamente como ASCII para que ele possa ser lido por você.

Expressões de consulta de corpo da mensagem

Uma consulta em um corpo de mensagem precisa ter o prefixo $body. Você pode usar uma referência de corpo simples, referência de matriz de corpo ou várias referências de corpo na expressão de consulta. A expressão de consulta também poderá combinar uma referência de corpo com uma referência de propriedades do sistema de mensagens ou uma referência de propriedades do aplicativo de mensagens. Por exemplo, os exemplos a seguir são todos de expressões de consultas 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'

Você pode executar consultas e funções somente em propriedades na referência de corpo. Você não pode executar consultas nem funções em toda a referência de corpo. Por exemplo, não há suporte para a seguinte consulta e, portanto, retorna undefined:

$body[0] = 'Feb'

Para filtrar um conteúdo de notificação de gêmeo com base no que mudou, execute a consulta no corpo da mensagem. Por exemplo, para filtrar quando houver uma alteração de propriedade desejada em sendFrequency e o valor for maior que 10:

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

Para filtrar mensagens que contêm uma alteração de propriedade, não importa o valor da propriedade, você pode usar a função is_defined() (quando o valor é um tipo primitivo):

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

Consulta baseada em dispositivo ou módulo gêmeo

O roteamento de mensagens permite consultar marcas e propriedades de dispositivo gêmeo ou módulo gêmeo, que são objetos JSON. O seguinte exemplo ilustra um dispositivo gêmeo com marcas e propriedades:

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

Observação

Os módulos não herdam marcas de cima de seus dispositivos correspondentes. Consultas de gêmeos para mensagens originadas dos módulos de dispositivos (por exemplo, de módulos IoT Edge) consultam o módulo gêmeo e não o dispositivo gêmeo correspondente.

Expressões de consulta de gêmeos

Uma consulta em um dispositivo gêmeo ou módulo gêmeo precisa ser prefixada com $twin. A expressão de consulta também poderá combinar uma marca gêmea ou referência de propriedade com uma referência de corpo, uma referência de propriedades do sistema de mensagens ou uma referência de propriedades do aplicativo de mensagens. É recomendável usar nomes exclusivos em marcas e propriedades porque a consulta não diferencia maiúsculas de minúsculas. Essa recomendação se aplica a dispositivos gêmeos e módulos gêmeos. É recomendável também evitar usar twin, $twin, body ou $body como nomes de propriedade. Por exemplo, os exemplos a seguir são todos de expressões de consultas válidas:

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

Limitações

As consultas de roteamento não dão suporte ao uso de espaço em branco nem dos seguintes caracteres em nomes de propriedade, no caminho do corpo da mensagem nem no caminho gêmeo do dispositivo/módulo: ()<>@,;:\"/?={}.

Próximas etapas