"Auto" Triggers?

Template sensors and such have a nice feature that cause the update to happen whenever any of the entities used in the state expression change. And I was thinking that it would be nice to be able to have a similar feature for automations.

For example, I have several automations which are like:

If
turn on foo
else
turn off foo

Or a similar thing using “choose” with multiple complex expressions.

And I then need to add triggers that are (in theory) computable from the expression(s). And since I am only human, I have several times forgotten to update the triggers when I change the expressions.

I have also tried using a template binary_sensor with the expression there, and then making the automation only trigger when that binary sensor changes. This works… but involves editing yaml instead of a nice UI.

It would be nice to have a trigger just called “Automatic” or “Smart” or whatever, which just looks at any of the entities used in if-then, choose, template expressions, etc… in the conditionals and actions, and causes the automation to trigger when they change.

Thoghts?

So if the automation’s action turns on a switch, it will cause the automation to be triggered because it’s designed to be triggered by state-changes in “if-then, choose, template expressions, etc…”

Can you clarify what it is you are proposing? I’ve read the original post a few times, but I don’t get what the actual request is.

Another way to say it:

I am suggesting a new type of trigger which causes the automation to trigger whenever an entity changes which is used in the automation conditions, or conditions used in if/then or choose actions.

So for example, you could make an automation like “If blinds are closed or the sun is down, and there is motion in the motion sensor within the last 30 minutes”, and then it would trigger any time the state of the blinds, sun, or motion sensor change, without having to make those three triggers manually.

I don’t think it would make sense to trigger if the entity is used in any action… only the conditionals.

The intent is to be able to easily express ideas like “I want the lights to be on if any combination of conditions, otherwise it should be off” without having to mention the entities in the conditions twice.

I’m struggling to follow. Do you have an existing automation that you can share that would benefit from this improvement?

This is true for template triggers for automations. The one that’s different is if you use now() in your template, in which case it will evaluate the template every minute.

To paraphrase: a single trigger using a “smart”/“auto” platform where listeners are created for all entities referenced in the condition or action blocks?

Yes, exactly.

Here is one automation that would certainly be easier with such a thing.
It adjusts the blinds in the house based on a lot of different situations.
I feel that all the triggers are pretty much computable from the conditions

(Though probably not the trigger id stuff… that would need to be reworked… it is only there as an optimization now anyway)

Every time I modify the logic in the actions, I have to readjust all the triggers, and really, they should be computable from the actions.

alias: Blinds set based on Time of Day, Away Mode, Darkness, etc..
description: ""
trigger:
  - platform: homeassistant
    event: start
    id: global
  - platform: state
    entity_id:
      - input_boolean.away_mode
      - input_select.time_of_day
      - input_boolean.it_s_dark_outside
      - binary_sensor.blinds_should_stay_closed
    id: global
    to: null
  - platform: state
    entity_id:
      - input_boolean.ester_at_desk
      - input_boolean.charlie_at_desk
      - switch.801f12f10c90_connect
      - binary_sensor.master_bedroom_door_sensor_intrusion_2
      - media_player.lg_webos_smart_tv_2
      - media_player.lg_webos_smart_tv
      - media_player.gloomytv
    from: "on"
    id: global
  - platform: state
    entity_id:
      - input_boolean.ester_at_desk
    to: "on"
    id: local_office
  - platform: state
    entity_id:
      - input_boolean.charlie_at_desk
    to: "on"
    id: local_loft
  - platform: numeric_state
    entity_id:
      - sensor.house_sun_angle
    above: 165
    id: local_loft
  - platform: numeric_state
    entity_id:
      - sensor.house_sun_angle
    above: 175
    id: local_loft
  - platform: numeric_state
    entity_id:
      - sensor.house_sun_angle
    above: 218
    id: local_loft
  - platform: state
    entity_id:
      - media_player.lg_webos_smart_tv_2
      - media_player.lg_webos_smart_tv
    to: "on"
    id: local_loft
  - platform: state
    entity_id:
      - media_player.gloomytv
    to: "on"
    id: local_kitchen
  - platform: state
    entity_id:
      - binary_sensor.master_bedroom_door_sensor_intrusion_2
    to: "on"
    for:
      hours: 0
      minutes: 0
      seconds: 30
    id: local_loft
  - platform: state
    entity_id:
      - switch.801f12f10c90_connect
    to: "on"
    id: local_mudroom
