How to filter json for value_json

Dear all,

I have an MQTT sensor that serves a JSON string like this:

{"clients":[
  {
    "field1": "aaa",
    "field2": "1.2.3.4:45980",
    "field3": "10.8.0.3",
    "field4": "925KiB",
    "field5": "7.9MiB",
    "field6": "16:19:22",
    "field7": "1648559962",
    "field8": "206",
    "field9": "-",
    "field10": "UNDEF"
  },
  {
    "field1": "bbb",
    "field2": "4.3.2.1:40681",
    "field3": "10.8.0.2",
    "field4": "61KiB",
    "field5": "215KiB",
    "field6": "16:34:35",
    "field7": "1648560875",
    "field8": "207",
    "field9": "-",
    "field10": "UNDEF"
  }
]}

How do I filter the above to feed only one of the clients to my sensor?

I have this filter expression, that works as expected here:

$.clients[?(@.field1=="aaa")]

HA (template editor) wouldn’t accept this notation with this error:

TemplateSyntaxError: unexpected char '?' at 597

In the template documentation I haven’t found any filtering related content. Is it at all possible? If yes, how?

Thanks in advance for any pointers!

post your configuration for the MQTT sensor.

Well, there is no sensor, because HA complains about the filter expression I am trying to use. I use it in the template editor.

I could make the sensor to filter like this: value_json.clients[0] but it is not good as the ordinal number of an item is not always the same.

And what are you trying in the template editor? Please post something that I can work with.

Just share your mqtt configuration and what you’re trying in the editor. I don’t know why you’re being reluctant to post a configuration.

{% set item = value_json | selectattr('field1', 'eq', 'aaa') | first | default %}
{{ item.field5 | default }}

It still doesn’t seem to work - it throws an error.

I’m trying this in the template editor:

{%
  set value_json = 

{"clients":[
  {
    "field1": "aaa",
    "field2": "1.2.3.4:45980",
    "field3": "10.8.0.3",
    "field4": "925KiB",
    "field5": "7.9MiB",
    "field6": "16:19:22",
    "field7": "1648559962",
    "field8": "206",
    "field9": "-",
    "field10": "UNDEF"
  },
  {
    "field1": "bbb",
    "field2": "4.3.2.1:40681",
    "field3": "10.8.0.2",
    "field4": "61KiB",
    "field5": "215KiB",
    "field6": "16:34:35",
    "field7": "1648560875",
    "field8": "207",
    "field9": "-",
    "field10": "UNDEF"
  }
]}

%}

{% set item value_json | selectattr('field1', 'eq', 'aaa') | first | default %}
{{ item.field5 | default }}

Gives me this error:

TemplateSyntaxError: expected token 'end of statement block', got 'value_json'

I thought you missed the = at the set item value_json part, but if I put it there like this:

{% set item = value_json | selectattr('field1', 'eq', 'aaa') | first | default %}
{{ item.field5 | default }}

It doesn’t give an error, but still, an empty string is returned.

I have no problem showing the sensor config, but I don’t have one. :frowning:
I tried this in template editor previously, but it failed miserably:

{{ value_json.clients[?(@.field1=="aaa")] }}

The template editor is for jinja.

That’s not jinja. Stop trying that.

{% set item = value_json.clients | selectattr('field1', 'eq', 'aaa') | first | default %}
{{ item.field5 | default }}
3 Likes

First: sorry about the late reply - it was night here.
Second: Yes, this did the trick. Now I understand how I should have done it. Thank you for your help, I really appreciate it.
Finally, here is my finished sensor, which now works the way I always wanted:

- platform: mqtt
  name: PiVpn-viktor-op3
  state_topic: "viktak/network/pivpn"
  value_template: >
    {% set c = value_json.clients | selectattr('field1', 'eq', 'viktor-op3') | first | default %}
    {% if c.field1 == 'viktor-op3' %}
      {{ 'Connected' }}
    {% else %}
      {{ 'Disconnected' }}
    {% endif %}

  json_attributes_topic: "viktak/network/pivpn"
  json_attributes_template: >-
    {% set c = value_json.clients | selectattr('field1', 'eq', 'viktor-op3') | first | default %}
    {% if c.field1 == 'viktor-op3' %}
      {% set name = c.field1 %}
      {% set remoteIP = c.field2 %}
      {% set virtualIP = c.field3 %}
      {% set bytesReceived = c.field4 %}
      {% set bytesSent = c.field5 %}
      {% set connectedSince = c.field6 %}
    {% else %}
      {% set name = 'n/a' %}
      {% set remoteIP = 'n/a' %}
      {% set virtualIP = 'n/a' %}
      {% set bytesReceived = 'n/a' %}
      {% set bytesSent = 'n/a' %}
      {% set connectedSince = 'n/a' %}
    {% endif %}
    {{
      {
      'Name' : name,
      'RemoteIP' : remoteIP,
      'VirtualIP' : virtualIP,
      'BytesReceived' : bytesReceived,
      'BytesSent' : bytesSent,
      'ConnectedSince' : connectedSince
      } | tojson
    }}

Thanks again for sticking with me and for setting me straight!!!