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 :
- Spécifiez les sources de données : définissez l'origine de vos données.
- Définir la logique et le traitement : configurez des règles pour déterminer quand collecter les données et comment les traiter.
- Créer une sortie : regroupez les données traitées dans un message final.
- 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.
Services SDV (basés sur Pub/Sub) : les données sont disponibles à partir des canaux Pub/Sub définis dans VSIDL.
Services SDV (basés sur RPC) : les données sont disponibles si le service expose les RPC
CreateSubscriptionouGetLatestMessage.Éditeurs configurables basés sur le Registre des éditeurs : les données sont disponibles si l'application s'enregistre à l'aide de l'interface Android Binder
IConfigurablePublisherRegistryou de la bibliothèque Registre des éditeurs configurables du SDK Telemetry.
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). |
||||
facultatifconfiguration |
RPC et registre des éditeurs configurables uniquement.Objet permettant de configurer la source de données avec les champs suivants :
|
||||
Champs pour le type de connexion SUBSCRIPTION |
|||||
facultatifsub_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. | ||||
facultatiffetch_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 : Sisub_sampling_interval_msest 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 champspeedà partir de la source de donnéesSpeedSource.SpeedSource.speed > 27.7: renvoietruesi 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. |
periodicdataconditional |
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_trueis_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 Peut contenir un objet |
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 Peut contenir un objet |
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 |
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. |
facultatifrequire_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. |
facultatifreset_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 :
|
||||||
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. |
facultatifreport_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. |
facultatifreport_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_nameetstop_trigger_namepour contrôler le moment où la collecte a lieu. Par exemple, pour collecter des données uniquement lorsque le véhicule est en mouvement, utilisezIgnitionOncomme déclencheur de début etIgnitionOffcomme 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_namesi 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) | |
|---|---|
facultatifstart_trigger_name |
Nom d'un déclencheur qui démarre la session de collecte. Peut être défini sans stop_trigger_name. |
facultatifstop_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. |
facultatifdeactivate_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 :
- Échec de l'inférence de type : comme expliqué dans le format
source_identifier, MCG ne peut pas inférer le type lorsquesource_identifierutilise un FQIN ou un nom personnalisé. - 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éfinissezmessage_typedans unmessage_builderpour 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 lorsqueSpeedSourceenvoie des données. - Déclencheur périodique (
EveryMinute) qui se déclenche toutes les 60 secondes. - Un agrégateur (
SpeedAggregator) qui utiliseOnNewSpeedpour 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 utiliseEveryMinutepour déclencher un rapport contenant la vitesse moyenne et le nombre deSpeedAggregator. - 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_namesource_name.fieldsource_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 ouMONOTONIC_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é |