Run an automation during a time period

Hi!.

I wrote a template condition that it’s working fine, but I would like to tweak it a little further so that it will run from last Saturday of October to the last Saturday of March instead of a fixed day. This is to detect the change from winter time to summer time.

{% set n = now() %}
{{ not (n.month == 10 and n.day >=24 or n.month == 3 and n.day <= 27) }}

Any inputs?

Thanks!

@123 and @jocnnor, will you be able to help me again? You are the two people I know that better control jinja and I’ve been stuck for a few days with this issue. I have been looking in the community but can’t find how to implement a solution.

Thanks a lot!

Probably this? Not sure. You can create this sensor and use it in your automations

sensor:
  - platform: template
    sensors:
      time_change:
        value_template: >
          {% if now().weekday() == 5 and now().month == 10 and now().day >= 25 %}
            winter_time
          {% elif  now().weekday() == 5 and now().month == 3 and now().day >= 25%}
            summer_time
          {% endif %}

I’m afraid it’s not working. The sensor reports unknown state.

I know how to do this but it’s involves calculations that are a bit messy in Jinja2 (neater in python).

What requires calculation is determining the date of the last given weekday (Monday to Sunday) for a given month (January to December) for a given year (the current year or some other year in the past or future).

In your case you’re asking for:

  • Date of the last Saturday in October this year
  • Date of the last Saturday in March next year

After we have calculated these two dates, let’s say we call them start_date and end_date, it’s easy to determine if the current date lies within the range or not.

{{ start_date <= now().date < end_date }}

Is this the approach that you had in mind? To calculate the starting and ending dates?


EDIT

I can show you the template to calculate the last given weekday of a given month but it may not help you meet your requirements. The challenge is that your date range spans from one year to another.

That little detail makes the calculation more challenging. Here’s what I mean:

In 2020, it calculates the last Saturday of October to be 2020-10-31. It calculates the last Saturday of March for the next year by adding 1 to the current year. It produces 2021-03-27.

So far it looks good, but what happens when the current year changes from 2020 to 2021? It’s now 2021-01-01, so it calculates the last Saturday of October to be 2021-10-30 and calculates the last Saturday of March for the next year by adding 1 to the current year 2021. It produces 2022-03-26.

So on 2021-01-01 it calculates the winter period as being 2021-10-30 to 2022-03-26. See the problem? 2021-01-01 is not within this freshly-calculated date range so the template will report it is now summer, not winter.

Oh, I see! So since one of the two periods expands over a year, the winter time will fail when the year changes.

In Spain, where I live, you can choose to have a discriminated electric price and the peak and valley hours change between winter and summer. Winter period starts with the winter savings hour change (last sunday of october) and ends with the summer hour change (last sunday of march) son that during winter time the valley hours are between 10pm to 12 am and in summer are between 11pm to 1pm.

I’m currently running an automation that starts different electric appliances when the valley period starts, but this period has to be adapted during the year for summer/winter.

I tried the season sensor, but it’s not exactly the period I’m looking for.

I won’t mind adjusting my template manually once every year, but if you can provide another solution it will help me learning other methods.

Kind regards!

The “other solution” is to simply create a Template Sensor with hard-coded start and end dates.

{{ 'winter' if as_timestamp('2020-10-31') <= now().timestamp() < as_timestamp('2021-03-27') else 'summer' }}

The drawback is, of course, that you have to manually change the dates every October (or at any time between early April and late October).


EDIT

If you are interested, here’s the calculation for determining the last given weekday in a given month. In this example, it calculates the last Saturday (isoweekday=6) in March (month=3) for next year (year=now().year+1)

{% set isoweekday = 6 %}
{% set month = 3 %}
{% set year = now().year + 1 %}

{% if month == 12 %}
  {% set month = 1 %}
  {% set year = year + 1 %}
{% else %}
  {% set month = month + 1 %}
{% endif %}

{% set lastday = now().date().replace(year=year).replace(month=month).replace(day=1) - timedelta(days=1) %}

{% set ns = namespace(lastday = lastday) %}
{% for i in range(1, 8) if ns.lastday.isoweekday() != isoweekday %}
  {% set ns.lastday = ns.lastday - timedelta(days=1) %}
{% endfor %}
{{ ns.lastday }}

Thanks a lot, @123! I guess I will adjust the dates every year, it’s not a big deal.

The sensor from @obaldius only reports unknown, because it’s not saturday and the “else” is missing. You could still use it though.

EDIT: Well, I was wrong. This only works on the exact days.
Anyway, you didn’t mention, what you are trying to achieve. In most cases it is more useful to use the sun elevation as a trigger, as this is smoother and represents the real world much better. DST is just a crutch :wink:

I just found this great line in the forum, that tells you, weather DST is active or not:

{{ now().timetuple().tm_isdst > 0 }}

You can put this in your automation or a template sensor.

I’m am using the following binary template sensor to determine if it summer time or not:

  - platform: template
    sensors:       
      summer_time:
        friendly_name: "Summer time"       
        value_template: "{{ now().timetuple().tm_isdst > 0 }}"

@dennis84de haha, the edit of my post and research took so long, that you found the same thing quicker :wink:

It’s explained in the sixth post. Electricity rates change on those two floating dates.

As for DST, the change occurs the day after, early Sunday, as opposed to the desired day of Saturday.

However, it may be ‘good enough’ for the purpose of knowing when the rates change.

1 Like

The template {{ now().timetuple().tm_isdst > 0 }} seems that will do the trick! Thanks a lot to everyone!