WTH Why isn’t there a date range or month condition?

I use Seasons and Time of Day for conditions in various places and it’s a super quick way of making sure automations only run when you want. But it’s not quite flexible enough. If I wanted a condition for the month of October or something on a specific date, it requires the very unpleasing task of messing with date/time templates.

One specific example is how lighting automations change throughout the year. (I live at 60deg North). I have some that kick in in Autumn but that’s a little too early for some lights which I only want to kick in now (October to Feb).

Always happy to be corrected, but the presence of a date range condition would provide a very easy and more flexible solution.

Do calendar-based State conditions not meet that need?

Fair point - i suppose they could but it’s not something I’ve experimented with since they were introduced recently. My understanding is that calendar states are more designed for ‘do something before/when an event starts’. Not really suitable for situations when you only want an automation to run if a date range applies. I’d have to create an event for e.g. October to February every year?? It seems a bit unnecessary to create calendar events for something like this.

I agree the Time Condition should support dates and months in addition to its current support for time and day of the week.

Until it’s enhanced (if ever), is there a particular template you require?

For example, if you need the month of October.

{{ now().month == 10 }}

For a numerically continuous range of months, May to August:

{{ 5 <= now().month <= 8 }}

For a numerically non-continuous range of months, October to February

{{ now().month in [10, 11, 12, 1, 2] }}

For a specific date

{{ now().date() | string == '2022-10-04' }}

For a month and day for any year

{{ (now().month, now().day) == (12, 25) }}

For a range of days for any year (this won’t work if the range spans December 31st)

{{ (12, 1) <= (now().month, now().day) <= (12, 25) }}
19 Likes

Thanks for this. Nice to have a cheat sheet. I have done some reasonably advanced stuff with date/time in the past - it would just be much nicer to have a simple UI way of setting date/month conditions.

1 Like

With the holiday season coming up, this feels like a themed feature for the time!

1 Like

If the last one does span the year, you can use or

{% set today= (now().month, now().day) %}
{{ (12, 1) <= today or today  <= (1, 25) }}

or not

{{ not ((1, 25) < (now().month, now().day) < (12, 1)) }}

Yes. I was trying to avoid posting examples that might scare away potential users who describe it as “the very unpleasing task of messing with date/time templates”. :wink:

Even the last example I posted probably looks gnarly for a new user unfamiliar with Jinja2 syntax, tuples, etc.

I don’t mind dabbling with a bit of Jinja, but in the interest of streamlining experiences I think this idea is an easy win.

And yes, festive theme would be appropriate! I currently have a light sequence triggered by motion for Christmas day morning, but others might appreciate an easy way to automate their thousands of WLEDs for the month of December!!

1 Like

Sorry to bump this if I should’ve just created a new post.

How did you end up adding the conditions? I’m trying to automate the HVAC based on dates from cool, heat_cool, and heat with set temps, etc. Anyways, I get a template error in the logs and it all fails out.

“could not be validated and has been disabled: invalid template (TemplateSyntaxError: expected token ‘)’, got ‘integer’) for dictionary value @ data[‘condition’][0][‘conditions’][1][‘conditions’][0][‘value_template’]. Got None”

Here are the three templates I’m using:

    - condition: template
      value_template: "{{ (06, 10) <= (now().month, now().day) <= (09, 15) }}"   # jun 10 through sep 15
      - condition: template
        value_template: "{{ (04, 10) <= (now().month, now().day) <= (06, 9) }}"   # apr 10 through jun 6
      - condition: template
        value_template: "{{ (09, 16) <= (now().month, now().day) <= (11, 15) }}"   # sep 16 through nov 15 
      - condition: template
        value_template: "{{ (01, 1) <= (now().month, now().day) <= (04, 9) }}" # jan 1 through april 9
      - condition: template
        value_template: "{{ (11, 16) <= (now().month, now().day) <= (12, 31) }}"  # nov 16 through dec 31

You can’t use inline comments like that with yaml.

e.g.
good:

      # jun 10 through sep 15
    - condition: template
      value_template: "{{ (06, 10) <= (now().month, now().day) <= (09, 15) }}"

Apologies, I added the inline comments prior to posting to detail what I was attempting date wise. They aren’t in use yaml file.

Delete the leading zeros.

Brilliant! No errors. Amused it was that simple. Thank you both for commenting. Now I’ll go into the shadows.

Maybe this can be useful to others, so allow me to share my own way to write a template condition on dates of the year.

{{ "04-01" <= now().strftime('%m-%d') <= "11-10" }}

This might not be the most readable, but it is kind of readable, and avoids being a long line, which helps a lot with readability.

Here’s the breakdown:

  • now().strftime('%m-%d') formats today’s date to month (double digits) and day of the month (double digits), separated by a hyphen
  • because this snippet relies on string (alphanumeric) ordering, it is crucial to:
    • have the month (biggest unit) first
    • use a leading zero (if you don’t, then April’s “4” is greater than November’s “11” using alphanumeric ordering)
  • it is possible to surround an expression with two lower than (or equal) sign to test that the expression belongs to the interval (I think this is a Python feature)
  • here, my condition can be described as “today is between April 1st and November 10th, both dates included”

For a “winter” interval (that crosses the new year), you could modify the pattern above in two ways:

  • negate the expression with a not, saying “today is not in this interval”:
    {{ not "04-01" <= now().strftime('%m-%d') <= "11-10" }}
    
  • use an or operator to say “today is before X or today is after Y”:
    {{ now().strftime('%m-%d') < "04-01" or now().strftime('%m-%d') > "11-10" }}
    
    (you can also set a variable first to avoid repetition:)
    {% set today = now().strftime('%m-%d') %}
    {{ today < "04-01" or today > "11-10" }}
    
2 Likes

I have an event where I do intermittent fasting and a special health regiment of supplementscalled 11 day jumpstart.

I agree, date range would be nice.

I have an event that is 11 days and happens every single month except Decmber.

I’d like to set up automations during this time to remind me to get up and move every 45 minutes, a schedule of drinking water every hour, and taking my supplements in the morning and before I go to bed. And everything stops after 6pm. I’m going to re-read this thread and see if I can at least come up with a flowsheet…Thanks for the solid examples…

Just use a schedule entity

The OP makes a good point. It’s all possible with templates but a UI method would be way better for many people. I’m using a condition where I need to check if the time is before or after a time and date gotten from a frontend input, which really is more complicated than I think is pleasant for users who aren’t used to writing code.

Use a schedule entity……

Maybe I am missing something, but do you mean a schedule helper? A schedule helper knows about days of the week but not date, right? Or is there another thing called a schedule entity? If I want to do the following thing:
a) Select a specific time and date from the frontend, in a method that can be adjusted by users that do not have access to the ‘settings’ menu
b) Check in an automation whether it is before or after this specific time and date

And do all this without going into Yaml code, but purely from the UI, is this possible currently? I tried but it didn’t work, which is expected because according to the documentation, the ‘time’ condition ignores the date. So I made a template for it, which required some re-casting of the datetime because of time zone not being included in the selector.
I thought about possibly creating a local calendar specifically for this purpose. It might work but it seemed like overkill so I didn’t. But for non-coding people it might be the better option?