Better automations with "schedules"

Better Automations

I feel like this must have been discussed a million times, but since I couldn’t find a discussion like it - here we go:

Also, before I start. I am aware there are more advanced extensions/plugins/add-ons that provides functionality similar to what I suggest. However, I would personally love to have something like this in the core distribution. I have therefore tried to not make it too complicated and keep the syntax similar to the current workflow with automation.

The problem with the current system

I cannot be the only one here who likes Home Assistant, but gets frustrated with automations as soons as they become anything but the simplest “if this then that”. A typical example would be my outdoor lights.

  • I want them to turn on at 30% brightness at sunset
  • I want them to turn off at 22:00
  • If my motion sensor(s) detects any motion I want to turn them up to 100% for 5 minutes

The scenatio above seems simple enough af first glace, but as most of you probably already see there a a bunch of edge cases which are not easily handeled.

The naiive approach would be to make a few automations like this

  • One which turns the lights on at 30% at sunset
  • One which turns them off at 22:00
  • One which turns them up to 100% when motion is detected
  • One which turns them back to 30% 5 minutes after the motion was detected

The problem is obviously. What happens if I detect motion at 21:58 ? Then the lights would turn off at 22:00 and then turn back on at 30% at 22:03 and stay on for the rest of the night.

This can of course be fixed by a “hack” using a fifth automation, or perhaps just stop motion detection 5 minutes before the lights turn off anyway.

It gets even worse in my living room. I have a morning/evening mode (lights on), a night mode (dim lights), and a TV mode. All these modes seems to interact in annoying ways which requires way too much tinkering to get right.

For instance: If the lights turn on for an hour from motion in the evening, and 10 minutes (dimmed) during the night, and should stay dimmed when I watch TV. If I then trigger an “evening motion” 20 minutes before it’s night, and then a “night motion”, then watch some TV, pause the TV and the timers run out - what should happen? Don’t try to figure it out, because it was just a senario I made up, and I don’t know if it’s actually an edgecase. However, it’s something you need to think about when automating you home, and I think it’s a mess.

I think the main point is that automations lack some sort of encapsulation. When I have written an automation I never feel it is “done”. Because it always seems to be affected by the next automation I might write.

Scheduling

This is not a replacement for the current system, but rather an addition.
Since all the good names (automation, state, scenes, events etc) are taken I will here call it a schedule.

Instead of the current automation layout:

  • Trigger
  • Condition
  • Action

One could have a system where a schedule looks like this:

  • Start
  • End
  • Condition
  • Priority
  • Scene

I believe this is much more flexibel to the current system and can coexist with it.
It does require that home assistant keeps track of all the active schedules, but it feels like the coexistence of multiple use cases becomes so much easier. For instance, my outdoor lights could be written as:

start:
  - platform: sun
    event: sunset 
end:
  - platform: time
    at: "22:00:00"
priority: 5
scene: scene.outdoor_evening

start:
  - platform: state
    entity_id: binary_sensor.occupancy_outside
    to: 'on'
end:
    platform: state
    entity_id: binary_sensor.occupancy_outdoor
    to: 'off'
    for:
      minutes: 5
condition:
  - condition: state
    entity_id: sun.sun
    state: 'below_horizon'
  - platform: time
    before: "22:00:00"
priority: 10
scene: scene.outdoor_evening_motion

Depending on how advanced you want to go it will in many cases (but not all) make sense to build a tree structure of schedules. Defining a parent makes it easier to limit some schedules to only be active when the parent is active.

id: light outside
start:
  - platform: sun
    event: sunset 
end:
  - platform: time
    at: "22:00:00"
priority: 5
scene: scene.outdoor_evening

id: motion light outside
parent: light outside
start:
  - platform: state
    entity_id: binary_sensor.occupancy_outside
    to: 'on'
end:
    platform: state
    entity_id: binary_sensor.occupancy_outdoor
    to: 'off'
    for:
      minutes: 5
