במדריך הזה מפורט הפורמט של בקשת JSON לנקודת הקצה /api/v2/generate_metrics_config של הכלי Metrics Configuration Generator (MCG). הפורמט הזה מאפשר להגדיר קמפיין טלמטריה – לציין איסוף נתונים, עיבוד במכשיר ויצירת דוחות – במבנה קריא לאנשים.
כלי ה-MCG מאמת את אובייקט ה-JSON הזה, בודק אם יש בעיות כמו אי-התאמות בסוגים, תלויות מעגליות או הפניות לא מוגדרות, ואז מקמפל אותו להודעת מאגר אחסון לפרוטוקולים (protobuf) של MetricsConfig. ההודעה הזו של MetricsConfig היא הפורמט הבינארי ששירות הטלמטריה במכשיר מפעיל כדי להריץ את הקמפיין.
דרישות מוקדמות: אתם צריכים להכיר סכימות JSON, protobuf ומבני נתונים בסיסיים. לסקירה כללית של המושגים, קראו את המאמר מושגים שקשורים להגדרת מדדים.
איך כותבים תיאור של הגדרה
כדי לתכנן קמפיין לאיסוף מדדים, פועלים לפי השלבים הבאים:
- מציינים מקורות נתונים: מגדירים מאיפה הנתונים מגיעים.
- הגדרת לוגיקה ועיבוד: מגדירים כללים לגבי מתי לאסוף נתונים ואיך לעבד אותם.
- יצירת פלט: אריזת הנתונים שעובדו להודעה סופית.
- שדות ברמה העליונה: מוסיפים שדות ברמה העליונה כמו UUID, הגדרות של אותות ובקרת מחזור חיים.
דוגמה: דוח מהירות ממוצעת
במדריך הזה יש דוגמה שמראה איך כל הרכיבים משתלבים יחד. הוא יוצר דוח שמחשב את מהירות הרכב הממוצעת בכל דקה. הוא מגדיר מקור נתונים (SpeedSource) לאיסוף נתוני מהירות, טריגרים (OnNewSpeed, EveryMinute) לשליטה בתהליך הביצוע, אגרגטור (SpeedAggregator) לחישוב הממוצע והגדרת דוח מדדים (MinuteReport) לאריזת התוצאה. הדוגמאות בקטעים הניתנים להרחבה מבוססות על התרחיש הזה.
ציון מקורות נתונים
הטלמטריה תומכת באיסוף נתונים משירותי SDV (דרך SDV Middleware) ומבעלי תוכן דיגיטלי שמבוססים על Configurable Publisher Registry.
שירותי SDV (מבוססי Pub/Sub): הנתונים זמינים מערוצי Pub/Sub שמוגדרים ב-VSIDL.
שירותי SDV (מבוססי-RPC): הנתונים זמינים אם השירות חושף
CreateSubscriptionאוGetLatestMessageRPCs.בעלי תוכן דיגיטלי שרשומים ב-Configurable Publisher Registry: הנתונים זמינים אם האפליקציה רשומה באמצעות ממשק Android Binder של
IConfigurablePublisherRegistryאו ספריית Configurable Publisher Registry מ-Telemetry SDK.
כדי להשתמש בנתונים ב-SDV, מגדירים מקור נתונים (concept) ומוסיפים אותו למערך data_sources.
שדות של אובייקט מקור נתונים (פריט ברשימה data_sources) |
|||||
|---|---|---|---|---|---|
name |
מחרוזת שמוגדרת על ידי המשתמש ומזהה את מקור הנתונים הזה בהגדרת המדדים. | ||||
source_identifier |
המזהה שמשמש לאיתור השירות. לפרטים נוספים, קראו את המאמר פורמט source_identifier. |
||||
connection_type |
SUBSCRIPTION למקור נתונים רציף (נדרש בשביל טריגרים של נתונים), או ON_DEMAND לאחזור לפי דרישה (לפרטים, ראו הגדרת מקורות נתונים). |
||||
אופציונליconfiguration |
רק RPC ו-Configurable Publisher Registry. אובייקט להגדרת מקור הנתונים עם השדות הבאים:
|
||||
שדות לסוג החיבור SUBSCRIPTION |
|||||
אופציונליsub_sampling_interval_ms |
Pub/Sub בלבד. מספר שלם לא שלילי (באלפיות השנייה) כדי להגביל את תדירות ההודעות על ידי ציון המרווח המינימלי בין ההודעות. | ||||
אופציונליfetch_last_message(ברירת מחדל: false) |
Pub/Sub בלבד. בוליאני. אם true,
מאחזר את ההודעה האחרונה בזמן החיבור. |
||||
לא כל האפשרויות זמינות לכל סוגי מקורות הנתונים. מידע מפורט זמין במדריך לשילוב מקורות נתונים.
הפורמט של source_identifier
שירות הטלמטריה מקבל כמה פורמטים של מזהי מקור. לסקירה כללית, קראו את המאמר הגדרת מקור נתונים בהגדרות של מדדים.
MCG מסיק את סוג ההודעה של protobuf מ-source_identifier רק אם הוא משתמש בפורמט Unit Type Name. אם אתם משתמשים ב-FQIN או בשם מותאם אישית (מ-Configurable Publisher Registry), המערכת של MCG לא יכולה להסיק את הסוג. במקרים כאלה, צריך לספק data_source_message_types. אם הסוג לא נמצא בקטלוג, צריך לספק גם את ההגדרה שלו ב-descriptor_protos.
דוגמה: הגדרת מקור נתונים
בדוגמה הזו מדווחת מהירות הרכב. קודם כל, צריך לעיין בקטלוג של VSIDL כדי לזהות את השירות שמפרסם את הנתונים האלה.
משתמשים בקטלוג לדוגמה בבסיס הקוד של ה-SDV כדי לזהות את השירות הרלוונטי. בהתאם לפורמט של source_identifier, מציינים את סוג ההודעה של protobuf mcg.test.subpkg.speed_msg. בדרך כלל המהירות מתפרסמת בתדירות גבוהה, לכן כדאי להשתמש ב-sub_sampling_interval_ms כדי להגביל את העדכונים להודעה אחת בשנייה:
{ "name": "SpeedSource", "source_identifier": "mcg.test.subpkg.speed_msg", "connection_type": "SUBSCRIPTION", "sub_sampling_interval_ms": 1000 // Limit updates to 1 per second }
הגדרת הלוגיקה והעיבוד
הלוגיקה מנוהלת על ידי שני רכיבים שפועלים יחד: טריגרים (מושג) שמגדירים מתי משהו קורה. אגרגטורים (מושג) מגדירים איך הנתונים מעובדים על סמך הטריגרים האלה. מכיוון שביטויים (מושג) הם המפתח לתנאי הטריגר וללוגיקת הצבירה, בקטע הזה קודם מתואר איך לכתוב אותם.
הבעות
ביטויים מאפשרים להגדיר חישובים ותנאים באמצעות תחביר קריא לאנשים. MCG מקמפל את המחרוזות האלה לפורמט שניתן להפעלה, שעבר אופטימיזציה להערכה במכשיר.
ביטויים יכולים לבטא חישובים אריתמטיים, תנאים לוגיים והשוואות נתונים. התחביר המלא, כולל אופרטורים ופונקציות, מפורט במאמר תחביר של ביטויים.
עדכניות הנתונים: כשביטוי ניגש למקור נתונים, התנהגות השליפה תלויה בסוג החיבור:
-
SUBSCRIPTION: משתמש בהודעה האחרונה שהתקבלה ונשמרה במטמון של שירות הטלמטריה. (הערה: אם מוגדרsub_sampling_interval_ms, יכול להיות שההודעה תהיה שונה מההודעה האחרונה שפורסמה). -
ON_DEMAND: מפעיל קריאה מיידית לאחזור ההודעה החדשה מהשירות.
אילוצי סוגים
- מערכים: אין תמיכה בגישה ישירה לאינדקס של מערך (לדוגמה,
my_data_source.my_array[0]). - מניעת שגיאות הקלדה: חשוב לוודא שמשווים בין סוגים תואמים (לדוגמה, לא להשוות בין שדה מחרוזת לרשימה של מספרים שלמים).
דוגמה: ביטויים
בדוגמה הזו צריך לחלץ את ערך המהירות כדי לחשב את הממוצע שלו. הוא גם צריך לקבוע אם הרכב נוסע במהירות מופרזת (מעל 100 קמ"ש) בשביל הטריגר המותנה. אפשר למצוא את שמות השדות (במקרה הזה, speed) בהגדרה של הודעת ה-protobuf שבה משתמש מקור הנתונים. הביטויים הבאים מבצעים את הפעולה הזו:
-
SpeedSource.speed: מאחזר את הערך של השדהspeedממקור הנתוניםSpeedSource. -
SpeedSource.speed > 27.7: הערך שמוחזר הואtrueאם המהירות גבוהה מ-27.7 מטר לשנייה (בערך 100 קמ"ש).
טריגרים: הגדרת הזמן שבו הפעולות מתרחשות
טריגרים מגדירים מתי הפעולות מתבצעות: הערכת אגרגטור, יצירת דוח או שליטה במחזור החיים של האיסוף. מוסיפים את כל הטריגרים שהוגדרו למערך triggers ברמה העליונה.
שדות של אובייקט טריגר (פריט ברשימה triggers) |
|
|---|---|
name |
מזהה ייחודי של הטריגר הזה בהגדרת המדדים. |
periodicdataconditional |
כדי להגדיר את ההתנהגות, צריך למלא בדיוק אחד מהשדות האלה. |
טריגר נתונים
מופעל כשמקור נתונים מסוג SUBSCRIPTION מספק הודעה חדשה (קונספט).
שדות של האובייקט data (בטריגר) |
|
|---|---|
source_name |
ה-name של ה-data_source שהטריגר הזה מאזין לו. |
דוגמה: טריגר נתונים
בדוגמה, מעדכנים את חישוב המהירות הממוצעת בכל פעם ש-SpeedSource מפרסם הודעה חדשה. הטריגר הזה מופעל בכל פעם שמתרחש האירוע הבא:
{ "name": "OnNewSpeed", "data": { "source_name": "SpeedSource" // Reference to the defined data source } }
טריגר תקופתי
מופעל במרווחי זמן קבועים (קונספט).
שדות של האובייקט periodic (בטריגר) |
|
|---|---|
period_ms |
מספר לא שלילי שמגדיר את המרווח באלפיות השנייה. |
דוגמה: טריגר תקופתי
בדוגמה הזו נדרש דוח בכל דקה. הטריגר התקופתי הזה מופעל כל 60,000 אלפיות השנייה כדי ליצור את הדוח:
{ "name": "EveryMinute", "periodic": { "period_ms": 60000 // 60,000 ms = 60 seconds } }
טריגר מותנה
מופעל על סמך הערכה של ביטוי (קונספט). כדי להתחיל את ההערכה, צריך טריגר הורה אחד או יותר. לרוב מדובר בטריגר של נתונים למקורות הנתונים או לאגרגטורים בביטוי, או בטריגר תקופתי לדגימת נתונים.
שדות של האובייקט conditional (בטריגר) |
|
|---|---|
triggers |
מערך עם שם אחד לפחות של טריגר הורה. כשטריגר הורה מופעל, הטריגר המותנה מעריך את הביטוי. |
expression |
הביטוי שצריך להעריך. למידע נוסף על ביטויים |
condition_type |
מציין מתי הטריגר צריך לפעול, על סמך הערכת הביטוי. |
סוגי התנאים
המילון condition_type חייב להכיל בדיוק אחד מסוגי התנאים הזמינים כמפתח. מידע נוסף זמין במאמר טריגרים מותנים.
שדות של האובייקט condition_type (לא יכולים להתקיים בו-זמנית) |
|
|---|---|
is_trueis_false |
מופעל כשביטוי בוליאני מקבל את הערך true או false, בהתאמה. |
rising_edge |
אם הערך מספרי, הוא מופעל כשהערך עולה. אם הביטוי הוא בוליאני, הטריגר מופעל כשהוא משתנה מ- יכול להכיל אובייקט |
falling_edge |
אם מדובר בערך מספרי, הטריגר מופעל כשהערך יורד. אם הביטוי הוא בוליאני, הטריגר מופעל כשהוא משתנה מ- יכול להכיל אובייקט |
all_changes |
מופעל כשהתוצאה של הביטוי שונה מהערך הקודם שלו. אם מוגדרות אפשרויות קצה, הן תומכות רק בערכים מספריים ובוליאניים. יכול להכיל את |
אפשרויות קצה
האובייקטים rising_options ו-falling_options מכילים את השדות הבאים. אם מציינים את המאפיין הזה, המעבר המתאים חייב לעמוד בדרישות לגבי משך הזמן.
מעברים בלי אפשרויות מוגדרות מופעלים באופן מיידי.
| שדות לאובייקטים של אפשרויות קצה | |
|---|---|
min_duration_ms |
מספר לא שלילי (באלפיות השנייה) שמציין כמה זמן התנאי צריך להתקיים במצב החדש לפני שהטריגר מופעל. |
אופציונליrequire_exact |
בוליאני. אם הערך הוא true, כל הערכים שפורסמו במהלך משך הזמן צריכים להיות זהים כדי שהטריגר יופעל. |
דוגמה: טריגר מותנה
הטריגר הבא משתמש באפשרויות של קצוות. הוא מופעל אם המהירות עולה על 27.7 מטר לשנייה ונשארת גבוהה למשך 5 שניות לפחות:
{ "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 } } } } }
אגרגטורים: הגדרת אופן עיבוד הנתונים
שימוש באגרגטור לעיבוד נתונים זמניים עם שמירת מצב (מושג).
מגדירים אגרגטור ומוסיפים אותו למערך aggregators.
הוא משנה את הנתונים ומאפשר להשתמש בהם בדוחות ובאגרגטורים אחרים.
שדות של אגרגטור (פריט ברשימה aggregators) |
|
|---|---|
name |
מחרוזת שמוגדרת על ידי המשתמש ומזהה את האגרגטור הזה. ביטויים יכולים להפנות לצבירה הזו לפי השם שלה כדי לגשת לתוצאות שלה. |
trigger_names |
מערך של שם טריגר אחד או יותר שגורם להערכה של הצבירה הזו. |
אופציונליreset_on_get |
ערך בוליאני, ברירת המחדל: `false`. אם הערך הוא `true`, המערכת מאפסת את מצב הצבירה אחרי שגורם צבירה אחר, דוח מדדים או טריגר מותנה ניגשים לערך שלו. |
message_builder |
מגדיר את הנתונים שצריך לקרוא, לעבד ולצבור. השדות של הודעת הפלט הופכים למקור נתונים עבור דוחות ורכיבי צבירה אחרים. הוא משתמש ב-field_assignments, כאשר כל הקצאה מגדירה שדה בהודעת הפלט. |
הכלי ליצירת הודעות
אובייקט message_builder מגדיר את מבנה הודעת הפלט ואת הלוגיקה של הצבירה שמשמשת לחישוב השדות שלה. הוא משמש גם לצבירת נתונים וגם להגדרות של דוחות.
שדות של אובייקט message_builder (בכלי צבירת הנתונים או בדוח) |
|
|---|---|
message_type |
השם המלא של סוג ההודעה של protobuf לפלט. אם משמיטים את הפרמטר, MCG יוצר סוג הודעה בהתאמה אישית על סמך סוגי הפלט המשוערים של field_assignments. צריך להשתמש בזה רק אם בונה ההודעות הוא חלק מדוח מדדים, והדוח חייב להתאים להגדרה ספציפית ומוגדרת מראש של הודעת protobuf. |
field_assignments |
מערך של אובייקטים להגדרת שדות. כל אובייקט מציין שדה בהודעת הפלט ואת הלוגיקה לחישוב הערך שלו. |
שדות של אובייקט הקצאת שדות (פריט ברשימה field_assignments) |
|||||||
|---|---|---|---|---|---|---|---|
field_name |
שם שהמשתמש מגדיר לשדה. הוא מזהה את הערך הספציפי בתוך האובייקט כשמשתמשים בסימון נקודה בביטויים (aggregator_name.field_name). |
||||||
aggregation |
אובייקט שמגדיר איך המערכת מחשבת את הערך של השדה, עם השדות הבאים:
|
||||||
דוגמה: אתר אגרגטור
לדוגמה, חישוב נתונים סטטיסטיים בין דוחות של דקות. האגרגטור הזה מופעל על ידי OnNewSpeed כדי לחשב את המהירות הממוצעת (avg), לספור את הקריאות (count) ולאחסן את 5 ערכי המהירות האחרונים (vector). מגדירים את reset_on_get לערך true. הפעולה הזו מאפסת את הנתונים הסטטיסטיים בכל פעם ש-MinuteReport קורא אותם, ומתחילה חלון איסוף חדש לצבירה בדקה הבאה:
{ "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 } } ] } }
יצירת פלט
כדי להגדיר את הפלט הסופי של קמפיין הטלמטריה, מוסיפים אובייקטים למערך report_configs (קונספט). ההגדרות האלה קובעות איך הנתונים המעובדים נארזים ומתי הם נוצרים. אתם יכולים להגדיר כמה דוחות בהגדרת מדדים אחת כדי להשתמש שוב ברכיבים.
אתם יכולים לשלוט ביצירת הדוחות באמצעות השדה trigger_names. בנוסף, אפשר להשתמש ב-report_initial כדי ליצור דוח מיד כשההגדרה מופעלת, וב-report_incomplete כדי ליצור דוח סופי כשיש הפרעה באיסוף הנתונים.
הערה: כדי לחבר את העיבוד לפלט, משתמשים בסוג הצבירה none (@type: "none") כדי לקרוא ערכים שחושבו מראש מ-Aggregator. בדרך כלל, דוחות הם תמונות מצב בלי שמירת מצב, ולכן הלוגיקה המורכבת של שמירת המצב נשארת בתוך האגרגטורים, והדוחות משמשים רק לעיצוב.
שדות של אובייקט הגדרת דוח (פריט ברשימה report_configs) |
|
|---|---|
name |
שם ייחודי לדוח. השם הזה מופיע במטא-נתונים של הדוח שנוצר. |
trigger_names |
מערך של שמות טריגרים שגורמים ליצירה ולפרסום של הדוח. |
message_builder |
פרטים נוספים זמינים בקטע הכלי ליצירת הודעות. המאפיין הזה מגדיר את תוכן הדוח. הצבירות נבדקות רק כשהדוח מופעל. לדוגמה, צבירת וקטורים מוסיפה ערך אחד לכל דוח, וצבירת ספירה משקפת את מספר הדוחות. |
אופציונליreport_incomplete(ברירת המחדל: "false") |
ערך בוליאני. אם הערך הוא True, המערכת יוצרת דוח סופי כשהיא נכבית או כשאיסוף הנתונים מסתיים, גם אם חסרים נתונים. |
אופציונליreport_initial(ברירת המחדל: "false") |
ערך בוליאני. אם הערך הוא `true`, המערכת יוצרת דוח מיד כשהגדרת המדדים מופעלת. |
דוגמה: הגדרת הדוח
בשלב האחרון, מגדירים את הדוח לדוגמה. הוא מופעל על ידי EveryMinute. הוא קורא את המהירות הממוצעת המחושבת ואת מספר הקריאות מ-SpeedAggregator באמצעות צבירה מסוג none, שמעבירה את הערך שנצבר מראש לדוח:
{ "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" } } ] } }
שדות ברמה העליונה
בנוסף למערכים data_sources, aggregators, triggers ו-report_configs, התיאור של הגדרת המדדים דורש הפניה לקטלוג האותות. אפשר גם לכלול שדות אופציונליים כדי להקצות UUID ספציפי ולנהל את מחזור החיים של האוסף.
הגדרת UUID
לכל MetricsConfig נדרש מזהה ייחודי אוניברסלי (UUID). אם תספקו existing_uuid, המערכת תשתמש בו. אחרת, המערכת יוצרת מזהה אקראי. כדי לשמור על עקביות בין פריסות וכלים, צריך לציין existing_uuid.
המחרוזת חייבת להיות UUID תקין עם מקפים, שמכיל רק אותיות קטנות.
"existing_uuid": "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
הגדרות של אותות
כדי לאמת את השמות והסוגים של האותות, ל-MCG נדרשת גישה לקטלוג האותות של הרכב. זהו protobuf FileDescriptorSet שמכיל את הגדרות ה-VSIDL .proto (ארוזות ומועלות ל-MCG). פרטים נוספים על יצירה והעלאה של קטלוג זמינים במאמר קטלוגים של אותות רכב.
מציינים את גרסת הקטלוג בשדה vs_version של אובייקט ה-JSON:
"vs_version": "v1.0",
הגדרת טריגרים של מחזור חיים
בהקשר של קמפיין טלמטריה, מחזור החיים של MetricsConfig קובע מתי הנתונים נרשמים בפועל. בזמן שמערכת ניהול הקמפיינים פורסת ומפעילה את ההגדרות במכשיר, אתם יכולים להשתמש בטריגרים של מחזור חיים כדי לקבוע בדיוק מתי הנתונים ייאספו במסגרת הפריסה הזו.
כך אפשר להתאים את איסוף הנתונים לדפוסי השימוש ברכב, כמו "נסיעה" (IgnitionOn עד IgnitionOff) או "סשן טעינה", בלי להשבית את ההגדרות האישיות.
שליטה בסשן (התחלה/השהיה): משתמשים ב-
start_trigger_nameוב-stop_trigger_nameכדי לשלוט במועד האיסוף. לדוגמה, כדי לאסוף נתונים רק כשהרכב בנסיעה, משתמשים ב-IgnitionOnכטריגר להתחלה וב-IgnitionOffכטריגר לעצירה. ההגדרה נשארת פעילה במכשיר, אבל למעשה היא "מושהית" (מפסיקה לאסוף ולעבד נתונים) כשהטריגר להפסקה מופעל, ומתחדשת רק כשהטריגר להפעלה מופעל שוב.חשוב: הפעולה הזו רק משהה את האיסוף. היא לא מגדירה חלונות לוגיים, קבוצות נתונים נפרדות או כל השפעה אחרת. ערכי הצבירה לא מתאפסים כשהאיסוף מושהה או מתחדש.
זיהוי חד-פעמי (סיום): משתמשים ב-
deactivate_trigger_nameאם ההגדרה צריכה לפעול רק פעם אחת (לדוגמה, כדי לזהות את המופע הראשון של קוד שגיאה ספציפי) ואז להשבית את עצמה באופן סופי במכשיר הזה, גם אם הקמפיין עדיין פעיל מבחינה טכנית.
אם לא תציינו טריגרים של מחזור חיים, איסוף הנתונים יתחיל מיד כשההגדרה תופעל על ידי הקמפיין, ויימשך עד שהקמפיין יסתיים.
| שדות מחזור חיים ברמה העליונה (אובייקט ברמה הבסיסית) | |
|---|---|
אופציונליstart_trigger_name |
השם של הטריגר שמתחיל את סשן האיסוף. אפשר להגדיר בלי stop_trigger_name. |
אופציונליstop_trigger_name |
השם של טריגר שמשהה את סשן האיסוף (לדוגמה, כשהרכב לא בתנועה). אם המדיניות הזו מוגדרת, חובה להגדיר גם את start_trigger_name. |
אופציונליdeactivate_trigger_name |
השם של טריגר שמסיים את הפעולה של `MetricsConfig` ומשבית אותו לגמרי. |
מתקדם: הגדרות proto בהתאמה אישית
יש שני מקרים עיקריים שבהם vs_version לבדו לא מספיק כדי ש-MCG יבין את כל סוגי ההודעות בתיאור של הגדרת המדדים:
- כשל בהסקת סוג: כפי שמוסבר בפורמט
source_identifier, MCG לא יכול להסיק את הסוג כש-source_identifierמשתמש ב-FQIN או בשם מותאם אישית. - הודעות בהתאמה אישית: התיאור של הגדרת המדדים משתמש בהודעות protobuf שלא נמצאות בקטלוג VSIDL שצוין ב-
vs_version. זה קורה כשמגדירים אתmessage_typeב-message_builderלפורמט של דוח בהתאמה אישית.
במקרים כאלה, משתמשים ב-data_source_message_types כדי לעזור ל-MCG להסיק סוגים וב-descriptor_protos כדי לספק הגדרות של הודעות.
data_source_message_types
ממפים את המחרוזת source_identifier לסוג ההודעה המלא של protobuf.
המפתח ב-data_source_message_types צריך להתאים לערך של source_identifier מהרשומה של data_sources:
"data_source_message_types": {
"MyCustomSpeedService": "com.sdv.example.SampleMessage"
}
descriptor_protos
צריך לספק הגדרות לכל סוגי ההודעות שנעשה בהם שימוש ב-data_source_message_types או ב-message_builder, שלא נמצאים ב-vs_version שהוגדר.
מעבירים את הערך של descriptorpb.FileDescriptorSet בקידוד Base64 במערך descriptor_protos. אפשר ליצור את זה מקובצי .proto באמצעות המהדר של Protobuf protoc.
"descriptor_protos": [
"Cu8BCiZtY2cvdGVzdGRhdGEvbWF4YXZnY3..." // Base64 string
]
דוגמה: תיאור מלא של ההגדרה
בקטעים הקודמים הגדרנו את כל הרכיבים של הדוגמה: יצירת דוח בכל דקה עם מהירות הרכב הממוצעת שנצפתה באותה דקה.
הרכיבים הם:
- מקור נתונים (
SpeedSource) כדי לקבל נתוני מהירות עד פעם בשנייה. - טריגר נתונים (
OnNewSpeed) שמופעל כשנשלחים נתונים מ-SpeedSource. - טריגר תקופתי (
EveryMinute) שמופעל כל 60 שניות. - אגרגטור (
SpeedAggregator) שמשתמש ב-OnNewSpeedכדי לחשב את המהירות הממוצעת, לספור את הקריאות ולאחסן את הערכים האחרונים, ומתאפס כשהוא נקרא. - הגדרת דוח (
MinuteReport) שמשתמשת ב-EveryMinuteכדי להפעיל דוח שמכיל את המהירות הממוצעת ואת הספירה מ-SpeedAggregator. - שדות ברמה העליונה (
existing_uuid,vs_version) כדי לזהות את הגדרת המדדים ולציין באיזה קטלוג VSIDL להשתמש להגדרות האותות.
כשמשלבים את החלקים האלה, הם יוצרים את התיאור המלא של הגדרת המדדים:
{ "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" } } ] } } ] }
תבנית של קובץ עזר
הגדרת ה-API מופיעה במאמרי העזרה של ה-API.
בקטעים הבאים מפורטות כל ההגדרות של המדדים. אפשר להשתמש בו כמדריך ליצירת תיאור משלכם להגדרת מדדים.
שדות ברמה העליונה
{
"existing_uuid": "1cbec8e6-46f5-4649-9fa2-09f81bc93f8b", // 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
}
קלט: מקורות נתונים ואגרגטורים
{
"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
}
}
]
}
}
]
}
לוגיקה ועיבוד: טריגרים
{
"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 }
}
}
}
}
]
}
פלט: הגדרות הדוח
{
"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"
}
}
]
}
}
]
}
תחביר של ביטויים
| קטגוריה | תחביר | תיאור |
|---|---|---|
| גישה לנתונים | source_namesource_name.fieldsource_name.field.subfield |
גישה להודעה מלאה ממקור נתונים או מצובר גישה לשדה ספציפי בהודעה (כולל שדות בתצוגת עץ) |
| חשבון | +, -, *, /, %, ** |
מתמטיקה רגילה. ** היא העלאה בחזקה. |
| לוגי | &&, ||, !, ^ |
AND, OR, NOT, XOR. |
| יחסי | ==, !=, <, <=, >, >= |
== ו-!= פועלים בכל הסוגים. באחרים צריך להזין מספרים. |
| רשימה | contains(list, item)doesnotcontain(list, item)alleq(list, value) |
פועלת על וקטורים (מערכים). הפונקציה alleq(list, value) מחזירה את הערך true אם כל הפריטים ב-list שווים ל-value. |
| פונקציות | timestamp(clock_type) |
השעה הנוכחית במיקרו-שניות.clock_type: REALTIME_CLOCK אוMONOTONIC_TIME_SINCE_BOOT_OR_RESUME |
abs(n) |
ערך מוחלט | |
floor(n), round(n), ceil(n) |
פונקציות עיגול | |
| סדר הפעולות | () |
קיבוץ רגיל לפי קדימות |