Time Pattern needs to support ranges

I have found that if you want something to happen reliably you have to keep on doing it until it’s done. With home automation lots of things can go wrong that prevent an automation from executing that should have executed: HA was down at the time of the event, HA never got an event because of a network issue, HA got the event and executed the automation but some other element dropped it (zigbee device not reachable at that particular moment, etc)

So if I really want something to happen I have found that I need to trigger the event several times in order to make sure that it gets done.

As an example, I want my outdoor lights to turn on when the sun goes down, and off when the sun comes up. Lots of people probably do that. I used to do it by having an EVENT trigger based on sun.sun, but I don’t do that anymore–it’s just not reliable enough. Lots of days I come out in the morning and find the lights are still on, when they should be off. Some days it works, some days it doesn’t. Probably zigbee issue? Or network issue? Anyway, it happens.

So I solved that by switching the trigger to a time pattern: Trigger an event every 30min, with condition sun above the horizon and outdoor lights are on, and turn the outdoor lights off. So that works pretty well! But it runs all day long.

I’d really like to be able to use a range.

I have lots of examples like that, where I have moved to using time pattern triggers to ensure something happens reliably. Mostly routines that turn devices off: turn lights off when no one is around, turn heaters off when no one is around, turn the alarm on if no one is home. I have achieved reliability with time patterns.

But some of my time patterns are clunky. If I want something to happen every evening hour I have to set up a different time pattern trigger for 7pm, 8pm, 9pm, 10pm, and 11pm. I should be able to say 7-11 for that.

The fact you had to do that indicates your communication system (for lights, etc) is somewhere in the range of marginal to inoperative. In other words, it’s completely unreliable and you should focus your attention on correcting it, not building bigger, better workarounds to mitigate it.

Everyone is free to post whatever Feature Request they desire. However, you should know that the odds of a developer volunteering their time to implement it depend on the request’s perceived value to the community. The justification for this request is an unreliable ZigBee network. It will be interesting to see if that justifies creating a more complicated Time Pattern Trigger.

If you only want it to trigger at specific hours of the day, use a Time Trigger.

- alias: example
  trigger:
    platform: time
    at:
      - '19:00:00'
      - '20:00:00'
      - '21:00:00'
      - '22:00:00' 
      - '23:00:00'
3 Likes

I want to trigger an event every 5min from 7-11, not just once an hour during those times. Using the time trigger I would need to create 60 rows laying out all the points in time, and I would need to do that for a whole bunch of automations. It’s unwieldy.

I agree with @123, primarily. Fix your network. That being said, I have a handful of dodgy devices that don’t always work every time and I’m either too cheap or too lazy to replace them or there are just no other reasonable alternatives. So, I often have to do something several times to ensure it takes as well.

An example, I like music to play when I’m in the shower. I use Alexa and Spotify for this. But, both are a bit dodgy. So, when my automation to start music doesn’t work, I do it again. For something like music, if I keep doing it again and again, the song or playlist starts over again, which is not desirable. So I have to find a way to detect if it happened like I expected it to (in this case, I look for the media_player to be ‘playing’). But, for something like a light, just doing it again hurts very little.

The “range” feature you seek is already there in the form of a time condition.

- alias: turn on the lights... FOR SURE
  trigger:
    platform: time_pattern
    minutes: "/5"
  condition:
    condition: time
    after: "00:08:00"
    before: "10:00:00"

Or, if you’d prefer:

- alias: turn on the lights... FOR SURE
  trigger:
    - platform: time_pattern
      minutes: "/5"
      hours: 8
    - platform: time_pattern
      minutes: "/5"
      hours: 9

Or, if your the request isn’t always received by the light, but, when it does get it, the state is updated correctly:

- alias: turn on the lights.... FOR SURE
  trigger:
    - whatever you need here
  action:
   - repeat:
     sequence:
      - service: light.turn_on
        data:
          entity_id: light.mine    
      - delay: 60
     until: "{{ is_state('light.mine', 'on') }}"

To make all my automations work by fixing “my” network you’re basically asking met to get ahold of Comcast and make sure that my internet is never down just at sunset, e.g., and like @swiftly said, there’s a bunch of devices that are sometimes dodgy and a LOT that are dodgy at least once a month. The underlying protocols that home automation are built on – zigbee, zwave, and wifi – are simply not highly available networks that provide any sort of a guarantee. Ever.

If you want a guarantee, you have to guarantee it yourself, either by having an automation repeatedly execute until it can positively confirm the action is taken (hard) or have the automation run a bunch of times to dramatically improve the odds it succeeds (easier).

I agree with @123, but would also add that there are occasions where one can have a known unreliability and work around it more simply.

