MQTT Nested Value Help

Hello, I’m looking for a little bit of help. I have zoneminder set up to publish MQTT messages to a mosquito broker. Home Assistant subscribes to the zoneminder topic. When I have Home Assistant configured to output {{ value_json.name }} to a sensor, it works. It displays the full line "Front Door Halo:(19328) [s] detected:person:97% Door Step”. But I would like to get the label value of “person” to display. I’ve tried different value template configurations with different results. Below I have the MQTT output from zoneminder, Home Assistant platform configuration, and the different values I’ve tried so far and the associated results. I’ve been trying to use the Processing JSON Home Assistant document, but my programming skills are novice at best. Any help you can provide is appreciated. Also as a side not, I’ve verified that Home Assistant receives the topic information by using the MQTT Developer Tool as well has using MQTT Explorer.

Zoneminder MQTT Output

{
“state”: “alarm”,
“eventid”: “19328”,
“hookvalue”: “0”,
“name”: “Front Door Camera:(19328) [s] detected:person:97% Door Step”,
“monitor”: “1”,
“detection”: [
{
“label”: “person”,
“type”: “object”,
“confidence”: “97.47%”,
“box”: [
1,
93,
259,
725
]
}
],
“eventtype”: “event_start”
}

Home Assistant Platform Configuration

  • platform: mqtt
    state_topic: “zoneminder/1”
    name: Front Door Camera Messages
    #value_template: “{{ value_json.name }}”
    value_template: “{{ value_json[‘detection’][‘label’] }}”

Results:

Works but returns blank value

value_template: "{{ value_json.detection.label }}"

Doesn’t change value in Home Assistant it stays showing Unknown

value_template: "{{ value_json[detection].label }}"
value_template: "{{ value_json[detection]['label'] }}"
value_template: "{{ value_json[detection].label }}"
value_template: "{{ value_json.detection[0].label }}"
1 Like

If you write it out clearly (use triple-backticks for code block formatting and indent it logically), you’ll see that detection is a list with a dictionary as its only item, and you want the label of that dictionary, hence the [0] in @123’s answer above.

{
  "state": "alarm",
  "eventid": "19328",
  "hookvalue": "0",
  "name": "Front Door Camera:(19328) [s] detected:person:97% Door Step",
  "monitor": "1",
  "detection": [
    {
      "label": "person",
      "type": "object",
      "confidence": "97.47%",
      "box": [
        1,
        93,
        259,
        725
      ]
    }
  ],
  "eventtype": "event_start"
}
1 Like

Thanks @123 you for your help. This worked perfectly.

1 Like

Thanks for your explanation @Troon. I seen examples with the [0] listed, but i didnt know what it meant.

It’s the item index in a list, and computer languages tend to count from 0. As another example, to pull out the 259 in the box list, you’d use:

{{value_json.detection[0]['box'][2] }}

…which means:

  • look in the detection item
  • at the first ([0]) item in the list
  • at the box item
  • and at the third ([2]) item in that list

You can usually mix and match dot notation and bracket notation, so you could also use:

{{value_json.detection.0.box.2 }}

but there are occasions where you might encounter problems, if the identifiers have other meanings (see here for an example).

1 Like

For future reference, you can use this to help you find the ‘JSON Path’:

https://jsonpathfinder.com/

Paste your JSON string into jsonpathfinder’s window and it will be converted to a JSON object. Navigate through the object to the key whose value you want (in your case it was label). When it’s highlighted, the UI will display the JSON path required to access the desired value.

Example:

3 Likes

Sorry to raise an old thread, but I am having similar issues

Herwith my MQTT Binary Sensor yaml

  - state_topic: "application/38/device/70b3d52c0001e5bd/event/up"
    name: sensative02
    unique_id: sensative02
    value_template: '{{ value_json.object.presence.value }}'
    device_class: occupancy
    payload_on: "true"
    payload_off: "false"

any herewith json payload from mqtt explorer

