Variables and templates - are there limitations?

I want to do this but for some reason my automation will not use the variable schedule_no.
The template works and the condition evaulates to true. I’ve watched it all in real time in the devtools.

Also I put a persistant_notification before the condition to print schedule_no but it was blank.

Do I have something wrong in my syntax (I cant see it, obviously) or is there a limitation to what is allowed in variables templates e.g. for loops (seems unlikely).

    action:
      - variables:
          schedule_no: >
            {% for schedule in states.input_datetime if schedule.object_id.startswith('heating_downstairs_schedule_time') %} 
              {% if schedule.state == states('sensor.time') ~ ':00' %}
                {{ loop.index }}
              {% endif %} 
            {% endfor %}

      - condition: template
        value_template: >
          {{ is_state('input_boolean.heating_downstairs_schedule' ~ schedule_no ~ '_enabled', 'on') }}

      - service: input_boolean.turn_on
        data:
          entity_id: >
            {{ 'input_boolean.heating_downstairs_schedule' ~ schedule_no ~ '_active' }}

For the record my trigger is this and it would all be a whole lot easier the trigger.entity_id was populated!

    trigger:
      - platform: time
        at:
          - input_datetime.heating_downstairs_schedule_time1
          - input_datetime.heating_downstairs_schedule_time2
          - input_datetime.heating_downstairs_schedule_time3
          - input_datetime.heating_downstairs_schedule_time4
          - input_datetime.heating_downstairs_schedule_time5
          - input_datetime.heating_downstairs_schedule_time6

What’s the result of the for loop? Kinda feels like that result isn’t going to fit where it is then used below.

Would it not be easier to use the trigger object anyway? (presuming I understand what the action is doing)

    action:
      - condition: template
        value_template: >
          {{ set no = trigger.to_state.entity_id|replace('input_datetime.heating_downstairs_schedule_time', '') }} 
          {{ is_state('input_boolean.heating_downstairs_schedule' ~ no ~ '_enabled', 'on') }}
      - service: input_boolean.turn_on
        data:
          entity_id: >
            {{ set no = trigger.to_state.entity_id|replace('input_datetime.heating_downstairs_schedule_time', '') }} 
            {{ 'input_boolean.heating_downstairs_schedule' ~ no ~ '_active' }}

The result was a number e.g. 2 which I was expecting to fit into

'input_boolean.heating_downstairs_schedule' ~ schedule_no ~ '_enabled'

and return

input_boolean.heating_downstairs_schedule2_enabled.

However, yes it might be better your way, if it works.
I’ll give it at try… but is trigger.to_state.entity_id populated because trigger.entity_id isn’t.

I guess I’m about to find out…

Also, I was hoping to use a variable to save repeating the code…


UPDATE:
Nope…

    trigger:
      - platform: time
        at:
          - input_datetime.heating_downstairs_schedule_time1
          - input_datetime.heating_downstairs_schedule_time2
          - input_datetime.heating_downstairs_schedule_time3
          - input_datetime.heating_downstairs_schedule_time4
          - input_datetime.heating_downstairs_schedule_time5
          - input_datetime.heating_downstairs_schedule_time6

    action:
      - variables:
          schedule_no: >
            {% for schedule in states.input_datetime if schedule.object_id.startswith('heating_downstairs_schedule_time') %} 
              {% if schedule.state == states('sensor.time') ~ ':00' %}
                {{ loop.index }}
              {% endif %} 
            {% endfor %}

          mf_no: >
            {{ trigger.to_state.entity_id | replace('input_datetime.heating_downstairs_schedule_time', '') }}

      - service: script.notify
        data:
          show: true
          message: >
            schedule_no: {{ schedule_no }}

            mf_no: {{ mf_no }}

            trigger.to_state.entity_id: {{ trigger.to_state.entity_id }}

Gave me this:


jinja2.exceptions.UndefinedError: 'dict object' has no attribute 'to_state'


You’re right of course, the time trigger doesn’t have a to_state :see_no_evil:

Does the loop return exactly a number, or does it return like a new line character and a number and a space? Maybe the loop needs a load of - characters in the jinja to strip out everything but the number?

I’m clutching at straws a bit as I can’t really visualise what you’re doing/achieving with the automation.

Thanks, that’s a good point… I’ll check that.

I’m replicating my heating thermostats which have six presets. It’s something I knocked up quickly and almost certainly needs a complete rewrite with a little more thought behind it…

UPDATE:
Nope, no spurious characters (using devtools)

OK, I don’t know why the template doesn’t do what you need, but how does the replication work? Presumably the 6 input_datetimes start a sequence, what are all the input_booleans for?

Six input datetimes - for the time to set a temperature.
Six input numbers - for the temperatures at those times.
There are six input booleans - because not all six presets are always used.

And I currently use six more input booleans to indicate which preset is currently active.

So at datetime1 if the input_boolean is On, it sets the temperature to input_number1 and updates the ‘active’ input_booleans to show which preset is active…

I’ll have a head scratch and try and work out how I’d do that and come back to you in the morning if nobody pipes up in the meantime with something pretty :+1:

1 Like