IoT industrial

Referência de Tipos de Dados e Propriedades de Métricas do Sparkplug B

Uma referência prática de todos os tipos de dados do Sparkplug B, do campo Protobuf em que cada um trafega, de propriedades de métricas como Quality, das flags de métricas e dos DataSets, com exemplos decodificados e erros comuns de conversão.

Tabela de referência dos tipos de dados do Sparkplug B com códigos, campos de valor Protobuf e propriedades de métricas
Rode isso no seu próprio broker MQTTTenha um broker MQTT privado e gerenciado no plano Free e comece com exemplos de código prontos.
Teste grátis Exemplos de código Sem cartão de crédito

Os tipos de dados do Sparkplug B definem exatamente como cada valor de métrica é codificado, de um inteiro de 8 bits com sinal até uma tabela inteira de linhas e colunas. Esta referência lista todos os códigos de datatype com o campo Protobuf que cada um usa, explica as propriedades de métricas e os códigos de qualidade e mostra exemplos decodificados para que você reconheça cada tipo ao inspecionar tráfego real.

Por que o Sparkplug tem os seus próprios tipos de dados

O JSON tem números, strings e booleanos. Sistemas industriais precisam de mais precisão do que isso. Um registrador de CLP pode ser um inteiro de 16 bits sem sinal, um contador pode ser um valor de 64 bits sem sinal e um timestamp não pode ser confundido com um número comum. O Sparkplug B atribui a cada métrica um código datatype explícito para que uma aplicação host do outro lado do mundo interprete o valor exatamente como o edge node pretendia.

O datatype é declarado para cada métrica nas mensagens de birth. As mensagens de dados podem omiti-lo, e é por isso que os consumidores armazenam os datatypes a partir dos births, como descrito no nosso guia de payload Sparkplug B.

Tipos de dados escalares do Sparkplug B

Código Nome Campo de valor Protobuf Observações
0 Unknown nenhum Marcador, não deve aparecer em métricas válidas
1 Int8 int_value Com sinal, complemento de dois em um campo sem sinal
2 Int16 int_value Com sinal, complemento de dois
3 Int32 int_value Com sinal, complemento de dois
4 Int64 long_value Com sinal, complemento de dois em uint64
5 UInt8 int_value Sem sinal
6 UInt16 int_value Sem sinal
7 UInt32 int_value Sem sinal
8 UInt64 long_value Sem sinal
9 Float float_value IEEE 754 de 32 bits
10 Double double_value IEEE 754 de 64 bits
11 Boolean boolean_value true ou false
12 String string_value Texto UTF-8
13 DateTime long_value Milissegundos desde a época Unix, UTC
14 Text string_value Texto mais longo, mesma codificação de String
15 UUID string_value UUID em forma de string
16 DataSet dataset_value Tabela de colunas e linhas tipadas
17 Bytes bytes_value Dados binários brutos
18 File bytes_value Conteúdo de arquivo, descrito por MetaData
19 Template template_value Tipo ou instância definido pelo usuário

Os códigos 20 e 21 (PropertySet e PropertySetList) são usados para valores de propriedades, não para valores de métricas.

A armadilha dos inteiros com sinal

O bug de decodificação mais comum no Sparkplug é ler inteiros com sinal diretamente. Como int_value é um campo de 32 bits sem sinal, um Int32 de -5 chega como 4294967291, e um Int64 de -1 chega como 18446744073709551615 em long_value. O consumidor precisa aplicar o complemento de dois com base no datatype declarado. Os edge nodes precisam fazer o inverso ao codificar. Se um dashboard de repente mostrar uma temperatura de quatro bilhões de graus, quase sempre o motivo é este.

DateTime não é um número

Uma métrica DateTime e uma métrica Int64 usam o mesmo campo, mas significam coisas diferentes. Trate DateTime como milissegundos desde a época em UTC e converta-o para exibição. Nunca envie segundos e nunca envie horário local.

Tipos de dados array

