Cheapest Energy Hours - Jinja macro for dynamic energy prices

Hi TheFes,

I did al the steps needed for installation and restart HA.
cheapest_energy_hours.jinja is located in in * /config/custom_templates
I also use the EntsoE integration. I use “sensor.steven_average_electricity_price_today”

Attributes for the sensor give me

state_class: measurement
prices_today:
  - time: '2023-10-19 00:00:00+02:00'
    price: 0.00544
  - time: '2023-10-19 01:00:00+02:00'
    price: -0.0032
  - time: '2023-10-19 02:00:00+02:00'
    price: -0.00393
  - time: '2023-10-19 03:00:00+02:00'
    price: 0.00031
  - time: '2023-10-19 04:00:00+02:00'
    price: -0.00214
  - time: '2023-10-19 05:00:00+02:00'
    price: 0.0065
  - time: '2023-10-19 06:00:00+02:00'
    price: 0.06553
  - time: '2023-10-19 07:00:00+02:00'
    price: 0.08791
  - time: '2023-10-19 08:00:00+02:00'
    price: 0.11521
  - time: '2023-10-19 09:00:00+02:00'
    price: 0.127
  - time: '2023-10-19 10:00:00+02:00'
    price: 0.1232
  - time: '2023-10-19 11:00:00+02:00'
    price: 0.12572
  - time: '2023-10-19 12:00:00+02:00'
    price: 0.12531
  - time: '2023-10-19 13:00:00+02:00'
    price: 0.12156
  - time: '2023-10-19 14:00:00+02:00'
    price: 0.11933
  - time: '2023-10-19 15:00:00+02:00'
    price: 0.11805
  - time: '2023-10-19 16:00:00+02:00'
    price: 0.12146
  - time: '2023-10-19 17:00:00+02:00'
    price: 0.14234
  - time: '2023-10-19 18:00:00+02:00'
    price: 0.14632
  - time: '2023-10-19 19:00:00+02:00'
    price: 0.14472
  - time: '2023-10-19 20:00:00+02:00'
    price: 0.1168
  - time: '2023-10-19 21:00:00+02:00'
    price: 0.09748
  - time: '2023-10-19 22:00:00+02:00'
    price: 0.10174
  - time: '2023-10-19 23:00:00+02:00'
    price: 0.08958
