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 %}
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
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
- 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
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+),") }}
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 %}