priority: 10
scene: scene.outdoor_evening_motion

In any case. The main advantage is that when the “motion outside” start, and then ends, home assistant will automatically transition to the active scene with the highest priority. There is no need to handle a lot of edge cases with overlapping time intervals. If there is no active scene they should probably just turn off or go to some other sensible default.

Please let me know what you think

Several of us are in the process of looking into this: https://github.com/home-assistant/architecture/issues/148 – come join the discussion!

I’ve considered “priorities” for automations many times. I’ve half-written the needed bits for it a few times over.

Ultimately, what I do now, and what I think a lot of people do, involves an input_select.

In the example of your outside lights, you’d have an input_select.outside_lights_mode. The options would be “on” and “off” (which you could just use a switch for, but, input_select will allow you to extend it further, later.

At sunset, input_select becomes “on”
At 22:00, input_select becomes “off”
if input_select goes “on” and the light is off, turn on to 30%
if input_select goes “off” and the light is at 30%, turn it off.
if there is motion, the light goes to 100%
when motion stops and input_select is “on”, light goes to 30%
when motion stops and input_select is “off”, light turns off.

Priority, as you describe it, is a very elegant solution to this problem.

I think it’s also important to note that while the “schedule” portion is critical to your use case, it’s the automation “priority” here that really makes it happen.

To take a non-schedule based use case as an example:

Lights in the living room. I want:

  1. 100% with motion
    1a) unless I’m watching a movie
    1b) unless it’s bright out
    1c) unless the alarm has been tripped

  2. 10% when watching a movie
    2a) unless it’s bright out
    2b) unless the alarm has been tripped

  3. 100% red when the alarm has been tripped

Since scenes have been enhanced, I’ll use that as a stepping stone. So I make several scenes:

  1. living_off
  2. living_motion
  3. living_movie
  4. living_alarm

I put the scenes in a scene_group (which would be a new feature). Then my automations change the priority of the scenes.

At “sunrise”, living_off goes priority 9. Maybe with an automation service call like:

- service: scene_group.set_priority
  entity_id: scene_group.living
  scene: scene.living_off
  priority: 9

At “sunset”, living_off goes priority 1
With “motion”, living_motion goes priority 2
With “motion stop”, living_motion goes priority 0
With “movie start”, living_movie goes priority 3
With “movie stop”, living_movie goes priority 0
With “alarm start”, living_alarm goes priority 10
With “alarm stop”, living_alarm goes priority 0

The scene_group is responsible for taking in all the priorities of all the scenes and activating the highest priority scene with each change.

I am struggling with the same issues. IMO this is mainly due to the fact that items are loosely defined. i.e. they are not embedded in a larger structure on with you apply your mutations. When your setup is relatively small the overview over the state of items and with automation is affecting them at a certain point still can be kept in mind. However as you system grows you’ll get more and more mutators the overview will be lost.
In this topic Home Graph Solid Base For 1000+ Items it is proposed to put items, and the mutations thereof in a graph-like structure.

I realize that requires an extensive rewrite. But if HA wants to be the home automation in the future, I think it should be done.

Thank you very much, nice work you have done here. I have added a few comments and will follow the development here. However, I think the initial proposal is a bit to limited.

I have to admit I do not understand how your priorities work without some kind of “ending” to an automation. If I invoke an action with high priority - how do I know it’s okay to leave this state again?

I did consider a graph structure before writing this post. However, I do not think this is the answer.

First of all: You are correct that it sounds like a large rewrite of a lot of things.
But more importantly: I don’t think it always makes sense. Take my outdoor lights as an example; Here is makes sense to represent it as a graph.

  • The base state is off.
    • When the sun goes down they turn on at 30%
      • When motion is detected they go to 100%

In my living room it doesn’t make that much sense. The TV-light is not really strongly connected to wheter the lights should be on or off. I make watch TV late at night when the lights would normally be off, but I still want them on. I tried representing this as a graph, but always ended up with a base state and just a lot of leafs only connected to the base state