prices_tomorrow: []
prices:
  - time: '2023-10-18 00:00:00+02:00'
    price: 0.06433
  - time: '2023-10-18 01:00:00+02:00'
    price: 0.04301
  - time: '2023-10-18 02:00:00+02:00'
    price: 0.033
  - time: '2023-10-18 03:00:00+02:00'
    price: 0.01761
  - time: '2023-10-18 04:00:00+02:00'
    price: 0.00973
  - time: '2023-10-18 05:00:00+02:00'
    price: 0.01745
  - time: '2023-10-18 06:00:00+02:00'
    price: 0.05565
  - time: '2023-10-18 07:00:00+02:00'
    price: 0.08221
  - time: '2023-10-18 08:00:00+02:00'
    price: 0.12
  - time: '2023-10-18 09:00:00+02:00'
    price: 0.10571
  - time: '2023-10-18 10:00:00+02:00'
    price: 0.09008
  - time: '2023-10-18 11:00:00+02:00'
    price: 0.07692
  - time: '2023-10-18 12:00:00+02:00'
    price: 0.07009
  - time: '2023-10-18 13:00:00+02:00'
    price: 0.064
  - time: '2023-10-18 14:00:00+02:00'
    price: 0.061
  - time: '2023-10-18 15:00:00+02:00'
    price: 0.04898
  - time: '2023-10-18 16:00:00+02:00'
    price: 0.05099
  - time: '2023-10-18 17:00:00+02:00'
    price: 0.07788
  - time: '2023-10-18 18:00:00+02:00'
    price: 0.09273
  - time: '2023-10-18 19:00:00+02:00'
    price: 0.10917
  - time: '2023-10-18 20:00:00+02:00'
    price: 0.09844
  - time: '2023-10-18 21:00:00+02:00'
    price: 0.08666
  - time: '2023-10-18 22:00:00+02:00'
    price: 0.0661
  - time: '2023-10-18 23:00:00+02:00'
    price: 0.0351
  - time: '2023-10-19 00:00:00+02:00'
    price: 0.00544
  - time: '2023-10-19 01:00:00+02:00'
    price: -0.0032
  - time: '2023-10-19 02:00:00+02:00'
    price: -0.00393
  - time: '2023-10-19 03:00:00+02:00'
    price: 0.00031
  - time: '2023-10-19 04:00:00+02:00'
    price: -0.00214
  - time: '2023-10-19 05:00:00+02:00'
    price: 0.0065
  - time: '2023-10-19 06:00:00+02:00'
    price: 0.06553
  - time: '2023-10-19 07:00:00+02:00'
    price: 0.08791
  - time: '2023-10-19 08:00:00+02:00'
    price: 0.11521
  - time: '2023-10-19 09:00:00+02:00'
    price: 0.127
  - time: '2023-10-19 10:00:00+02:00'
    price: 0.1232
  - time: '2023-10-19 11:00:00+02:00'
    price: 0.12572
  - time: '2023-10-19 12:00:00+02:00'
    price: 0.12531
  - time: '2023-10-19 13:00:00+02:00'
    price: 0.12156
  - time: '2023-10-19 14:00:00+02:00'
    price: 0.11933
  - time: '2023-10-19 15:00:00+02:00'
    price: 0.11805
  - time: '2023-10-19 16:00:00+02:00'
    price: 0.12146
  - time: '2023-10-19 17:00:00+02:00'
    price: 0.14234
  - time: '2023-10-19 18:00:00+02:00'
    price: 0.14632
  - time: '2023-10-19 19:00:00+02:00'
    price: 0.14472
  - time: '2023-10-19 20:00:00+02:00'
    price: 0.1168
  - time: '2023-10-19 21:00:00+02:00'
    price: 0.09748
  - time: '2023-10-19 22:00:00+02:00'
    price: 0.10174
  - time: '2023-10-19 23:00:00+02:00'
    price: 0.08958
unit_of_measurement: €/kWh
attribution: Data provided by ENTSO-e Transparency Platform
device_class: monetary
icon: mdi:currency-eur
friendly_name: Average electricity price today (steven)

In the template editor I throw

{% from "cheapest_energy_hours.jinja" import cheapest_energy_hours %}
{{ cheapest_energy_hours("sensor.steven_average_electricity_price_today", hours=3) }}

and give me this error :
TemplateSyntaxError: expected token ‘,’, got ‘plot_attr’

Would you like to take a look at this?
Many thanks !

looks like I might screwed something up in the last update. Let me check.

Thanks :+1:

found it, fixed in 3.0.3

Note that you also need to provide the attr_today, price_key and value_key like I did here:
https://community.home-assistant.io/t/cheapest-energy-hours-jinja-macro-for-dynamic-energy-prices/569370/5

If you want to use the data of tomorrow, you also need to provide attr_tomorrow

Wow, you’re fast. I’ll try it right away when V3.0.3 is available :+1:

You can press the Update information button in 3 dot menu in HACS to immediately get the update message for the new version

These works as expected

{% from 'cheapest_energy_hours.jinja' import cheapest_energy_hours %}
{{ cheapest_energy_hours('sensor.steven_average_electricity_price_today', attr_today='prices_today', hours=1, lowest=False, mode='max', value_key='price', time_key='time') }}

{% from 'cheapest_energy_hours.jinja' import cheapest_energy_hours %}
{{ cheapest_energy_hours('sensor.steven_average_electricity_price_today', attr_today='prices_today', hours=1, lowest=True, mode='max', value_key='price', time_key='time') }}

Result

0.14632
-0.00393

This one is not working

