In diesem Leitfaden wird das JSON-Anfrageformat für den /api/v1/generate_metrics_config-Endpunkt des Tools „Metrics Configuration Generator“ (MCG) beschrieben. In diesem Format können Sie eine Telemetriekampagne definieren, indem Sie die Datenerhebung, die Verarbeitung auf dem Gerät und die Berichterstellung in einer für Menschen lesbaren Struktur angeben.
Das MCG-Tool validiert dieses JSON-Objekt und sucht nach Problemen wie Typkonflikten, Zirkelbezügen oder nicht definierten Referenzen. Anschließend wird es in eine MetricsConfig-Protokollzwischenspeichernachricht (protobuf) kompiliert. Diese MetricsConfig-Nachricht ist das binäre Format, das der Telemetriedienst auf dem Gerät ausführt, um die Kampagne auszuführen.
Voraussetzungen:Sie sollten sich mit JSON-Schemas, Protobuf und grundlegenden Datenstrukturen auskennen. Eine konzeptionelle Übersicht finden Sie unter Konzepte für die Messwertkonfiguration.
Konfigurationsbeschreibung verfassen
So erstellen Sie eine Kampagne zum Erfassen von Messwerten:
- Datenquellen angeben: Legen Sie fest, woher Ihre Daten stammen.
- Logik und Verarbeitung definieren: Richten Sie Regeln dafür ein, wann Daten erhoben und wie sie verarbeitet werden sollen.
- Ausgabe erstellen: Die verarbeiteten Daten werden in einer endgültigen Nachricht zusammengefasst.
- Felder der obersten Ebene: Fügen Sie Felder der obersten Ebene wie UUID, Signaldefinitionen und Lebenszyklussteuerung hinzu.
Beispiel: Bericht zur Durchschnittsgeschwindigkeit
In dieser Anleitung wird anhand eines Beispiels gezeigt, wie alle Komponenten zusammenarbeiten. Es wird ein Bericht erstellt, in dem die durchschnittliche Fahrzeuggeschwindigkeit pro Minute berechnet wird. Dazu werden eine Datenquelle (SpeedSource) zum Erfassen von Geschwindigkeitsdaten, Trigger (OnNewSpeed, EveryMinute) zum Steuern des Ausführungsablaufs, ein Aggregator (SpeedAggregator) zum Berechnen des Durchschnitts und eine Konfiguration für Messwertberichte (MinuteReport) zum Verpacken des Ergebnisses definiert. Die Beispiele in den aufklappbaren Abschnitten bauen auf diesem Szenario auf.
Datenquellen angeben
Telemetrie unterstützt das Erheben von Daten von SDV-Diensten (über die SDV-Middleware) und von Verlagen und Webpublishern, die auf der Configurable Publisher Registry basieren.
SDV-Dienste (auf Pub/Sub basierend): Daten sind über Pub/Sub-Channels verfügbar, die in VSIDL definiert sind.
SDV-Dienste (RPC-basiert): Daten sind verfügbar, wenn der Dienst
CreateSubscription- oderGetLatestMessage-RPCs bereitstellt.Konfigurierbare Publisher-Registrierung: Daten sind verfügbar, wenn die Anwendung sich über die
IConfigurablePublisherRegistry-Android-Binder-Schnittstelle oder die Bibliothek für die konfigurierbare Publisher-Registrierung aus dem Telemetry SDK registriert.
Wenn Sie Daten in SDV verwenden möchten, definieren Sie eine Datenquelle (Konzept) und fügen Sie sie dem Array data_sources hinzu.
Felder eines Datenquellenobjekts (Element in der Liste data_sources) |
|||||
|---|---|---|---|---|---|
name |
Ein benutzerdefinierter String, der diese Datenquelle in der Messwertkonfiguration identifiziert. | ||||
source_identifier |
Die Kennung, die zum Erkennen des Dienstes verwendet wird. Weitere Informationen finden Sie unter source_identifier-Format. |
||||
connection_type |
SUBSCRIPTION für einen kontinuierlichen Datenstream (erforderlich für Datentrigger) oder ON_DEMAND für das On-Demand-Abrufen (weitere Informationen finden Sie unter Datenquellen konfigurieren). |
||||
optionalconfiguration |
Nur RPC und konfigurierbares Publisher-Register. Ein Objekt zum Konfigurieren der Datenquelle mit den folgenden Feldern:
|
||||
Felder für den Verbindungstyp SUBSCRIPTION |
|||||
optionalsub_sampling_interval_ms |
Nur Pub/Sub: Eine nicht negative Ganzzahl (Millisekunden), um die Häufigkeit von Nachrichten zu drosseln, indem das Mindestintervall zwischen Nachrichten angegeben wird. | ||||
optionalfetch_last_message(Standard: false) |
Nur Pub/Sub. Boolescher Wert. Bei true wird beim Herstellen der Verbindung die letzte Nachricht abgerufen. |
||||
Nicht alle Optionen sind für alle Arten von Datenquellen verfügbar. Weitere Informationen
Format von „source_identifier“
Der Telemetriedienst akzeptiert mehrere Quell-ID-Formate. Eine Übersicht finden Sie unter Datenquellendefinition in Messwertkonfigurationen.
MCG leitet den Protobuf-Nachrichtentyp nur dann aus source_identifier ab, wenn das Format „Unit Type Name“ verwendet wird. Wenn Sie FQIN oder einen benutzerdefinierten Namen (aus der Configurable Publisher Registry) verwenden, kann MCG den Typ nicht ableiten. In diesen Fällen müssen Sie data_source_message_types angeben. Wenn der Typ nicht in Ihrem Katalog enthalten ist, müssen Sie auch seine Definition in descriptor_protos angeben.
Beispiel: Datenquelle definieren
In diesem Beispiel wird die Fahrzeuggeschwindigkeit gemeldet. Sehen Sie zuerst im VSIDL-Katalog nach, um den Dienst zu ermitteln, der diese Daten veröffentlicht.
Suchen Sie im Beispielkatalog in der SDV-Codebasis nach dem relevanten Dienst. Geben Sie entsprechend dem Format von source_identifier den Protobuf-Nachrichtentyp mcg.test.subpkg.speed_msg an. Da die Geschwindigkeit in der Regel häufig veröffentlicht wird, verwenden Sie sub_sampling_interval_ms, um die Aktualisierungen auf eine Nachricht pro Sekunde zu beschränken:
{ "name": "SpeedSource", "source_identifier": "mcg.test.subpkg.speed_msg", "connection_type": "SUBSCRIPTION", "sub_sampling_interval_ms": 1000 // Limit updates to 1 per second }
Logik und Verarbeitung definieren
Die Logik wird von zwei Komponenten übernommen, die zusammenarbeiten: Mit Triggern (Konzept) wird definiert, wann etwas passiert. Aggregatoren (Konzept) definieren, wie Daten basierend auf diesen Triggern verarbeitet werden. Da Ausdrücke (Konzept) für Triggerbedingungen und Aggregationslogik von entscheidender Bedeutung sind, wird in diesem Abschnitt zuerst beschrieben, wie sie geschrieben werden.
Ausdrücke
Mit Ausdrücken können Sie Berechnungen und Bedingungen in einer für Menschen lesbaren Syntax definieren. MCG kompiliert diese Strings in ein ausführbares Format, das für die On-Device-Auswertung optimiert ist.
Mit Ausdrücken lassen sich arithmetische Berechnungen, logische Bedingungen und Datenvergleiche darstellen. Die vollständige Syntax, einschließlich Operatoren und Funktionen, finden Sie unter Syntax für Ausdrücke.
Datenaktualität:Wenn in einem Ausdruck auf eine Datenquelle zugegriffen wird, hängt das Abrufverhalten vom Verbindungstyp ab:
SUBSCRIPTION: Verwendet die vom Telemetriedienst zwischengespeicherte Nachricht last received. Hinweis: Wennsub_sampling_interval_msfestgelegt ist, kann dies von der absolut neuesten veröffentlichten Nachricht abweichen.ON_DEMAND: Löst einen sofortigen Aufruf aus, um die aktuelle Nachricht vom Dienst abzurufen.
Typeinschränkungen
- Arrays:Der direkte Zugriff auf Arrayindexe (z. B.
my_data_source.my_array[0]) wird nicht unterstützt. - Typsicherheit:Achten Sie darauf, dass Sie kompatible Typen vergleichen. Vergleichen Sie beispielsweise kein String-Feld mit einer Liste von Ganzzahlen.
Beispiel: Ausdrücke
Im Beispiel muss der Geschwindigkeitswert extrahiert werden, um den Durchschnitt zu berechnen. Außerdem muss ermittelt werden, ob das Fahrzeug die Geschwindigkeitsbegrenzung (über 100 km/h) überschreitet, um den bedingten Trigger auszulösen. Die Feldnamen (in diesem Fall speed) finden Sie in der Protobuf-Nachrichtendefinition, die von der Datenquelle verwendet wird. Die folgenden Ausdrücke bewirken dies:
SpeedSource.speed: Ruft den Wert des Feldsspeedaus der DatenquelleSpeedSourceab.SpeedSource.speed > 27.7: Ergibttrue, wenn die Geschwindigkeit höher als 27,7 m/s (ca.100 km/h) ist.
Trigger: Definieren, wann Aktionen ausgeführt werden
Mit Triggern wird definiert, wann Aktionen ausgeführt werden, z. B. wenn ein Aggregator ausgewertet, ein Bericht generiert oder der Erfassungslebenszyklus gesteuert wird. Fügen Sie alle definierten Trigger dem triggers-Array der obersten Ebene hinzu.
Felder eines Triggerobjekts (Element in der Liste triggers) |
|
|---|---|
name |
Eine eindeutige Kennung für diesen Trigger in der Messkonfiguration. |
periodicdataconditional |
Sie müssen genau eines dieser Felder angeben, um das Verhalten zu definieren. |
Datentrigger
Wird ausgelöst, wenn eine SUBSCRIPTION-Datenquelle eine neue Nachricht (Konzept) bereitstellt.
Felder des data-Objekts (in einem Trigger) |
|
|---|---|
source_name |
Die name des data_source, auf die dieser Trigger reagiert. |
Beispiel: Datentrigger
Im Beispiel wird die Berechnung der Durchschnittsgeschwindigkeit jedes Mal aktualisiert, wenn SpeedSource eine neue Nachricht veröffentlicht. Dieser Datentrigger wird jedes Mal ausgelöst, wenn Folgendes passiert:
{ "name": "OnNewSpeed", "data": { "source_name": "SpeedSource" // Reference to the defined data source } }
Regelmäßiger Trigger
Wird in regelmäßigen Abständen ausgelöst (Konzept).
Felder des periodic-Objekts (in einem Trigger) |
|
|---|---|
period_ms |
Eine nicht negative Zahl, die das Intervall in Millisekunden definiert. |
Beispiel: Regelmäßiger Trigger
Im Beispiel ist ein Bericht pro Minute erforderlich. Dieser periodische Trigger wird alle 60.000 ms ausgelöst,um den Bericht zu generieren:
{ "name": "EveryMinute", "periodic": { "period_ms": 60000 // 60,000 ms = 60 seconds } }
Bedingungstrigger
Wird ausgelöst, wenn ein Ausdruck (Konzept) ausgewertet wird. Für die Auswertung sind ein oder mehrere übergeordnete Trigger erforderlich. Das ist oft ein Datentrigger für die Datenquellen oder Aggregatoren im Ausdruck oder ein periodischer Trigger zum Abrufen von Daten.
Felder des conditional-Objekts (in einem Trigger) |
|
|---|---|
triggers |
Ein Array mit mindestens einem übergeordneten Triggernamen. Wenn ein übergeordneter Trigger ausgelöst wird, wertet der bedingte Trigger den Ausdruck aus. |
expression |
Der auszuwertende Ausdruck. Weitere Informationen finden Sie unter Ausdrücke. |
condition_type |
Gibt an, wann der Trigger ausgelöst werden soll, basierend auf der Auswertung des Ausdrucks. |
Bedingungstypen
Das condition_type-Dictionary muss genau einen der verfügbaren Bedingungstypen als Schlüssel enthalten. Weitere Informationen finden Sie unter Bedingungstrigger.
Felder des condition_type-Objekts (schließen sich gegenseitig aus) |
|
|---|---|
is_trueis_false |
Wird ausgelöst, wenn ein boolescher Ausdruck zu true oder false ausgewertet wird. |
rising_edge |
Wenn der Wert numerisch ist, wird das Ereignis ausgelöst, wenn er steigt. Wenn der Ausdruck boolesch ist, wird das Ereignis ausgelöst, wenn sich der Wert von Kann ein |
falling_edge |
Wenn der Wert numerisch ist, wird das Ereignis ausgelöst, wenn der Wert sinkt. Wenn der Ausdruck boolesch ist, wird das Ereignis ausgelöst, wenn sich der Wert von Kann ein |
all_changes |
Wird ausgelöst, wenn sich das Ergebnis des Ausdrucks vom vorherigen Wert unterscheidet. Wenn Edge-Optionen festgelegt sind, werden nur numerische und boolesche Werte unterstützt. Kann |
Edge-Optionen
Die Objekte rising_options und falling_options haben die folgenden Felder. Falls angegeben, muss der entsprechende Übergang die Anforderung an die Dauer erfüllen.
Übergänge ohne angegebene Optionen werden sofort ausgelöst.
| Felder für Edge-Optionsobjekte | |
|---|---|
min_duration_ms |
Eine nicht negative Zahl (in Millisekunden), die angibt, wie lange die Bedingung im neuen Status erfüllt sein muss, bevor der Trigger ausgelöst wird. |
optionalrequire_exact |
Boolescher Wert. Wenn „true“, müssen alle während des Zeitraums veröffentlichten Werte gleich sein, damit der Trigger ausgelöst wird. |
Beispiel: Bedingter Trigger
Im folgenden Trigger werden Edge-Optionen verwendet. Die Benachrichtigung wird ausgelöst, wenn die Geschwindigkeit 27,7 m/s überschreitet und mindestens 5 Sekunden lang hoch bleibt:
{ "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 } } } } }
Aggregatoren: Definieren, wie Daten verarbeitet werden
Verwenden Sie einen Aggregator für die zustandsbehaftete Zwischenverarbeitung von Daten (Konzept).
Definieren Sie einen Aggregator und fügen Sie ihn dem Array aggregators hinzu.
Ein Aggregator transformiert Daten und stellt sie anderen Aggregatoren und Berichten zur Verfügung.
Felder eines Aggregators (Element in der Liste aggregators) |
|
|---|---|
name |
Ein benutzerdefinierter String, der diesen Aggregator identifiziert. Ausdrücke können anhand des Namens auf diesen Aggregator verweisen, um auf seine Ergebnisse zuzugreifen. |
trigger_names |
Ein Array mit einem oder mehreren Triggernamen, die dazu führen, dass diese Aggregation ausgewertet wird. |
optionalreset_on_get |
Boolesch, Standardwert: „false“. Wenn „true“, setzt das System den Aggregationsstatus zurück, nachdem sein Wert von einem anderen Aggregator, Messwertbericht oder bedingten Trigger abgerufen wurde. |
message_builder |
Definiert die Daten, die gelesen, verarbeitet und zusammengefasst werden sollen. Die Felder der Ausgabenachricht werden dann zu einer Datenquelle für andere Aggregatoren und Berichte. Dabei wird field_assignments verwendet. Jede Zuweisung definiert ein Feld in der Ausgabenachricht. |
Nachrichten-Builder
Ein message_builder-Objekt definiert die Struktur der Ausgabenachricht und die Aggregationslogik, die zum Berechnen der Felder verwendet wird. Sie wird sowohl in Aggregatoren als auch in Berichtskonfigurationen verwendet.
Felder eines message_builder-Objekts (im Aggregator oder Bericht) |
|
|---|---|
message_type |
Der voll qualifizierte Name des Protobuf-Nachrichtentyps für die Ausgabe. Wenn dieser Parameter weggelassen wird, erstellt MCG einen benutzerdefinierten Nachrichtentyp basierend auf den abgeleiteten Ausgabetypen von field_assignments. Verwenden Sie diese Option nur, wenn der Message-Builder Teil eines Messwertberichts ist und Ihr Bericht einer bestimmten, vordefinierten Protobuf-Nachrichtendefinition entsprechen muss. |
field_assignments |
Ein Array von Felddefinitionsobjekten. Jedes Objekt gibt ein Feld in der Ausgabenachricht und die Logik zum Berechnen seines Werts an. |
Felder eines Feldzuweisungsobjekts (Element in der Liste field_assignments) |
|||||||
|---|---|---|---|---|---|---|---|
field_name |
Ein benutzerdefinierter Name für das Feld. Sie gibt den spezifischen Wert innerhalb des Objekts an, wenn in Ausdrücken die Punktnotation verwendet wird (aggregator_name.field_name). |
||||||
aggregation |
Ein Objekt, das definiert, wie der Wert des Felds berechnet wird. Es enthält die folgenden Felder:
|
||||||
Beispiel: Aggregator
Im Beispiel werden Statistiken zwischen den Minutenberichten berechnet. Dieser Aggregator wird durch OnNewSpeed ausgelöst, um die Durchschnittsgeschwindigkeit (avg) zu berechnen, Messwerte zu zählen (count) und die letzten fünf Geschwindigkeitswerte zu speichern (vector). Setzen Sie reset_on_get auf true. Dadurch werden die Statistiken jedes Mal zurückgesetzt, wenn MinuteReport sie liest. Für die nächste Minute wird ein neues Erfassungsfenster für den Aggregator gestartet:
{ "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 } } ] } }
Ausgabe erstellen
Um die endgültige Ausgabe Ihrer Telemetriekampagne zu definieren, fügen Sie dem report_configs-Array (Konzept) Objekte hinzu. Diese Konfigurationen legen fest, wie verarbeitete Daten verpackt und wann sie generiert werden. Sie können mehrere Berichtskonfigurationen in einer Messwertkonfiguration definieren, um Komponenten wiederzuverwenden.
Sie steuern die Berichterstellung mit dem Feld trigger_names. Außerdem können Sie mit report_initial einen Bericht sofort nach der Aktivierung der Konfiguration und mit report_incomplete einen endgültigen Bericht erstellen, wenn die Datenerhebung unterbrochen wird.
Hinweis:Wenn Sie die Verarbeitung mit der Ausgabe verbinden möchten, verwenden Sie den Aggregationstyp none (@type: "none"), um vorab berechnete Werte aus einem Aggregator zu lesen. Da Berichte in der Regel zustandslose Snapshots sind, wird so komplexe zustandsbehaftete Logik in Aggregatoren beibehalten und Berichte werden für die Formatierung reserviert.
Felder eines Berichtskonfigurationsobjekts (Element in der Liste report_configs) |
|
|---|---|
name |
Ein eindeutiger Name für den Bericht. Dieser Name wird in den generierten Berichtsmetadaten angezeigt. |
trigger_names |
Ein Array von Triggernamen, die dazu führen, dass der Bericht generiert und veröffentlicht wird. |
message_builder |
Weitere Informationen finden Sie unter Message Builder. Dadurch wird der Inhalt des Berichts definiert. Aggregationen werden nur ausgewertet, wenn der Bericht ausgelöst wird. Bei einer Vektoraggregation wird beispielsweise ein Wert pro Bericht hinzugefügt und bei einer Zählaggregation wird die Berichtsnummer gespiegelt. |
optionalreport_incomplete(Standard: „false“) |
Boolescher Wert. Bei „true“ generiert das System beim Herunterfahren oder wenn die Datenerfassung endet einen Abschlussbericht, auch wenn Daten fehlen. |
optionalreport_initial(Standard: „false“) |
Boolescher Wert. Wenn „true“, generiert das System sofort einen Bericht, wenn die Messwertkonfiguration aktiviert wird. |
Beispiel: Berichtskonfiguration
Definieren Sie schließlich die Berichtskonfiguration für das Beispiel. Sie wird durch EveryMinute ausgelöst. Die berechnete Durchschnittsgeschwindigkeit und die Anzahl der Messwerte werden aus SpeedAggregator mit einer none-Aggregation gelesen, die den vorab aggregierten Wert an den Bericht übergibt:
{ "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" } } ] } }
Felder der obersten Ebene
Zusätzlich zu den Arrays data_sources, aggregators, triggers und report_configs ist für die Beschreibung einer Messwertkonfiguration ein Verweis auf den Signalkatalog erforderlich. Sie können auch optionale Felder einfügen, um eine bestimmte UUID zuzuweisen und den Erfassungslebenszyklus zu verwalten.
Set-UUID
Jeder MetricsConfig erfordert einen Universally Unique Identifier (UUID). Wenn Sie einen existing_uuid angeben, wird dieser von MCG verwendet. Andernfalls wird ein zufälliger existing_uuid erstellt. Geben Sie einen existing_uuid an, um die Konsistenz über Bereitstellungen und Tools hinweg zu gewährleisten.
Der String muss eine gültige UUID mit Bindestrichen sein, die nur Kleinbuchstaben enthält.
"existing_uuid": "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
Signaldefinitionen
Zur Validierung von Signalnamen und ‑typen benötigt MCG Zugriff auf einen Fahrzeugsignalkatalog. Dies ist ein Protobuf FileDescriptorSet, der Ihre VSIDL-Definitionen .proto enthält (verpackt und in das MCG hochgeladen). Weitere Informationen zum Erstellen und Hochladen eines Katalogs finden Sie unter Fahrzeugsignalkataloge.
Geben Sie die Katalogversion im Feld vs_version des JSON-Objekts an:
"vs_version": "v1.0",
Lebenszyklus-Trigger definieren
Im Rahmen einer Telemetriekampagne bestimmt der Lebenszyklus eines MetricsConfig, wann Daten tatsächlich erfasst werden. Während das Kampagnenverwaltungssystem die Konfiguration auf dem Gerät bereitstellt und aktiviert, können Sie mit Lebenszyklus-Triggern genau steuern, wann Daten im Rahmen dieser Bereitstellung erfasst werden.
So können Sie die Datenerhebung an die Nutzungsmuster des Fahrzeugs anpassen, z. B. an eine „Fahrt“ (IgnitionOn bis IgnitionOff) oder eine „Ladesitzung“, ohne die Konfiguration deaktivieren zu müssen.
Sitzungssteuerung (Start/Pause): Mit
start_trigger_nameundstop_trigger_namekönnen Sie steuern, wann die Erfassung erfolgt. Wenn Sie beispielsweise Daten nur während der Fahrt des Fahrzeugs erfassen möchten, verwenden SieIgnitionOnals Start- undIgnitionOffals Stopp-Trigger. Die Konfiguration bleibt auf dem Gerät aktiv, wird aber effektiv „pausiert“ (es werden keine Daten mehr erhoben und verarbeitet), wenn der Stopp-Trigger ausgelöst wird. Die Erhebung und Verarbeitung wird erst fortgesetzt, wenn der Start-Trigger wieder ausgelöst wird.Wichtig:Dadurch wird die Erhebung lediglich pausiert. Es werden keine logischen Zeiträume oder separaten Datasets definiert und es gibt auch keine anderen Nebenwirkungen. Aggregatorwerte werden nicht zurückgesetzt, wenn die Erhebung pausiert oder fortgesetzt wird.
Einmalige Erkennung (Abschluss): Verwenden Sie
deactivate_trigger_name, wenn die Konfiguration nur einmal ausgeführt werden soll (z. B. um das erste Auftreten eines bestimmten Fehlercodes zu erkennen) und sich dann auf diesem Gerät dauerhaft deaktivieren soll, auch wenn die Kampagne technisch noch aktiv ist.
Wenn Sie keine Triggers für den Lebenszyklus angeben, beginnt die Datenerhebung sofort, wenn die Konfiguration durch die Kampagne aktiviert wird, und wird bis zum Ende der Kampagne fortgesetzt.
| Lebenszyklusfelder der obersten Ebene (Stammobjekt) | |
|---|---|
optionalstart_trigger_name |
Der Name eines Triggers, der die Erfassungssitzung startet. Kann ohne stop_trigger_name festgelegt werden. |
optionalstop_trigger_name |
Der Name eines Triggers, der die Erfassungssitzung pausiert, z. B. wenn das Fahrzeug steht. Wenn dieser Wert festgelegt ist, muss auch start_trigger_name festgelegt werden. |
optionaldeactivate_trigger_name |
Der Name eines Triggers, der die `MetricsConfig` abschließt und vollständig deaktiviert. |
Erweitert: Benutzerdefinierte Proto-Definitionen
In zwei Hauptfällen reicht vs_version allein nicht aus, damit MCG alle Nachrichtentypen in der Beschreibung einer Messwertkonfiguration versteht:
- Fehler beim Ableiten des Typs:Wie im
source_identifier-Format beschrieben, kann der Typ nicht abgeleitet werden, wenn fürsource_identifierein FQIN oder ein benutzerdefinierter Name verwendet wird. - Benutzerdefinierte Nachrichten:In der Beschreibung der Messwertkonfiguration werden Protobuf-Nachrichten verwendet, die nicht im VSIDL-Katalog in
vs_versionenthalten sind. Das passiert, wenn Siemessage_typein einemmessage_builderfür ein benutzerdefiniertes Berichtsformat festlegen.
Verwenden Sie in diesen Fällen data_source_message_types, damit MCG Typen ableiten kann, und descriptor_protos, um Nachrichtendefinitionen bereitzustellen.
data_source_message_types
Ordnen Sie den String source_identifier dem vollständig qualifizierten Protobuf-Nachrichtentyp zu.
Der Schlüssel in data_source_message_types muss mit dem source_identifier-Wert aus dem data_sources-Eintrag übereinstimmen:
"data_source_message_types": {
"MyCustomSpeedService": "com.sdv.example.SampleMessage"
}
descriptor_protos
Geben Sie Definitionen für alle Nachrichtentypen an, die in data_source_message_types oder message_builder verwendet werden und nicht in der konfigurierten vs_version enthalten sind.
Übergeben Sie einen base64-codierten descriptorpb.FileDescriptorSet im Array descriptor_protos. Generieren Sie diese aus .proto-Dateien mit dem Protobuf-Compiler protoc.
"descriptor_protos": [
"Cu8BCiZtY2cvdGVzdGRhdGEvbWF4YXZnY3..." // Base64 string
]
Beispiel: Vollständige Konfigurationsbeschreibung
In den vorherigen Abschnitten werden alle Komponenten für das Beispiel definiert: Es wird jede Minute ein Bericht mit der durchschnittlichen Fahrzeuggeschwindigkeit in dieser Minute erstellt.
Die Komponenten sind:
- Eine Datenquelle (
SpeedSource) zum Abrufen von Geschwindigkeitsdaten bis zu einmal pro Sekunde. - Ein Datentrigger (
OnNewSpeed), der ausgelöst wird, wennSpeedSourceDaten sendet. - Ein periodischer Trigger (
EveryMinute), der alle 60 Sekunden ausgelöst wird. - Ein Aggregator (
SpeedAggregator), derOnNewSpeedverwendet, um die Durchschnittsgeschwindigkeit zu berechnen, Messwerte zu zählen und aktuelle Werte zu speichern. Er wird zurückgesetzt, wenn er gelesen wird. - Eine Berichtskonfiguration (
MinuteReport), mit der mithilfe vonEveryMinuteein Bericht mit der Durchschnittsgeschwindigkeit und der Anzahl ausSpeedAggregatorausgelöst wird. - Felder der obersten Ebene (
existing_uuid,vs_version) zur Identifizierung der Messwertkonfiguration und zur Angabe, welcher VSIDL-Katalog für Signaldaten verwendet werden soll.
Zusammen bilden diese Elemente die vollständige Beschreibung einer Messwertkonfiguration:
{ "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" } } ] } } ] }
Referenzvorlage
Die API-Definition finden Sie in der MCG API-Referenz.
In den folgenden Abschnitten finden Sie eine vollständige Referenz für die Beschreibung einer Messwertkonfiguration. Sie können sie als Leitfaden für die Erstellung einer eigenen Beschreibung einer Messwertkonfiguration verwenden.
Felder der obersten Ebene
{
"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
}
Eingabe: Datenquellen und Aggregatoren
{
"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
}
}
]
}
}
]
}
Logik und Verarbeitung: Trigger
{
"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 }
}
}
}
}
]
}
Ausgabe: Berichtskonfigurationen
{
"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"
}
}
]
}
}
]
}
Syntax für Ausdrücke
| Kategorie | Syntax | Beschreibung |
|---|---|---|
| Datenzugriff | source_namesource_name.fieldsource_name.field.subfield |
Auf die vollständige Nachricht aus einer Datenquelle oder einem Aggregator zugreifen Auf ein bestimmtes Feld in der Nachricht zugreifen (einschließlich verschachtelter Felder) |
| Arithmetik | +, -, *, /, %, ** |
Standardmathematik ** ist die Exponentiation. |
| Logisch | &&, ||, !, ^ |
AND, OR, NOT, XOR. |
| Beziehungsbezogen | ==, !=, <, <=, >, >= |
== und != funktionieren für alle Typen. Für andere sind Zahlen erforderlich. |
| Liste | contains(list, item)doesnotcontain(list, item)alleq(list, value) |
Wird für Vektoren (Arrays) verwendet. alleq(list, value) gibt true zurück, wenn alle Elemente in list gleich value sind. |
| Funktionen | timestamp(clock_type) |
Aktuelle Zeit in Nanosekunden.clock_type: REALTIME_CLOCK oderMONOTONIC_TIME_SINCE_BOOT_OR_RESUME |
abs(n) |
Absolutwert | |
floor(n), round(n), ceil(n) |
Rundungsfunktionen | |
| Operatorrangfolge | () |
Standardgruppierung für Vorrang |