Format JSON de la requête de génération de la configuration des métriques

Ce guide décrit en détail le format de requête JSON pour le point de terminaison /api/v1/generate_metrics_config de l'outil Metrics Configuration Generator (MCG). Ce format vous permet de définir une campagne de télémétrie (en spécifiant la collecte de données, le traitement sur l'appareil et la génération de rapports) dans une structure lisible par l'humain.

L'outil MCG valide cet objet JSON en recherchant des problèmes tels que des incompatibilités de type, des dépendances circulaires ou des références non définies, puis le compile en un message de tampon de protocole (protobuf) MetricsConfig. Ce message MetricsConfig est le format binaire que le service de télémétrie sur l'appareil exécute pour diffuser la campagne.

Conditions préalables : vous devez connaître les schémas JSON, protobuf et les structures de données de base. Pour obtenir une présentation conceptuelle, consultez Concepts de configuration des métriques.

Comment rédiger une description de configuration

Pour concevoir une campagne de collecte de métriques, suivez ce flux logique :

  1. Spécifiez les sources de données : définissez l'origine de vos données.
  2. Définir la logique et le traitement : configurez des règles pour déterminer quand collecter les données et comment les traiter.
  3. Créer une sortie : regroupez les données traitées dans un message final.
  4. Champs de premier niveau : ajoutez des champs de premier niveau tels que UUID, signal definitions et lifecycle control.

Exemple : Rapport sur la vitesse moyenne

Ce guide utilise un exemple pour montrer comment tous les composants s'assemblent. Il crée un rapport qui calcule la vitesse moyenne du véhicule toutes les minutes. Il définit une source de données (SpeedSource) pour collecter les données de vitesse, des déclencheurs (OnNewSpeed, EveryMinute) pour contrôler le flux d'exécution, un agrégateur (SpeedAggregator) pour calculer la moyenne et une configuration de rapport sur les métriques (MinuteReport) pour regrouper le résultat. Les exemples des sections développables s'appuient sur ce scénario.

Spécifier des sources de données

La télémétrie permet de collecter des données à partir des services SDV (via le middleware SDV) et des éditeurs basés sur le registre d'éditeurs configurables.

Pour utiliser des données dans SDV, définissez une source de données (concept) et ajoutez-la au tableau data_sources.

Champs d'un objet de source de données (élément de la liste data_sources)
name Chaîne définie par l'utilisateur qui identifie cette source de données dans la configuration des métriques.
source_identifier Identifiant utilisé pour découvrir le service. Pour en savoir plus, consultez Format source_identifier.
connection_type SUBSCRIPTION pour un flux de données continu (obligatoire pour les déclencheurs de données) ou ON_DEMAND pour une récupération à la demande (pour en savoir plus, consultez la configuration des sources de données).
facultatif
configuration

RPC et registre des éditeurs configurables uniquement.Objet permettant de configurer la source de données avec les champs suivants :

type_url Nom de domaine complet du message protobuf de la configuration.
value_json,
value_textproto,
ou value
Charge utile au format JSON, textproto ou base64.
Champs pour le type de connexion SUBSCRIPTION
facultatif
sub_sampling_interval_ms
Pub/Sub uniquement : entier non négatif (en millisecondes) permettant de limiter la fréquence des messages en spécifiant l'intervalle minimal entre les messages.
facultatif
fetch_last_message
(par défaut : false)
Pub/Sub uniquement Valeur booléenne. Si la valeur est true, le dernier message est récupéré lors de la connexion.

Toutes les options ne sont pas disponibles pour tous les types de sources de données. Pour en savoir plus, consultez le guide d'intégration des sources de données.

Format de source_identifier

Le service de télémétrie accepte plusieurs formats d'identifiants de source. Pour obtenir une présentation, consultez Définition de la source de données dans les configurations de métriques.

MCG déduit le type de message protobuf à partir de source_identifier uniquement s'il utilise le format de nom de type d'unité. Si vous utilisez un FQIN ou un nom personnalisé (à partir du Registre des éditeurs configurables), MCG ne peut pas déduire le type. Dans ce cas, vous devez fournir data_source_message_types. Si le type ne figure pas dans votre catalogue, vous devez également fournir sa définition dans descriptor_protos.

