Formato JSON da solicitação de geração de configuração de métricas

Este guia detalha o formato de solicitação JSON para o endpoint /api/v1/generate_metrics_config da ferramenta Metrics Configuration Generator (MCG). Esse formato permite definir uma campanha de telemetria especificando coleta de dados, processamento no dispositivo e geração de relatórios em uma estrutura legível por humanos.

A ferramenta MCG valida esse objeto JSON, verificando problemas como incompatibilidades de tipo, dependências circulares ou referências indefinidas, e depois o compila em uma mensagem de buffer de protocolo (protobuf) MetricsConfig. Essa mensagem MetricsConfig é o formato binário que o serviço de telemetria no dispositivo executa para veicular a campanha.

Pré-requisitos:é preciso ter familiaridade com esquemas JSON, protobuf e estruturas de dados básicas. Para uma visão geral conceitual, consulte Conceitos de configuração de métricas.

Como escrever uma descrição de configuração

Para criar uma campanha de coleta de métricas, siga este fluxo lógico:

  1. Especificar fontes de dados: defina de onde vêm seus dados.
  2. Defina a lógica e o processamento: configure regras para quando coletar dados e como processá-los.
  3. Criar saída: empacote os dados processados em uma mensagem final.
  4. Campos de nível superior: adicione campos de nível superior, como UUID, definições de indicador e controle de ciclo de vida.

Exemplo: relatório de velocidade média

Este guia usa um exemplo para mostrar como todos os componentes se encaixam. Ele cria um relatório que calcula a velocidade média do veículo a cada minuto. Ele define uma fonte de dados (SpeedSource) para coletar dados de velocidade, gatilhos (OnNewSpeed, EveryMinute) para controlar o fluxo de execução, um agregador (SpeedAggregator) para calcular a média e uma configuração de relatório de métricas (MinuteReport) para empacotar o resultado. Os exemplos em seções expansíveis se baseiam nesse cenário.

Especificar fontes de dados

A telemetria permite coletar dados de serviços de SDV (pelo middleware de SDV) e de editores baseados no registro de editores configuráveis.

Para usar dados no SDV, defina uma fonte de dados (conceito) e adicione-a à matriz data_sources.

Campos de um objeto de fonte de dados (item na lista data_sources)
name Uma string definida pelo usuário que identifica essa fonte de dados na configuração de métricas.
source_identifier O identificador usado para descobrir o serviço. Para mais detalhes, consulte formato source_identifier.
connection_type SUBSCRIPTION para um fluxo de dados contínuo (necessário para gatilhos de dados) ou ON_DEMAND para busca sob demanda. Para mais detalhes, consulte configuração de fontes de dados.
opcional
configuration

Somente RPC e registro de publisher configurável. Um objeto para configurar a fonte de dados com os seguintes campos:

type_url O FQN da mensagem protobuf da configuração.
value_json,
value_textproto,
ou value
O payload no formato JSON, textproto ou base64.
Campos para o tipo de conexão SUBSCRIPTION
opcional
sub_sampling_interval_ms
Somente Pub/Sub.Um número inteiro não negativo (milissegundos) para limitar a frequência de mensagens especificando o intervalo mínimo entre elas.
opcional
fetch_last_message
(padrão: false)
Somente Pub/Sub. Booleano. Se true, recupera a mensagem mais recente ao se conectar.

Nem todas as opções estão disponíveis para todos os tipos de fontes de dados. Consulte o guia de integração de fontes de dados para mais informações.

Formato de source_identifier

O serviço de telemetria aceita vários formatos de identificador de origem. Consulte Definição de fonte de dados nas configurações de métricas para uma visão geral.

O MCG infere o tipo de mensagem protobuf do source_identifier somente se ele usar o formato de nome do tipo de unidade. Se você usar FQIN ou um nome personalizado (do registro de editores configuráveis), o MCG não poderá inferir o tipo. Nesses casos, é necessário fornecer data_source_message_types. Se o tipo não estiver no seu catálogo, também será necessário fornecer a definição dele em descriptor_protos.

Exemplo: definição de uma fonte de dados

Este exemplo informa a velocidade do veículo. Primeiro, consulte o catálogo VSIDL para identificar o serviço que publica esses dados.

Usando o catálogo de amostras na base de código do SDV, identifique o serviço relevante. De acordo com o formato de source_identifier, especifique o tipo de mensagem protobuf mcg.test.subpkg.speed_msg. Como a velocidade geralmente é publicada com frequência, use sub_sampling_interval_ms para limitar as atualizações a uma mensagem por segundo:

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

