for-loopjinja2home-assistant

Jinja2 How to return one match in a for


I've little knowledge developing, I've spent days looking for a solution for this, doing tests and nothing.

I have in Home Assistant, a rest sensor, who gives a JSON with unsorted data of all the gas stations in my area, this is part of it:

{
   "Fecha": "22/03/2022 12:10:11",
   "ListaEESSPrecio": [
      {
         "C.P.": "09003",
         "Dirección": "CL GENERAL SANZ PASTOR, S.N.",
         "Horario": "L-V: 08:00-16:00",
         "Latitud": "42,344667",
         "Localidad": "BURGOS",
         "Longitud (WGS84)": "-3,698667",
         "Margen": "D",
         "Municipio": "Burgos",
         "PrecioProducto": "1,789",
         "Provincia": "BURGOS",
         "Remisión": "OM",
         "Rótulo": "REPSOL",
         "Tipo Venta": "P",
         "IDEESS": "5989",
         "IDMunicipio": "1220",
         "IDProvincia": "09",
         "IDCCAA": "08"
      },
      {
         "C.P.": "09001",
         "Dirección": "LOPEZ BRAVO, 93",
         "Horario": "L-V: 06:30-22:00; S: 08:00-14:30",
         "Latitud": "42,362528",
         "Localidad": "BURGOS",
         "Longitud (WGS84)": "-3,762083",
         "Margen": "D",
         "Municipio": "Burgos",
         "PrecioProducto": "1,798",
         "Provincia": "BURGOS",
         "Remisión": "dm",
         "Rótulo": "VILLALÓN",
         "Tipo Venta": "P",
         "IDEESS": "9803",
         "IDMunicipio": "1220",
         "IDProvincia": "09",
         "IDCCAA": "08"
      },
      {
         "C.P.": "09001",
         "Dirección": "CALLE CONDADO DE TREVIÑO, 30",
         "Horario": "L-D: 06:00-00:00",
         "Latitud": "42,370528",
         "Localidad": "BURGOS",
         "Longitud (WGS84)": "-3,718528",
         "Margen": "I",
         "Municipio": "Burgos",
         "PrecioProducto": "1,792",
         "Provincia": "BURGOS",
         "Remisión": "dm",
         "Rótulo": "VILLALONQUEJAR",
         "Tipo Venta": "P",
         "IDEESS": "11878",
         "IDMunicipio": "1220",
         "IDProvincia": "09",
         "IDCCAA": "08"
      }]
}

Then in home assistant I have a lovelace card to show the data of the 5 cheapest gas stations, the code is like this:

example of card

- name: Gasolinera 1 nombre
  value_template: "{{ value_json['ListaEESSPrecio'][0]['Rótulo'] }}"
- name: Gasolinera 1 precio
  value_template: "{{ value_json['ListaEESSPrecio'][0]['PrecioProducto'] }}"
  unit_of_measurement: "€"
- name: Gasolinera 1 dirección
  value_template: "{{ value_json['ListaEESSPrecio'][0]['Dirección'] }}"

As you can see I have to created for each gas station, it's related data on the JSON.

To sort the JSON I tested this, that works:

{% for item in ListaEESSPrecio | sort(attribute='PrecioProducto') %}
    {{ item.Rótulo, item.PrecioProducto, item.Dirección }}
{%- endfor %}

This gives me all the JSON data sorted, I selected too the fields I'm interested in:

('REPSOL', '1,789', 'CL GENERAL SANZ PASTOR, S.N.')
('VILLALONQUEJAR', '1,792', 'CALLE CONDADO DE TREVIÑO, 30')
('VILLALÓN', '1,798', 'LOPEZ BRAVO, 93')

Now the problem, is how to access only to one item of all the dict or array for putting it on the lovelace card, where I select each sensor data to the data on the JSON. gas_station1.price = in JSON data the first sorted gas station.

I have tested things like these, but with no luck.

{% for item in value_json['ListaEESSPrecio'][0] | sort(attribute='PrecioProducto') %}
    {% if loop.index == 1 %}
        {{ item.Rótulo, item.PrecioProducto, item.Dirección }}
    {% endif %}
{% endfor %}
{% for item in ListaEESSPrecio | sort(attribute='PrecioProducto') if item[0] <= t <= item[1]  %}
  {{ item[0] }}
{% endfor %}

The last trial gives the error:

UndefinedError: dict object has no element 0


Solution

  • You don't need a loop to achieve that, you can use the first filter after you have applied your sort filter to pull only one item out of your list:

    {% set item = ListaEESSPrecio | sort(attribute='PrecioProducto') | first %}
    {{ item['Rótulo'], item['PrecioProducto'], item['Dirección'] }}
    

    Or, use the square brackets notation [ ] to access a specific item of your list — mind that a Python list always start at the index 0:

    {% set item = (ListaEESSPrecio | sort(attribute='PrecioProducto'))[0] %}
    {{ item['Rótulo'], item['PrecioProducto'], item['Dirección'] }}
    

    Mind that, because you do have Spanish accents in the property names of your dictionary, you might have to use the square brackets notation [ ] to access those property too.