Template trigger-based sensors: add "variables"

(could be already proposed)

Consider this template sensor(-s):

  - trigger:
      - platform: ...
        ...
      - platform: ...
        ...

    action:
      - ...
      - ...

    sensor:
      - name: ...
        state: ...
      - name: ...
        state: ...

I can define variables which may be used inside the “action” section:

    action:
      - variables:
          var_1: ...
          var_2: ...
      - ... use vars in actions ...
      - ... use vars in actions ...

But I also see some use cases for this:

    action:
      - variables:
          var_1: ...
          var_2: ...
      - ... use vars in actions ...
      - ... use vars in actions ...

    sensor:
      - name: ...
        ... use vars to define a sensor ...
     
      - name: ...
        ... use vars to define a sensor ...

So variables may be used to define states, attributes etc.

Feature requests are here to propose new stuff based on existing code or things you think are missing in the current code base, basically.

Is this a question or are you just figuring out what variables do?
Script Syntax - Home Assistant.

Vars may be used inside actions as it was stated in my post.
This FR about using them for a sensor declaration.

So, template sensors?
Template - Home Assistant.

Yes, template sensors. As it is stated in the FR’s title (and in the 1st post as well).

You can use variables in them. They are mostly Jinja. Jinja uses variables everywhere.

Also template sensors are not done inline like that , they are in the templates integration section.

Ofc, this is what was just missed to save a space.
Guess I can use template sensors a little and place them into “template” section always.

Currently, if you define a script variable in the action section (of a Trigger-based Template Sensor) the variable is available in the sensor section.

Is that what you are requesting or have I misunderstood your FR?

Correct!
Never knew I could use these vars in sensors themself.
This works:

template:
  - trigger:
      - platform: state
        entity_id: input_number.testing_number
        to:
    action:
      - variables:
          ENTITY_NAME: >-
            {{ trigger.entity_id }}
    sensor:
      - name: testing_vars_in_sensor
        state: >-
          {{ ENTITY_NAME }}

Thanks a lot, Taras.

But docs for template sensors need to be updated:
the fact that variables may be used in actions does not mean these variables may be used inside sensors as well.
If it is already defined there as


I would say this is a bit cryptic.

I do believe there is a link there to help you suggest wording that would help the entire community understand it better thru your eyes.

Right, and I do know it & do gonna do it.

it would still be the one thing we are waiting for on regular template: entities.

this only works on trigger based templates.

the only work around we now have is the custom_templates, and we can import those in state and each attributes of a template: entity.

dont think we should call that a true variable

I probably should have pasted “trigger-based” words into the FR’s title - this was my only intention, was not thinking about “not-trigger-based” template sensors.

And I agree that variables could be also useful for “not-trigger-based” template sensors.
Example:

- sensor:
    - name: ...
      state: ...   
      attributes:
        attr_1: ...
        attr_2: ...
      availability: ...

Assume that some of these keys uses same expressions.
Then it would be great define them in 1 place:

- sensor:
    - name: ...
      variables:
        var_1: ...
        var_2: ...
      state: ...   
      attributes:
        attr_1: ...
        attr_2: ...
      availability: ...

and then use these vars in these keys.

What we can do now:
– either another FRs is created for “not-trigger-based” template sensors (and I rename this FR);
– or I “reopen” this FR and update the 1st post to describe a case for “not-trigger-based” template sensors.

yes exactly that last scenario would be a miracle. I do believe Taras did write that up before?

just add trigger based to the title and lookup Taras’s FR

I found out about this last night and tried to implement this as part of a clean-up of an existing sensor.

This is my existing implementation:

template:
  - trigger:
    - platform: time_pattern
      minutes: "*"
    sensor:
      - name: Unavailable Entities
        icon: mdi:help-circle-outline
        state: "{{ states | selectattr('state', 'in', ['unavailable', 'unknown', 'none']) | rejectattr('domain','eq','button') | map(attribute='entity_id') | reject('==', 'sensor.unavailable_entities') | list | length }}"
        unit_of_measurement: entities
        state_class: measurement
        attributes:
          # buttons don't have state – we don't care about buttons here
          unavailable: "{{ states | selectattr('state', 'in', ['unavailable']) | rejectattr('domain','eq','button') | map(attribute='entity_id') | reject('==', 'sensor.unavailable_entities') | list }}"
          unknown: "{{ states | selectattr('state', 'in', ['unknown']) | rejectattr('domain','eq','button') | map(attribute='entity_id') | reject('==', 'sensor.unavailable_entities') | list }}"
          none: "{{ states | selectattr('state', 'in', ['none']) | rejectattr('domain','eq','button') | map(attribute='entity_id') | reject('==', 'sensor.unavailable_entities') | list }}"

