Partager via


Convertir des données à l’aide de conversions de flux de données

Important

Opérations Azure IoT Préversion avec Azure Arc est actuellement en préversion. Vous ne devez pas utiliser ce logiciel en préversion dans des environnements de production.

Lorsqu’une version en disponibilité générale sera publiée, vous devrez déployer une nouvelle installation d’Opérations Azure IoT. Vous ne pourrez pas mettre à niveau une installation en préversion.

Pour connaître les conditions juridiques qui s’appliquent aux fonctionnalités Azure en version bêta, en préversion ou plus généralement non encore en disponibilité générale, consultez l’Avenant aux conditions d’utilisation des préversions de Microsoft Azure.

Vous pouvez utiliser des conversions de flux de données pour transformer des données dans Opérations Azure IoT. L’élément de conversion dans un flux de données est utilisé pour calculer des valeurs pour les champs de sortie. Vous pouvez utiliser des champs d’entrée, des opérations disponibles, des types de données et des conversions de types dans les conversions de flux de données.

L’élément de conversion de flux de données est utilisé pour calculer des valeurs pour les champs de sortie :

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

Plusieurs aspects doivent être compris concernant les conversions :

  • Référence aux champs d’entrée : comment référencer des valeurs à partir de champs d’entrée dans la formule de conversion.
  • Opérations disponibles : opérations qui peuvent être utilisées dans les conversions. Par exemple, addition, soustraction, multiplication et division.
  • Types de données : types de données qu’une formule peut traiter et manipuler. Par exemple, entier, virgule flottante et chaîne.
  • Conversions de types : conversion des types de données entre les valeurs des champs d’entrée, l’évaluation de formule et les champs de sortie.

Champs d’entrée

Dans les conversions, les formules peuvent fonctionner sur des valeurs statiques comme un nombre tel que 25 ou des paramètres dérivés de champs d’entrée. Un mappage définit ces champs d’entrée auxquels la formule peut accéder. Chaque champ est référencé conformément à son ordre dans la liste d’entrée :

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