{
  "applicationID": "38",
  "applicationName": "Buildings-Project",
  "deviceName": "sensative-2",
  "deviceProfileName": "sensative-strips",
  "deviceProfileID": "REDACTED",
  "devEUI": "REDACTED",
  "rxInfo": [
    {
      "gatewayID": "REDACTED",
      "uplinkID": "REDACTED",
      "name": "IoTCI-HQ",
      "rssi": -79,
      "loRaSNR": 10.5
      }
    },
    {
      "gatewayID": "REDACTED",
      "uplinkID": "REDACTED",
      "name": "HP0D_La-",
      "time": "2023-02-22T19:36:52.105088Z",
      "rssi": -77,
      "loRaSNR": 13.5,
      "location": {
        "latitude": REDACTED,
        "longitude": -REDACTED,
        "altitude": 10
      }
    }
  ],
  "txInfo": {
    "frequency": 868300000,
    "dr": 5
  },
  "adr": true,
  "fCnt": 23,
  "fPort": 1,
  "data": "//8BYxIBFQA=",
  "object": {
    "battery": 99,
    "closeProximityAlarm": {
      "value": false
    },
    "historySeqNr": 65535,
    "presence": {
      "value": true
    },
    "prevHistSeqNr": 65535
  }
}

The error message I get is

> * Error parsing value: 'dict object' has no attribute 'presence' (value: {"applicationID":"38","applicationName":"Buildings-Project","deviceName":"sensative-1","deviceProfileName":"sensative-strips","deviceProfileID":"REDACTED","devEUI":"REDACTED","rxInfo":[{"gatewayID":"REDACTED","uplinkID":"REDACTED","name":"HP0D_La","time":"2023-02-22T19:52:26.157912Z","rssi":-67,"loRaSNR":9.5,"location":{"latitude":REDACTED,"longitude":REDACTED,"altitude":10}},{"gatewayID":"REDACTED","uplinkID":"REDACTED","name":"IoTCI-HQ","rssi":-63,"loRaSNR":7.8,"location":{"latitude":REDACTED,"longitude":REDACTED,"altitude":0}}],"txInfo":{"frequency":867500000,"dr":5},"adr":true,"fCnt":23,"fPort":1,"data":"//9uDOYlKQYAAAA=","object":{"historySeqNr":65535,"prevHistSeqNr":65535}}, template: {{ value_json.object.presence.value }})

Can anyone spot where I am going wrong?

Many thanks for any help

This is dot notation:

value_json.foo.whatever

This is bracket notation:

value_json["foo"]["whatever"]

This is a hybrid of dot and bracket notation:

value_json.foo["whatever"]

Dot notation is more compact but it has a few limitations. For example, the key name cannot start with a number and it cannot contain a space character. Another limitation is that the key cannot have the same name as any built-in functions and, as you may have already guessed, the name value is also the name of a built-in function. Therefore you can’t use dot notation to reference a key named value.

You can use a hybrid like this:

    value_template: '{{ value_json.object.presence["value"] }}'

Or full bracket notation:

    value_template: '{{ value_json["object"]["presence"]["value"] }}'

Hi,

Thanks for getting back to me. I had been playing around with both options, however I always get the same error:

  • Error parsing value: ‘dict object’ has no attribute ‘presence’ (value: {“applicationID”:“38”,“applicationName”:“Buildings-Project”,“deviceName”:“sensative-1”,“deviceProfileName”:“sensative-strips”,“deviceProfileID”:“REDACTED”,“devEUI”:“REDACTED”,“rxInfo”:[{“gatewayID”:“REDACTED”,“uplinkID”:“REDACTED”,“name”:“HP0D_La”,“time”:“2023-02-22T21:07:00.326738Z”,“rssi”:-66,“loRaSNR”:13.8,“location”:{“latitude”:REDACTED,“longitude”:REDACTED,“altitude”:10}}],“txInfo”:{“frequency”:867100000,“dr”:5},“adr”:true,“fCnt”:36,“fPort”:1,“data”:"//9uDOYlKQYAAAA=",“object”:{“historySeqNr”:65535,“prevHistSeqNr”:65535}}, template: {{ value_json[“object”][“presence”][“value”] }})

There is no presence in the response in the error message.

You’ll need to test for that field’s existence in the template, and decide what you want to do if it’s not there.

EDIT: now I’m not responding on a phone, you could do something like this:

  - state_topic: "application/38/device/70b3d52c0001e5bd/event/up"
    name: sensative02
    unique_id: sensative02
    value_template: >
      {% if 'presence' in value_json['object'] %}
        {{ value_json['object']['presence']['value'] }}
      {% else %}
        false
      {% endif %}
    device_class: occupancy
    payload_on: "true"
    payload_off: "false"

or if you work out that the presence is only included in the response when value is true, the value_template could be as simple as "{{ ('presence' in value_json['object']) }}".

1 Like

Like the error message and Troon said:

‘dict object’ has no attribute ‘presence’

1 Like

That did it! Many many thanks for your guys help!