Support variables in a Template Trigger

It would be very useful if a variable could be used in a Template Trigger.

Currently (0.118.X) the following automation fails to be triggered.

- alias: test
  variables:
    inputs: >
      {{ expand('group.input_booleans') 
         | selectattr('state', 'eq', 'on')
         | map(attribute='name') | list }}
  trigger:
    platform: template
    value_template: "{{ inputs | count > 0 }}"
  action:
    service: persistent_notification.create
    data:
      title: 'Test'
      message: "{{ inputs | join(', ') }}"

Manually triggering the automation results in a notification containing the value of inputs. In other words, the variable is correctly defined, and contains a list, but it fails to be understood within the trigger.

Voted for this.
Another case was described here:

In short - a variable need to be used inside a "for" section.
This will make possible to create a blueprint for automations like “Toggle when some entity = OFF for XXXX minutes”, where XXXX- an input variable.

I tried the new trigger_variables feature introduced in 2021.3.0. I converted my original example to this:

- alias: test
  trigger_variables:
    inputs: >
      {{ expand('group.input_booleans') 
         | selectattr('state', 'eq', 'on')
         | map(attribute='name') | list }}
  trigger:
    platform: template
    value_template: "{{ inputs | count > 0 }}"
  action:
    service: persistent_notification.create
    data:
      title: 'Test'
      message: "{{ inputs | join(', ') }}"

Unfortunately, it was rejected for the following reason:

Error rendering trigger variables: TemplateError: str: Use of ‘expand’ is not supported in limited templates

I removed expand and replaced it with a list of state objects:

      {{ [ states.input_boolean.switch_1, states.input_boolean.switch_2 ] 
         | selectattr('state', 'eq', 'on')
         | map(attribute='name') | list }}

However, that was also rejected:

Error rendering trigger variables: UndefinedError: ‘function object’ has no attribute ‘input_boolean’

tl;dr
The new trigger_variables feature is promising but, in its current state, has limited functionality; this Feature Request remains open.

6 Likes

Another use-case I’d love to make a blueprint for is trigger a blueprint to happen x minutes before a calendar’s start_time. I’d like to be able to do this, but currently can’t because trigger_variables is a limited template.

variables:
    time_before_event_mins_input: !input time_before_event_mins_input
    calendar_input: !input calendar_input
trigger_variables: 
    calendar_start_time: "{{ state_attr(calendar_input, 'start_time') }}"
trigger:
  - platform: template
    value_template: >
      {{ as_timestamp(calendar_start_time) - as_timestamp(now()) < (time_before_event_mins_input * 60)}}

1 Like

This request has been up most of a year, and it needs a little boost. This is something you would think would be obviously needed, especially for blueprints, but is not there, so it is forgotten OR hard to do, don’t know…

I’m going to have to find a way around this…

Please give it a boost vote.

Voted. With the advent of blueprints this becomes essential in many scenarios What workarounds are everyone here using? I’d hate to “poll” with a fake trigger…

This post was extremely helpful to me, thanks. You may know that you can achieve the same by keeping the trigger_variables a list of entity id strings, rather than states objects, since as you said, those aren’t supported.

I just made this and it worked a treat:

trigger_variables:
  CURRENT_SENSORS:
    - sensor.sonoff_10014911cb_current
    - sensor.sonoff_10012efb58_current
    - sensor.sonoff_10012efb6e_current

trigger:
  - platform: template
    value_template: |
      {% set data = namespace(currents=[]) %}
      {% for current_sensor in CURRENT_SENSORS %}
        {% set data.currents = data.currents + [states(current_sensor)|float] %}
      {% endfor %}

      {{ data.currents|select('greaterthan', 1)|first|default }}
    id: any high

and for when all currents are low, an unfortunate copy pasting of the for loop and then:

      {{ data.currents|select('lessthan', 1)|list == data.currents }}
    id: all low

(list|length == data.currents|length is likely more performant but whatever, when the {{ }} becomes too long the HA yaml editor does nasty reformatting)

You may also know that one can also achieve the same without even employing trigger_variables. :slight_smile:

All this to say that there are many paths to the same destination; the aim of this FR is to allow for more extensive templating in trigger_variables (even more than the “limited templates” that were introduced after this FR was posted).

FWIW, if you want to eliminate the for-loop from your template, you can do this:

{{ expand(CURRENT_SENSORS) | map(attribute='state') | map('float') | select('>', 1) | first | default }}

Oh good call. I’m so used to avoiding map like the plague in Python (favoring comprehensions instead) that it didn’t occur to me it would be good here in a Jinja template. :+1: Thanks.

That was version 1 before I found this topic. :stuck_out_tongue_winking_eye:

trigger_variables:
  CURRENT_SENSORS:
    - sensor.sonoff_10014911cb_current
    - sensor.sonoff_10012efb58_current
    - sensor.sonoff_10012efb6e_current
trigger:
  - platform: template
    value_template: >-
      {{ expand(CURRENT_SENSORS) | map(attribute='state') | map('float') |
      select('>', 1) | first is defined }}
    id: any high
  - platform: template
    value_template: >-
      {{ expand(CURRENT_SENSORS) | map(attribute='state') | map('float') |
      select('<', 1) | list | length == CURRENT_SENSORS | length }}
    id: all low

It’s so glorious. :heart_eyes: Thank you!

Now if only the yaml editor wouldn’t move trigger_variables to the bottom each time it’s opened, which if re-saved causes a log warning about the variable being undefined, despite everything working perfectly…