This isn’t the most efficient, for various reasons: There’s a lot of duplication and the order of filters can be improved.

Using this action section, I set a variable with a reduced list that I can re-use:

template:
  - trigger:
    - platform: time_pattern
      minutes: "*"
    action:
      - variables:
          reduced_list: >-
            {# the midea fan and outdoor temp sensors are unavailable when a unit isn't running #}
            {% set exclusions = [
                     'sensor.unavailable_entities',
                     'number.living_room_ac_fan_speed',
                     'number.main_bedroom_ac_fan_speed',
                     'sensor.living_room_ac_outdoor_temperature',
                     'sensor.main_bedroom_ac_outdoor_temperature',
                     'sensor.solar_reserve_percentage_5min_average',
                     'sensor.pv_power_5min_average'] %}
            {# buttons and event entities don't have state – we don't care about those here #}
            {% set reduced_list = states
                     | rejectattr('domain','search','button|event')
                     | rejectattr('entity_id', 'in', exclusions)
                     | selectattr('state', 'in', ['unavailable', 'unknown', 'none'])
                     | list %}
            {{ reduced_list }}
    sensor:
      - name: Unavailable Entities
        icon: mdi:help-circle-outline
        state: "{{ reduced_list | length }}"
        unit_of_measurement: entities
        state_class: measurement
        attributes:
          unavailable: "{{ reduced_list | selectattr('state', 'eq', 'unavailable') | map(attribute='entity_id') | list }}"
          unknown: "{{ reduced_list | selectattr('state', 'eq', 'unknown') | map(attribute='entity_id') | list }}"
          none: "{{ reduced_list | selectattr('state', 'eq', 'none') | map(attribute='entity_id') | list }}"

This, however, seem to go haywire. It’s not reporting the correct entities and count – not even remotely. I have about 950 entities in my system. This version reports 637 (unavailable) entities.

Evaluating the templates in the dev tools give the correct result: A state of 3, with all 3 being unavailable entities. Cross-checking this by filtering on entities from the Entities view under the Devices & Services menu confirms this (taking my exclusions into account).

Do I have an error that I’m not spotting? Otherwise, I can only think there’s some multiple evaluations of the action block going on. Honestly, I actually have no idea.

I’ve read this for the 10th time, and I think I get it now: I cannot use these variables in the sensor section (I understood it to be the opposite).

We really, really need this kind of thing implemented.

I’ll just make use of Jinja macros for now. Not a full win, but it will help reducing the duplication.

@parautenbach
Was going to answer for a very long time ))))
I guess you already know the answer - the “reduced_list” variable is stored not as a LIST, that is why you are getting a huge value.

Check this:

template:
  - trigger:
      - platform: state
        entity_id: input_button.testing_button

    action:
      - variables:
          reduced_list: abcd

    sensor:
      - name: test_vars
        state: >-
          {{ reduced_list | length }}

which returns a correct value:
image

And then check this:

template:
  - trigger:
      - platform: state
        entity_id: input_button.testing_button

    action:
      - variables:
          reduced_list: >-
            {% set reduced_list = states.input_boolean
                                    | selectattr('entity_id','search','input_boolean.test')
                                    | selectattr('state','eq','on')
                                    | list -%}
            {{ reduced_list }}

    sensor:
      - name: test_vars
        state: >-
          {{ reduced_list | length }}

which returns this:
image

This is a length of this string (from MS Word):

A possible way:

template:
  - trigger:
      - platform: state
        entity_id: input_button.testing_button

    action:
      - variables:
          # reduced_list: abcd
          reduced_list: >-
            {% set reduced_list = states.input_boolean
                                    | selectattr('entity_id','search','input_boolean.test')
                                    | selectattr('state','eq','on')
                                    | map(attribute='entity_id')
                                    | list -%}
            {{ reduced_list }}

    sensor:
      - name: test_vars
        state: >-
          {{ LIST|length }}

I think the variable in the initial example (w/o “map(attribute=‘entity_id’)”) is not stored as a list.
This

        state: >-
          is string_like: {{ reduced_list is string_like }}, is list: {{ reduced_list is list }}

returns
image

And with using “map(attribute=‘entity_id’)” it returns
image

1 Like

Ah, right! It’s a character count because the list type isn’t preserved. I actually didn’t spend more time on it back then, so good to know now.