Hi !
First of all, two thumbs up to all the developpers of this amazing Home Assistant !
I have a problem understanding how to parse json dictionnary.
I have a sensor that returns a json payload with two values and I try to use both in a automation but it does not work. I used the Templates in home assistant to perform tests and here’s what I get
```
{% set my_test_json = {"Message": "Unknown due to HA restart", "Severity": "warning"} %}
{% set m_test_json = states.sensor.front_door_last_state.state %}
{{my_test_json}}
{{m_test_json}}
Result with the values :
Message: {{ my_test_json.Message }}
Severity: {{ my_test_json.Severity }}
Result with the Sensor state
Message: {{ m_test_json.Message }}
Severity: {{ m_test_json.Severity }}
```
And here is the result I get
```
{'Severity': 'warning', 'Message': 'Unknown due to HA restart'}
{"Message": "Unknown due to HA restart", "Severity": "warning" }
Result with the values :
Message: Unknown due to HA restart
Severity: warning
Result with the Sensor state
Message:
Severity:
```
I should get the same result wheter I use the direct variable or the sensor result but not…
Could somebody help me ?
Thanks a lot !
I modified your sensor to work within my Home Assistant environment. Here is the sensor’s state as seen in the States page:
The issue is that the sensor’s state looks like a JSON object but is actually just a string. That’s why your template, {{ m_test_json.Message }}, doesn’t work.
You are grabbing the state, which is a string. You need to turn it into json before accessing it.
{% set m_test_json = states.sensor.front_door_last_state.state | tojson %}
Result with the Sensor state
Message: {{ m_test_json.Message }}
Severity: {{ m_test_json.Severity }}
I had tried tojson and it escapes all the quotations. I tried safe | json and that failed as well (i.e. made no difference).
FWIW, googling “Jinja2 convert string to JSON” didn’t produce anything usable. That’s where I got the idea to use tojson but it didn’t have the desired effect. I gave up trying … but it seems there must be an elegant way to do it.
EDIT
Kind of surprising there’s no filter to convert a well-formed JSON string into a JSON object. I know there’s a node in Node-red that does it.
So if you just rewrote your if else if statements to output comma separated values (without keywords) instead of json objects. I.e “message, severity”, You could do this:
{% set m_test_json = states.sensor.front_door_last_state.state.split(',') %}
Result with the Sensor state
Message: {{ m_test_json[0] }}
Severity: {{ m_test_json[1] }}
Also, if you were feeling up to it, you could attempt to streamline your if statements so that there is less overhead if you have to add codes or names into your sensor. This is what I would use because you’d just need to add a code and a name, or a code and a statement.
sensor:
- platform: template
sensors:
front_door_last_state:
friendly_name: Front Door Last Code
entity_id:
- sensor.frontlock_alarm_type
- sensor.frontlock_alarm_level
value_template: >-
{% set danger = [ 9, 161 ] %}
{% set who = {
1: 'laurent',
2: 'Valerie',
3: 'Juliette',
4: 'Lucas',
5: 'Chloé',
6: 'Any and Hubert',
7: 'Myriam and Hervé',
8: 'Agnès',
} %}
{% set statements = {
9: 'Lock Jammed',
18: 'Locked via Outside Button',
21: 'Locked via Thumbturn',
22: 'Unlocked via Thumbturn',
24: 'Wireless Lock',
25: 'Wireless Unlock',
27: 'Auto Locked',
161: 'Tamper Alarm',
} %}
{% set alarm_type = states('sensor.frontlock_alarm_type') | int %}
{% set alarm_level = states('sensor.frontlock_alarm_level') | int %}
{% if alarm_type == 19 %}
{% if alarm_level in who %}
Unlocked by {{ who[alarm_level] }}, good
{% else %}
Unlocked by an Untracked User Code, good
{% else %}
{% if alarm_type in statements %}
{{ statements[alarm_type] }}, {{ 'danger' if alarm_type in danger else 'good' }}
{% else %}
Unknown due to HA restart, warning
{% endif %}
{% endif %}
- platform: template
sensors:
front_door_last_state:
friendly_name: Front Door Last Code
entity_id:
- sensor.frontlock_alarm_type
- sensor.frontlock_alarm_level
value_template: >-
{% set danger = [ 9, 161 ] %}
{% set who = {
1: 'laurent',
2: 'Valerie',
3: 'Juliette',
4: 'Lucas',
5: 'Chloé',
6: 'Any and Hubert',
7: 'Myriam and Hervé',
8: 'Agnès',
} %}
{% set statements = {
9: 'Lock Jammed',
18: 'Locked via Outside Button',
21: 'Locked via Thumbturn',
22: 'Unlocked via Thumbturn',
24: 'Wireless Lock',
25: 'Wireless Unlock',
27: 'Auto Locked',
161: 'Tamper Alarm',
} %}
{% set alarm_type = states('sensor.frontlock_alarm_type') | int %}
{% set alarm_level = states('sensor.frontlock_alarm_level') | int %}
{% if alarm_type == 19 %}
Good Idea Petro. I like your solution. Much more easy to read than the one I suggested !
I’m going to give your solution a try tomorrow and let you know !
I’m a home assistant beginner but I love it.
The sensor Works perfect (If someone needs to use this code, there is a {% endif %} missing).
now, i’m wondering how may I “parse” the sensor state in an automation.
I’d like to use the part before the comma as a message and the part after the comma for the color of the message I will send as a notification
Ok, replying to my own question. The split function does the trick
Just use {{ states.sensor.xxx.state.split(",")[0]}} or [1] for the part of the message before or after the comma !
Thank you a lot. I learned many things thanx to you today
I am back to really wanting this functionality to work in templates. How hard is it to add a filter to the templating language? I’ll even attempt it myself.
Rooting for your PR to quickly run the gamut and get included in the next release. Like the recent inclusion of the expand filter, the from_json filter will open up new ways of solving old templating problems.