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.
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…”
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?
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.
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.