Extracting Individual Elements of List

Hello,

I have a list currently stored in a sensor template.

{{states.sensor.sorted_bus_etas}} gives me

<template TemplateState(<state sensor.sorted_bus_etas=[{‘name’: ‘196’, ‘eta’: “01:00”}, {‘name’: ‘196’, ‘eta’: “02:00”}, {‘name’: ‘196e’, ‘eta’:“03:00”}, {‘name’: ‘196e’, ‘eta’: “04:00”}, {‘name’: ‘196a’, ‘eta’: “05:00”}, {‘name’: ‘196a’, ‘eta’: “06:00”]; friendly_name=Sorted Bus ETAs @ 2023-03-29T00:29:45.263858+08:00>)>

I just want to extract the ‘eta’ of the first 2 elements and store in another sensor.

Sensor1 = “01:00”
Sensor2 = “02:00”

I tried using attributes but {{states.sensor.sorted_bus_etas.attributes}} give me only

{‘friendly_name’: ‘Sorted Bus ETAs’}

Could someone help me solve this? Thank you

1 Like

Something is not right.
That code block contains 323 characters, that can’t be the state.
Where do you get this sensor? What integration creates it?

What does

{{ states('sensor.sorted_bus_etas') }}

Give you?

Hello,

The sensor sorted_bus_etas is a template I also created that created the sorted list.

{{ states('sensor.sorted_bus_etas') }} gives me

[{‘name’: ‘196’, ‘eta’: 9999}, {‘name’: ‘196’, ‘eta’: 9999}, {‘name’: ‘196e’, ‘eta’: 9999}, {‘name’: ‘196e’, ‘eta’: 9999}, {‘name’: ‘196a’, ‘eta’: 9999}, {‘name’: ‘196a’, ‘eta’: 9999}]

States are always strings, so if you store a list in the state you need to fix the ' and use the from_json filter to get it back into an array.

{% set x = states('sensor.sorted_bus_etas')
| replace("\'","\"") | from_json %}
Sensor 1: {{ x[0].eta }}
Sensor 2: {{ x[1].eta }}
1 Like

Post where ever you get the data from originally.
If this is a template sensor then there must be something before it.
Creating more sensors based on the same base entity (or even worse chaining them on each other) will just cause headaches.

I suggest we go back from the start and do it properly.
What Drew posted above will probably work but I strongly advice you not to do that. You will just create more issues the more you chain on.

The string you have is in json and that is perfect if used properly

1 Like

Thank you! This totally worked. I should remember states are strings.

Hello,

Thank you very much. Indeed, the post from Drew worked but I would like also to improve my code in order to not have this chain of templates.

Here is the template I created for sorted_bus_etas. It combines and sorts the ETAs for 6 buses (next 2 buses of 3 different bus numbers). The ETAs are from a rest entity consuming the data from an API with output JSON. I defaulted some numbers (99:99) for debugging.

 - platform: template
    sensors:
      sorted_bus_etas:
        friendly_name: "Sorted Bus ETAs"
        value_template: >  
          {% if state_attr('sensor.rest_next_196_bus_a', 'EstimatedArrival') != '' and state_attr('sensor.rest_next_196_bus_a', 'EstimatedArrival') != none %}
            {% set bus196A = as_timestamp(state_attr('sensor.rest_next_196_bus_a', 'EstimatedArrival')) | timestamp_custom('%H:%M')%}
          {% else %} {%set bus196A = "99:99" %} {%- endif %}		  
          {% if state_attr('sensor.rest_next_196_bus_b', 'EstimatedArrival') != '' and state_attr('sensor.rest_next_196_bus_b', 'EstimatedArrival') != none %}
            {% set bus196B = as_timestamp(state_attr('sensor.rest_next_196_bus_b', 'EstimatedArrival')) | timestamp_custom('%H:%M')%} 
          {% else %} {%set bus196B = "99:99" %} {%- endif %}
          {% if state_attr('sensor.rest_next_196e_bus_a', 'EstimatedArrival') != '' and state_attr('sensor.rest_next_196e_bus_a', 'EstimatedArrival') != none %}
            {% set bus196eA = as_timestamp(state_attr('sensor.rest_next_196e_bus_a', 'EstimatedArrival')) | timestamp_custom('%H:%M')%}
          {% else %} {%set bus196eA = "99:99" %} {%- endif %}
          {% if state_attr('sensor.rest_next_196e_bus_b', 'EstimatedArrival') != '' and state_attr('sensor.rest_next_196e_bus_b', 'EstimatedArrival') != none %}
            {% set bus196eB = as_timestamp(state_attr('sensor.rest_next_196e_bus_b', 'EstimatedArrival')) | timestamp_custom('%H:%M')%}
          {% else %} {%set bus196eB = "99:99" %} {%- endif %}
          {% if state_attr('sensor.rest_next_196a_bus_a', 'EstimatedArrival') != '' and state_attr('sensor.rest_next_196a_bus_a', 'EstimatedArrival') != none %}
            {% set bus196aA = as_timestamp(state_attr('sensor.rest_next_196a_bus_a', 'EstimatedArrival')) | timestamp_custom('%H:%M')%}
          {% else %} {%set bus196aA = "99:99" %} {%- endif %}
          {% if state_attr('sensor.rest_next_196a_bus_b', 'EstimatedArrival') != '' and state_attr('sensor.rest_next_196a_bus_b', 'EstimatedArrival') != none %}
            {% set bus196aB = as_timestamp(state_attr('sensor.rest_next_196a_bus_b', 'EstimatedArrival')) | timestamp_custom('%H:%M')%}
          {% else %} {%set bus196aB = "99:99" %} {%- endif %}
          {% set bus_etas = [
            {"name": "196", "eta": bus196A},
            {"name": "196", "eta": bus196B},
            {"name": "196e", "eta": bus196eA},
            {"name": "196e", "eta": bus196eB},
            {"name": "196a", "eta": bus196aA},
            {"name": "196a", "eta": bus196aB}
          ] %}
          {% set sorted_bus_etas = bus_etas | sort(attribute="eta") %}
          {{sorted_bus_etas}}

I would suggest you place this in the attributes instead.
That would give you the busses easily indexed and accessible.
I just copy pasted it to make the point. Perhaps you can use the state as something else if you need that?

- platform: template
    sensors:
      sorted_bus_etas:
        friendly_name: "Sorted Bus ETAs"
        value_template: >  
          {% if state_attr('sensor.rest_next_196_bus_a', 'EstimatedArrival') != '' and state_attr('sensor.rest_next_196_bus_a', 'EstimatedArrival') != none %}
            {% set bus196A = as_timestamp(state_attr('sensor.rest_next_196_bus_a', 'EstimatedArrival')) | timestamp_custom('%H:%M')%}
          {% else %} {%set bus196A = "99:99" %} {%- endif %}		  
          {% if state_attr('sensor.rest_next_196_bus_b', 'EstimatedArrival') != '' and state_attr('sensor.rest_next_196_bus_b', 'EstimatedArrival') != none %}
            {% set bus196B = as_timestamp(state_attr('sensor.rest_next_196_bus_b', 'EstimatedArrival')) | timestamp_custom('%H:%M')%} 
          {% else %} {%set bus196B = "99:99" %} {%- endif %}
          {% if state_attr('sensor.rest_next_196e_bus_a', 'EstimatedArrival') != '' and state_attr('sensor.rest_next_196e_bus_a', 'EstimatedArrival') != none %}
            {% set bus196eA = as_timestamp(state_attr('sensor.rest_next_196e_bus_a', 'EstimatedArrival')) | timestamp_custom('%H:%M')%}
          {% else %} {%set bus196eA = "99:99" %} {%- endif %}
          {% if state_attr('sensor.rest_next_196e_bus_b', 'EstimatedArrival') != '' and state_attr('sensor.rest_next_196e_bus_b', 'EstimatedArrival') != none %}
            {% set bus196eB = as_timestamp(state_attr('sensor.rest_next_196e_bus_b', 'EstimatedArrival')) | timestamp_custom('%H:%M')%}
          {% else %} {%set bus196eB = "99:99" %} {%- endif %}
          {% if state_attr('sensor.rest_next_196a_bus_a', 'EstimatedArrival') != '' and state_attr('sensor.rest_next_196a_bus_a', 'EstimatedArrival') != none %}
            {% set bus196aA = as_timestamp(state_attr('sensor.rest_next_196a_bus_a', 'EstimatedArrival')) | timestamp_custom('%H:%M')%}
          {% else %} {%set bus196aA = "99:99" %} {%- endif %}
          {% if state_attr('sensor.rest_next_196a_bus_b', 'EstimatedArrival') != '' and state_attr('sensor.rest_next_196a_bus_b', 'EstimatedArrival') != none %}
            {% set bus196aB = as_timestamp(state_attr('sensor.rest_next_196a_bus_b', 'EstimatedArrival')) | timestamp_custom('%H:%M')%}
          {% else %} {%set bus196aB = "99:99" %} {%- endif %}
          {% set bus_etas = [
            {"name": "196", "eta": bus196A},
            {"name": "196", "eta": bus196B},
            {"name": "196e", "eta": bus196eA},
            {"name": "196e", "eta": bus196eB},
            {"name": "196a", "eta": bus196aA},
            {"name": "196a", "eta": bus196aB}
          ] %}
          {% set sorted_bus_etas = bus_etas | sort(attribute="eta") %}
          {{sorted_bus_etas}}
        attribute_templates: 
          busses: >-        
          {% if state_attr('sensor.rest_next_196_bus_a', 'EstimatedArrival') != '' and state_attr('sensor.rest_next_196_bus_a', 'EstimatedArrival') != none %}
            {% set bus196A = as_timestamp(state_attr('sensor.rest_next_196_bus_a', 'EstimatedArrival')) | timestamp_custom('%H:%M')%}
          {% else %} {%set bus196A = "99:99" %} {%- endif %}		  
          {% if state_attr('sensor.rest_next_196_bus_b', 'EstimatedArrival') != '' and state_attr('sensor.rest_next_196_bus_b', 'EstimatedArrival') != none %}
            {% set bus196B = as_timestamp(state_attr('sensor.rest_next_196_bus_b', 'EstimatedArrival')) | timestamp_custom('%H:%M')%} 
          {% else %} {%set bus196B = "99:99" %} {%- endif %}
          {% if state_attr('sensor.rest_next_196e_bus_a', 'EstimatedArrival') != '' and state_attr('sensor.rest_next_196e_bus_a', 'EstimatedArrival') != none %}
            {% set bus196eA = as_timestamp(state_attr('sensor.rest_next_196e_bus_a', 'EstimatedArrival')) | timestamp_custom('%H:%M')%}
          {% else %} {%set bus196eA = "99:99" %} {%- endif %}
          {% if state_attr('sensor.rest_next_196e_bus_b', 'EstimatedArrival') != '' and state_attr('sensor.rest_next_196e_bus_b', 'EstimatedArrival') != none %}
            {% set bus196eB = as_timestamp(state_attr('sensor.rest_next_196e_bus_b', 'EstimatedArrival')) | timestamp_custom('%H:%M')%}
          {% else %} {%set bus196eB = "99:99" %} {%- endif %}
          {% if state_attr('sensor.rest_next_196a_bus_a', 'EstimatedArrival') != '' and state_attr('sensor.rest_next_196a_bus_a', 'EstimatedArrival') != none %}
            {% set bus196aA = as_timestamp(state_attr('sensor.rest_next_196a_bus_a', 'EstimatedArrival')) | timestamp_custom('%H:%M')%}
          {% else %} {%set bus196aA = "99:99" %} {%- endif %}
          {% if state_attr('sensor.rest_next_196a_bus_b', 'EstimatedArrival') != '' and state_attr('sensor.rest_next_196a_bus_b', 'EstimatedArrival') != none %}
            {% set bus196aB = as_timestamp(state_attr('sensor.rest_next_196a_bus_b', 'EstimatedArrival')) | timestamp_custom('%H:%M')%}
          {% else %} {%set bus196aB = "99:99" %} {%- endif %}
          {% set bus_etas = [
            {"name": "196", "eta": bus196A},
            {"name": "196", "eta": bus196B},
            {"name": "196e", "eta": bus196eA},
            {"name": "196e", "eta": bus196eB},
            {"name": "196a", "eta": bus196aA},
            {"name": "196a", "eta": bus196aB}
          ] %}
          {% set sorted_bus_etas = bus_etas | sort(attribute="eta") %}
          {{sorted_bus_etas}}

This should mean:

{{ state_attr('sensor.sorted_bus_etas', 'busses')[0]['name'] }} arrives in {{ state_attr('sensor.sorted_bus_etas', 'busses')[0]['eta'] }}
1 Like

This method retains the JSON format and keeps everything neat and perfect for traceability. I have simplified my code removed the unnecessary templates. Thank you for the help!

I would suggest you use the state as the next bus and the attributes as your sorted list.

If you agree then replace the last line of the state template {{sorted_bus_etas}} to this:

{{ sorted_bus_etas[0]['name'] }} in {{ sorted_bus_etas[0]['eta'] }}