Exemple : Définir une source de données

Cet exemple indique la vitesse du véhicule. Commencez par consulter le catalogue VSIDL pour identifier le service qui publie ces données.

À l'aide de l'exemple de catalogue dans la codebase SDV, identifiez le service concerné. Conformément à Format de source_identifier, spécifiez le type de message protobuf mcg.test.subpkg.speed_msg. Étant donné que la vitesse est généralement publiée fréquemment, utilisez sub_sampling_interval_ms pour limiter les mises à jour à un message par seconde :

{
  "name": "SpeedSource",
  "source_identifier": "mcg.test.subpkg.speed_msg",
  "connection_type": "SUBSCRIPTION",
  "sub_sampling_interval_ms": 1000 // Limit updates to 1 per second
}

Définir la logique et le traitement

La logique est gérée par deux composants qui fonctionnent ensemble : les déclencheurs (concept) définissent quand quelque chose se produit. Les agrégateurs (concept) définissent la façon dont les données sont traitées en fonction de ces déclencheurs. Étant donné que les expressions (concept) sont essentielles aux conditions de déclenchement et à la logique d'agrégation, cette section décrit d'abord comment les écrire.

Expressions

Les expressions vous permettent de définir des calculs et des conditions à l'aide d'une syntaxe lisible. MCG compile ces chaînes dans un format exécutable optimisé pour l'évaluation sur l'appareil.

Les expressions peuvent exprimer des calculs arithmétiques, des conditions logiques et des comparaisons de données. Pour obtenir la syntaxe complète, y compris les opérateurs et les fonctions, consultez Syntaxe des expressions.

Fraîcheur des données : lorsqu'une expression accède à une source de données, le comportement de récupération dépend du type de connexion :

  • SUBSCRIPTION : utilise le message reçu en dernier mis en cache par le service de télémétrie. (Remarque : Si sub_sampling_interval_ms est défini, cela peut différer du dernier message publié.)
  • ON_DEMAND : déclenche un appel immédiat pour récupérer le nouveau message du service.

Contraintes de type

  • Tableaux : l'accès direct à l'index du tableau (par exemple, my_data_source.my_array[0]) n'est pas accepté.
  • Sûreté du typage : assurez-vous de comparer des types compatibles (par exemple, ne comparez pas un champ de chaîne à une liste d'entiers).

Exemple : Expressions

L'exemple doit extraire la valeur de la vitesse pour calculer sa moyenne. Il doit également déterminer si le véhicule est en excès de vitesse (plus de 100 km/h) pour le déclencheur conditionnel. Vous trouverez les noms de champs (dans ce cas, speed) dans la définition du message protobuf utilisé par la source de données. Les expressions suivantes permettent d'y parvenir :

  • SpeedSource.speed : récupère la valeur du champ speed à partir de la source de données SpeedSource.
  • SpeedSource.speed > 27.7 : renvoie true si la vitesse est supérieure à 27,7 m/s (environ 100 km/h).

Déclencheurs : définissez le moment où les actions se produisent

Les déclencheurs définissent le moment où les actions s'exécutent : évaluation d'un agrégateur, génération d'un rapport ou contrôle du cycle de vie de la collecte. Ajoutez tous les déclencheurs définis au tableau triggers de premier niveau.

Champs d'un objet de déclencheur (élément de la liste triggers)
name Identifiant unique de ce déclencheur dans la configuration des métriques.
periodic
data
conditional
Vous devez fournir exactement l'un de ces champs pour définir le comportement.

Déclencheur de données

Se déclenche lorsqu'une source de données SUBSCRIPTION fournit un nouveau message (concept).

Champs de l'objet data (dans un déclencheur)
source_name Le name du data_source que ce déclencheur écoute.

Exemple : Déclencheur de données

Dans l'exemple, mettez à jour le calcul de la vitesse moyenne chaque fois que SpeedSource publie un nouveau message. Ce déclencheur de données se déclenche chaque fois que :

{
  "name": "OnNewSpeed",
  "data": {
    "source_name": "SpeedSource" // Reference to the defined data source
  }
}

Déclencheur périodique

Déclenchement à intervalles réguliers (concept).

Champs de l'objet periodic (dans un déclencheur)
period_ms Nombre non négatif qui définit l'intervalle en millisecondes.

Exemple : Déclencheur périodique

L'exemple nécessite un rapport toutes les minutes. Ce déclencheur périodique se déclenche toutes les 60 000 ms pour générer ce rapport :

{
  "name": "EveryMinute",
  "periodic": {
    "period_ms": 60000 // 60,000 ms = 60 seconds
  }
}

Déclencheur conditionnel

Se déclenche en fonction de l'évaluation d'une expression (concept). Il nécessite un ou plusieurs déclencheurs parents pour démarrer son évaluation. Il s'agit souvent d'un déclencheur de données pour les sources de données ou les agrégateurs de l'expression, ou d'un déclencheur périodique pour interroger les données.

Champs de l'objet conditional (dans un déclencheur)
triggers Tableau contenant au moins un nom de déclencheur parent. Lorsqu'un déclencheur parent se déclenche, le déclencheur conditionnel évalue l'expression.
expression Expression à évaluer. Consultez Expressions.
condition_type Indique quand le déclencheur doit se déclencher, en fonction de l'évaluation de l'expression.
Types de conditions

Le dictionnaire condition_type doit contenir exactement l'un des types de conditions disponibles en tant que clé. Pour en savoir plus, consultez Déclencheurs conditionnels.

Champs de l'objet condition_type (s'excluent mutuellement)
is_true

