How to avoid duplicate triggers/conditions in automations?

I have created an automation to automatically turn on/off my outside lights based on a number of different factors. It is currently working, but I feel like I’m brute forcing this a bit.

My automation (below) uses a service_template to manage the logic for the light, and I just trigger it every minute with a time_pattern.

Originally, I tried to create everything using the GUI-friendly triggers and actions, but I found that it was a ton of redundant code. I had to set up triggers for the sun set, the sun rise, people arriving, people leaving, time changing, etc. And then nearly identical conditions. Doing it with the service_template is significantly less redundant, but the use of time_pattern feels really brute-forcey.

Is there a better way to do this? What improvements would you all suggest?

alias: Outside Lights Control (new)
description: >-
  Turns outside lights on at sunset, off at sunrise.  Turn lights off when
  everyone is in bed.  Turn lights on once someone is up.  Keep lights on when
  anyone is away.
trigger:
  - platform: time_pattern
    minutes: /1
  - platform: homeassistant
    event: start
condition: []
action:
  - service_template: >
      {% set person_home = ( states.person | selectattr('state', 'eq', 'home') |
      join(', ', attribute="entity_id") ) | length %}

      {% if (state_attr('sun.sun', 'elevation') < 3.5) %}
        {# Sundown State #}
        {% if not person_home %}
          {# Someone is not home state #}
          switch.turn_on
        {% elif now().hour >= 22 or now().hour < 5 %}
          {# Everyone is asleep state #}
          switch.turn_off
        {% else %}
          switch.turn_on
        {% endif %}
      {% else %}
        switch.turn_off
      {% endif %}
    entity_id: switch.front_outside_lights_switch
mode: single

Yes time pattern triggers are rarely the most efficient way of doing things. I suggest you create two automations. One for turning the lights on, one for turning the lights off. Your automation description contains all the information you need.

For your lights on automation you have these state triggers:

For your lights off automation you have these state triggers:

But with the following condition for the off automation:

Bass ackwards.

1 Like

Maybe I’m misunderstanding, but I’m not sure how that solves the redundancy issue. I still have to have a trigger for each thing as well as a condition for each thing.

For example, if I just have the condition of “anyone is away” on the off automation, I still have to trigger whenever anyone come home, so that the light go on. And furthermore, I’d have to have that trigger duplicated on the “on” automation so that the lights would come on whenever someone leaves.

1 Like

Care to elaborate?

You were on the right track here:

Who cares if it’s a lot of triggers and conditions; it’s efficient because it triggers only when events actually occur.

Your current automation may seem shorter but it triggers every single minute, whether events occur or not, then proceeds to digest a hairball of logic.

2 Likes

I mean…I care… :grin:

More realistically, this is one of the simplest “complex” automations that I have in my house. When I started making other automations (and even tweaking this one as I enabled presense detection and Google routine integration), managing that duplication introduces error, difficulty troubleshooting, and is just general bad practice from a coding perspective.

With more complex automations where the conditions number in the dozens, managing a dozen+ triggers and an identical dozen+ conditions is beyond frustrating.

Fundamentally, most of my automations are of the type: if conditions A, B, C, …, Z are true, then do 123. I’m surprised that there’s no better way to automate this than: set triggers for A, B, C, …, Z AND set triggers for not A, not B, not C, …, not Z AND set conditions for A, B, C, …, Z.

To turn the question back around to you, who cares? :slight_smile:

Is this a meaningful load on the system? I don’t fully understand the trigger system, but at some level Home Assistant must be evaluating trigger conditions in near real time, so I can’t imagine that this is really all that different from a system load perspective.

The “hairball” of logic is fundamentally the same as must be point-and-click coded into triggers and conditions. Going back to my A, B, C, …, Z example, whether it’s coded in Jinja templates or through the GUI, it’s the same degree of "hairball"ness.

To be honest, and answer my rhetorical question, I also obviously care about it triggering every second (or else I wouldn’t have posted this question). If the real trade off is (1) run every second, or (2) massively duplicate triggers and conditions, then I’d pick (1) every time. However, I just can’t believe that this is the real choice here, and I have faith that there’s something in the middle that I’m missing.

Doing some more research, I found that automations used to support a use_trigger_values condition which appears to do exactly what I’m looking for. However, this condition was removed sometime around 2015.

Is there a replacement for use_trigger_values that approximates this behavior?

In one breath you express concern for coding maintenance/aesthetics yet show no concern for making the software do needless busy work.

If you can’t see the difference between “interrupt” vs “polling” then have it; write all of your automations with a Time Pattern Trigger and a long-winded chain of if-elif-else.

You’ve received guidance from two individuals who have spent untold hours with Home Assistant and helping community members. However, you’re free to ignore the advice and pursue whatever you see fit. Good luck!

1 Like

Your advice is much appreciated! I would hope that the fact that I’m engaging here shows that I’m not at all ignoring the advice you are providing. I’m sorry if I’m coming across otherwise.

My questions are meant to clarify what I’m reading and make sure that I understand. From my experience, when I get responses that “feel” wrong to me, it’s because I either have a fundamental misunderstanding of the process, or I’m very much asking the wrong question.

I know how time consuming it can be helping people on a forum. I really appreciate the time you’re putting in to this. I promise that I’m not here to waste your time!

I think that may be a bit unfair; I am asking the question to correct this, after all. My goal is not to make the software do needless busy work.

Really, I’m trying to solve both of those problems. I don’t want software to do needless busy work, and I don’t want me to do needless busy work. I just can’t believe that there’s not a solution that addresses both of these points.

Doing some more research, it looks like I could perhaps have the best of both world by defining a template sensor that contains my logic, and then just set the automation based on that template sensor.

According to the template documentation, it appears that template sensors automatically define triggers based on the states referenced in the trigger logic, which deals with the redundant triggers/conditions problem we’re dealing with here in “automation” land.

I’m going to test and see if that work properly.

1 Like

Read the answers you got again.

They contain simple state trigger solutions to your initial post.

No Jinja templates required.

I must be extremely dense here, because I am not understanding.

With regards to your earlier suggestion, my understanding is that limited trigger/condition won’t work, because Home Assistant evaluates triggers in an OR logical manner.

As such, the “turn on” triggers will turn on if sunset occurs OR if someone is up. However, depending on the time of year, I may awake after sunrise. Therefore, if I have no conditions on the “turn on” automation, it would turn on my lights even if it’s not dark outside.

Similarly, I also need the light to turn on if someone leaves the house when it’s dark. Therefore, I have to have a trigger on people leaving. And vice-versa for triggering when people get home to trigger on the “turn off” state.

So, thinking about the “Turn Off Automation” based on my current (perhaps flawed) understanding, I need to have:

  • Turn Off Automation
    • Triggers
      • Someone comes home
      • Sunrise
      • Someone goes to bed
    • Conditions
      • Everyone is home AND sunset AND everyone is in bed

This is the duplication that I’m seeing when I try to do this the GUI way.

If you use identical state triggers and conditions they become AND logic (conditions are AND by default).

OK, so to restate my Turn Off Automation:

  • Triggers
    • Someone comes home
    • Sunrise
    • Someone goes to bed
  • Conditions
    • Everyone is home
    • Sun is down
    • Everyone is in bed

This still feels like unnecessary duplication here. And then thinking about the Turn On Automation, which has nearly identical triggers and conditions, which is another layer of duplication.

This is where I’m super confused.

EDIT: Just to add, thank you so much for all this! I’m sorry I’m being so dense.

There are ways around your perceived duplication of symbols and coding inefficiency. And they do involve templates.

But we were talking about triggering efficiently with a limited (and easy to learn) YAML instruction set.

It may be bloated but its still better than triggering every minute indiscriminately.

Do you have an example of this or some documentation you could point to?

So, if I’m understanding you correctly, there’s no way to automagically tie triggers and conditions together through the automation interface? No replacement for use_trigger_values?

Both:

Templating

I’ve only been here 3 years or so and have never heard of that. Got an internet archive link or something?

Me neither; even its removal predates me by almost a year. See the Breaking Changes section of the 0.3 Release Notes

0.3 !