{% from 'cheapest_energy_hours.jinja' import cheapest_energy_hours %}
{{ cheapest_energy_hours("sensor.steven_average_electricity_price_today",attr_today='prices_today', hours=3,  lowest=True, mode='max', value_key='price', time_format="time24") }}

Result

1 error: Time key "start" not found in data

Would you like to take a look at this?
Many thanks !

That’s because you removed the time_key='time' parameter.
That makes it default to "start"

I’m also confused why you want to provide a time_format parameter there, as mode='max' will not return a datetime

Oops, my mistake
let’s say if I want to get the start datetime of an a 3 hour time block when the energy price is lowest, for today would this one be correct?

{% from 'cheapest_energy_hours.jinja' import cheapest_energy_hours %}
{{ cheapest_energy_hours("sensor.steven_average_electricity_price_today", attr_today='prices_today', hours=3, time_key='time') }}

Now you removed value_key='price'
But besides that, yes

Sorry, confused with the given nordpool examples.
I have it working.Thanks

Much respect for this fantastic jinja macro.I have it up and running. Thank you TheFes!

2 Likes

@HAstevo
Would you mind sharing the code?

@TheFes

Hello,

I use your jinja script for my energy data from EnergyZero.
This works fine, except when I request the time I get the UTC (English) time instead of the local (Dutch) time.

{% from 'cheapest_energy_hours.jinja' import cheapest_energy_hours %}
{{ cheapest_energy_hours('sensor.electricity_price_today', attr_today='Prices', value_key='price', time_key='readingDate', hours=1, lowest='true', mode='time_min', time_format='time24') }}

This results in 11:00 instead of 13:00
How can I adjust that?

unit_of_measurement: EUR/kWh
friendly_name: Electricity price today
Prices:
   -price: 0.06
     readingDate: '2023-10-20T22:00:00Z'
   -price: 0.05
     readingDate: '2023-10-20T23:00:00Z'
   -price: 0.05
     readingDate: '2023-10-21T00:00:00Z'
   -price: 0.04
     readingDate: '2023-10-21T01:00:00Z'
   -price: 0.05
     readingDate: '2023-10-21T02:00:00Z'
   -price: 0.05
     readingDate: '2023-10-21T03:00:00Z'
   -price: 0.05
     readingDate: '2023-10-21T04:00:00Z'
   -price: 0.07
     readingDate: '2023-10-21T05:00:00Z'
   -price: 0.08
     readingDate: '2023-10-21T06:00:00Z'
   -price: 0.07
     readingDate: '2023-10-21T07:00:00Z'
   -price: 0.05
     readingDate: '2023-10-21T08:00:00Z'
   -price: 0.04
     readingDate: '2023-10-21T09:00:00Z'
   -price: 0.02
     readingDate: '2023-10-21T10:00:00Z'
   -price: 0.01
     readingDate: '2023-10-21T11:00:00Z'
   -price: 0.01
     readingDate: '2023-10-21T12:00:00Z'
   -price: 0.04
     readingDate: '2023-10-21T13:00:00Z'
   -price: 0.07
     readingDate: '2023-10-21T14:00:00Z'
   -price: 0.11
     readingDate: '2023-10-21T15:00:00Z'
   -price: 0.13
     readingDate: '2023-10-21T16:00:00Z'
   -price: 0.13
     readingDate: '2023-10-21T17:00:00Z'
   -price: 0.11
     readingDate: '2023-10-21T18:00:00Z'
   -price: 0.06
     readingDate: '2023-10-21T19:00:00Z'
   -price: 0.06
     readingDate: '2023-10-21T20:00:00Z'
   -price: 0.05
     readingDate: '2023-10-21T21:00:00Z'
average: 0.06

I’ll update the macro to update the datetimes to local time
For now you can use

{% from 'cheapest_energy_hours.jinja' import cheapest_energy_hours %}
{{ (cheapest_energy_hours('sensor.electricity_price_today', attr_today='Prices', value_key='price', time_key='readingDate', hours=1, lowest='true', mode='time_min') | as_datetime | as_local).strftime('%H:%M') }}
1 Like

