Trigger template using "for" option

Good evening,

I’m trying to tidy up my automations a bit by using templates, but i’ve hit a brick wall with this one. I’ve got some motion sensors to control the lights and depending on the time of day, they switch on different scenes. The time of day also controls how long the lights will stay on for after the motion sensor reports no motion. The different times of day are stored in an input_select list and are called “Day”, “Evening”, “Night” and “Movie”.

Before i started using templates i just had separate automations that were triggered by motion and had the input_select value as the condition, but this looked untidy and i wanted to combine them all into a single automation. When motion was detected I was able to use a template for the action part of the automation which selects the light scene based on the input_select value, but i can’t figure out how to get templating to work with the “for” option in the trigger section to control how long the lights stay on for after the motion sensor returns a false. The time that i’d like the lights to stay on for is stored in a input_number variable.

I found the following example on the github pull requests which added templating to the “for” option back in Jul 19 (Pull request 24912):

automation:
  - alias: Use template in trigger's for option
    trigger:
      platform: state
      entity_id: sensor.a
      to: some_state
      for:
        minutes: "{{ states('input_number.minutes')|int }}"
        seconds: "{{ states('input_number.seconds')|int }}"
      action:

Based on this i came up with the following trigger template:

id: '1650815020918'
alias: Living light auto off debug
description: ''
trigger:
  - platform: template
    value_template: '''{{ is_state(''input_boolean.living_light_request'', ''off'') }}'''
    for:
      minutes:
        data_template: |-
          {% if is_state('input_select.light_mode_flat','Day') %}
            {{ states('input_number.motion_living_not_detected_day') | int }}
          {% elif is_state('input_select.light_mode_flat','Evening') %}
            {{ states('input_number.motion_living_not_detected_evening') | int }}
          {% elif is_state('input_select.light_mode_flat','Night') %}
            {{ states('input_number.motion_living_not_detected_night') | int }}
          {% elif is_state('input_select.light_mode_flat','Movie') %}
            {{ states('input_number.motion_living_not_detected_evening') | int }}
          {% endif %}
condition: []
action:
  - service: scene.turn_on
    target:
      entity_id: scene.living_all_lights_off
    metadata: {}
mode: single

This obviously doesn’t work and i’m sure there’s a simple reason why, but i just can’t see it.

Any help to get to the bottom of this would be greatly appreciated.

Cheers

David

Hassio running natively on a RPi 4
Version : core-2022.4.6
Version : supervisor-2022.04.0
Operating System : Home Assistant OS 7.6

Change this:

    for:
      minutes:
        data_template: |-

to this:

    for:
      minutes: |-
1 Like

Thanks Taras, that was exactly what i needed. Looks simple when someone else solves it for you ;). I made a few alterations and my final automation looks like this.

alias: Living light request off
description: ''
trigger:
  - platform: template
    value_template: '{{ is_state(''binary_sensor.motion_living_room'', ''off'') }}'
    for: |
      {% if is_state('input_select.light_mode_flat','Day') %}
        {{0}}:{{ states('input_number.motion_living_not_detected_day') | int }}:{{0}}
      {% elif is_state('input_select.light_mode_flat','Evening') %}
        {{0}}:{{ states('input_number.motion_living_not_detected_evening') | int }}:{{0}}
      {% elif is_state('input_select.light_mode_flat','Movie') %}
        {{0}}:{{ states('input_number.motion_living_not_detected_movie') | int }}:{{0}}
      {% elif is_state('input_select.light_mode_flat','Night') %}
        {{0}}:{{0}}:{{ states('input_number.motion_living_not_detected_night') | int }}
      {% else %}
        {{0}}:{{0}}:{{0}}
      {% endif %}
condition: []
action:
  - service: input_boolean.turn_off
    data: {}
    target:
      entity_id: input_boolean.living_light_request
mode: single

I’m sure it’s not optimised, but it might help someone else in the future.

Thanks again.

Dave

1 Like

If you wish, I can help you simplify the template.

Is the value of input_select.light_mode_flat limited to Day, Evening, Movie, and Night or are there others?

Hi Tara,

There are others, which is why i added the else expression that puts in no delay. Anything you can do to help simplify the template would be greatly appreciated.

Thanks

David

trigger:
  - platform: template
    value_template: "{{ is_state('binary_sensor.motion_living_room', 'off') }}"
    for:
      minutes: |
        {% set m = states('input_select.light_mode_flat') | lower %}
        {% set t = iif(m in ['day', 'evening', 'movie', 'night'], states('input_number.motion_living_not_detected_' ~ m), 0) %}
        {{ iif(m == 'night', t/60, t) }}

Hi Taras,

That’s far more elegant than my brute force approach. If i’m reading it right, you’re writing the input_select state to a variable called ‘m’ after putting it all to lower case. Then you’re confirming that it’s ‘day’, ‘evening’, ‘movie’ or ‘night’ and appending the entity id with the correct term before writing the state of the entity to another variable, ‘t’. Finally you’re checking to see if the variable is ‘night’ and if it is, you’re dividing it by 60 to effectively make it a seconds value and if it’s not ‘night’ the value just get’s put in as minutes.

The one question i have is about the variable type. I thought that the ‘for’ option in the trigger template had to be an integer and if the input_select value is ‘night’ then it’ll get fed a float. Was i wrong about ‘for’ needing an int?

Thanks

David

It accepts a float value.

You can confirm it using the following simple automation:

alias: Example
trigger:
  - platform: state
    entity_id: input_boolean.test
    to: 'on'
    for:
      minutes: 1.25
condition: []
action:
  - service: notify.persistent_notification
    data:
      message: Turned on 1.25 minutes ago.
      title: '{{ now().timestamp()|timestamp_custom}}'
mode: single