Help with decoding base16 mqtt message


I am getting this MQTT message from a LoRa station, encoded in base16:

ffffffe20000005a505332323a30333a31303a31303a 30353a303030303032202b36312e3036202b31362e36313830

When decoded manually it contains this string:

ZPS22:03:10:10:05:000002 +61.06 +16.6180

with a timestamp and two data: humidity and temperature measurements.

My problem is that I don’t know how to configure telegraf to extract those data and save into the InfluxDB database.

Is there any base16 decoder processor?

I haven’t found that in the documentation.

Thanks in advance.

There are also some non-printable leading characters included.

Afaik, there is no such parser in Telegraf.

I would solve this with a processors.execd plugin.
Here is a quick working example in python that i tested with your data:

Telegraf Config

  files = ["AntMan.txt"]
  name_override = "AntMan"
  data_format = "value"
  data_type = "string"

  namepass = ["AntMan"]
  command = ["python", ""]

[[outputs.file]]  # only for debugging
  files = ["AntMan.out"]
  influx_sort_fields = true

Python Script

import base64
import re
from datetime import datetime

# 3rd party libraries:
# pip install influxdb-client
# pip install line-protocol-parser

from influxdb_client import Point
from line_protocol_parser import parse_line

while True:
        input_line = input()  # read from stdin
    except (EOFError, KeyboardInterrupt):  # catch EOF and KeyboardInterrupt error
        data = parse_line(input_line)  # parse input line
        value = data['fields'].pop('value')  # get and remove original field
        decoded = base64.b16decode(value, casefold=True)  # decode base16
        decoded = decoded.decode('ascii', errors='ignore')  # convert to ascii
        decoded = re.sub(r'[^\x20-\x7f]', "", decoded)  # remove non-printable characters
        decoded = decoded.strip('ZPS')  # remove leading characters
        timestamp, humidity, temperature = decoded.split(' ')
        temperature = float(temperature)  # convert string to float
        humidity = float(humidity)  # convert string to float
        timestamp = datetime.strptime(timestamp, '%y:%m:%d:%H:%M:%f')  # convert string to datetime
        data['fields'].update({'temperature': temperature, 'humidity': humidity})  # add fields
        data['time'] = timestamp  # set new time
        point = Point.from_dict(data)  # metric from dict
        print(point.to_line_protocol())  # write to stdout