is_false
Se déclenche lorsqu'une expression booléenne renvoie true ou false, respectivement.
rising_edge

Si la valeur est numérique, l'événement se déclenche lorsqu'elle augmente. Si l'expression est booléenne, elle se déclenche lorsqu'elle passe de false à true.

Peut contenir un objet rising_options (voir Options de bordure).

falling_edge

Si la valeur est numérique, l'événement se déclenche lorsque sa valeur diminue. Si l'expression est booléenne, elle se déclenche lorsqu'elle passe de true à false.

Peut contenir un objet falling_options (voir Options de bordure).

all_changes

Se déclenche lorsque le résultat de l'expression est différent de sa valeur précédente. Si des options de bord sont définies, il n'accepte que les valeurs numériques et booléennes.

Peut contenir rising_options, falling_options ou les deux (voir Options Edge).

Options de périphérie

Les objets rising_options et falling_options comportent les champs suivants. Si une transition correspondante est fournie, elle doit respecter la durée requise. Les transitions sans options spécifiées se déclenchent immédiatement.

Champs pour les objets d'option Edge
min_duration_ms Nombre non négatif (en millisecondes) indiquant la durée pendant laquelle la condition doit être remplie dans le nouvel état avant le déclenchement.
facultatif
require_exact
Valeur booléenne. Si la valeur est "true", toutes les valeurs publiées pendant la durée doivent être identiques pour que le déclencheur se déclenche.

Exemple : Déclencheur conditionnel

Le déclencheur suivant utilise des options de bord. Elle se déclenche si la vitesse dépasse 27,7 m/s et reste élevée pendant au moins cinq secondes :

{
  "name": "SpeedingFor5Seconds",
  "conditional": {
    "triggers": ["OnNewSpeed"],
    "expression": "SpeedSource.speed > 27.7",
    "condition_type": {
      "rising_edge": {
        "rising_options": {
          "min_duration_ms": 5000 // Condition must hold for 5s in new state
        }
      }
    }
  }
}

Agrégateurs : définissez la façon dont les données sont traitées.

Utilisez un agrégateur pour le traitement des données intermédiaires avec état (concept). Définissez un agrégateur et ajoutez-le au tableau aggregators.

Un agrégateur transforme les données et les met à la disposition d'autres agrégateurs et rapports.