Wow, this is an answer at the speed of light.
A small addition and the problem is solved.
If only life were that simple.
Thank you.

@complex1 or you update to 3.0.4 which I just released :slight_smile:

See this post on how to ask HACS to update the information so you immediately get the update.

1 Like

Sure, here you go

type: custom:stack-in-card
mode: vertical
title: Tarieven vandaag
cards:
  - type: custom:layout-card
    layout_type: grid
    layout:
      grid-template-columns: 33% 66%
      grid-gap: 0px;
    cards:
      - type: custom:mushroom-template-card
        primary: Huidig
        secondary: ''
        card_mod:
          style: |
            ha-card {
              --card-primary-font-size: 16px;
              --card-primary-font-weight: normal;
              background: none;
              height: 30px !important;
            }
      - type: custom:mushroom-template-card
        primary: >-
          {{ states("sensor.steven_current_electricity_market_price") | round(3)
          }} om {{ states("sensor.time")  }} u.
        secondary: null
        card_mod:
          style: |
            mushroom-state-item {
                text-align: center;
                transform: translateX(0%);
              }
            ha-card {
              --card-primary-font-size: 16px;
              --card-primary-font-weight: 400;
              height: 30px !important;
            }
  - type: custom:mushroom-template-card
    card_mod:
      style: |
        ha-card {
          margin: -25px 0px 0px 6px;
          border-bottom: solid 2px rgba(var(--rgb-disabled), 0.2);
        }
  - type: custom:layout-card
    layout_type: grid
    layout:
      grid-template-columns: 33% 66%
      grid-gap: 0px;
    cards:
      - type: custom:mushroom-template-card
        primary: Volgend
        secondary: ''
        card_mod:
          style: |
            ha-card {
              --card-primary-font-size: 16px;
              --card-primary-font-weight: normal;
              background: none;
              height: 30px !important;
            }
      - type: custom:mushroom-template-card
        primary: >-
          {{ states("sensor.steven_next_hour_electricity_market_price") |
          round(3) }} om 0{{ states("sensor.uur_volgend_tarief")  }}.00 u.
        secondary: null
        card_mod:
          style: |
            mushroom-state-item {
                text-align: center;
                transform: translateX(0%);
              }
            ha-card {
              --card-primary-font-size: 16px;
              --card-primary-font-weight: 400;
              height: 30px !important;
            }
  - type: custom:mushroom-template-card
    card_mod:
      style: |
        ha-card {
          margin: -25px 0px 0px 6px;
          border-bottom: solid 2px rgba(var(--rgb-disabled), 0.2);
        }
  - type: custom:layout-card
    layout_type: grid
    layout:
      grid-template-columns: 33% 66%
      grid-gap: 0px;
    cards:
      - type: custom:mushroom-template-card
        primary: Laagste
        secondary: ''
        card_mod:
          style: |
            ha-card {
              --card-primary-font-size: 16px;
              --card-primary-font-weight: normal;
              background: none;
              height: 30px !important;
            }
      - type: custom:mushroom-template-card
        primary: '{{ states("sensor.jinja_goedkoopste_uur_vandaag")  }}              '
        secondary: null
        card_mod:
          style: |
            mushroom-state-item {
                text-align: center;
                transform: translateX(0%);
              }
            ha-card {
              --card-primary-font-size: 16px;
              --card-primary-font-weight: 400;
              height: 30px !important;
            }
  - type: custom:mushroom-template-card
    card_mod:
      style: |
        ha-card {
          margin: -25px 0px 0px 6px;
          border-bottom: solid 2px rgba(var(--rgb-disabled), 0.2);
        }
  - type: custom:layout-card
    layout_type: grid
    layout:
      grid-template-columns: 33% 66%
      grid-gap: 0px;
    cards:
      - type: custom:mushroom-template-card
        primary: Hoogste
        secondary: ''
        card_mod:
          style: |
            ha-card {
              --card-primary-font-size: 16px;
              --card-primary-font-weight: normal;
              background: none;
              height: 30px !important;
            }
      - type: custom:mushroom-template-card
        primary: '{{ states("sensor.jinja_duurste_uur_vandaag") }} '
        secondary: null
        card_mod:
          style: |
            mushroom-state-item {
                text-align: center;
                transform: translateX(0%);
              }
            ha-card {
              --ha-card-box-shadow: 0px;
              --card-primary-font-size: 16px;
              --card-primary-font-weight: 400;
              height: 30px !important;
            }
  - type: custom:mushroom-template-card
    card_mod:
      style: |
        ha-card {
          margin: -25px 0px 0px 6px;
          border-bottom: solid 2px rgba(var(--rgb-disabled), 0.2);
        }
  - type: custom:layout-card
    layout_type: grid
    layout:
      grid-template-columns: 74% 26%
      grid-gap: 0px;
    cards:
      - type: custom:mushroom-template-card
        primary: Starttijd goedkoopste 2 uur blok
        secondary: ''
        card_mod:
          style: |
            ha-card {
              --card-primary-font-size: 16px;
              --card-primary-font-weight: normal;
              background: none;
              height: 30px !important;
            }
      - type: custom:mushroom-template-card
        primary: '{{ states("sensor.jinja_start_goedkoopste_2ublok_vandaag") }} u. '
        secondary: null
        card_mod:
          style: |
            mushroom-state-item {
                text-align: center;
                transform: translateX(0%);
              }
            ha-card {
              --card-primary-font-size: 16px;
              --card-primary-font-weight: 400;
              height: 30px !important;
            }
  - type: custom:gap-card
    height: 20
  - square: false
    type: grid
    columns: 3
    cards:
      - type: custom:gap-card
        height: 20
      - show_name: true
        name: Lijst Dynamic
        show_icon: false
        show_state: false
        type: button
        entity: select.inverter_operation_mode
        card_mod:
          style: |
            ha-card { 
              background: rgba(150,150,150, 0.1) !important ;
              box-shadow: 1px 4px 4px 2px rgba(0,0,0,0.4) !important;
              border-radius: 10px !important;
              margin-left: auto;
              margin-right: auto;
            }
        tap_action:
          action: fire-dom-event
          browser_mod:
            service: browser_mod.popup
            data:
              card_mod:
                style:
                  ha-dialog$: |
                    div.mdc-dialog__scrim {
                      backdrop-filter: blur(50px) !important;
                      -webkit-backdrop-filter: blur(50px) !important;
                      background: var(--background-image);
                      background-blend-mode: overlay;
                    }
              title: Aankoop
              content:
                type: vertical-stack
                cards:
                  - type: vertical-stack
                    cards:
                      - type: markdown
                        content: >-
                          {%- set prices =
                          state_attr('sensor.steven_average_electricity_price_today','prices_today')
                          -%} <table width=80%><td align=left><b><font
                          size="4">Uur </td><td align=cent><b><font
                          size="4">Prijs</td></tr> {%- for price in prices -%}
                            <tr><td align=left>{{as_timestamp(price.time,0)|timestamp_custom('%H:%M')}}</td></td><td align=>{{'%0.3f' % price.price}}</td></tr>
                          {%- endfor -%} </table>
                        title: Vandaag
                        card_mod:
                          style: |
                            :host {
                              --masonry-view-card-margin: -12px 8px 0px 8px; 
                              --ha-card-border-width: 0;
                              #--ha-card-background: none;
                              --ha-card-box-shadow: 0;
                            }
                            .: |
                            .card-content {
                              padding: 0;
                            }
      - type: custom:gap-card
        height: 20
      - type: custom:gap-card
        height: 20

1 Like

Thank you. :+1:

Hi TheFes,

Update to 3.0.4 gives me

list object has no element 1

Would you like to take a look at this?
Thanks