Definir lógica e processamento

A lógica é processada por dois componentes que trabalham juntos: os gatilhos (conceito) definem quando algo acontece. Os agregadores (conceito) definem como os dados são processados com base nesses gatilhos. Como as expressões (conceito) são essenciais para condições de acionamento e lógica de agregação, esta seção descreve primeiro como escrevê-las.

Expressões

Com as expressões, é possível definir cálculos e condições usando uma sintaxe legível. O MCG compila essas strings em um formato executável otimizado para avaliação no dispositivo.

Elas podem expressar cálculos aritméticos, condições lógicas e comparações de dados. Para conferir a sintaxe completa, incluindo operadores e funções, consulte Sintaxe de expressões.

Atualização de dados:quando uma expressão acessa uma fonte de dados, o comportamento de recuperação depende do tipo de conexão:

  • SUBSCRIPTION: usa a mensagem recebida por último armazenada em cache pelo serviço de telemetria. Observação: se sub_sampling_interval_ms estiver definido, isso poderá ser diferente da mensagem publicada mais recente.
  • ON_DEMAND: aciona uma chamada imediata para buscar a mensagem atualizada do serviço.

Restrições de tipo

  • Arrays:o acesso direto ao índice de array (por exemplo, my_data_source.my_array[0]) não é compatível.
  • Segurança de tipo:compare tipos compatíveis. Por exemplo, não compare um campo de string com uma lista de números inteiros.

Exemplo: expressões

O exemplo precisa extrair o valor da velocidade para calcular a média. Ele também precisa determinar se o veículo está em alta velocidade (mais de 100 km/h) para o acionador condicional. Você pode encontrar os nomes dos campos (neste caso, speed) na definição de mensagem protobuf usada pela fonte de dados. As expressões a seguir fazem isso:

  • SpeedSource.speed: recupera o valor do campo speed da fonte de dados SpeedSource.
  • SpeedSource.speed > 27.7: será true se a velocidade for maior que 27,7 m/s (aproximadamente 100 km/h).

Gatilhos: definem quando as ações ocorrem

Os gatilhos definem quando as ações são executadas: avaliando um agregador, gerando um relatório ou controlando o ciclo de vida da coleta. Adicione todos os gatilhos definidos à matriz triggers de nível superior.

Campos de um objeto de acionador (item na lista triggers)
name Um identificador exclusivo para esse gatilho na configuração de métricas.
periodic
data
conditional
Você precisa fornecer exatamente um desses campos para definir o comportamento.

Gatilho de dados

Acionada quando uma fonte de dados SUBSCRIPTION fornece uma nova mensagem (conceito).

Campos do objeto data (em um gatilho)
source_name O name do data_source que essa lista de acionadores detecta.

Exemplo: acionador de dados

No exemplo, atualize o cálculo da velocidade média sempre que SpeedSource publicar uma nova mensagem. Esse acionador de dados é disparado sempre que isso acontece:

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

Acionador periódico

É acionado em um intervalo regular (conceito).

Campos do objeto periodic (em um gatilho)
period_ms Um número não negativo que define o intervalo em milissegundos.

Exemplo: acionador periódico

O exemplo exige um relatório a cada minuto. Esse gatilho periódico é acionado a cada 60.000 ms para gerar o relatório:

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

Gatilho condicional

É acionado com base na avaliação de uma expressão (conceito). Ele exige um ou mais acionadores principais para iniciar a avaliação. Geralmente, é um acionador de dados para as fontes de dados ou agregadores na expressão ou um acionador periódico para pesquisar dados.

Campos do objeto conditional (em um gatilho)
triggers Uma matriz com pelo menos um nome de gatilho principal. Quando um acionador principal é disparado, o acionador condicional avalia a expressão.
expression A expressão a ser avaliada. Consulte Expressões.
condition_type Especifica quando o acionador deve ser disparado, com base na avaliação da expressão.
Tipos de condição

O dicionário condition_type precisa conter exatamente um dos tipos de condição disponíveis como chave. Para mais informações, consulte Gatilhos condicionais.

Campos do objeto condition_type (mutuamente exclusivos)
is_true

is_false
É acionada quando uma expressão booleana é avaliada como true ou false, respectivamente.
rising_edge

Se for numérico, será acionado quando o valor aumentar. Se a expressão for booleana, será disparada quando mudar de false para true.

Pode conter um objeto rising_options (consulte Opções de borda).

falling_edge

Se for numérico, será acionado quando o valor diminuir. Se a expressão for booleana, será disparada quando mudar de true para false.

