ADR-0001 – Conversion des unités à la lecture
Contexte
Le service apps/api/legacy-metrics/src/metrics-v3 ingère les métriques des capteurs, applique historiquement les transformations lors de l'écriture, puis stocke les valeurs transformées dans InfluxDB.
Cette approche simplifie les lectures, mais rend tout changement d'unité extrêmement coûteux puisqu'il faudrait recalculer et réécrire l'ensemble de l'historique.
Afin de répondre aux nouveaux besoins de changement d'unité, les conversions doivent désormais être réalisées à la lecture, sans modifier les données stockées.
Problème
Les lectures de métriques sont aujourd'hui réparties dans plusieurs chemins legacy.
Pour une première version (V1), le périmètre est volontairement limité aux principales requêtes utilisateur :
getMetricsV3getMetricsMultipleV3
La conversion doit être appliquée de manière cohérente sur l'ensemble de la réponse :
- les séries (
datasets) - les premières et dernières valeurs
- les valeurs minimales et maximales
- les seuils affichés
- les métadonnées d'unité
En revanche, les calculs internes doivent continuer à utiliser les unités canoniques afin d'éviter toute régression métier :
- données stockées dans InfluxDB
- seuils persistés
- calculs d'alerting
Décision
Introduire un mécanisme explicite de conversion d'unité à la lecture, piloté par la requête du client.
Le client peut envoyer un champ optionnel unitByField.
Exemple :
[
{
field: ANGLEX,
unit: millimeter_per_meter,
},
];
Si un champ n'est pas présent dans unitByField, il est retourné dans son unité canonique.
Chaque DatasetV3 expose les unités effectivement utilisées au travers d'un champ units.
Unités supportées (V1)
Angles
Champs supportés :
ROLLPITCHANGLEXANGLEY
Unités supportées :
degreemillimeter_per_meter
Formules :
degree → millimeter_per_meter
= tan(degree × PI / 180) × 1000
millimeter_per_meter → degree
= atan(mmPerM / 1000) × 180 / PI
Température
Unités supportées :
celsiusfahrenheit
Formules :
celsius → fahrenheit
= (celsius × 9) / 5 + 32
fahrenheit → celsius
= ((fahrenheit - 32) × 5) / 9
Aucun arrondi n'est effectué côté backend.
Données converties
Les éléments suivants sont convertis avant d'être renvoyés au client :
datasetsMetricsValues.yMetricsValues.yBrutfirst_and_last_valuesmin_and_max_valuesthresholds_values
Les éléments suivants restent toujours en unité canonique :
- les données stockées dans InfluxDB
- les seuils persistés
- les calculs d'alerting
CurveEvent
Les valeurs minimales et maximales continuent d'être calculées en unité canonique avant d'être converties dans la réponse.
Validation
La validation est stricte.
Une erreur est retournée lorsque :
- une unité est incompatible avec le champ demandé ;
- un champ est présent dans
unitByFieldmais n'a pas été demandé ; - un même champ apparaît plusieurs fois dans
unitByField.
Exemple :
Duplicate unit requested for field ANGLEX
Pour cette V1, une erreur de validation classique est suffisante. Aucun type d'erreur métier spécifique n'est nécessaire.
Architecture
Contrat partagé (@feelbat/core/metrics)
Ajout de :
MetricUnitEnum- l'entrée
unitByField - la sortie
units
Service de métriques
Ajouter un service de conversion d'unités dans metrics-v3, réutilisable ultérieurement par MetricsV3TmpService.
MetricsV3Service devient le point central de la conversion :
- reçoit
unitByField; - valide les unités après résolution des champs ;
- récupère les métriques en unité canonique ;
- construit le dataset existant ;
- convertit la réponse finale ;
- renseigne le champ
units.
Les resolvers ne doivent contenir aucune logique de conversion. Ils se contentent de transmettre filter.unitByField.
Compatibilité
unitByField est optionnel.
Lorsqu'il est absent, les réponses restent strictement identiques au comportement actuel et utilisent les unités canoniques.
Cela garantit la rétrocompatibilité avec les clients existants.
Chaque DatasetV3, y compris ceux renvoyés par getMetricsMultipleV3, possède son propre champ units.
Conséquences
Avantages
- Plus aucune réécriture de l'historique InfluxDB n'est nécessaire lors d'un changement d'unité.
- Les unités d'affichage deviennent indépendantes du stockage.
- La solution est rétrocompatible.
- Le mécanisme pourra être réutilisé par les futurs endpoints de métriques.
Compromis
- Les conversions sont désormais réalisées à chaque lecture, ce qui ajoute un faible coût CPU.
- Les nouveaux endpoints devront utiliser le service de conversion afin de garantir un comportement homogène.
Tests recommandés
- conversion des angles ;
- conversion des températures ;
- validation d'une unité incompatible ;
- validation d'un champ non demandé ;
- validation des doublons ;
- conversion des
datasets; - conversion des
first_and_last_values; - conversion des
min_and_max_values; - conversion des
thresholds_values; - génération complète du champ
units, y compris pour les champs non convertis explicitement.