Change tariffs based on DST

template:
  - binary_sensor:
      - name: "Peak Rate"
        icon: "mdi:power-plug"
        state: >
          {% if states('binary_sensor.is_dst')|bool(0) %}
            {% set t_on = today_at('09:15') %}
            {% set t_off = today_at('00:15') + timedelta(hours=24) %}
          {% else %}
            {% set t_on = today_at('08:15') %}
            {% set t_off = today_at('23:15') %}
          {% endif %}
          {% set t_now = now() %}
          {{ t_on <= t_now <= t_off }}
1 Like

That did the trick thanks.

1 Like

@tom_l Just checked this and it should have flipped to off peak 5 mins ago but it didn’t.
Still on peak, the binary sensor
Assuming something up with {{ t_on <= t_now <= t_off }} which makes sense as this is not possible 08:15 <= 23:20 <= 23:15

Sure it is possible.

When now() is inside the range the statement is true and the sensor turns on, e.g.

08:15 <= 23:10 <= 23:15

When now() is outside the range the statement is false and the sensor turns off, e.g.

08:15 <= 23:20 <= 23:15

What does this show in the template editor:

{% set t_on = today_at('08:15') %}
{% set t_off = today_at('23:15') %}
{% set t_now = now() %}
{{ t_on <= t_now <= t_off }}

Logically yes but look, it’s True for some reason


The other bit does show correct, False

What does this show in the template editor:

{% set t_on = today_at('08:15') %}
{% set t_off = today_at('23:15') %}
{% set t_now = now() %}
{{ t_on }}
{{ t_now }}
{{ t_off }}
{{ t_on <= t_now <= t_off }}

I mean - I might be overlooking something here - but -
the is_dst binary sensor in the picture above is ON?

So the evaluation is the first time range - and not the second time range, in which case it is correctly saying that the statement is still true, because it is not after 00:15 yet?

1 Like

Yeah, you’re right.

Yes that sensor is on but I did change the bool from 0 to 1 here {% if states('binary_sensor.is_dst')|bool(0) %} and it still stays True so it’s like it’s always picking the first part of the if statement and never the else:


This should go to the else but it’s not, is the main if wrong?

That’s not what that does. the value you put after bool is telling Jinja what value to use if the value in th state cannot be converted to a boolean (eg if the value is unknown or unavailable). You could change it to 99 right now, it wouldn’t make a difference.

EDIT:
The first thing you need to do is figure out why the DST sensor thinks it is DST - because I pasted the code in to my template editor:

{{ now().timetuple().tm_isdst == 1 }}

and it returned False - as it should in the UK.

Ok I get it so the if means if it’s true.
Ok so that’s wrong then as mine is True

- name: "Is DST"
    state: "{{ now().timetuple().tm_isdst == 1 }}"

The DST sensor

Yes it’s the confusing naming scheme, we call it British Summer Time, but other parts of the world (like America) call it Daylight Savings Time (DST). DST is NOT Winter Time. Your sensor should be saying False.

I think I misunderstood what the bool(0) meant but also - name: "Is DST" state: "{{ now().timetuple().tm_isdst == 1 }}" is true for me and I’m just over the water in Ireland

1 Like

And Home Assistant is definitely set to the correct time zone in:

Settings > System > General ?

1 Like

GMT+00 Dublin yup.
I think this is the correct one now:

{% if states('binary_sensor.is_dst')|bool(1) %}
        {% set t_on = today_at('08:15') %}
        {% set t_off = today_at('23:15') %}        
      {% else %}
        {% set t_on = today_at('09:15') %}
        {% set t_off = today_at('00:15') + timedelta(hours=24) %}
      {% endif %}
      {% set t_now = now() %}
      {{ t_on <= t_now <= t_off }}

WTF even knows anymore image
Let’s hope they kill it next year

1 Like

It’s not “the correct one” - it’s a work around, but it’s not correct. Because any day now Home Assistant might realise it really is in Winter Time, and then your logic will be wrong again.

Though I have to say - I don’t understand why there is a need to figure out if it is DST or not, the whole point of today_at as was my understanding, is that it copes with timezones transparently - so today_at should work correctly regardless of whether we are an hour ahead of GMT or not, as long Home Assistant knows what the correct timezone is.

From the docs:

today_at(value) converts a string containing a military time format to a datetime object with today’s date in your time zone.

Well it matters as automations need to be ran at different times based on DST on or off.
I don’t want to be charging my batteries on peak times :sweat_smile:
And yeah sure can always update that manually twice a year but that’s not the point of HA
Need to figure out why it gives me bad data I agree
Sounds like I need to submit an issue and I have feeling it will break itself at this time:
image
Probably got it wrong an using the US date?

No you are missing what I am saying.

{% if states('binary_sensor.is_dst')|bool(1) %}
        {% set t_on = today_at('08:15') %}
        {% set t_off = today_at('23:15') %}        
      {% else %}
        {% set t_on = today_at('09:15') %}
        {% set t_off = today_at('00:15') + timedelta(hours=24) %}
      {% endif %}
      {% set t_now = now() %}
      {{ t_on <= t_now <= t_off }}

SHOULD be able to replaced with:

      {% set t_on = today_at('08:15') %}
      {% set t_off = today_at('23:15') %}        
      {% set t_now = now() %}
      {{ t_on <= t_now <= t_off }}

Home Assistant SHOULD correctly cope with that regardless of whether you are an hour ahead of GMT or not, that’s the whole point of the function - so that you don’t have to deal with timezones.

In Winter time:

t_on = 08:15+0000
t_off = 23:15+0000

and in Summer time:

t_on = 08:15+0100 (09:15)
t_off = 23:15+0100 (00:15)

Without you having to do anything. The only reason it is not working correctly for you now, is because Home Assistant believes that you are in DST (Summer Time).

My energy supplier does not change their peak/off-peak timers when DST starts and ends, so the times change by an hour.

To change it would mean reprogramming everyone’s meter twice a year.