condition: []
action:
  - alias: If triggered by global event, choose based on Time of Day and Darkness
    choose:
      - conditions:
          - alias: If not triggered by global event
            condition: trigger
            id:
              - local_loft
              - local_office
              - local_kitchen
              - local_mudroom
        sequence: []
        alias: If not triggered by global event, do nothing.
      - conditions:
          - condition: state
            entity_id: binary_sensor.blinds_should_stay_closed
            state: "on"
        sequence:
          - continue_on_error: true
            target:
              entity_id: scene.closed
            data: {}
            action: scene.turn_on
        alias: Closed if blinds should stay closed
      - alias: Evening if Evening or Dark
        conditions:
          - condition: or
            conditions:
              - condition: state
                entity_id: input_select.time_of_day
                state: Evening
              - condition: state
                entity_id: input_boolean.it_s_dark_outside
                state: "on"
        sequence:
          - continue_on_error: true
            target:
              entity_id: scene.evening
            data: {}
            action: scene.turn_on
      - alias: Morning if Morning
        conditions:
          - condition: state
            entity_id: input_select.time_of_day
            state: Morning
        sequence:
          - continue_on_error: true
            target:
              entity_id: scene.morning
            data: {}
            action: scene.turn_on
  - alias: Open Mudroom if McGrillface is on.
    if:
      - alias: Triggered by global or mudroom event
        condition: not
        conditions:
          - condition: trigger
            id:
              - local_loft
              - local_office
              - local_kitchen
    then:
      - if:
          - condition: state
            entity_id: switch.801f12f10c90_connect
            state: "on"
        then:
          - data: {}
            target:
              entity_id: cover.mudroom_side_front
            action: cover.open_cover
  - alias: Set Office Blinds if Ester is at Desk
    if:
      - condition: state
        entity_id: input_boolean.ester_at_desk
        state: "on"
      - alias: Early or Morning
        condition: or
        conditions:
          - condition: state
            entity_id: input_select.time_of_day
            state: Early
          - condition: state
            entity_id: input_select.time_of_day
            state: Morning
      - alias: Triggered by global or office event
        condition: not
        conditions:
          - condition: trigger
            id:
              - local_loft
              - local_kitchen
              - local_mudroom
    then:
      - continue_on_error: true
        metadata: {}
        data: {}
        target:
          entity_id: cover.office_side_front
        action: cover.close_cover
  - alias: "---------- Stop here if close_everything ----------"
    if:
      - condition: state
        entity_id: binary_sensor.blinds_should_stay_closed
        state: "on"
    then:
      - stop: close_everything
  - alias: Set TV Blinds
    if:
      - alias: Triggered by global or Loft event
        condition: not
        conditions:
          - condition: trigger
            id:
              - local_office
              - local_kitchen
              - local_mudroom
      - condition: or
        conditions:
          - condition: state
            entity_id: media_player.lg_webos_smart_tv_2
            state: "on"
          - condition: state
            entity_id: input_boolean.charlie_at_desk
            state: "on"
        alias: Bed TV is on or Charlie is at desk
    then:
      - continue_on_error: true
        target:
          entity_id: scene.tv_blinds
        metadata: {}
        action: scene.turn_on
  - alias: "---------- Stop here if it is dark or not Morning ----------"
    if:
      - condition: or
        conditions:
          - condition: state
            entity_id: input_boolean.it_s_dark_outside
            state: "on"
          - condition: not
            conditions:
              - condition: state
                entity_id: input_select.time_of_day
                state: Morning
            alias: Not Morning
        alias: Dark or not Morning
    then:
      - stop: Its Dark or not Morning
  - alias: Set Loft Driveway 1
    if:
      - alias: Triggered by global or loft event
        condition: not
        conditions:
          - condition: trigger
            id:
              - local_office
              - local_kitchen
              - local_mudroom
      - condition: state
        entity_id: input_boolean.charlie_at_desk
        state: "on"
    then:
      - alias: Set Loft Driveway 1 based on sun angle
        choose:
          - conditions:
              - condition: numeric_state
                entity_id: sensor.house_sun_angle
                below: 165
            sequence:
              - continue_on_error: true
                data: {}
                target:
                  entity_id: cover.loft_driveway_1_rear
                action: cover.close_cover
          - conditions:
              - condition: numeric_state
                entity_id: sensor.house_sun_angle
                below: 218
            sequence:
              - continue_on_error: true
                target:
                  entity_id: cover.loft_driveway_1_front
                data: {}
                action: cover.close_cover
        default:
          - continue_on_error: true
            target:
              entity_id: cover.loft_driveway_1_front
            data: {}
            action: cover.open_cover
  - alias: Set Loft Street 1
    if:
      - alias: Triggered by global or loft event
        condition: not
        conditions:
          - condition: trigger
            id:
              - local_office
              - local_kitchen
              - local_mudroom
    then:
      - choose:
          - alias: Watching TV in Bed
            conditions:
              - condition: state
                entity_id: media_player.lg_webos_smart_tv
                state: "on"
              - condition: state
                entity_id: binary_sensor.master_bedroom_door_sensor_intrusion_2
                state: "on"
            sequence:
              - metadata: {}
                data: {}
                target:
                  entity_id: cover.loft_street_1_rear_2
                action: cover.close_cover
          - alias: Working at desk
            conditions:
              - condition: state
                entity_id: input_boolean.charlie_at_desk
                state: "on"
              - condition: numeric_state
                entity_id: sensor.house_sun_angle
                above: 175
              - condition: numeric_state
                entity_id: sensor.house_sun_angle
                below: 218
            sequence:
              - continue_on_error: true
                target:
                  entity_id: cover.loft_street_1_front_2
                data: {}
                action: cover.close_cover
  - alias: Set Kitchen Blinds if GloomyTV is on
    if:
      - alias: Triggered by global or kitchen event
        condition: not
        conditions:
          - condition: trigger
            id:
              - local_loft
              - local_office
              - local_mudroom
    then:
      - if:
          - condition: state
            entity_id: media_player.gloomytv
            state: "on"
        then:
          - continue_on_error: true
            target:
              entity_id: cover.kitchen_front_rear
            data: {}
            action: cover.close_cover