Champs d'un agrégateur (élément de la liste aggregators)
name Chaîne définie par l'utilisateur qui identifie cet agrégateur. Les expressions peuvent faire référence à cet agrégateur par son nom pour accéder à ses résultats.
trigger_names Tableau d'un ou de plusieurs noms de déclencheurs qui entraînent l'évaluation de cette agrégation.
facultatif
reset_on_get
Booléen, valeur par défaut : "false". Si la valeur est "true", le système réinitialise l'état d'agrégation après que sa valeur a été consultée par un autre agrégateur, un rapport sur les métriques ou un déclencheur conditionnel.
message_builder Définit les données à lire, à traiter et à agréger. Les champs du message de sortie deviennent alors une source de données pour d'autres agrégateurs et rapports. Il utilise field_assignments, chaque affectation définissant un champ dans le message de sortie.

Générateur de message

Un objet message_builder définit la structure du message de sortie et la logique d'agrégation utilisée pour calculer ses champs. Elle est utilisée dans les agrégateurs et les configurations de rapports.

Champs d'un objet message_builder (dans un agrégateur ou un rapport)
message_type Nom complet du type de message protobuf pour la sortie. Si elle est omise, MCG crée un type de message personnalisé basé sur les types de sortie inférés de field_assignments. N'utilisez cette option que si le générateur de messages fait partie d'un rapport sur les métriques et que votre rapport doit correspondre à une définition de message protobuf spécifique et prédéfinie.
field_assignments Tableau d'objets de définition de champ. Chaque objet spécifie un champ dans le message de sortie et la logique permettant de calculer sa valeur.
Champs d'un objet d'attribution de champ (élément de la liste field_assignments)
field_name Nom défini par l'utilisateur pour le champ. Il identifie la valeur spécifique dans l'objet lorsque vous utilisez la notation par points dans les expressions (aggregator_name.field_name).
aggregation

Objet qui définit la façon dont le système calcule la valeur du champ, avec les champs suivants :

@type Fonction d'agrégation.

  • avg, min, max, sum, stddev : statistiques mathématiques standards.
  • count : comptabilise le nombre de fois où cet agrégateur a été déclenché.
  • delta : différence entre la valeur actuelle et la valeur précédente.
  • vector : crée une liste de valeurs (tampon circulaire).
  • none : transmet la valeur brute.
expression Expression d'entrée pour l'agrégation. Obligatoire pour tous les types d'agrégation, sauf count.
max_length Pour @type: "vector" uniquement. Entier facultatif qui limite la taille du vecteur, créant ainsi un tampon en anneau.

Exemple : Agrégateur

Pour l'exemple, calculez les statistiques entre les rapports par minute. Cet agrégateur est déclenché par OnNewSpeed pour calculer la vitesse moyenne (avg), comptabiliser les lectures (count) et stocker les cinq dernières valeurs de vitesse (vector). Définissez reset_on_get sur true. Cela réinitialise les statistiques chaque fois que MinuteReport les lit, ce qui lance une nouvelle période de collecte pour l'agrégateur pour la minute suivante :

{
  "name": "SpeedAggregator",
  "trigger_names": ["OnNewSpeed"], // Update aggregation on new speed data
  "reset_on_get": true, // Reset stats after they are read by the report configuration
  "message_builder": {
    "field_assignments": [
      {
        "field_name": "average_speed",
        "aggregation": {
          "@type": "avg",
          "expression": "SpeedSource.speed"
        }
      },
      {
        "field_name": "speed_reading_count",
        "aggregation": {
          "@type": "count" // Counts triggers (that is, processed speed readings) since last reset
        }
      },
      {
        "field_name": "speed_history_last5",
        "aggregation": {
          "@type": "vector",
          "expression": "SpeedSource.speed",
          "max_length": 5 // Keep last 5 readings
        }
      }
    ]
  }
}

Créer une sortie

