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 umdatetime
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.
- Se o campo de saída for
- 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.
- Convertido para
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 parte2 ^ 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
, Division
e 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
porque2 * 3
é executado primeiro devido à precedência mais alta demultiplication
.($1 + 2) * 3
priorizaAddition
antes deMultiplication
.
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