mode: queued
max: 10

It feels to much “AI” for me.
Anything “AI” is more or less just a fancy word that means it doesn’t work as intended.
Thinking through my automations I’m not sure there is a lot of them where this would work.
Most of the times you want something to happen when this exact moment is, and this “AI” can probably at best add a state trigger with it blank.

I could see it as a good addition if it proposed this entity as the top entity list when I add a state trigger or numeric trigger.
But more than that is probably just going to make things worse.
Predicting things is hard and predicting how an automation should be written is kind of what we see when people code here with their GPT automations.

I really don’t see how having a blanket trigger that fires whenever any of those entities’ states change is going to make anything easier… it just moves the logic to a different location; changing from an opt-in approach to an opt-out approach. You would need to make sure your conditional logic accounts for all the edge cases and false positives that will be generated by the loss of the use of more specific triggers, as well as some of their powerful features like trigger IDs, durations, etc.

As @Hellis81 mentioned, I can’t think of more than one or two automations where it would even be possible to apply such a trigger. There just aren’t that many cases where the “sensing/triggering” entity is the same as the “acting” entity. And while it is common for triggers and condition to mirror each other in multi-trigger automations, the less specific your trigger is, the more specific your condition usually have to be.

I’m also thinking some of this could be remedied by some clever UX (although I don’t use the UI for config much myself).

I think one will have to write more defensive conditions, which to me would be a worse position. Some implicit config will be needed in some cases.

I think this point is more important than it seems. I think, you should mock up one example automation with your suggestion, and then let’s see how things would work from there.

1 Like

From what it looks like at first glance of trying to understand your automation, you are putting dozens of things in one automation that could be separated out in simpler automations. There are lots of if elses and chooses in one automation - causing you to need the blanket triggering.

I would never write one automation for this, but multiple. Each compound test involving multiple entities could be template sensors instead. What you say, that involves yaml, isn’t true. It can be done in the gui, but it does require jinja2 though. In doing so you could likely do with a few way simpler automations with clear triggers and minimal if or chooses.

But what I think this boils down to, and what I do dislike about HA is the frequently needed pattern that two or more conditions need to meet for one thing to happen. It involves that the two or more triggers also need two or more pretty much identical corresponding conditions in the condition block:

trigger:
  A becomes true
  B becomes true
  C becomes true
condition:
  A is true
  B is true
  C is true
Action:
  D

I’m guessing that this feature request is a very complicated way of wanting to remedy that. I would like that to happen as well. I’m not sure I would not want it to scan the action block as well though.
The proposed solution would be something equivalent to:

triggering_condition:
  A 
  B
  C
Action:
  D

Getting back to your binary sensor complaint: being able to define one without jinja, but as a list of conditions would be a great idea though, worth another FR.

That’s why I pointed it out because in your first post you said it would also automatically include entities found in actions.

Similarly there’s a pitfall with automatically triggering for entities in conditionals.

Take the example of an automation that triggers on motion. Its condition checks if the time is later than an input_datetime (and then turns on a light). I don’t want it to automatically trigger if I change the input_datetime’s value (only on motion).

You compared this requested feature to how Template entities work but that’s a false equivalence. One deliberately selects entities for the template; they’re there by choice and in one place (the template).

In contrast, an automation’s trigger and condition are separate places and serve different purposes; they behave differently by design. You don’t normally want conditions to also behave as triggers.