Pour définir le résultat final de votre campagne de télémétrie, ajoutez des objets au tableau report_configs (concept). Ces configurations déterminent la façon dont les données traitées sont regroupées et le moment où elles sont générées. Vous pouvez définir plusieurs configurations de rapports dans une même configuration de métriques pour réutiliser des composants.

Vous contrôlez la génération de rapports à l'aide du champ trigger_names. De plus, vous pouvez utiliser report_initial pour générer un rapport immédiatement lorsque la configuration est activée, et report_incomplete pour générer un rapport final lorsque la collecte de données est interrompue.

Remarque : Pour associer le traitement au résultat, utilisez le type d'agrégation none (@type: "none") pour lire les valeurs précalculées d'un agrégateur. Étant donné que les rapports sont généralement des instantanés sans état, cela permet de conserver une logique avec état complexe dans les agrégateurs et de réserver les rapports à la mise en forme.

Champs d'un objet de configuration de rapport (élément de la liste report_configs)
name Nom unique du rapport. Ce nom apparaît dans les métadonnées du rapport généré.
trigger_names Tableau de noms de déclencheurs qui entraînent la génération et la publication du rapport.
message_builder Pour en savoir plus, consultez Créateur de messages. Définit le contenu du rapport. Les agrégations ne sont évaluées que lorsque le rapport est déclenché. Par exemple, une agrégation de vecteur ajoute une valeur par rapport, et une agrégation de nombre reflète le nombre de rapports.
facultatif
report_incomplete
(par défaut : "false")
Valeur booléenne. Si la valeur est "true", le système génère un rapport final à l'arrêt ou à la fin de la collecte de données, même si des données sont manquantes.
facultatif
report_initial
(par défaut : "false")
Valeur booléenne. Si la valeur est "true", le système génère un rapport immédiatement lorsque la configuration des métriques est activée.

Exemple : Configuration de rapport

Enfin, définissez la configuration du rapport pour l'exemple. Il est déclenché par EveryMinute. Il lit la vitesse moyenne calculée et le nombre de lectures à partir de SpeedAggregator à l'aide d'une agrégation none, qui transmet la valeur pré-agrégée au rapport :

{
  "name": "MinuteReport",
  "trigger_names": ["EveryMinute"], // Generate report every minute
  "message_builder": {
    "field_assignments": [
      {
        "field_name": "average_speed",
        "aggregation": {
          "@type": "none", // Read the value directly from the aggregator
          "expression": "SpeedAggregator.average_speed"
        }
      },
      {
        "field_name": "reading_count",
        "aggregation": {
          "@type": "none",
          "expression": "SpeedAggregator.speed_reading_count"
        }
      }
    ]
  }
}

Champs de premier niveau

En plus des tableaux data_sources, aggregators, triggers et report_configs, la description d'une configuration de métriques nécessite une référence au catalogue de signaux. Vous pouvez également inclure des champs facultatifs pour attribuer un UUID spécifique et gérer le cycle de vie de la collection.

Définir l'UUID

Chaque MetricsConfig nécessite un identifiant unique universel (UUID). Si vous fournissez un existing_uuid, MCG l'utilise. Sinon, il en crée un aléatoire. Pour assurer la cohérence entre les déploiements et les outils, spécifiez un existing_uuid.

La chaîne doit être un UUID valide avec des traits d'union et ne contenir que des lettres minuscules.

"existing_uuid": "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",

Définitions des signaux

Pour valider les noms et les types de signaux, MCG a besoin d'accéder à un catalogue de signaux de véhicule. Il s'agit d'un protobuf FileDescriptorSet contenant vos définitions VSIDL .proto (empaquetées et importées dans MCG). Pour savoir comment créer et importer un catalogue, consultez Catalogues de signaux de véhicules.

Spécifiez la version du catalogue dans le champ vs_version de l'objet JSON :

"vs_version": "v1.0",

Définir des déclencheurs de cycle de vie

Dans le contexte d'une campagne de télémétrie, le cycle de vie d'un MetricsConfig détermine le moment où les données sont réellement enregistrées. Pendant que le système de gestion des campagnes déploie et active la configuration sur l'appareil, vous pouvez utiliser des déclencheurs de cycle de vie pour contrôler précisément quand les données sont collectées lors de ce déploiement.

