Compartilhar via


Converter dados usando as conversões de fluxo de dados

Importante

Esta página inclui instruções para gerenciar componentes do serviço Operações do Azure IoT usando manifestos de implantação do Kubernetes, que estão em versão prévia. Esse recurso é fornecido com várias limitações e não deve ser usado para cargas de trabalho de produção.

Veja os Termos de Uso Complementares para Versões Prévias do Microsoft Azure para obter termos legais que se aplicam aos recursos do Azure que estão em versão beta, versão prévia ou que, de outra forma, ainda não foram lançados em disponibilidade geral.

Você pode usar as conversões de fluxo de dados para transformar dados nas Operações do Azure IoT. O elemento de conversão em um fluxo de dados é usado para calcular valores para campos de saída. Você pode usar campos de entrada, operações disponíveis, tipos de dados e conversões de tipo em conversões de fluxo de dados.

O elemento de conversão de um fluxo de dados é usado para calcular valores para campos de saída:

inputs: [
  '*.Max' // - $1
  '*.Min' // - $2
]
output: 'ColorProperties.*'
expression: '($1 + $2) / 2'

Há vários aspectos para entender sobre conversões:

  • Referência a campos de entrada: como fazer referência a valores de campos de entrada na fórmula de conversão.
  • Operações disponíveis: operações que podem ser utilizadas em conversões. Por exemplo, adição, subtração, multiplicação e divisão.
  • Tipos de dados: tipos de dados que uma fórmula pode processar e manipular. Por exemplo, inteiro, ponto flutuante e cadeia de caracteres.
  • Conversões de tipo: como os tipos de dados são convertidos entre os valores de campo de entrada, a avaliação da fórmula e os campos de saída.

Campos de entrada

Em conversões, as fórmulas podem operar em valores estáticos, como um número como 25 ou parâmetros derivados de campos de entrada. Um mapeamento define esses campos de entrada que a fórmula pode acessar. Cada campo é referenciado de acordo com sua ordem na lista de entrada:

inputs: [
  '*.Max'      // - $1
  '*.Min'      // - $2
  '*.Mid.Avg'  // - $3
  '*.Mid.Mean' // - $4
]
output: 'ColorProperties.*'
expression: '($1, $2, $3, $4)'

