Returning dictionary from a template sensor

Hi,

I’m wondering what would be the correct syntax/method for returning a dictionary from a template sensor. I have a template sensor code calculating multiple values which would be of interest in the UI and I would not want to duplicate the phases where calculus is being done and just return single state but a dictionary with multiple keys.

So, I have a sensor in my templates.yaml specifying the sensor, here’s a simplified version:

    - name: "dict_sensor"
      icon: mdi:exponent-box
      unique_id: 1fc4c3c2-d5e9-400b-897b-31b5260249f4
      state: |
        {% set result = [
          ("value", 1),
          ("something", 2)
          ]
        %}
        {{ dict.from_keys(result) }}

In Developer Tools → Template editor I can test this sensor output and the problem is the result is not being recognized as a dictionary properly even if the result window shows the result type being parsed as a dict. Also, if creating the same dictionary locally in the template editor it works just fine:

{# Get dictionary from sensor #}
{% set from_sensor = states('sensor.dict_sensor') %}
{{ from_sensor }}
{{ from_sensor.value }}

{# Create dictionary locally #}
{% set result = [
  ("value", 1),
  ("something", 2)
  ]
%}
{% set local_dict = dict.from_keys(result) %}
{{ local_dict }}
{{ local_dict.value }}

…produces output of:

'str object' has no attribute 'value'
{'value': 1, 'something': 2}





{'value': 1, 'something': 2}
1
Result type: string

This template listens for the following state changed events:

Entity: sensor.dict_sensor

So, the dict coming from sensor has no attribute “value”. The dictionary defined locally has it. What is the correct way to do this with dictionaries?

Thanks!

Every entity’s state value is handled as a string.

An entity’s state value may look like a boolean, number, list, dict, etc but it’s ultimately a string.

Try this:

{# Get dictionary from sensor #}
{% set from_sensor = states('sensor.dict_sensor') | from_json %}
{{ from_sensor.value }}

EDIT

Remove dict function from the Template Sensor.

Your clarification the return value is actually a string solved it! However, It seems we cannot convert returned dict from the sensor with from_json filter as suggested (ends up with vJSONDecodeError: unexpected character: line 1 column 2 (char 1) error as dictionary is not properly formatted as JSON.

I ended up converting the template sensor to output a JSON string like this:

    - name: "dict_sensor"
      icon: mdi:exponent-box
      unique_id: 1fc4c3c2-d5e9-400b-897b-31b5260249f4
      state: >
        {% set result = '{
          "value":"1",
          "something":"2"}' 
        %}
        {{ result  }}

Values need to be strings in quotes. After this the template editor shows:

{% set json_from_sensor = states('sensor.dict_sensor') | from_json %}
{{ json_from_sensor }}
{{ json_from_sensor.value }}

and result is

{'value': '1', 'something': '2'}
1
Result type: string

This template listens for the following state changed events:

Entity: sensor.dict_sensor

Thanks a lot!

I forgot to mention to remove the dict function from the Template Sensor’s template (because it produces a python dict object which cannot be converted with from_json). Anyways, you discovered that part by yourself.