O Sparkplug também define arrays de tipos escalares. Eles trafegam em bytes_value como valores compactados em little-endian, uma codificação que o Sparkplug 3.0 detalha com precisão (veja a nossa comparação do Sparkplug 3.0 para saber o que mais foi esclarecido).

Código Nome Código Nome
22 Int8Array 29 UInt64Array
23 Int16Array 30 FloatArray
24 Int32Array 31 DoubleArray
25 Int64Array 32 BooleanArray
26 UInt8Array 33 StringArray
27 UInt16Array 34 DateTimeArray
28 UInt32Array

O suporte a arrays varia entre produtos. Se você depende de arrays entre fornecedores diferentes, teste cedo com as duas pontas conectadas ao mesmo broker.

Flags de métricas

Cada métrica pode carregar flags booleanas que mudam a forma como os consumidores a tratam:

Flag Significado Comportamento do consumidor
is_null A métrica existe, mas não tem valor Exibir como nulo ou qualidade ruim, não substituir por zero
is_historical O valor é do passado, por exemplo de store and forward Armazenar, sem sobrescrever o valor ao vivo
is_transient O valor não deve ser historiado Exibir, sem armazenar

As métricas também têm um timestamp opcional, separado do timestamp do payload. Use-o para registrar quando o valor foi amostrado na origem.

Propriedades de métricas

Uma métrica pode carregar um PropertySet: listas paralelas de chaves e valores tipados. Os valores de propriedades usam os mesmos códigos de datatype, mais PropertySet (20) e PropertySetList (21), que permitem aninhamento.

A propriedade Quality

A única propriedade à qual a especificação dá um significado definido é Quality, um Int32:

Valor Significado
192 Boa
0 Ruim
500 Desatualizada (stale)

Um host que recebe uma métrica com Quality 0 deve exibi-la como ruim, mesmo que haja um valor presente. Muitas plataformas de borda definem Quality 500 quando perdem contato com o device subjacente, mas mantêm o node conectado.

Outras propriedades comuns

Unidades de engenharia, faixas, descrições e formatos de exibição costumam ser transportados como propriedades, mas os nomes das chaves são convenções de cada plataforma, e não parte da especificação. Combine um vocabulário de propriedades entre os seus edge nodes, ou a sua aplicação host verá o mesmo conceito sob chaves diferentes.

DataSets

Um DataSet é uma pequena tabela tipada dentro de uma única métrica. Ele tem um número de colunas, nomes de colunas, um código de datatype para cada coluna e uma lista de linhas. Cada valor de linha usa um conjunto restrito de campos: int, long, float, double, boolean ou string.

Decodificada, uma tabela de parâmetros de receita pode ficar assim:

{
  "name": "Recipe/Steps",
  "datatype": 16,
  "datasetValue": {
    "numOfColumns": 3,
    "columns": ["Step", "Temperature", "Duration"],
    "types": [3, 9, 7],
    "rows": [
      { "elements": [{ "intValue": 1 }, { "floatValue": 180.0 }, { "intValue": 600 }] },
      { "elements": [{ "intValue": 2 }, { "floatValue": 220.0 }, { "intValue": 300 }] }
    ]
  }
}

DataSets são úteis para lotes de valores relacionados que precisam ficar juntos. Para modelos estruturados de equipamentos, os templates costumam ser mais adequados; veja templates e UDTs do Sparkplug.

Exemplos decodificados

Este é um trecho de birth com vários tipos de dados e uma propriedade Quality, como você o veria depois de decodificado:

[
  { "name": "Pump/Running", "alias": 1, "datatype": 11, "booleanValue": true },
  { "name": "Pump/Speed", "alias": 2, "datatype": 9, "floatValue": 1475.0,
    "properties": { "keys": ["Quality"], "values": [{ "type": 3, "intValue": 192 }] } },
  { "name": "Pump/StartCount", "alias": 3, "datatype": 8, "longValue": "18342" },
  { "name": "Pump/LastService", "alias": 4, "datatype": 13, "longValue": "1789000000000" },
  { "name": "Pump/Offset", "alias": 5, "datatype": 2, "intValue": 4294967286 },
  { "name": "Pump/Serial", "alias": 6, "datatype": 12, "stringValue": "P-0042" }
]

Repare no offset Int16: o valor bruto 4294967286 é -10 depois do complemento de dois. Repare também que algumas representações em JSON mostram valores de 64 bits como strings para evitar perda de precisão no JavaScript.

Verificando tipos de dados na prática

A forma mais rápida de verificar os datatypes é ler os births decodificados. O ConnectMQ decodifica Sparkplug B no topic explorer do portal, então você pode abrir um NBIRTH ou DBIRTH e conferir o datatype e o valor de cada métrica sem escrever código. Para verificações automatizadas, o decodificador do nosso tutorial sobre como decodificar Sparkplug B em Python mapeia códigos para nomes e trata a conversão de sinal.

Quando testar no servidor MQTT público, use um group ID aleatório e lembre-se de que tudo ali pode ser lido por qualquer pessoa.

Checklist de tipos de dados para configurar edge nodes

  1. Faça cada tipo Sparkplug corresponder ao tipo do registrador de origem; não converta tudo para Double.
  2. Use tipos sem sinal para contadores que nunca ficam negativos.
  3. Use DateTime para timestamps, sempre em milissegundos UTC.
  4. Defina Quality nas métricas cuja origem pode falhar independentemente do node.
  5. Use is_null em vez de zero quando um valor não estiver disponível.
  6. Marque os dados de store and forward como históricos.
  7. Combine os nomes das chaves de propriedades entre todos os edge nodes.
  8. Teste arrays, DataSets e templates de ponta a ponta antes da implantação.

Onde os tipos de dados se encaixam

Tipos de dados corretos são o que permite que os dados Sparkplug alimentem historians, SCADA, um Unified Namespace e um gêmeo digital sem correções tag a tag, seja numa usina, numa mineradora ou numa linha de manufatura. Para orientações de arquitetura, veja o guia de IoT Industrial com MQTT. Qualquer broker MQTT compatível transporta esses payloads; um broker MQTT gerenciado que também os decodifica torna a verificação muito mais rápida.

Comece com o ConnectMQ

Crie um broker Serverless gratuito em app.connectmq.com, sem cartão de crédito. Conecte o seu edge node e confira o datatype, o valor e a qualidade de cada métrica no topic explorer do ConnectMQ.

Perguntas frequentes

Quantos tipos de dados o Sparkplug B tem?

A especificação define tipos escalares com códigos de 1 a 19, tipos de property set 20 e 21 e tipos array de 22 a 34. O código 0 é Unknown.

Por que o meu valor negativo do Sparkplug aparece como um número enorme?

Inteiros com sinal são armazenados em campos Protobuf sem sinal. Aplique o complemento de dois com base no datatype declarado ou use um decodificador que faça isso por você.

O que significa Quality 192 no Sparkplug?

Significa qualidade boa. A propriedade Quality usa 192 para boa, 0 para ruim e 500 para desatualizada.

Os tipos de dados do Sparkplug são obrigatórios nas mensagens de dados?

Eles são obrigatórios nas mensagens de birth e opcionais em NDATA e DDATA. Os consumidores devem memorizar o datatype de cada métrica a partir do birth.

Artigos relacionados

Cliente MQTT no CODESYS: Publicando Variáveis do CLP em um Broker

Configure a biblioteca IIoT MQTT Client do CODESYS para publicar variáveis do CLP em JSON, verifique-as no servidor MQTT público broker.connectmq.com e depois migre para um broker privado com credenciais e TLS.

8 min de leitura

Todos os artigos →

Seu broker MQTT privado está a poucos cliques de distância

Crie uma conta, receba as credenciais do seu broker e conecte seu primeiro dispositivo — sem servidores para instalar, atualizar ou escalar.