Help needed processing JSON

I’m trying to parse some JSON via mqtt into telegraf (then into influxdb).

The JSON looks like:

{
    "Time": "2024-02-22T17:50:25",
    "INA3221": {
        "Id": "0x40",
        "Voltage": [
            4.048,
            4.896,
            0
        ],
        "Current": [
            0.123,
            0.11,
            0
        ],
        "Power": [
            0.497,
            0.541,
            0
        ]
    },
    "SGP40": {
        "VOC_Raw": 29635,
        "TVOC": 49
    },
    "TempUnit": "C"
}

I’m having trouble parsing the field for Voltage, current and power with multiple values.

What I’d like, is for this to result in an Influx statement along the lines of this, for each value in the array.

Current1=0.126,Power1=0.497,Voltage1=4.048 1708573439000000000
Current2=0.1,Power2=0.541,Voltage2=4.896 1708573439000000000
Current3=0,Power3=0,Voltage3=0 1708573439000000000

Is this possible using either json_v2 or xpath?

Hey @mabnz,

I fear this is not directly possible because XPath does not support list-zipping… However, you can use the starlark processor to achieve your goal:

[[inputs.file]]
  files = ["test_configs/jsontest_forum_mabnz.json"]

  data_format = "xpath_json"
  xpath_native_types = true

  [[inputs.file.xpath]]
    metric_name = "'mymetric'"
    metric_selection = "/INA3221"
    timestamp = "/Time"
    timestamp_format = "2006-01-02T15:04:05"
    field_selection = "*/*"

    [inputs.file.xpath.tags]
      id = "Id"

[[processors.starlark]]
  source = '''
def apply(metric):
  # Split the fields into field-name part and index
  fields = [(k.rsplit("_", 1), v) for (k,v) in metric.fields.items()]

  # Get a field list with elements in format (index, field-name, value) for
  # grouping the data by index.
  fields = [(int(x[0][1]), x[0][0], x[1]) for x in fields]

  # Get indices and iterate over those to collect the data per metric
  indices = list(set([i for i,_,_ in fields]))

  # Create the new metrics after grouping the fields
  results = list()
  for idx in indices:
    f = {k: v for i, k, v in fields if i == idx}
    m = Metric(metric.name, tags=metric.tags, fields=f)
    m.tags["index"] = str(idx)
    m.time = metric.time
    results.append(m)


  return results
'''

returns

> mymetric,host=Hugin,id=0x40,index=1 Current=0.11,Power=0.541,Voltage=4.896 1708624225000000000
> mymetric,host=Hugin,id=0x40,index=0 Current=0.123,Power=0.497,Voltage=4.048 1708624225000000000
> mymetric,host=Hugin,id=0x40,index=2 Current=0,Power=0,Voltage=0 1708624225000000000

for your example. Please note: You have to change inputs.file to whatever input plugin you use the parser in…

That’s worked perfectly. Thank you!