Pode conter um objeto falling_options (consulte Opções de borda).

all_changes

É acionado quando o resultado da expressão é diferente do valor anterior. Se as opções de borda estiverem definidas, elas vão aceitar apenas valores numéricos e booleanos.

Pode conter rising_options, falling_options ou ambos (consulte Opções de borda).

Opções de borda

Os objetos rising_options e falling_options têm os seguintes campos. Se fornecida, a transição correspondente precisa atender ao requisito de duração. As transições sem opções especificadas são acionadas imediatamente.

Campos para objetos de opção de borda
min_duration_ms Um número não negativo (em milissegundos) que especifica quanto tempo a condição precisa ser mantida no novo estado antes do acionador ser disparado.
opcional
require_exact
Booleano. Se for "true", todos os valores publicados durante a duração precisam ser iguais para que o gatilho seja acionado.

Exemplo: gatilho condicional

O gatilho a seguir usa opções de borda. Ele é acionado se a velocidade exceder 27,7 m/s e permanecer alta por pelo menos 5 segundos:

{
  "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
        }
      }
    }
  }
}

Agregadores: definem como os dados são tratados

Use um agregador para processamento de dados intermediários com estado (conceito). Defina um agregador e adicione-o à matriz aggregators.

Um agregador transforma dados e os disponibiliza para outros agregadores e relatórios.

Campos de um agregador (item na lista aggregators)
name Uma string definida pelo usuário que identifica esse agregador. As expressões podem fazer referência a esse agregador por nome para acessar os resultados dele.
trigger_names Uma matriz com um ou mais nomes de gatilhos que fazem com que essa agregação seja avaliada.
opcional
reset_on_get
Booleano, padrão: "false". Se for "true", o sistema vai redefinir o estado de agregação depois que o valor for acessado por outro agregador, relatório de métricas ou acionador condicional.
message_builder Define os dados a serem lidos, processados e agregados. Os campos da mensagem de saída se tornam uma fonte de dados para outros agregadores e relatórios. Ele usa field_assignments, e cada atribuição define um campo na mensagem de saída.

Criador de mensagens

Um objeto message_builder define a estrutura da mensagem de saída e a lógica de agregação usada para calcular os campos. Ele é usado em agregadores e configurações de relatórios.

Campos de um objeto message_builder (no agregador ou relatório)
message_type O nome totalmente qualificado do tipo de mensagem protobuf para a saída. Se omitido, o MCG vai criar um tipo de mensagem personalizada com base nos tipos de saída inferidos de field_assignments. Use isso apenas se o criador de mensagens fizer parte de um relatório de métricas e seu relatório precisar corresponder a uma definição de mensagem protobuf específica e predefinida.
field_assignments Uma matriz de objetos de definição de campo. Cada objeto especifica um campo na mensagem de saída e a lógica para calcular o valor dele.
Campos de um objeto de atribuição de campo (item na lista field_assignments)
field_name Um nome definido pelo usuário para o campo. Ele identifica o valor específico no objeto ao usar a notação de ponto em expressões (aggregator_name.field_name).
aggregation

Um objeto que define como o sistema calcula o valor do campo com os seguintes campos:

@type A função de agregação.

  • avg, min, max, sum, stddev: estatísticas matemáticas padrão.
  • count: conta quantas vezes esse agregador foi acionado.
  • delta: diferença entre o valor atual e o anterior.
  • vector: cria uma lista de valores (buffer circular).
  • none: transmite o valor bruto.
expression A expressão de entrada para a agregação. Obrigatório para todos os tipos de agregação, exceto count.
max_length Somente para @type: "vector". Um número inteiro opcional que limita o tamanho do vetor, criando um buffer circular.

Exemplo: agregador

Por exemplo, calcule as estatísticas entre os relatórios por minuto. Esse agregador é acionado por OnNewSpeed para calcular a velocidade média (avg), contar leituras (count) e armazenar os últimos cinco valores de velocidade (vector). Defina reset_on_get como true. Isso redefine as estatísticas sempre que MinuteReport as lê, iniciando uma nova janela de coleta para o agregador no próximo minuto:

{
  "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
        }
      }
    ]
  }
}

Criar saída

Para definir a saída final da sua campanha de telemetria, adicione objetos à matriz report_configs (conceito). Essas configurações determinam como os dados processados são empacotados e quando são gerados. É possível definir várias configurações de relatório em uma configuração de métricas para reutilizar componentes.

