Using templated variables in automations

I have an automation where I need to compute some values to be used in multiple actions. the variables: section should be used for that. However to make it efficient I want to do the computation for multiple variables in one go. That seems not to be possible. This definition of the variables section is not accepted:

variables: >-
  {% set ns = namespace() %}
  {% set ns.highamprice = -1 %}
  {% set ns.highpmprice = -1 %}
  {% set ns.highamhour = 0 %}
  {% set ns.highpmhour = 0 %}
  {% for item in state_attr("sensor.epex_average_electricity_price", "prices_today") %}
    {% set hour = as_datetime(item.time).hour %}
    {% set price = item.price|float %}
    {% if hour < 12 %}
      {% if price > ns.highamprice %}
        {% set ns.highamprice = price %}
        {% set ns.highamhour = hour %}
      {% endif %}
    {% else %}
      {% if price > ns.highpmprice %}
        {% set ns.highpmprice = price %}
        {% set ns.highpmhour = hour %}
      {% endif %}
    {% endif %}
  {% endfor %} 
  highamhour: '{{ ns.highamhour }}'
  highpmhour: '{{ ns.highpmhour }}'
  highamprice: '{{ ns.highamprice }}'
  highpmprice: '{{ ns.highpmprice }}'

A template per variable is working ok.
Anyone knows a way around this.

You cannot template the entire variables section. Only options inside variables. Do this

variables:
  high: >
    {% set am = namespace(price=-1, hour=0) %}
    {% set pm = namespace(price=-1, hour=0) %}
    {% for item in state_attr("sensor.epex_average_electricity_price", "prices_today") %}
      {% set hour = as_datetime(item.time).hour %}
      {% set price = item.price|float %}
      {% if hour < 12 %}
        {% if price > am.price %}
          {% set am.price = price %}
          {% set am.hour = hour %}
        {% endif %}
      {% else %}
        {% if price > pm.price %}
          {% set pm.price = price %}
          {% set pm.hour = hour %}
        {% endif %}
      {% endif %}
    {% endfor %}
    {{ dict(am=dict(price=am.price, hour=am.hour), pm=dict(price=pm.price, hour=pm.hour)) }}

You’d access the information using:

{{ high.am.price }}
{{ high.am.hour }}

Also, you could go a different route which uses jinja’s strengths instead of if else logic.

    {% set ns = namespace(items=[]) %}
    {% for item in state_attr("sensor.epex_average_electricity_price", "prices_today") %}
      {% set ns.items = ns.items + [{'price': item.price|float, 'hour': as_datetime(item.time).hour}] %}
    {% endfor %}
    {% set am = ns.items | selectattr('hour', '<', 12) | sort(attribute="price") | last %}
    {% set pm = ns.items | selectattr('hour', '>=', 12) | sort(attribute="price") | last %}
    {{ dict(am=am, pm=pm) }}

Thanks, your second solution is very nice, I’ll use that. Just needs quotes around the attribute in the sort filter.