В этом руководстве подробно описан формат запроса JSON для конечной точки /api/v2/generate_metrics_config инструмента Metrics Configuration Generator (MCG). Этот формат позволяет определить кампанию телеметрии, указав сбор данных, обработку на устройстве и создание отчетов в человекочитаемой структуре.
Инструмент MCG проверяет этот объект JSON на наличие проблем, таких как несоответствие типов, циклические зависимости или неопределенные ссылки, а затем компилирует его в сообщение буфера протокола MetricsConfig. Это сообщение MetricsConfig в двоичном формате, которое сервис телеметрии на устройстве выполняет для запуска кампании.
Предварительные требования. Вы должны быть знакомы со схемами JSON, protobuf и базовыми структурами данных. Общие сведения о настройке показателей приведены в этой статье.
Как составить описание конфигурации
Чтобы разработать кампанию по сбору показателей, следуйте этой логической схеме:
- Укажите источники данных. Определите, откуда поступают ваши данные.
- Определите логику и обработку. Настройте правила, определяющие, когда собирать данные и как их обрабатывать.
- Создание выходных данных. Упаковка обработанных данных в итоговое сообщение.
- Поля верхнего уровня. Добавьте поля верхнего уровня, такие как UUID, определения сигналов и управление жизненным циклом.
Пример: отчет о средней скорости
В этом руководстве на примере показано, как все компоненты работают вместе. Она создает отчет, в котором рассчитывается средняя скорость транспортного средства каждую минуту. Он определяет источник данных (SpeedSource) для сбора данных о скорости, триггеры (OnNewSpeed, EveryMinute) для управления потоком выполнения, агрегатор (SpeedAggregator) для расчета среднего значения и конфигурацию отчета о показателях (MinuteReport) для упаковки результата. Примеры в раскрывающихся разделах основаны на этом сценарии.
Укажите источники данных
Телеметрия поддерживает сбор данных из сервисов SDV (через промежуточное ПО SDV) и издателей на основе настраиваемого реестра издателей.
Сервисы SDV (на основе издателя-подписчика). Данные доступны в каналах издателя-подписчика, определенных в VSIDL.
Сервисы SDV (на основе RPC). Данные доступны, если сервис предоставляет RPC
CreateSubscriptionилиGetLatestMessage.Издатели, использующие Configurable Publisher Registry. Данные доступны, если приложение регистрируется с помощью
IConfigurablePublisherRegistryинтерфейса Android Binder или библиотеки Configurable Publisher Registry из Telemetry SDK.
Чтобы использовать данные в SDV, определите источник данных (концепция) и добавьте его в массив data_sources.
Поля объекта источника данных (элемент в списке data_sources) |
|||||
|---|---|---|---|---|---|
name |
Заданная пользователем строка, которая идентифицирует этот источник данных в конфигурации показателей. | ||||
source_identifier |
Идентификатор, используемый для обнаружения сервиса. Подробнее о формате source_identifier… |
||||
connection_type |
SUBSCRIPTION для непрерывного потока данных (требуется для триггеров данных) или ON_DEMAND для получения данных по запросу (подробнее о настройке источников данных). |
||||
Необязательноconfiguration |
Только для RPC и настраиваемого реестра издателей. Объект для настройки источника данных со следующими полями:
|
||||
Поля для типа подключения SUBSCRIPTION |
|||||
Необязательноsub_sampling_interval_ms |
Только Pub/Sub. Неотрицательное целое число (в миллисекундах), которое позволяет ограничить частоту отправки сообщений, задав минимальный интервал между ними. | ||||
Необязательноfetch_last_messageЗначение по умолчанию: false. |
Только Pub/Sub. Логическое значение. Если установлено значение true, при подключении извлекается последнее сообщение. |
||||
Не все варианты доступны для всех типов источников данных. Подробную информацию вы найдете в руководстве по интеграции источников данных.
Формат source_identifier
Сервис телеметрии принимает несколько форматов идентификаторов источников. Подробнее об определении источника данных в конфигурациях показателей…
MCG определяет тип сообщения protobuf по source_identifier, только если используется формат Unit Type Name. Если вы используете FQIN или собственное название (из настраиваемого реестра издателей), MCG не сможет определить тип. В таких случаях необходимо указать data_source_message_types. Если типа нет в каталоге, необходимо также указать его определение в descriptor_protos.
Пример: определение источника данных
В этом примере передается скорость автомобиля. Сначала найдите в каталоге VSIDL сервис, который публикует эти данные.
Используя пример каталога в базе кода SDV, определите нужный сервис. Укажите тип сообщения protobuf mcg.test.subpkg.speed_msg в соответствии с форматом source_identifier. Поскольку данные о скорости обычно публикуются часто, используйте 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 содержат следующие поля. Если вы указываете этот параметр, то соответствующий переход должен соответствовать требованиям к длительности.
Переходы без указанных параметров выполняются немедленно.
| Поля для объектов EdgeOption | |
|---|---|
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) и сохранения последних пяти значений скорости (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"), который позволяет считывать предварительно рассчитанные значения из агрегатора. Поскольку отчеты обычно представляют собой снимки без отслеживания состояния, это позволяет сохранить сложную логику с отслеживанием состояния в агрегаторах и зарезервировать отчеты для форматирования.
Поля объекта конфигурации отчета (элемент в списке 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, MCG будет использовать его. В противном случае будет создан случайный идентификатор. Чтобы обеспечить согласованность между развертываниями и инструментами, укажите 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используется полное имя интерфейса или специальное название. - Специальные сообщения. В описании конфигурации показателей используются сообщения 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.
Передайте закодированный по стандарту Base64 параметр descriptorpb.FileDescriptorSet в массиве 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 приведено в справочнике по MCG 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) |
Функции округления | |
| Порядок операций | () |
Стандартная группировка по приоритету |