Você controla a geração de relatórios usando o campo trigger_names. Além disso, você pode usar report_initial para gerar um relatório imediatamente quando a configuração é ativada e report_incomplete para gerar um relatório final quando a coleta de dados é interrompida.

Observação:para conectar o processamento à saída, use o tipo de agregação none (@type: "none") para ler valores pré-calculados de um agregador. Como os relatórios são geralmente snapshots sem estado, isso mantém a lógica com estado complexa nos agregadores e reserva os relatórios para formatação.

Campos de um objeto de configuração de relatório (item na lista report_configs)
name Um nome exclusivo para o relatório. Esse nome aparece nos metadados do relatório gerado.
trigger_names Uma matriz de nomes de gatilhos que fazem com que o relatório seja gerado e publicado.
message_builder Consulte Criador de mensagens para mais detalhes. Isso define o conteúdo do relatório. As agregações são avaliadas somente quando o relatório é acionado. Por exemplo, uma agregação de vetor adiciona um valor por relatório, e uma agregação de contagem reflete o número do relatório.
optional
report_incomplete
(padrão: `false`)
Um booleano. Se for "true", o sistema vai gerar um relatório final no desligamento ou quando a coleta de dados terminar, mesmo que faltem dados.
optional
report_initial
(padrão: `false`)
Um booleano. Se for "true", o sistema vai gerar um relatório imediatamente quando a configuração de métricas for ativada.

Exemplo: configuração de relatório

Por fim, defina a configuração do relatório para o exemplo. Ele é acionado por EveryMinute. Ele lê a velocidade média calculada e a contagem de leituras de SpeedAggregator usando uma agregação none, que transmite o valor pré-agregado ao relatório:

{
  "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"
        }
      }
    ]
  }
}

Campos de nível superior

Além das matrizes data_sources, aggregators, triggers e report_configs, a descrição de uma configuração de métricas exige uma referência ao catálogo de indicadores. Também é possível incluir campos opcionais para atribuir um UUID específico e gerenciar o ciclo de vida da coleta.

Definir UUID

Cada MetricsConfig exige um identificador universal exclusivo (UUID). Se você fornecer um existing_uuid, o MCG vai usá-lo. Caso contrário, ele cria um aleatório. Para manter a consistência entre implantações e ferramentas, especifique um existing_uuid.

A string precisa ser um UUID hifenizado válido que contenha apenas letras minúsculas.

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

Definições de indicadores

Para validar nomes e tipos de indicadores, o MCG precisa de acesso a um catálogo de indicadores de veículos. É um protobuf FileDescriptorSet que contém suas definições VSIDL .proto (empacotadas e enviadas para o MCG). Para detalhes sobre como criar e fazer upload de um catálogo, consulte Catálogos de sinais de veículos.

Especifique a versão do catálogo no campo vs_version do objeto JSON:

"vs_version": "v1.0",

Definir gatilhos de ciclo de vida

No contexto de uma campanha de telemetria, o ciclo de vida de um MetricsConfig determina quando os dados são realmente registrados. Enquanto o sistema de gerenciamento de campanhas implanta e ativa a configuração no dispositivo, você pode usar gatilhos de ciclo de vida para controlar precisamente quando os dados são coletados nessa implantação.

Isso permite alinhar a coleta de dados com padrões de uso do veículo, como uma "Viagem" (IgnitionOn a IgnitionOff) ou uma "Sessão de carregamento", sem precisar desativar a configuração.

  • Controle de sessão (iniciar/pausar): use start_trigger_name e stop_trigger_name para controlar quando a coleta acontece. Por exemplo, para coletar dados apenas enquanto o veículo está dirigindo, use IgnitionOn como o acionador de início e IgnitionOff como o acionador de parada. A configuração permanece ativa no dispositivo, mas é "pausada" (interrompe a coleta e o processamento) quando o gatilho de parada é acionado, sendo retomada apenas quando o gatilho de início é acionado novamente.

    Importante:isso apenas pausa a coleta. Ela não define janelas lógicas, conjuntos de dados separados nem tem outros efeitos colaterais. Os valores do agregador não são redefinidos quando a coleta é pausada ou retomada.

  • Detecção única (conclusão): use deactivate_trigger_name se a configuração precisar ser executada apenas uma vez (por exemplo, para detectar a primeira ocorrência de um código de falha específico) e depois se desativar permanentemente no dispositivo, mesmo que a campanha ainda esteja tecnicamente ativa.

Se você não especificar nenhum gatilho de ciclo de vida, a coleta de dados vai começar imediatamente quando a configuração for ativada pela campanha e vai continuar até o fim dela.

