How to convert a string to a dictionary in a template

I’m trying to use output of a state_attr but apparently it outputs as string, while it had a valid json structure of a list of dictionaries

in the admin tools template tool:

{% set test = state_attr('sensor.chromecast_devices', 'devices_json')  %}

{% set test2 = [{"name": "huiskamer speaker", "cast_type": "audio", "model_name": "Google Home Mini", "uuid": "00927829-f57d-92ee-8b66-640f3b55ffd9", "manufacturer": "Unknown manufacturer"}, {"name": "Slaapkamer speaker", "cast_type": "audio", "model_name": "Google Home", "uuid": "206c829b-1e12-04f4-561e-3edf9af42526", "manufacturer": "Google Inc."}, {"name": "Googlehome", "cast_type": "group", "model_name": "Google Cast Group", "uuid": "54cb14ed-1d0c-4708-b2fc-66da30c04aee", "manufacturer": "Unknown manufacturer"}, {"name": "Speakers", "cast_type": "group", "model_name": "Google Cast Group", "uuid": "9f0ee336-04df-4ed3-908f-9d3b9eb52c98", "manufacturer": "Unknown manufacturer"}, {"name": "HT-NT5 95651E1 Surround", "cast_type": "cast", "model_name": "HT-NT5", "uuid": "46129bc1-3a80-7931-177a-d75eafa773fa", "manufacturer": "Sony Corporation"}, {"name": "studeerkamer speaker", "cast_type": "audio", "model_name": "Google Home Mini", "uuid": "b36ce072-e3f1-cd41-d38a-382f5f65b401", "manufacturer": "Google Inc."}, {"name": "studeerkamer speaker", "cast_type": "audio", "model_name": "Google Home Mini", "uuid": "b36ce072-e3f1-cd41-d38a-382f5f65b401", "manufacturer": "Google Inc."}, {"name": "studeerkamer speaker", "cast_type": "audio", "model_name": "Google Home Mini", "uuid": "b36ce072-e3f1-cd41-d38a-382f5f65b401", "manufacturer": "Google Inc."}, {"name": "huiskamer TV", "cast_type": "cast", "model_name": "Chromecast", "uuid": "73a794ca-8d1a-87b0-d4fb-a96feb715132", "manufacturer": "Google Inc."}, {"name": "Slaapkamer speaker", "cast_type": "audio", "model_name": "Google Home", "uuid": "206c829b-1e12-04f4-561e-3edf9af42526", "manufacturer": "Google Inc."}, {"name": "studeerkamer speaker", "cast_type": "audio", "model_name": "Google Home Mini", "uuid": "b36ce072-e3f1-cd41-d38a-382f5f65b401", "manufacturer": "Google Inc."}] %}



{{test}}

{% if test is mapping %}
 mapping
{% else %}
 no mapping
{% endif %}

{% if test is string %}
 string
{% else %}
 no string
{% endif %}

{{test[0]}}
{{test2[0]}}

gives output:

[{"name": "huiskamer speaker", "cast_type": "audio", "model_name": "Google Home Mini", "uuid": "00927829-f57d-92ee-8b66-640f3b55ffd9", "manufacturer": "Unknown manufacturer"}, {"name": "Googlehome", "cast_type": "group", "model_name": "Google Cast Group", "uuid": "54cb14ed-1d0c-4708-b2fc-66da30c04aee", "manufacturer": "Unknown manufacturer"}, {"name": "Speakers", "cast_type": "group", "model_name": "Google Cast Group", "uuid": "9f0ee336-04df-4ed3-908f-9d3b9eb52c98", "manufacturer": "Unknown manufacturer"}, {"name": "Slaapkamer speaker", "cast_type": "audio", "model_name": "Google Home", "uuid": "206c829b-1e12-04f4-561e-3edf9af42526", "manufacturer": "Google Inc."}, {"name": "HT-NT5 95651E1 Surround", "cast_type": "cast", "model_name": "HT-NT5", "uuid": "46129bc1-3a80-7931-177a-d75eafa773fa", "manufacturer": "Sony Corporation"}, {"name": "studeerkamer speaker", "cast_type": "audio", "model_name": "Google Home Mini", "uuid": "b36ce072-e3f1-cd41-d38a-382f5f65b401", "manufacturer": "Google Inc."}, {"name": "studeerkamer speaker", "cast_type": "audio", "model_name": "Google Home Mini", "uuid": "b36ce072-e3f1-cd41-d38a-382f5f65b401", "manufacturer": "Google Inc."}, {"name": "studeerkamer speaker", "cast_type": "audio", "model_name": "Google Home Mini", "uuid": "b36ce072-e3f1-cd41-d38a-382f5f65b401", "manufacturer": "Google Inc."}, {"name": "huiskamer TV", "cast_type": "cast", "model_name": "Chromecast", "uuid": "73a794ca-8d1a-87b0-d4fb-a96feb715132", "manufacturer": "Google Inc."}, {"name": "Slaapkamer speaker", "cast_type": "audio", "model_name": "Google Home", "uuid": "206c829b-1e12-04f4-561e-3edf9af42526", "manufacturer": "Google Inc."}, {"name": "studeerkamer speaker", "cast_type": "audio", "model_name": "Google Home Mini", "uuid": "b36ce072-e3f1-cd41-d38a-382f5f65b401", "manufacturer": "Google Inc."}]


 no mapping



 string


[
{'name': 'huiskamer speaker', 'cast_type': 'audio', 'model_name': 'Google Home Mini', 'uuid': '00927829-f57d-92ee-8b66-640f3b55ffd9', 'manufacturer': 'Unknown manufacturer'}

Note that I have set test2 to the output of test manually and that I am able to use that as dictionary, so proving that the output is a validly formatted.
However test is still treated as a string. Is there a good way to filter or loop through it to convert it back to a list of dictionaries?

I’ve already googled and tried all kind of things like | tojson, dict() but they either give errors or don’t do the trick.

Any help is appreciated.

There was an interesting topic a few days ago.

yep seems like the same issue I’m encountering

btw, the sensor comes from https://github.com/fondberg/spotcast @fondberg
which does seem (to me, python noob) to dump the data as json:

        self._attributes['devices_json'] = json.dumps(chromecasts, ensure_ascii=False)

From that other thread i learned that the json.dumps converts the json “object” into a string. If they use the output of the devices_jason as the attribute then it would be real json.

I think…:wink:

I’m no jinja2 expert but I think you can use normal python code inside it. If so then you need to parse the string first like

ccDevices = JSON.parse(attributesString)

Then use the new variable

doesn’t look like it:

{% set devices = state_attr("sensor.chromecast_devices", "devices_json")| replace("[","")|replace ("]", "") %}

{% set ccdevices = JSON.parse(devices) %}
{{ccdevices }} 
 Error rendering template: UndefinedError: 'JSON' is undefined

Hmmm. I’m the author of spotcast and the lovelace card spotify-card and I am in the midst of trying to make the sensor optional because I don’t like my hass having 2 sets of pychromecast listeners simultaneously. The other one is used by the cast media_player and internally it has the devices as a list but it is not exposed as a sensor or attributes in the state.
What is your use case you are trying to solve? Maybe I have an easier way to solve the same problem another way

You can’t parse a string into a dictionary object (in jinja, it’s really limited). You the developer needs to change the attribute so that it returns a dictionary instead of a string. Attributes have the ability to store objects that are not strings.

As with all OSS there is no single developer. The community adds changes and fixes. You are welcome to create a PR but I am still interested in what you want to solve…

I’m not after anything. Op is trying to get information out and because it’s a string he cant. Was just letting you know what to do seeing that you said you made it :wink: