[solved] Data_template with some {% ... %} before


I have the following automation:

event: my_event
  p1: {{ 'v1' if ( ... a complicated condition ...) else 'v2' }}
  p2: {{ 'v3' if ( ... the same complicated condition ...) else 'v4' }}
  p3: {{ 'v5' if ( ... the same complicated condition ...) else 'v6' }}

I would like to something as:

event: my_event
  {% ... %} ... {% ... %} to set my complicated condition c
  p1: {{ 'v1' if c else 'v2' }}
  p2: {{ 'v3' if c else 'v4' }}
  p3: {{ 'v5' if c else 'v6' }}

I don’t know if it is possible and which is the correct syntax.
I tried a lot of syntax but all failed.

event: my_event
  {% set c = ( ... a complicated condition ...) %} 
  p1: {{ 'v1' if c else 'v2' }}
  p2: {{ 'v3' if c else 'v4' }}
  p3: {{ 'v5' if c else 'v6' }}

I tried it. That doesn’t work for me.

What about:

event: my_event
event_data_template: >
  {% set c = ( ... a complicated condition ...) %} 
  p1: {{ 'v1' if c else 'v2' }}
  p2: {{ 'v3' if c else 'v4' }}
  p3: {{ 'v5' if c else 'v6' }}

Also make sure c resolves to either true or false.

Message malformed: extra keys not allowed @ data[‘action’][0][‘event’]

I am sure c resolves to either true or false.

Why don’t you post your automation here?

That won’t work because the {% %} and pX are not related, are they? :wink:

1 Like

That won’t work because the {% %} and pX are not related, are they?

Here the action part of my automation (with a simpler c condition):

event: set_room_thermostat
  {% set c = is_state('input_boolean.marcia_travail', 'off') %}
  debut: {{ '20:00' if c else '21:00' }}
  fin: {{ '21:00' if c else '22:00' }}
  room_name: sdb_parentale
  temp_cible: '22'

If I remove the first line ({% … %} and put the condition instead of w in ‘debut’ and ‘fin’ lines, the syntax is ok (and the automation runs fine).

The scope of a Jinja2 template is limited to the option where it is defined.

In other words, the template for debut knows nothing about the template for fin or a template created anywhere else.

1 Like

Well, the most simple and straightforward solution is to do it literally:

  debut: "{{ '20:00' if is_state('input_boolean.marcia_travail', 'off') else '21:00' }}"
  fin: "{{ '21:00' if is_state('input_boolean.marcia_travail', 'off') else '22:00' }}"

I explained above why {% %} separately doesn’t work, let me know if you need additional info.

Another option is to change your script as it depends in one condition (c) so if you pass that condition to the script alongside with all necessary values, you could use it in the script to select the right values. Something like

  cond: "{{ is_state('input_boolean.marcia_travail', 'off') }}"
  debut_off: '20:00'
  debut_on: '21:00'
  fin_off: '21:00'
  fin_on: '22:00'

and then in your script

if cond:
  debut = data('debut_on')
  fin = data('fin_on')
  debut = data('debut_off')
  fin = data('fin_off')

or you can pass that input_boolean.marcia_travail as a parameter and check its state in the script… a lot of options, really :wink:

p.s make sure you enclose your templates in single/double quotes and watch out for single/double quotes conflicts. Read this.

It was i did (see my first post) but that implies to repeat my “complicated” condition which is much more complicated than in my example so my question here about another solution. But I understand it is not possible the way I imagined due to the template limitations.

Thanks for the others suggestions.

That’s correct. Change your script and you’ll be fine.

Set your ‘complicated conditions’ (we are obviously too stupid to understand) in a binary sensor and then use that sensor in all of your ‘complicated templates’.
As everyone else has said you can only set one value per template.
If you have multiple things to set you are better triggering a script to set such.
It looks like you are trying to control heating which is ‘sooooooo’ complicated that no one here has ever tried to do before.
I think you are obsessing about one particular avenue of approach and thus it’s probably not the best way to do it.

Edit: Sorry was that “tooooo” sarcastic ?

we are obviously too stupid to understand

I never though that !!!
For me, the detail of my condition was not relevant for my question except the fact it was complicated long so I wanted to factorize it. I wanted to keep my question as simple as possible.

It looks like you are trying to control heating which is ‘sooooooo’ complicated that no one here has ever tried to do before.

Again, I don’t think that !

My need is not “soooo” complicated but for a HA beginner it was not so simple. For each room, I want to set the temperature according the interval of time (such as 09:00 < t < 10:00 or 18:00 < t < 20:00), which intervals can vary according some conditions (my wife working or not this day, week day or we, children at home or not, etc…), and also taking in account the duration needed to get the required temperature, duration which vary with the current temperature, in order to anticipate heating (my electric heaters take a long time to heat, such as 2°C per hour max). Since intervals of time (and the associated temp) and current temperature can dynamically change, I have to recalculate each minute the need to anticipate the heating to get the required temperature at the beginning for the next interval of time.

I set it to work, thank to the great help in this forum and to the HA documentation. Now I want to build a new solution as simple as possible in order to facilitate the maintenance. For that I try to factorize things as much as possible and to separate “domains” (conditions to set intervals of time in a different automation/script/… that calculation time to target the required temperature, for example). So my questions here in the forum. I don’t want the solution “out of the box”, just some help when I am blocked on the way. It is a good way to learn more about HA (and it is funny).

Sorry was that “tooooo” sarcastic ?

Yes, it was somewhat rude :sweat_smile: but no problem.

Thanks all for you help and sorry for any inconvenience.
(sorry for my poor english)

Your english is not poor, I think it very good.
you heating explanation is also good, we a;most have enough information to help you.
so you have a heating profile.
is it the same for each room (the times that is) ?
how do you want to set the times ? (ie do you want to tweak the times from the front end ?
What about the heating profile is that the same each day / workday/weekends or different every day ?
when you say IF my wife is home, do you have occupancy figured out ?
I have all the above.
So temp if doors/windows open, temp if out, temp if night, temp if dat time, temp if evening.
So explain what you are after and we’ll then point you in the right direction.

No question is an inconvenience, you just need to proveide the necessary information and context.

Thank you for the help.
As I said, I would prefer to build the solution myself (I am an ex-programmer, retired, and it is funny). I just need some help when I am blocked such as “it is not possible to do this way with template” or “the syntax to do that is …” or “better set an automation instead a script for your case”, etc…

How did you learn to code? Did you read docs/manuals?
If yes, here’s exactly the same - we’re not saying ‘it’s God’s will’ - we point you to the source of information and explain what’s wrong with your approach (as you’re learning, not us?).
Seriously, have a look at Jinja2 as that’s the HA tempting engine.
I do it every time and I believe that’s the way to go. The docs are generally well maintained here :wink:

p.s I just read your use case. Well, I’m glad I didn’t do anything like that when I lived in a flat with electric storage heaters!
Maybe you don’t need to over-complicate your system (unless you truly enjoy the process)? KISS they call it :wink:

Ahmad is right, reading the docs helps but let’s give you something to research.
Okay, so you need to set up a sensor that determines the heating segment you are in (doors open, out, night, day, evening) I specify that order as that increments for me, you can choose differently if you like.
So determine your factors and construct the sensor.
From that you can determine what heating you need according to time and other factors.
Then you need a heating set point value, so create an input number for that. (maybe for each room ?)
Then you’ll need a profile for each room (common profiles mean yo can save on entities and ease the automation)
Catagorise your profiles and create the entities.
When you sensor changes update the heating set point.
When the set point changes update the thermostat (I recommend you use the software generic_thermostat but you may have different plans

How did you learn to code? Did you read docs/manuals?

Of course but nobody read a whole Language Reference Book before to write its first line of code. It is difficult to read all documentation before to begin anything. I try to do that as often as possible but you are right, it is time for me to have a deeper look at Jinja2 doc.

Maybe you don’t need to over-complicate your system (unless you truly enjoy the process)? KISS they call it.

I enjoy it :grin:

they read something anyway to get the idea what is possible to write. then as they go, they learn new words and revisit that reference book to get necessary details. so it’s a long process, yes.
I just wanted to say that there is no such thing as “this stupid Jinja is blocking me” as they did not design it for that - more likely there is something you don’t know yet.
And that fine as soon as you want to learn.

Here is my time of day sensor and the script I use to determine which temperature is appropriate resulting from that.
Use, pull apart or throw away as you see fit.

  - platform: template
        entity_id: climate.house_heat, input_number.in_heat_temp_control_val
        friendly_name: Heating Set Temperature
        value_template: "{{ state_attr('climate.house_heat', 'temperature') }}"
        icon_template: "{{'mdi:emoticon-cool' if ((state_attr('climate.house_heat', 'current_temperature') | float) >= (states('input_number.in_heat_temp_control_val') | float)) else 'mdi:emoticon-sad-outline'}}"
        entity_id: sensor.time
        friendly_name: Heating Segment
        value_template: >
          {% set time = states('sensor.time') %}
          {% set slt1start = states('input_datetime.id_heat_day_on') [0:5] %}
          {% set slt1stop = states('input_datetime.id_heat_evening_on') [0:5] %}
          {% set dy = (slt1start <= time < slt1stop) if (slt1start < slt1stop) else (slt1start <= time or time < slt1stop) %}
          {% set slt1start = states('input_datetime.id_heat_evening_on') [0:5] %}
          {% set slt1stop = states('input_datetime.id_heat_night_on') [0:5] %}
          {% set evng = (slt1start <= time < slt1stop) if (slt1start < slt1stop) else (slt1start <= time or time < slt1stop) %}
          {% set slt1start = states('input_datetime.id_heat_night_on') [0:5] %}
          {% set slt1stop = states('input_datetime.id_heat_day_on') [0:5] %}
          {% set nght = (slt1start <= time < slt1stop) if (slt1start < slt1stop) else (slt1start <= time or time < slt1stop) %}
          {% if dy %}Day{% elif evng %}Evening{% else %}Night{% endif %}
        icon_template: >
          {% set seg = states('sensor.heat_day_segment') %}
          {% if seg == 'Day' %}mdi:shovel{% elif seg == 'Evening' %}mdi:glass-cocktail{% else %}mdi:sleep{% endif %}

## resets temperature following any pattern change
    alias: Heating Reset Value
    - service: input_number.set_value
        entity_id: input_number.in_heat_temp_control_val
        value: >
          {% if false and not is_state('binary_sensor.bs_door_open', 'on') %}
            {{ '6' | float }}
          {% elif not is_state('binary_sensor.bs_occupied', 'on') %}
            {{ states('input_number.in_heat_temp_away_val') | float }}
          {% elif is_state('sensor.heat_day_segment', 'Night') %}
            {{ states('input_number.in_heat_temp_night_val') | float }}
          {% elif is_state('sensor.heat_day_segment', 'Day') %}
            {{ states('input_number.in_heat_temp_day_val') | float }}
          {% else %}
            {{ states('input_number.in_heat_temp_evening_val') | float }}
          {% endif %}
#### end of template

I did a basic interpetation of jinja wrapped python in this post : -