JSON v2 parsing - variable string inside path

Hello, I am trying to parse the json below (which comes from IOT / BSB-LAN).
It is truncated to 3 objects (8005, 8009, 8308), but I actually have more objects, based on the device settings (the user can define which device parameters he wants to query by http).

And I don’t know how to properly define the path for json_v2.object. It should be a variable, because http query can change from time to time.
I ended up with the configuration below, but there I had to explicitly define a path (which is actually Tag) for each object.

  [[inputs.http.json_v2]]
    [[inputs.http.json_v2.object]]
      path = "8005"
      tags = ["name"]
      included_keys = ["value", "desc"]
    [[inputs.http.json_v2.object]]
      path = "8009"
      tags = ["name"]
      included_keys = ["value", "desc"]
    [[inputs.http.json_v2.object]]
      path = "8308"
      tags = ["name"]
      included_keys = ["value", "desc"]

json

{
“8005”: {
“name”: “Kotel - stav”,
“dataType_name”: “ENUM”,
“dataType_family”: “ENUM”,
“destination”: 0,
“error”: 0,
“value”: “25”,
“desc”: “Vyp”,
“payload”: “0019”,
“dataType”: 1,
“readwrite”: 1,
“unit”: “”
},
“8009”: {
“name”: “Stav hořáku”,
“dataType_name”: “ENUM”,
“dataType_family”: “ENUM”,
“destination”: 0,
“error”: 0,
“value”: “216”,
“desc”: “Vypnuto”,
“payload”: “00D8”,
“dataType”: 1,
“readwrite”: 1,
“unit”: “”
},
“8308”: {
“name”: “Otáčky čerpadla kotle”,
“dataType_name”: “PERCENT”,
“dataType_family”: “VALS”,
“destination”: 0,
“error”: 0,
“value”: “—”,
“desc”: “”,
“payload”: “0100”,
“precision”: 1,
“dataType”: 0,
“readwrite”: 1,
“unit”: “%”
}
}

Looking at your JSON structure and Telegraf configuration, the issue is that you have dynamic keys (8005, 8009, 8308, etc.) at the root level, but json_v2.object requires you to specify a static path.

Use JSONPath with wildcards

[[inputs.http.json_v2]]
  [[inputs.http.json_v2.object]]
    path = "*"  # Wildcard to match all top-level keys
    optional = true
    tags = ["name"]
    included_keys = ["value", "desc", "unit", "dataType_name", "error"]

I tried that, but Telegraf only returns the 1st object (8005)

> heater,name=Kotel\ -\ stav dataType_name="ENUM",desc="Vyp",error=0,unit="",value="25" 1752741621000000000

Now that it has reached the actual implementation stage, I have encountered a problem with objects that have decimal values (mostly temperatures). When I use Telegraf to run --test in the command line, I can see all the processed rows, but in InfluxDB Explorer (or Grafana) I can only query objects with the int data type. Decimal objects are missing.
What could be wrong?

Here is updated Json

json
{
  "8308": {
    "name": "Otáčky čerpadla kotle",
    "dataType_name": "PERCENT",
    "dataType_family": "VALS",
    "destination": 0,
    "error": 0,
    "value": "0",
    "desc": "",
    "payload": "0100",
    "precision": 1,
    "dataType": 0,
    "readwrite": 1,
    "unit": "%"
  },
  "8310": {
    "name": "Teplota kotle",
    "dataType_name": "TEMP",
    "dataType_family": "VALS",
    "destination": 0,
    "error": 0,
    "value": "34.7",
    "desc": "",
    "payload": "0008AF",
    "precision": 0.1,
    "dataType": 0,
    "readwrite": 1,
    "unit": "°C"
  },
  "8314": {
    "name": "Teplota zpátečky",
    "dataType_name": "TEMP",
    "dataType_family": "VALS",
    "destination": 0,
    "error": 0,
    "value": "33.2",
    "desc": "",
    "payload": "00084A",
    "precision": 0.1,
    "dataType": 0,
    "readwrite": 1,
    "unit": "°C"
  },
  "8325": {
    "name": "Aktuální řízení ventilátoru",
    "dataType_name": "PERCENT_100",
    "dataType_family": "VALS",
    "destination": 0,
    "error": 0,
    "value": "0.0",
    "desc": "",
    "payload": "000000",
    "precision": 0.1,
    "dataType": 0,
    "readwrite": 1,
    "unit": "%"
  },
  "8326": {
    "name": "Modulace hořáku",
    "dataType_name": "PERCENT",
    "dataType_family": "VALS",
    "destination": 0,
    "error": 0,
    "value": "0",
    "desc": "",
    "payload": "0100",
    "precision": 1,
    "dataType": 0,
    "readwrite": 1,
    "unit": "%"
  },
  "8700": {
    "name": "Venkovní teplota",
    "dataType_name": "TEMP",
    "dataType_family": "VALS",
    "destination": 0,
    "error": 0,
    "value": "2.2",
    "desc": "",
    "payload": "00008D",
    "precision": 0.1,
    "dataType": 0,
    "readwrite": 1,
    "unit": "°C"
  },
  "8740": {
    "name": "TO1 teplota prostoru",
    "dataType_name": "TEMP",
    "dataType_family": "VALS",
    "destination": 0,
    "error": 0,
    "value": "18.5",
    "desc": "",
    "payload": "00049D",
    "precision": 0.1,
    "dataType": 0,
    "readwrite": 1,
    "unit": "°C"
  },
  "8770": {
    "name": "TO2 teplota prostoru",
    "dataType_name": "TEMP",
    "dataType_family": "VALS",
    "destination": 0,
    "error": 0,
    "value": "20.7",
    "desc": "",
    "payload": "00052F",
    "precision": 0.1,
    "dataType": 0,
    "readwrite": 1,
    "unit": "°C"
  },
  "8830": {
    "name": "TV Skutečná teplota  B3",
    "dataType_name": "TEMP",
    "dataType_family": "VALS",
    "destination": 0,
    "error": 0,
    "value": "47.8",
    "desc": "",
    "payload": "000BF4",
    "precision": 0.1,
    "dataType": 0,
    "readwrite": 1,
    "unit": "°C"
  }
}