Neste exemplo, a conversão resulta em uma matriz que contém os valores de [Max, Min, Mid.Avg, Mid.Mean]. Os comentários no arquivo YAML (# - $1,# - $2) são opcionais, mas ajudam a esclarecer a conexão entre cada propriedade do campo e sua função na fórmula de conversão.

Tipos de dados

Diferentes formatos de serialização dão suporte a vários tipos de dados. Por exemplo, o JSON oferece alguns tipos primitivos: cadeia de caracteres, número, booliano e nulo. Também inclui matrizes desses tipos primitivos.

Quando o mapeador lê uma propriedade de entrada, ele a converte em um tipo interno. Essa conversão é necessária para manter os dados na memória até que sejam gravados em um campo de saída. A conversão em um tipo interno ocorre independentemente de os formatos de serialização de entrada e saída serem os mesmos.

A representação interna utiliza os seguintes tipos de dados:

Tipo Descrição
bool True/false lógico.
integer Armazenado como um inteiro assinado de 128 bits.
float Armazenado como número de ponto flutuante de 64 bits.
string Uma cadeia de caracteres UTF-8.
bytes Dados binários, uma cadeia de caracteres de valores não assinados de 8 bits.
datetime UTC ou hora local com resolução de nanossegundos.
time Hora do dia com resolução de nanossegundos.
duration Uma duração com resolução de nanossegundos.
array Uma matriz de todos os tipos listados anteriormente.
map Um vetor de pares (chave, valor) de todos os tipos listados anteriormente.

Campos de registro de entrada

Quando um campo de registro de entrada é lido, seu tipo subjacente é convertido em uma dessas variantes de tipo interno. A representação interna é versátil o suficiente para lidar com a maioria dos tipos de entrada com conversão mínima ou nenhuma.

Para alguns formatos, tipos alternativos são usados. Por exemplo, o JSON não tem um tipo datetime e armazena valores datetime como cadeias de caracteres formatadas de acordo com ISO8601. Quando o mapeador lê esse campo, a representação interna permanece uma cadeia de caracteres.

Campos de registro de saída

O mapeador foi projetado para ser flexível convertendo tipos internos em tipos de saída para acomodar cenários em que os dados vêm de um formato de serialização com um sistema de tipo limitado. Os exemplos a seguir mostram como as conversões são tratadas:

  • Tipos numéricos: esses tipos podem ser convertidos em outras representações, mesmo que isso signifique perder a precisão. Por exemplo, um número de ponto flutuante de 64 bits (f64) pode ser convertido em um inteiro de 32 bits (i32).
  • Cadeia de caracteres para números: se o registro de entrada contiver uma cadeia de caracteres como 123 e o campo de saída for um inteiro de 32 bits, o mapeador converterá e gravará o valor como um número.
  • Cadeias de caracteres para outros tipos:
    • Se o campo de saída for datetime, o mapeador tentará analisar a cadeia de caracteres como um datetime com formato ISO8601.
    • Se o campo de saída for binary/bytes, o mapeador tentará desserializar a cadeia de caracteres de uma cadeia de caracteres codificada em base64.
  • Valores boolianos:
    • Convertido para 0/1 se o campo de saída for numérico.
    • Convertido para true/false se o campo de saída for cadeia de caracteres.

Usar uma fórmula de conversão com tipos

Em mapeamentos, uma fórmula opcional pode especificar como os dados da entrada são processados antes de serem gravados no campo de saída. Se nenhuma fórmula for especificada, o mapeador copiará o campo de entrada para a saída usando o tipo interno e as regras de conversão.

Se uma fórmula for especificada, os tipos de dados disponíveis para uso em fórmulas serão limitados a:

  • Inteiros
  • Números de ponto flutuante
  • Cadeias de caracteres
  • Boolianos
  • Matrizes dos tipos anteriores
  • Valor ausente

Map e byte não podem participar de fórmulas.

Os tipos relacionados ao tempo (datetime, time e duration) são convertidos em valores inteiros que representam o tempo em segundos. Após a avaliação da fórmula, os resultados são armazenados na representação interna e não convertidos novamente. Por exemplo, datetime convertido em segundos permanece um inteiro. Se o valor for usado em campos datetime, um método de conversão explícito deverá ser aplicado. Um exemplo é converter o valor em uma cadeia de caracteres ISO8601 que é automaticamente convertida para o tipo datetime de formato de serialização de saída.

Usar tipos irregulares

Considerações especiais se aplicam a tipos como matrizes e valor ausente.

matrizes

As matrizes podem ser processadas usando as funções de agregação para calcular um único valor de vários elementos. Por exemplo, usando o registro de entrada:

{
  "Measurements": [2.34, 12.3, 32.4]
}

Com o mapeamento:

inputs: [
  'Measurements' // - $1
]
output: 'Measurement'
expression: 'min($1)'

Essa configuração seleciona o menor valor da matriz de Measurements para o campo de saída.

As matrizes também podem ser criadas com base em vários valores únicos:

inputs: [
  'minimum' // - - $1
  'maximum' // - - $2
  'average' // - - $3
  'mean'    // - - $4
]
output: 'stats'
expression: '($1, $2, $3, $4)'

Esse mapeamento cria uma matriz que contém o mínimo, o máximo e a média.

Valor ausente

O valor ausente é um tipo especial usado em cenários, como:

  • Manipulando campos ausentes na entrada fornecendo um valor alternativo.
  • Removendo condicionalmente um campo com base em sua presença.

Exemplo de mapeamento que usa um valor ausente:

{
  "Employment": {      
    "Position": "Analyst",
    "BaseSalary": 75000,
    "WorkingHours": "Regular"
  }
}

O registro de entrada contém o campo BaseSalary, mas possivelmente isso é opcional. Digamos que, se o campo estiver ausente, um valor deverá ser adicionado com base um conjunto de dados de contextualização:

{
  "Position": "Analyst",
  "BaseSalary": 70000,
  "WorkingHours": "Regular"
}

Um mapeamento pode verificar se o campo está presente no registro de entrada. Se o campo for encontrado, a saída receberá esse valor existente. Caso contrário, a saída receberá o valor do conjunto de dados de contexto. Por exemplo:

inputs: [
  'BaseSalary' // - - - - - - - - - - - $1
  '$context(position).BaseSalary' //  - $2
]
output: 'BaseSalary'
expression: 'if($1 == (), $2, $1)'

O conversion usa a função if que tem três parâmetros:

  • O primeiro parâmetro é a condição. No exemplo, ele verifica se o campo BaseSalary do campo de entrada (com alias de $1) é o valor ausente.
  • O segundo parâmetro será o resultado da função se a condição no primeiro parâmetro for verdadeira. Neste exemplo, é o campo BaseSalary do conjunto de dados de contextualização (com alias $2).
  • O terceiro parâmetro é o valor da condição se o primeiro parâmetro for false.

Funções disponíveis

Os fluxos de dados fornecem um conjunto de funções internas que podem ser usadas em fórmulas de conversão. Essas funções podem ser usadas para executar operações comuns, como aritmética, comparação e manipulação de cadeia de caracteres. As funções disponíveis são:

Função Descrição Exemplos
min Retorne o valor mínimo de uma matriz. min(2, 3, 1) retorna 1, min($1) retorna o valor mínimo da matriz $1
max Retorne o valor máximo de uma matriz. max(2, 3, 1) retorna 3, max($1) retorna o valor máximo da matriz $1
if Retorne um valor entre valores com base em uma condição. if($1 > 10, 'High', 'Low') retorna 'High' se $1 é maior que 10, caso contrário, 'Low'
len Retorne o comprimento do caractere de uma cadeia de caracteres ou o número de elementos em uma tupla. len("Azure") retorna 5, len(1, 2, 3) retorna 3, len($1) retorna o número de elementos na matriz $1
floor Retorne o maior inteiro menor ou igual a um número. floor(2.9) retorna 2
round Retorne o inteiro mais próximo a um número, arredondando os casos de meio caminho para longe de 0,0. round(2.5) retorna 3
ceil Retorne o menor inteiro maior ou igual a um número. ceil(2.1) retorna 3
scale Dimensione um valor de um intervalo para outro. scale($1, 0, 10, 0, 100) dimensiona o valor de entrada do intervalo de 0 a 10 para o intervalo de 0 a 100

Funções de conversão

Os fluxos de dados fornecem várias funções de conversão internas para conversões de unidade comuns, como temperatura, pressão, comprimento, peso e volume. Veja alguns exemplos:

Conversão Fórmula Nome da função
Celsius para Fahrenheit F = (C * 9/5) + 32 cToF
PSI para bar Bar = PSI * 0,0689476 psiToBar
Polegada para cm Cm = polegada * 2,54 inToCm
Pé para metro Metro = pé * 0,3048 ftToM
Lbs para kg Kg = lbs * 0,453592 lbToKg
Galões para litros Litros = galões * 3,78541 galToL

Também há suporte para conversões inversas:

Conversão Fórmula Nome da função
Fahrenheit para Celsius C = (F - 32) * 5/9 fToC
Bar para PSI PSI = bar / 0,0689476 barToPsi
Cm para polegada Polegada = cm / 2,54 cmToIn
Metro para pé Pé = metro / 0,3048 mToFt
Kg para lbs Lbs = kg / 0,453592 kgToLb
Litros para galões Galões = litros / 3,78541 lToGal

Além disso, você pode definir suas funções de conversão usando fórmulas matemáticas básicas. O sistema dá suporte a operadores como adição (+), subtração (-), multiplicação (*) e divisão (/). Esses operadores seguem regras padrão de precedência, que podem ser ajustadas com parênteses para garantir a ordem correta das operações. Isso permite que você personalize as conversões de unidade de acordo com necessidades específicas.

Operadores disponíveis por precedência

Operador Descrição
^ Exponenciação: $1 ^ 3

Como o Exponentiation tem a maior precedência, ele é executado primeiro, a menos que os parênteses substituam essa ordem:

  • $1 * 2 ^ 3 é interpretado como $1 * 8 porque a parte 2 ^ 3 é executada primeiro, antes da multiplicação.
  • ($1 * 2) ^ 3 processa a multiplicação antes da exponencialização.
Operador Descrição
- Negação
! Expressão NOT lógica

Negation e Logical not têm alta precedência, portanto, eles sempre mantêm seu vizinho imediato, exceto quando a exponencialização está envolvida:

  • -$1 * 2 nega $1 primeiro e depois multiplica.
  • -($1 * 2) multiplica e nega o resultado.
Operador Descrição
* Multiplicação: $1 * 10
/ Divisão: $1/25 (o resultado é um inteiro se ambos os argumentos forem inteiros, caso contrário, float)
% Módulo %: $1 % 25

Multiplication, Divisione Modulo, com a mesma precedência, são executados da esquerda para a direita, a menos que a ordem seja alterada por parênteses.

Operador Descrição
+ Adição para valores numéricos, concatenação para cadeias de caracteres
- Subtração

Addition e Subtraction são consideradas operações mais fracas em comparação às operações do grupo anterior:

  • $1 + 2 * 3 resulta em $1 + 6 porque 2 * 3 é executado primeiro devido à precedência mais alta de multiplication.
  • ($1 + 2) * 3 prioriza Addition antes de Multiplication.
Operador Descrição
< Menor que
> Maior que
<= Menor ou igual a
>= Maior ou igual a
== Igual a
!= Não igual a

Comparisons operam em valores numéricos, booleanos e de cadeia de caracteres. Como têm menor precedência do que os operadores aritméticos, não são necessários parênteses para comparar os resultados de forma eficaz:

  • $1 * 2 <= $2 é equivalente a ($1 * 2) <= $2.
Operador Descrição
|| OR lógico
&& AND lógico

Operadores lógicos são usados para encadear condições:

  • $1 > 100 && $2 > 200