Cela vous permet d'aligner la collecte de données sur les habitudes d'utilisation du véhicule, comme un "trajet" (IgnitionOn à IgnitionOff) ou une "session de recharge", sans avoir à désactiver la configuration.

  • Contrôle de la session (démarrer/mettre en veille) : utilisez start_trigger_name et stop_trigger_name pour contrôler le moment où la collecte a lieu. Par exemple, pour collecter des données uniquement lorsque le véhicule est en mouvement, utilisez IgnitionOn comme déclencheur de début et IgnitionOff comme déclencheur de fin. La configuration reste active sur l'appareil, mais est effectivement "mise en pause" (la collecte et le traitement des données s'arrêtent) lorsque le déclencheur d'arrêt se déclenche, et ne reprend que lorsque le déclencheur de démarrage se déclenche à nouveau.

    Important : Cette action ne fait que suspendre la collecte. Elle ne définit pas de fenêtres logiques ni de jeux de données distincts, et n'a aucun autre effet secondaire. Les valeurs d'agrégateur ne sont pas réinitialisées lorsque la collecte est suspendue ou reprise.

  • Détection unique (fin) : utilisez deactivate_trigger_name si la configuration ne doit s'exécuter qu'une seule fois (par exemple, pour détecter la première occurrence d'un code d'erreur spécifique), puis se désactiver définitivement sur cet appareil, même si la campagne est techniquement toujours active.

Si vous ne spécifiez aucun déclencheur de cycle de vie, la collecte de données commence immédiatement lorsque la configuration est activée par la campagne et se poursuit en continu jusqu'à la fin de la campagne.

Champs de cycle de vie de premier niveau (objet racine)
facultatif
start_trigger_name
Nom d'un déclencheur qui démarre la session de collecte. Peut être défini sans stop_trigger_name.
facultatif
stop_trigger_name
Nom d'un déclencheur qui met en pause la session de collecte (par exemple, lorsque le véhicule est à l'arrêt). Si cette valeur est définie, start_trigger_name doit également l'être.
facultatif
deactivate_trigger_name
Nom d'un déclencheur qui finalise et désactive entièrement le `MetricsConfig`.

Avancé : Définitions proto personnalisées

Dans deux cas principaux, vs_version seul ne suffit pas pour que MCG comprenne tous les types de messages dans la description d'une configuration de métriques :

  1. Échec de l'inférence de type : comme expliqué dans le format source_identifier, MCG ne peut pas inférer le type lorsque source_identifier utilise un FQIN ou un nom personnalisé.
  2. Messages personnalisés : la description de la configuration des métriques utilise des messages protobuf introuvables dans le catalogue VSIDL spécifié dans vs_version. Cela se produit lorsque vous définissez message_type dans un message_builder pour un format de rapport personnalisé.

Dans ce cas, utilisez data_source_message_types pour aider MCG à inférer les types et descriptor_protos pour fournir les définitions de message.

data_source_message_types

Mappez la chaîne source_identifier à son type de message protobuf complet. La clé dans data_source_message_types doit correspondre à la valeur source_identifier de l'entrée data_sources :

"data_source_message_types": {
  "MyCustomSpeedService": "com.sdv.example.SampleMessage"
}

descriptor_protos

Fournissez des définitions pour tous les types de messages utilisés dans data_source_message_types ou message_builder qui ne figurent pas dans vs_version configuré.

Transmettez un descriptorpb.FileDescriptorSet encodé en base64 dans le tableau descriptor_protos. Générez-le à partir des fichiers .proto à l'aide du compilateur Protobuf protoc.

"descriptor_protos": [
  "Cu8BCiZtY2cvdGVzdGRhdGEvbWF4YXZnY3..." // Base64 string
]

Exemple : description complète de la configuration

Les sections précédentes définissent tous les composants de l'exemple : générer un rapport toutes les minutes avec la vitesse moyenne des véhicules observée au cours de cette minute.