For example I have a smart socket that sometimes misses to the off command (as it just happens to dump the WiFi connection for a few seconds every now and then), and I only want it on for 15 minutes at a time. So I have a trigger that when it’s on for 15 minutes, switch it off.

To shore it up, I just added a second trigger for 16 minutes, so if it misses it at 15 minutes it gets another one a minute later, but if it doesn’t miss the first one then the automation remains dormant.

One could also add a short delay and wait_template, leveraging the timeout and continue options to check whether the desired result has occurred and send the command another X number of times and if it fails after that send a failure message via a notification platform.

For an unreliable network connection I’d do it like this:

trigger:
  platform: sun
  event: sunrise
action:
  - while: "{{ is_state('light.your_lights', 'on') and repeat.index < 20 }}"
    sequence:
      - service: light.turn_off
        entity_id: light.your_lights
      - delay:
          seconds: 30
  - condition: state
    entity_id: light.your_lights
    state: 'on'
  - service: notify.notify
    data:
      message: "Could not turn off the lights."

So starting at sunrise the script attempts to turn off the lights every 30 seconds until they turn off. If it can’t turn the lights off after 20 attempts (10 minutes) it gives up and notifies you that the lights did not turn off. Feel free to adjust the timing and number of attempts to suit your situation.

Completely agree with you. However, based on martingale’s description, it sounds like pretty much nothing works reliably … to the extent all commands must be sent multiple times because the only thing you can count on is that you can’t count on it to work on the first try. Cripes, even my old X10 switches worked far more reliably than that!

trigger:
platform: sun
event: sunrise

^ that won’t work if HA is off at sunrise, e.g., power failure or upgrade happened at that time.

@”However, based on martingale’s description, it sounds like pretty much nothing works reliably"

I think it depends how you define reliably. I will find a light on that’s supposed to be off somewhere in my house once a week or so. So it works most of the time.

I think I’m pushing the limits of what you should do with a zigbee network. Turning on one light works reliably, but flipping a couple dozen lights off, it seems sometimes a couple of them don’t get the message.

I consider Zigbee, ZWave and WiFi to be inherently unreliable. They provide no hard guarantees that a message will be routed. They just aren’t designed to do that.

If you want a hard guarantee I think that has to be implemented in a controller device that has the processing power to implement logic that provides the guarantee. I’m trying to make HA that device.

No t wont, but then I did specify:

If you don’t have your home assistant server (or any server for that matter) on a UPS (or battery power bank in the case of a home assistant pi) - you’re going to have a bad time.

Rubbish.

You can do this to include that case:

trigger:
  - platform: sun
    event: sunrise
  - platform: homeassistant
    event: start
conditions:
  - condition: state
    entity_id: lights.your_lights
    state: 'on'
  - condition: state
    entity_id: sun.sun
    state: above_horizon
action:
  - while: "{{ is_state('light.your_lights', 'on') and repeat.index < 20 }}"
    sequence:
      - service: light.turn_off
        entity_id: light.your_lights
      - delay:
          seconds: 30
  - condition: state
    entity_id: light.your_lights
    state: 'on'
  - service: notify.notify
    data:
      message: "Could not turn off the lights."

I guess a more radical proposal would be for HA to have an enforcing mode, where it has its own stored state representing what is supposed to be true, detects variance from the desired state, and corrects it.

In that case automation would not operate on the external device directly, but would update HA’s internal state. The change to internal state would they trigger an update to the actual device, and HA would keep trying until that state was achieved.

But that’s a big change. I could do something nearly as effective but with a much more modest change to HA if I could have more powerful time patterns (ie, ranges).

That’s worse reliability than the X10 lighting I used for over a decade.

Most of my lighting switches are UPB which is proving itself to be extremely reliable in my home. It regularly turns on/off about 14 lights simultaneously. I also have several Philips Hue lights, which use ZigBee, and they also work reliably, as well as a few WiFi-based switches.

Basically, you have a marginal ZigBee network that needs correction. Your experiences with lousy reliability are symptoms of a problem and not reflections of the norm.

As for dealing with power failures, I installed a UPS many years ago to deal with short outages. Long outages are moot because without electricity, none of the gadgetry is controllable anyway.

You already have that ability as has been posted above several ways to accomplish it. And there’s no reason to change HA at all.

@swiftlyfalling’s first solution is the easiest but I would add a condition that the thing is not actually in the correct state before performing the action.

- alias: turn on the lights... FOR SURE
  trigger:
    platform: time_pattern
    minutes: "/5"
  condition:
    - condition: time
      after: "00:08:00"
      before: "10:00:00"
    - condition: state
      entity_id: light.your_light
      state: the_state_you_don't_want_the_light_to_be_in