Campos de ciclo de vida de nível superior (objeto raiz)
opcional
start_trigger_name
O nome de um gatilho que inicia a sessão de coleta. Pode ser definido sem stop_trigger_name.
opcional
stop_trigger_name
O nome de um gatilho que pausa a sessão de coleta (por exemplo, quando o veículo está parado). Se definido, start_trigger_name também precisa ser definido.
opcional
deactivate_trigger_name
O nome de um gatilho que finaliza e desativa completamente o `MetricsConfig`.

Avançado: definições de protocolo personalizadas

Em dois casos principais, vs_version sozinho não é suficiente para que a MCG entenda todos os tipos de mensagem na descrição de uma configuração de métricas:

  1. Falha na inferência de tipo:conforme explicado no formato source_identifier, a MCG não consegue inferir o tipo quando source_identifier usa FQIN ou um nome personalizado.
  2. Mensagens personalizadas:a descrição da configuração de métricas usa mensagens protobuf que não são encontradas no catálogo VSIDL especificado em vs_version. Isso acontece ao definir message_type em um message_builder para um formato de relatório personalizado.

Nesses casos, use data_source_message_types para ajudar o MCG a inferir tipos e descriptor_protos para fornecer definições de mensagens.

data_source_message_types

Mapeie a string source_identifier para o tipo de mensagem protobuf totalmente qualificado. A chave em data_source_message_types precisa corresponder ao valor source_identifier da entrada data_sources:

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

descriptor_protos

Forneça definições para todos os tipos de mensagens usados em data_source_message_types ou message_builder que não estão no vs_version configurado.

Transmita um descriptorpb.FileDescriptorSet codificado em base64 na matriz descriptor_protos. Gere isso de arquivos .proto usando o compilador Protobuf protoc.

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

Exemplo: descrição completa da configuração

As seções anteriores definem todos os componentes do exemplo: gerar um relatório a cada minuto com a velocidade média do veículo observada durante esse minuto.

Os componentes são:

  • Uma fonte de dados (SpeedSource) para receber dados de velocidade até uma vez por segundo.
  • Um gatilho de dados (OnNewSpeed) que é acionado quando SpeedSource envia dados.
  • Um gatilho periódico (EveryMinute) que é acionado a cada 60 segundos.
  • Um agregador (SpeedAggregator) que usa OnNewSpeed para calcular a velocidade média, contar leituras e armazenar valores recentes, sendo redefinido quando lido.
  • Uma configuração de relatório (MinuteReport) que usa EveryMinute para acionar um relatório com a velocidade média e a contagem de SpeedAggregator.
  • Campos de nível superior (existing_uuid, vs_version) para identificar a configuração de métricas e especificar qual catálogo VSIDL usar para definições de indicadores.

Quando combinadas, essas partes formam a descrição completa de uma configuração de métricas:

{
  "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"
            }
          }
        ]
      }
    }
  ]
}

Modelo de referência

Para a definição da API, consulte a referência da API MCG.

As seções a seguir fornecem uma referência completa da descrição de uma configuração de métricas. Use-o como guia para criar sua própria descrição de uma configuração de métricas.

Campos de nível superior

{
  "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
}

Entrada: fontes de dados e agregadores

{
  "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
            }
          }
        ]
      }
    }
  ]
}

Lógica e processamento: acionadores

{
  "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 }
          }
        }
      }
    }
  ]
}

Saída: configurações de relatório

{
  "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"
            }
          }
        ]
      }
    }
  ]
}

Sintaxe de expressões

Categoria Sintaxe Descrição
Acesso a dados source_name
source_name.field
source_name.field.subfield
Acessar a mensagem completa de uma fonte de dados ou agregador
Acessar um campo específico na mensagem (incluindo campos aninhados)
Aritmética +, -, *, /, %, ** Matemática padrão. ** é exponenciação.
Lógica &&, ||, !, ^ AND, OR, NOT, XOR.
Relacional ==, !=, <, <=, >, >= == e != funcionam em todos os tipos. Outros exigem números.
Lista contains(list, item)
doesnotcontain(list, item)
alleq(list, value)
Opera em vetores (matrizes). alleq(list, value) retorna true se todos os itens em list forem iguais a value.
Funções timestamp(clock_type) Horário atual em nanossegundos.
clock_type: REALTIME_CLOCK ou
MONOTONIC_TIME_SINCE_BOOT_OR_RESUME
abs(n) Valor absoluto
floor(n), round(n), ceil(n) Funções de arredondamento
Ordem de operações () Agrupamento padrão para precedência