Les composants sont les suivants :

  • Une source de données (SpeedSource) pour obtenir des données de vitesse jusqu'à une fois par seconde.
  • Déclencheur de données (OnNewSpeed) qui se déclenche lorsque SpeedSource envoie des données.
  • Déclencheur périodique (EveryMinute) qui se déclenche toutes les 60 secondes.
  • Un agrégateur (SpeedAggregator) qui utilise OnNewSpeed pour calculer la vitesse moyenne, compter les lectures et stocker les valeurs récentes, en les réinitialisant lorsqu'elles sont lues.
  • Configuration de rapport (MinuteReport) qui utilise EveryMinute pour déclencher un rapport contenant la vitesse moyenne et le nombre de SpeedAggregator.
  • Champs de premier niveau (existing_uuid, vs_version) permettant d'identifier la configuration des métriques et de spécifier le catalogue VSIDL à utiliser pour les définitions des signaux.

Combinés, ces éléments forment la description complète d'une configuration de métriques :

{
  "existing_uuid": "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8", // Unique identifier for the configuration
  "vs_version": "example_version", // Version of the VSIDL catalog to use
  "data_sources": [
    {
      "name": "SpeedSource",
      "source_identifier": "mcg.test.subpkg.speed_msg",
      "connection_type": "SUBSCRIPTION",
      "sub_sampling_interval_ms": 1000
    }
  ],
  "aggregators": [
    {
      "name": "SpeedAggregator",
      "trigger_names": ["OnNewSpeed"],
      "reset_on_get": true,
      "message_builder": {
        "field_assignments": [
          {
            "field_name": "average_speed",
            "aggregation": {
              "@type": "avg",
              "expression": "SpeedSource.speed"
            }
          },
          {
            "field_name": "speed_reading_count",
            "aggregation": { "@type": "count" }
          },
          {
            "field_name": "speed_history_last5",
            "aggregation": {
              "@type": "vector",
              "expression": "SpeedSource.speed",
              "max_length": 5
            }
          }
        ]
      }
    }
  ],
  "triggers": [
    {
      "name": "OnNewSpeed",
      "data": { "source_name": "SpeedSource" }
    },
    {
      "name": "EveryMinute",
      "periodic": { "period_ms": 60000 }
    }
  ],
  "report_configs": [
    {
      "name": "MinuteReport",
      "trigger_names": ["EveryMinute"],
      "message_builder": {
        "field_assignments": [
          {
            "field_name": "average_speed",
            "aggregation": {
              "@type": "none",
              "expression": "SpeedAggregator.average_speed"
            }
          },
          {
            "field_name": "reading_count",
            "aggregation": {
              "@type": "none",
              "expression": "SpeedAggregator.speed_reading_count"
            }
          }
        ]
      }
    }
  ]
}

Modèle de référence

Pour la définition de l'API, consultez la documentation de référence de l'API MCG.

Les sections suivantes fournissent une référence complète de la description d'une configuration de métriques. Utilisez-le comme guide pour créer votre propre description d'une configuration de métriques.

Champs de premier niveau

{
  "existing_uuid": "00000000-0000-0000-0000-000000000000", // Optional
  "vs_version": "example_version", // Optional
  "descriptor_protos": ["..."], // Optional. Base64 encoded FileDescriptorSet
  "data_source_message_types": {
    "ExampleServiceName": "com.example.ProtoMessage"
  }, // Optional
  "start_trigger_name": "DataTriggerExample", // Optional
  "stop_trigger_name": "ConditionalTriggerExample", // Optional
  "deactivate_trigger_name": "PeriodicTriggerExample" // Optional
}

Entrée : sources de données et agrégateurs