In config, I use inputs.http to get data, here is inputs.file for easy debugging.
Is float correct datatype ?

config
[[inputs.file]]
  files = ["bsb-lan.json"]
  data_format = "json_v2"
[[inputs.file.json_v2]]
    [[inputs.file.json_v2.object]]
      path = "8308"
      tags = ["name","unit"]
      included_keys = ["value"]
      [inputs.file.json_v2.object.fields]
      value = "int"
    [[inputs.file.json_v2.object]]
      path = "8310"
      tags = ["name","unit"]
      included_keys = ["value"]
      [inputs.file.json_v2.object.fields]
      value = "float"
    [[inputs.file.json_v2.object]]
      path = "8314"
      tags = ["name","unit"]
      included_keys = ["value"]
      [inputs.file.json_v2.object.fields]
      value = "float"
    [[inputs.file.json_v2.object]]
      path = "8325"
      tags = ["name","unit"]
      included_keys = ["value"]
      [inputs.file.json_v2.object.fields]
      value = "float"
    [[inputs.file.json_v2.object]]
      path = "8326"
      tags = ["name","unit"]
      included_keys = ["value"]
      [inputs.file.json_v2.object.fields]
      value = "int"
    [[inputs.file.json_v2.object]]
      path = "8700"
      tags = ["name","unit"]
      included_keys = ["value"]
      [inputs.file.json_v2.object.fields]
      value = "float"
    [[inputs.file.json_v2.object]]
      path = "8740"
      tags = ["name","unit"]
      included_keys = ["value"]
      [inputs.file.json_v2.object.fields]
      value = "float"
    [[inputs.file.json_v2.object]]
      path = "8770"
      tags = ["name","unit"]
      included_keys = ["value"]
      [inputs.file.json_v2.object.fields]
      value = "float"
    [[inputs.file.json_v2.object]]
      path = "8830"
      tags = ["name","unit"]
      included_keys = ["value"]
      [inputs.file.json_v2.object.fields]
      value = "float"

Console output

Summary

file,host=xxx,name=Otáčky\ čerpadla\ kotle,unit=% value=0i 1765790732000000000
file,host=xxx,name=Teplota\ kotle,unit=°C value=34.7 1765790732000000000
file,host=xxx,name=Teplota\ zpátečky,unit=°C value=33.2 1765790732000000000
file,host=xxx,name=Aktuální\ řízení\ ventilátoru,unit=% value=0 1765790732000000000
file,host=xxx,name=Modulace\ hořáku,unit=% value=0i 1765790732000000000
file,host=xxx,name=Venkovní\ teplota,unit=°C value=2.2 1765790732000000000
file,host=xxx,name=TO1\ teplota\ prostoru,unit=°C value=18.5 1765790732000000000
file,host=xxx,name=TO2\ teplota\ prostoru,unit=°C value=20.7 1765790732000000000
file,host=xxx,name=TV\ Skutečná\ teplota\ \ B3,unit=°C value=47.8 1765790732000000000

GPT-4.1 provided the following explanation, which I was unaware of:

InfluxDB enforces field types by measurement and field name. If you write both an integer (0i) and a float (60.3) for the same field key in the same measurement, InfluxDB may drop or ignore conflicting writes.

Example:

  • One line: value=0i (integer)
  • Other line: value=60.3 (float)

Solution:

  • Make sure the data type for each field remains consistent for each unique measurement+field+tag combination.

Now I have set the float to all values, I can successfully query them :grinning_face:

1 Like