Payload Parser
Visão Geral
O Payload Parser é um componente essencial na integração de dispositivos IoT, pois sensores ou fontes de dados externas transmitem dados em diversos formatos como binário, hexadecimal, JSON e outros. Sua principal função é decodificar os payloads brutos e convertê-los em um Valeiot Data Point. Isso garante que os dados de qualquer sensor ou componente externo possam ser facilmente interpretados, armazenados e utilizados dentro da plataforma, como ilustrado no diagrama abaixo.

O Payload Parser é um script em JavaScript, que processa os dados recebidos dos sensores e os converte em valores legíveis. O script segue as especificações do protocolo definidas pela documentação do fabricante do hardware, para decodificar corretamente os campos de dados.
Características Principais
- Pré-processamento: Payload Parsers permitem transformar payloads de entrada arbitrários (ex.: JSON customizado, binário ou formatos específicos de fabricantes) em Valeiot Data Points padronizados antes de serem armazenados.
- Filtragem: Filtre ou descarte seletivamente campos específicos do payload para evitar que dados indesejados sejam inseridos no dispositivo.
- Linguagens atualmente suportadas: Javascript
Casos de Uso
- Decodificação de Dados: O Payload Parser decodifica os payloads brutos transmitidos por sensores ou fontes de dados externas, convertendo dados binários ou hexadecimais em valores significativos como latitude, longitude, voltagem da bateria, velocidade e outras métricas do dispositivo.
- Normalização de Valeiot Data Point: Ajuste de JSONs personalizados para conformidade com a estrutura do Valeiot Data Point, garantindo inserção bem-sucedida nos Data Sources.
- Flexibilidade: Capacidade de lidar com diferentes tipos de mensagens de uplink e permitir processamento customizado antes da inserção no Data Source.
- Tratamento de Erros: Detecção e tratamento de formatos de dados inesperados, garantindo robustez mesmo em casos de dados corrompidos ou incompletos.
- Personalização: O parser pode ser adaptado para atender a requisitos específicos, como ignorar determinados pontos de dados ou adicionar metadados adicionais aos dados decodificados.
Estrutura do Payload Parser
O Payload Parser deve conter obrigatoriamente uma função de entrada chamada parse, executada sempre que uma requisição for enviada. Essa função recebe como parâmetro o payload, que contém a mensagem da requisição. Ao final, ela deve retornar um array de Valeiot Data Points.
function parse(payload) {
let dataList = [];
// sua lógica vai aqui
return dataList;
}
Validação do Código
Um parser válido consiste em uma ou mais declarações de função, tendo parse como ponto de entrada que o runtime chamará com o payload recebido.
O código do parser deve atender às seguintes regras:
-
Sem referências a
this.
O código não deve conter a substringthis.. O acesso ao objeto global utilizandothisnão é permitido. -
JavaScript válido
O código deve ser um JavaScript válido. Qualquer erro de parsing (por exemplo, erro de sintaxe) fará com que a validação falhe. -
Apenas declarações de função no nível superior
O escopo de nível superior do script deve conter apenas declarações de função (por exemplo,function parse(payload) { ... }).
Qualquer outro tipo de instrução no nível superior — como expressões,var,let,constou atribuições — será rejeitado. -
Limite de tamanho do código
O tamanho máximo permitido para o código do parser é 10240 caracteres.
Funções nativas no runtime
As funções abaixo são injetadas no runtime JavaScript e ficam disponíveis globalmente.
Por razões de segurança, eval é removido (definido como undefined).
base64ToHex(base64String)
Converte uma string codificada em Base64 para sua representação hexadecimal.
- Argumento: string (codificada em Base64).
- Retorno: string (hexadecimal em letras minúsculas).
- Erros:
- Erro de tipo se o argumento estiver ausente ou não for uma string.
- Erro de tipo se a string não for um Base64 válido.
hexToBytes(hexStringOrBytes)
Converte uma string hexadecimal em um array de bytes.
- Argumento: string ou array de bytes (codificado em hex).
- Retorno: array de bytes.
- Erros:
- Erro de tipo se o argumento estiver ausente ou não for string/array de bytes.
- Erro de tipo se o valor não for hexadecimal válido.
bytesToString(bytes)
Converte um array de bytes em uma string UTF-8.
- Argumento: array de bytes.
- Retorno: string (interpretação UTF-8 dos bytes).
- Erros:
- Erro de tipo se o argumento estiver ausente ou não for um array de bytes.
toDatapoints(obj, [timestamp])
Constrói um array de datapoints do parser a partir de um objeto chave–valor.
-
Argumentos:
obj: objeto — cada chave se torna o nome da variable e cada valor se torna o value de um datapoint.timestamp(opcional): número representando o tempo Unix em segundos. Se fornecido, será utilizado como o time para todos os datapoints gerados.
-
Retorno: array de objetos
{ time, variable, value }.
Setimestampnão for informado, será utilizado o horário atual do servidor (RFC3339). -
Erros:
- Erro de tipo se o primeiro argumento estiver ausente ou não for um objeto.
- Erro de tipo se o segundo argumento for informado mas não for um número (Unix seconds).
Esta função é útil quando o payload é um objeto simples (por exemplo: { temperature: 22.5, humidity: 80 }) e você deseja gerar um datapoint para cada chave.
unixToRFC3339(unixSeconds)
Converte tempo Unix em segundos para o formato RFC3339.
- Argumento: número (tempo Unix em segundos).
- Retorno: string no formato RFC3339.
- Erros:
- Erro de tipo se o argumento estiver ausente ou não for um número.
unixMilliToRFC3339(unixMilliseconds)
Converte tempo Unix em milissegundos para o formato RFC3339.
- Argumento: número (tempo Unix em milissegundos).
- Retorno: string no formato RFC3339.
- Erros:
- Erro de tipo se o argumento estiver ausente ou não for um número.
Se o parser não estiver funcionando como esperado, inspecione o dispositivo utilizando a ferramenta Live Inspector.
Acesse a página do dispositivo, abra a aba Live Inspector e aguarde ou force uma nova requisição de payload. O Live Inspector captura a requisição bruta e o resultado da execução do parser, permitindo analisar o processamento do payload passo a passo e identificar possíveis erros.
Exemplo
Abaixo está um exemplo de um Payload Parser baseado em JavaScript, que decodifica o payload enviado do dispositivo e o converte em Valeiot Data Points:
function parse(payload) {
let dataList = [];
if (typeof payload === "string") {
const buffer = hexToUint8Array(payload);
if (buffer[0]) {
const batteryValue = buffer[0];
dataList.push({
variable: "battery",
value: batteryValue,
});
}
if (buffer[1]) {
const temperatureValue = buffer[1];
dataList.push({
variable: "temperature",
value: temperatureValue,
});
}
if (buffer[3]) {
const doorBit = buffer[3] & 0x08;
let doorState = "";
if (doorBit > 0x00) {
doorState = "Closed";
} else {
doorState = "Open";
}
dataList.push({
variable: "door_state",
value: doorState,
});
}
dataList = dataList.concat({ variable: "payload", value: payload });
} else {
dataList = dataList.concat(payload);
}
const ignoreVars = ["snr", "rssi", "gateway_eui", "fcnt", "fport"];
dataList = dataList.filter((x) => !ignoreVars.includes(x.variable));
return dataList;
}
O parser espera um payload como entrada, usando o seguinte exemplo de payload:
"621b6310";
O resultado esperado são os data points:
[
{ variable: "battery", value: 98 },
{ variable: "temperature", value: 27 },
{ variable: "position_state", value: "Open" },
{ variable: "payload", value: "621b6310" },
];
Explicação
O processo de decodificação é livre - você pode fazer basicamente o que quiser com JavaScript. Para o exemplo mencionado, o script decodifica a bateria, temperatura e estado da porta a partir do payload. Ele converte de hexadecimal para decimal e aplica uma simples operação de bitmask. Também remove algumas variáveis indesejadas como snr, rssi, gateway_eui, fcnt e fport.
function parse(payload) {
let dataList = [];
if (typeof payload === "string") {
const buffer = hexToUint8Array(payload);
if (buffer[0]) {
const batteryValue = buffer[0];
dataList.push({
variable: "battery",
value: batteryValue,
});
}
if (buffer[1]) {
const temperatureValue = buffer[1];
dataList.push({
variable: "temperature",
value: temperatureValue,
});
}
if (buffer[3]) {
const doorBit = buffer[3] & 0x08;
let doorState = "";
if (doorBit > 0x00) {
doorState = "Closed";
} else {
doorState = "Open";
}
dataList.push({
variable: "door_state",
value: doorState,
});
}
dataList = dataList.concat({ variable: "payload", value: payload });
} else {
dataList = dataList.concat(payload);
}
const ignoreVars = ["snr", "rssi", "gateway_eui", "fcnt", "fport"];
dataList = dataList.filter((x) => !ignoreVars.includes(x.variable));
return dataList;
}
A calculadora abaixo mostra os valores hexadecimal e binário.

Bateria: 0110 0010 ou 0x62 ou 98
Temperatura: 0001 1011 ou 0x1B ou 27
Estado da Porta: 0001 0000 que é 0x10 quando operado 0x10 & 0x08 o resultado é 0x00
00010000 (0x10)
& 00001000 (0x08)
--------
00000000 (Result)
Este exemplo demonstra como o Payload Parser pode ser usado para decodificar dados do dispositivo e convertê-los no formato Valeiot Data Point.