For loop within json table

Hi

Wondering if someone can have a look at this template data by copy + pasting https://pastebin.com/kwJAq3kd into the template tool.

Im wanting to search through a json table to find a certain value in the table.

When you copy + paste into the template editor you get the below code:

{% set my_json = [... see the pastebin above ...] %}

Find the raw value for id 5
eg. ID{{ my_json[3].id }} = {{ my_json[3].raw.value }}

{% for i in my_json %}
  # if (my_json[i].id == 5)
  #   my_json[i].raw.value
{% endfor %}

I’m just stuck on creating the if command inside a for loop inside a template as this part is not valid

{% for i in my_json %}
  {% if my_json[{{ loop.index }}].id|int == 5 %}
    my_json[{{ loop.index }}].raw.value
  {% endif %}
{% endfor %}

nope :frowning:

You can use jsonata for this:

$single($, function($v) { $v.id = 5 }).raw.value

will give you what you need.

You can copy/paste your json at try.jsonata.org and look at the doc.
The syntax of jsonata is a bit dark magic to me… But, parsing json with this tool is really fantastic !

GV

thank you, i’ll try that later. looks good though. a bit like witch craft. my wife will get angry if i persevere with this anymore tonight.

can you please give me some more help.

I can see that the function works on the try.jsonata.org website , but I’m unsure how to translate the syntax into a home assistant template.

My bad… I am using it in node-red. In HA template, it seems it is only jinja2 (which is another magic). I don’t practice jinja2 as all my automation/trigger/… are in node-red and not HA directly.

GV

ok thanks !

So does the table position of id : 5 change?

i.e. it’s not always at [3]

Is that what the problem is?

Have you thought about using regex instead of a for loop?

yes it is not always [3]

I’d have to learn regex :smiley: - I’m not a computer guy, I’m a doctor, this is a hobby for me.

so the string would be

{'id': 1, 'name': 'Raw_Read_Error_Rate', 'value': 200, 'worst': 200, 'thresh': 51, 'when_failed': '', 'flags': {'value': 47, 'string': 'POSR-K ', 'prefailure': True, 'updated_online': True, 'performance': True, 'error_rate': True, 'event_count': False, 'auto_keep': True}, 'raw': {'value': 2, 'string': '2'}}

set x = regex extract the id
set y = regex extract the raw_value

Then I can do if x = 5 then output y

What about this:

{% for i in my_json %}
    {%- if i.id == 5 %} {{ i.raw.value }}
    {% endif -%}
{% endfor %}

Seems to do the trick.

GV

1 Like

omg no way. i will try this.

Try this:

{{ my_json|regex_findall_index(find='"id": 5.+?"raw": {"value": (\d+),') }}

This assumes that the raw value is always a positive integer or 0. Is it?

yes it is always +ve / zero.

And integer (no decimal point)?

If so have a go with that template in the editor then.

Edit: I’ve just realised it will match on id: 50 to 59 (or even id : 500038394839048) as well. I can fix that:

{{ my_json|regex_findall_index("'id': 5,.+?'raw': {'value': (\d+),") }}
1 Like

it’s working with for for loop above now, I just have to make a small adjustment.

Thank you this works

{% set ns = namespace(found=false) %}
{% for i in my_json %}
    {%- if i.id == 5 %}
      {% set ns.found = true %}
      "{{ i.raw.value }}"
    {% endif -%}
{% endfor %}
{% if not ns.found %} "unknown" {% endif %}