Time until 6am every day - free power

The electricity provider who I am with in Auckland, NZ - Electric Kiwi - gives me a completely free hour of power every single day at a time of my choosing during off peak.

To maximise this, appliances I can run with a timer (not smart appliances) need to be scheduled for when we are typically in bed. Currently this hour runs between 6am and 7am for us.

So, my requirement was a sensor which would tell me how many hours until the free hour each day, so that I can set the appliance start delay accordingly.

This was surprisingly difficult working with jinja and times (for a novice, albeit a novice with good ability in vbscript/powershell). I daresay it would have taken less than 4 hours if there wasn’t beer involved, but then again it wouldn’t have been as much fun.

Anyway, this maybe simple and trivial compared to most of the amazing stuff I see here, but at the end of the day it makes my life simpler, and I couldn’t google up an precooked example.

I spent a considerable time messing with to_timestamp() before resorting to just pulling out the hours and minutes as integers.

So here it is:

sensor free_hour:
  - platform: template
        friendly_name: "Free Hour"
        unique_id: 000006
        icon_template: mdi:timer-outline
        value_template: >-
          {% set freeHourStartTime = "06:00" %}
          {% set nowHour = now().hour %}
          {% set nowMins = now().minute %}
          {% set freeHourStartTimeObj = strptime(freeHourStartTime, "%H:%M") %}
          {% set startTimeInt = freeHourStartTimeObj.strftime("%H") | int %}
          {% if nowHour >= startTimeInt%}
            {% set timeUntilFreeHours = 24 + startTimeInt - nowHour -1 %}
          {% else %}
            {% set timeUntilFreeHours = startTimeInt - nowHour -1 %}
          {% endif %}
          {% set timeUntilFreeMins = 60 - nowMins %}
          {% set timeUntilFreeStr = timeUntilFreeHours ~ ":" ~ timeUntilFreeMins %}
          {{ strptime(timeUntilFreeStr,"%H:%M").strftime("%H:%M") }}

Could it be done with less lines? definitely but then it would be harder to understand.

Is there a better way to achieve the same thing? Would love to know!

I don’t know, but welcome to a fellow kiwi!

1 Like

It will probably need to be calibrated at daylight savings. (or perhaps that can be templated in too…?)

But this currently returns 21:10 in my timezone, and it’s 08:50

{{ (86400 - (now().timestamp() - 1621393200))  | timestamp_custom('%H:%M') }}

So it uses the day 86400, and calculates the difference in timestamp and this morning at 06:00 and uses the H:M of the result.

Edit and just to prove the point:

This is with the timestamp of one week ago:

{{ (86400 - (now().timestamp() - 1620788400))  | timestamp_custom('%H:%M') }}

This is probably with DST included…

{{ (86400 - (now().timestamp() - 1612152000 + (now().timetuple().tm_isdst *3600)))  | timestamp_custom('%H:%M') }}

Only the timestamp needs to be adjusted for your timezone.

Best I can do (most compact, rather than most readable!) without any hard-coded timestamps. Returns an h:mm-formatted string.

{% set freeHourStartTime = "06:00" %}
{% set next=now().replace(hour=(freeHourStartTime.split(':')[0])|int).replace(minute=(freeHourStartTime.split(':')[1])|int).replace(second=0) %}
{{ (((next+timedelta(days=1 if next<now() else 0))-now())|string).split(":")[0:2]|join(":") }}

It builds a datetime object for today at freeHourStartTime, and adds a day if that’s in the past.

Thank you guys so much, my brain is melting trying to work those out :smiley: I would never have gotten there myself!

1 Like