{
  "data_sources": [
    {
      "name": "SubscriptionExample",
      "source_identifier": "com.example.sdv.ExampleMessage|example-unit",
      "connection_type": "SUBSCRIPTION", // Options: SUBSCRIPTION (default), ON_DEMAND
      "sub_sampling_interval_ms": 100, // Optional
      "fetch_last_message": false // Optional. Default: false
    },
    {
      "name": "RegistryExample",
      // Configurable Publisher Registry-based publisher (matches data_source_message_types)
      "source_identifier": "ExampleServiceName",
      "connection_type": "SUBSCRIPTION"
    },
    {
      "name": "GetterExample",
      "source_identifier": "com.example.sdv.ExampleConfig|example-unit",
      "connection_type": "ON_DEMAND",
      "configuration": {
        "type_url": "type.googleapis.com/example.Config",
        "value_json": {} // Or value_textproto, value (base64)
      }
    }
  ],
  "aggregators": [
    {
      "name": "AggregatorExample",
      "trigger_names": ["DataTriggerExample"],
      "reset_on_get": false, // Optional. Default: false. If true, resets state after it's read
      "message_builder": {
        "message_type": "com.example.AggregatedMessage", // Optional
        "field_assignments": [
          {
            "field_name": "avg_example",
            "aggregation": {
              // Options: avg, count, min, max, sum, stddev, delta, vector, none
              "@type": "avg",
              "expression": "SubscriptionExample.value"
            }
          },
          {
            "field_name": "count_example",
            "aggregation": {
              "@type": "count" // Counts number of evaluations. No expression needed
            }
          },
          {
            "field_name": "vector_example",
            "aggregation": {
              "@type": "vector",
              "expression": "SubscriptionExample.value",
              "max_length": 10 // Optional. If set, creates a ring buffer
            }
          }
        ]
      }
    }
  ]
}

Logique et traitement : déclencheurs

{
  "triggers": [
    {
      "name": "PeriodicTriggerExample",
      "periodic": { "period_ms": 1000 }
    },
    {
      "name": "DataTriggerExample",
      "data": { "source_name": "SubscriptionExample" }
    },
    {
      "name": "ConditionalTriggerExample",
      "conditional": {
        "triggers": ["PeriodicTriggerExample"],
        "expression": "SubscriptionExample.value > 0",
        "condition_type": {
          // Options: is_true, is_false, rising_edge, falling_edge, all_changes
          "rising_edge": {
            "rising_options": { "min_duration_ms": 0, "require_exact": false }
          }
        }
      }
    }
  ]
}

Sortie : configurations de rapport

{
  "report_configs": [
    {
      "name": "ReportExample",
      "trigger_names": ["PeriodicTriggerExample"],
      "report_incomplete": false, // Optional. Default: false
      "report_initial": false, // Optional. Default: false
      "message_builder": {
        "message_type": "com.example.ReportMessage", // Optional. Must be defined in VSIDL catalog or descriptor_protos. Message type will be inferred if not provided
        "field_assignments": [
          {
            "field_name": "avg_example",
            "aggregation": {
              "@type": "none", // Passthrough since aggregation is done in AggregatorExample
              "expression": "AggregatorExample.avg_example"
            }
          }
        ]
      }
    }
  ]
}

Syntaxe des expressions

Catégorie Syntaxe Description
Accès aux données source_name
source_name.field
source_name.field.subfield
Accéder au message complet à partir d'une source de données ou d'un agrégateur
Accéder à un champ spécifique du message (y compris les champs imbriqués)
Arithmétique +, -, *, /, %, ** Mathématiques standards. ** correspond à l'exponentiation.
Logique &&, ||, !, ^ AND, OR, NOT, XOR.
Relationnel ==, !=, <, <=, >, >= == et != fonctionnent sur tous les types. D'autres nécessitent des chiffres.
List contains(list, item)
doesnotcontain(list, item)
alleq(list, value)
Opère sur les vecteurs (tableaux). alleq(list, value) renvoie true si tous les éléments de list sont égaux à value.
Fonctions timestamp(clock_type) Heure actuelle en nanosecondes.
clock_type : REALTIME_CLOCK ou
MONOTONIC_TIME_SINCE_BOOT_OR_RESUME
abs(n) Valeur absolue
floor(n), round(n), ceil(n) Fonctions d'arrondi
Ordre des opérations () Regroupement standard pour la priorité