Dans cet exemple, la conversion génère un tableau contenant les valeurs de [Max, Min, Mid.Avg, Mid.Mean]. Les commentaires dans le fichier YAML (# - $1, # - $2) sont facultatifs, mais ils aident à clarifier la connexion entre chaque propriété de champ et son rôle dans la formule de conversion.

Types de données

Différents formats de sérialisation prennent en charge différents types de données. Par exemple, JSON propose quelques types primitifs : chaîne, nombre, Booléen et null. Sont également inclus des tableaux de ces types primitifs. En revanche, d’autres formats de sérialisation comme Avro ont un système de type plus complexe, y compris des entiers avec plusieurs longueurs de champ de bits et des horodatages avec différentes résolutions. Par exemple : millisecondes et microsecondes.

Lorsque le mappeur lit une propriété d’entrée, il le convertit en type interne. Cette conversion est nécessaire pour conserver les données en mémoire jusqu’à ce qu’elles soient écrites dans un champ de sortie. La conversion en type interne se produit, que les formats de sérialisation d’entrée et de sortie soient identiques ou non.

La représentation interne utilise les types de données suivants :

Type Description
bool True/false logique.
integer Stocké sous forme d’entier signé 128 bits.
float Stocké sous forme de nombre à virgule flottante 64 bits.
string Une chaîne UTF-8.
bytes Données binaires, chaîne de valeurs non signées 8 bits.
datetime Heure UTC ou locale avec résolution en nanosecondes.
time Heure de la journée avec résolution en nanosecondes.
duration Une durée avec résolution en nanosecondes.
array Un tableau de tous les types répertoriés précédemment.
map Un vecteur de paires (clé, valeur) de tous les types répertoriés précédemment.

Champs d’enregistrement d’entrée

Lorsqu’un champ d’enregistrement d’entrée est lu, son type sous-jacent est converti en l’une de ces variantes de type interne. La représentation interne est suffisamment polyvalente pour gérer la plupart des types d’entrée avec une conversion minimale ou aucune. Toutefois, certains types d’entrée nécessitent une conversion ou ne sont pas pris en charge. Exemples :

  • Type UUID d’Avro : il est converti en string, car il n’y a pas de type UUID spécifique dans la représentation interne.
  • Type decimal d’Avro : il n’est pas pris en charge par le mappeur, les champs de ce type ne peuvent donc pas être inclus dans les mappages.
  • Type duration d’Avro : la conversion peut varier. Si le champ months est défini, il n’est pas pris en charge. Si seulement days et milliseconds sont définis, il est converti en représentation duration interne.

Pour certains formats, des types de substitution sont utilisés. Par exemple, JSON n’a pas de type datetime et stocke à la place les valeurs datetime sous forme de chaînes mises en forme selon ISO8601. Lorsque le mappeur lit un tel champ, la représentation interne reste une chaîne.

Champs d’enregistrement de sortie

Le mappeur est conçu pour être flexible en convertissant des types internes en types de sortie pour prendre en charge les scénarios où les données proviennent d’un format de sérialisation avec un système de type limité. Les exemples suivants montrent comment les conversions sont gérées :

  • Types numériques : ces types peuvent être convertis en d’autres représentations, même si cela signifie perdre de la précision. Par exemple, un nombre à virgule flottante 64 bits (f64) peut être converti en entier 32 bits (i32).
  • Chaînes en nombres : si l’enregistrement entrant contient une chaîne telle que 123 et que le champ de sortie est un entier 32 bits, le mappeur convertit et écrit la valeur en nombre.
  • Chaînes en d’autres types :
    • Si le champ de sortie est datetime, le mappeur tente d’analyser la chaîne sous la forme d’un datetime formaté selon la norme ISO8601.
    • Si le champ de sortie est binary/bytes, le mappeur tente de désérialiser la chaîne à partir d’une chaîne encodée en base64.
  • Valeurs booléennes :
    • Converti en 0/1 si le champ de sortie est numérique.
    • Converti en true/false si le champ de sortie est chaîne.

Conversions de type explicite

Bien que les conversions automatiques fonctionnent comme on peut s’y attendre sur la base des pratiques d’implémentation courantes, il existe des cas où la conversion appropriée ne peut pas être déterminée automatiquement et entraîne une erreur de non prise en charge. Pour résoudre ces situations, plusieurs fonctions de conversion sont disponibles pour définir explicitement la façon dont les données doivent être transformées. Ces fonctions permettent de mieux contrôler la façon dont les données sont converties et de préserver l’intégrité des données même lorsque les méthodes automatiques ne suffisent pas.

Utiliser une formule de conversion avec des types

Dans les mappages, une formule facultative peut spécifier la façon dont les données de l’entrée sont traitées avant d’être écrites dans le champ de sortie. Si aucune formule n’est spécifiée, le mappeur copie le champ d’entrée dans la sortie à l’aide du type interne et des règles de conversion.

Si une formule est spécifiée, les types de données disponibles pour une utilisation dans les formules sont limités à :

  • Entiers
  • Nombres à virgule flottante
  • Chaînes
  • Valeurs booléennes
  • Tableaux des types précédents
  • Valeur manquante

Map et byte ne peuvent pas participer à des formules.

Les types liés à l’heure (datetime, timeet duration) sont convertis en valeurs entières qui représentent le temps en secondes. Après l’évaluation de formule, les résultats sont stockés dans la représentation interne et ne sont pas rétroconvertis. Par exemple, datetime converti en secondes reste un entier. Si la valeur sera utilisée dans les champs datetime, une méthode de conversion explicite doit être appliquée. Par exemple, convertir la valeur en chaîne ISO8601 qui est automatiquement convertie en type datetime du format de sérialisation de sortie.

Utiliser des types irréguliers

Des considérations spéciales s’appliquent aux types tels que les tableaux et valeur manquante.

Tableaux

Les tableaux peuvent être traités à l’aide de fonctions d’agrégation pour calculer une valeur unique à partir de plusieurs éléments. Par exemple, à l’aide de l’enregistrement d’entrée :

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

Avec le mappage :

- inputs:
  - Measurements # - $1
  output: Measurement
  expression: min($1)

Cette configuration sélectionne la plus petite valeur dans le tableau Measurements pour le champ de sortie.

Il est également possible d’utiliser des fonctions qui produisent un nouveau tableau :

- inputs:
  - Measurements # - $1
  output: Measurements
  expression: take($1, 10)  # taking at max 10 items

Les tableaux peuvent également être créés à partir de plusieurs valeurs uniques :

- inputs:
  - minimum  # - - $1
  - maximum  # - - $2
  - average  # - - $3
  - mean     # - - $4
  output: stats
  expression: ($1, $2, $3, $4)

Ce mappage crée un tableau contenant le minimum, le maximum, et la moyenne.

Valeur manquante

Valeur manquante est un type spécial utilisé dans des scénarios, tels que :

  • Gestion des champs manquants dans l’entrée en fournissant une autre valeur.
  • Suppression conditionnelle d’un champ en fonction de sa présence.

Exemple de mappage qui utilise une valeur manquante :

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

L’enregistrement d’entrée contient le champ BaseSalary, mais cela peut être facultatif. Supposons que si le champ est manquant, une valeur doit être ajoutée à partir d’un jeu de données de contextualisation :

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

Un mappage peut vérifier si le champ est présent dans l’enregistrement d’entrée. Si le champ est trouvé, la sortie reçoit cette valeur existante. Sinon, la sortie reçoit la valeur du jeu de données de contexte. Par exemple :

- inputs:
  - BaseSalary  # - - - - - - - - - - $1
  - $context(position).BaseSalary #  - $2 
  output: BaseSalary
  expression: if($1 == (), $2, $1)

Le conversion utilise la fonction if qui a trois paramètres :

  • Le premier paramètre est une condition. Dans l’exemple, il vérifie si le champ BaseSalary du champ d’entrée (alias $1) est la valeur manquante.
  • Le deuxième paramètre est le résultat de la fonction si la condition dans le premier paramètre est true. Dans cet exemple, il s’agit du champ BaseSalary du jeu de données de contextualisation (alias $2).
  • Le troisième paramètre est la valeur de la condition si le premier paramètre a la valeur false.

Fonctions disponibles

Des fonctions peuvent être utilisées dans la formule de conversion pour effectuer différentes opérations :

  • min pour sélectionner un élément unique dans un tableau
  • if pour sélectionner parmi des valeurs
  • Manipulation de chaînes (par exemple, uppercase())
  • Conversion explicite (par exemple, ISO8601_datetime)
  • Agrégation (par exemple, avg())

Opérations disponibles

Les flux de données offrent une large gamme de fonctions de conversion prêtes à l’emploi qui permettent aux utilisateurs d’effectuer facilement des conversions unitaires sans nécessiter de calculs complexes. Ces fonctions prédéfinies couvrent les conversions courantes telles que la température, la pression, la longueur, le poids et le volume. La liste suivante présente les fonctions de conversion disponibles, ainsi que leurs formules et noms de fonction correspondants :

Conversion Formule Nom de la fonction
Celsius en Fahrenheit F = (C * 9/5) + 32 cToF
PSI en bar Bar = PSI * 0,0689476 psiToBar
Pouce en cm Cm = pouce * 2,54 inToCm
Pied en mètre Mètre = pied * 0,3048 ftToM
Livre en kg Kg = livre * 0,453592 lbToKg
Gallon en litre Litre = gallon * 3,78541 galToL

En plus de ces conversions unidirectionnelles, nous prenons également en charge les calculs inverses :

Conversion Formule Nom de la fonction
Fahrenheit en Celsius C = (F - 32) * 5/9 fToC
Bar en PSI PSI = bar / 0,0689476 barToPsi
Cm en pouce Pouce = cm / 2,54 cmToIn
Mètre en pied Pied = mètre / 0,3048 mToFt
Kg en livre Livre = kg / 0,453592 kgToLb
Litre en gallon Gallon = litre / 3,78541 lToGal

Ces fonctions sont conçues pour simplifier le processus de conversion. Elles permettent aux utilisateurs d’entrer des valeurs dans une unité et de recevoir la valeur correspondante dans une autre unité sans effort.

Nous fournissons également une fonction de mise à l’échelle pour mettre à l’échelle la plage de valeurs vers la plage définie par l’utilisateur. Pour l’exemple scale($1,0,10,0,100), la valeur d’entrée est mise à l’échelle de la plage 0 à 10 vers la plage 0 à 100.

En outre, les utilisateurs ont la possibilité de définir leurs propres fonctions de conversion à l’aide de formules mathématiques simples. Notre système prend en charge les opérateurs de base tels que l’ajout (+), la soustraction (-), la multiplication (*) et la division (/). Ces opérateurs suivent les règles standard de précédence. Par exemple, la multiplication et la division sont effectuées avant l’addition et la soustraction. La priorité peut être ajustée à l’aide de parenthèses pour garantir l’ordre correct des opérations. Cette fonctionnalité permet aux utilisateurs de personnaliser leurs conversions d’unités pour répondre à des besoins ou préférences spécifiques, ce qui améliore l’utilité globale et la polyvalence du système.

Pour les calculs plus complexes, des fonctions telles que sqrt (qui recherche la racine carrée d’un nombre) sont également disponibles.

Les opérateurs arithmétiques, de comparaison et Booléen disponibles sont regroupés par priorité

Opérateur Description
^ Élévation à la puissance : $1 ^ 3

Exponentiation ayant la priorité la plus élevée, elle est exécutée en premier, sauf si les parenthèses remplacent cet ordre :

  • $1 * 2 ^ 3 est interprété comme $1 * 8, car la partie 2 ^ 3 est exécutée en premier, avant la multiplication.
  • ($1 * 2) ^ 3 traite la multiplication avant l’exposant.
Opérateur Description
- Négation
! Opérateur NOT logique

Negation et Logical not ont une priorité élevée, de sorte qu’ils s’accolent toujours leur voisin immédiat, sauf quand l’exposant est impliqué :

  • -$1 * 2 annule $1 d’abord, puis multiplie.
  • -($1 * 2) multiplie, puis annule le résultat.
Opérateur Description
* Multiplication : $1 * 10
/ Division : $1 / 25 (le résultat est un entier si les deux arguments sont des entiers, sinon float)
% Modulo : $1 % 25

Multiplication, Division et Modulo, ayant la même priorité, sont exécutés de gauche à droite, sauf si l’ordre est modifié par des parenthèses.

Opérateur Description
+ Ajout de valeurs numériques, concaténation pour les chaînes
- Soustraction

Addition et Subtraction sont considérés comme des opérations plus faibles par rapport aux opérations du groupe précédent :

  • $1 + 2 * 3 donne $1 + 6 parce que 2 * 3 est exécuté en premier en raison de la priorité supérieure de multiplication.
  • ($1 + 2) * 3 hiérarchise Addition avant Multiplication.
Opérateur Description
< Inférieur à
> Supérieur à
< = Inférieur ou égal à
>= Supérieur ou égal à
== Égal à
!= Non égal à

Comparisons fonctionnent sur des valeurs numériques, Booléennes et de chaînes. Étant donné qu’ils ont une priorité inférieure à celle des opérateurs arithmétiques, aucune parenthèse n’est nécessaire pour comparer efficacement les résultats :

  • $1 * 2 <= $2 est équivalent à ($1 * 2) <= $2.
Opérateur Description
|| OU logique
&& ET logique

Les opérateurs logiques sont utilisés pour chaîner des conditions :

  • $1 > 100 && $2 > 200