Cheapest Energy Hours - Jinja macro for dynamic energy prices

I will create this sensor myself and see what’s going wrong.
Those templates can be simplified as well though

I’m curious what the outcome is.

I would greatly appreciate any help to make the template simpler.

Under which integration do you have any config for this sensor?

Oh nevermind, it’s under sensor.

The error is in the attribute finder, but it works if you provide it as a parameter

{%- set sensor = "sensor.electricity_price_2days" -%}
{% from "cheapest_energy_hours.jinja" import cheapest_energy_hours %}
{{ cheapest_energy_hours(sensor=sensor, attr_all='Prices', hours=2, start="22:00", end="08:00", include_tomorrow=true) }}

How did you find this?
Can I do this myself?

Thank you.

I read the documentation, but the default string for attr_all is ‘prices’ (without capital P)

Yes, but your attribute is Prices with a capital P.
The settings should reflect your sensor.

@complex1

I wanted to look at this issue again today, but I can’t reproduce it anymore. The template now works for me without the need to provide the attribute.
But it is more resource friendly to provide it, to avoid that the macro has to spend time and processing power on values you already know.

This would be the most efficient way to call the macro:

{%- set sensor = "sensor.electricity_price_2days" -%}
{% from "cheapest_energy_hours.jinja" import cheapest_energy_hours %}
{{ cheapest_energy_hours(sensor=sensor, attr_all='Prices', time_key='readingDate', hours=2, start="22:00", end="08:00", include_tomorrow=true) }}

Also see: source sensor parameters

Regarding the rest sensor, I simplified the templates to this:

sensor:
  # "Elektriciteit (uur) prijs vandaag en morgen" bevat de stroomkosten (inkoopprijs)
  - platform: rest
    name: Electricity price 2days
    unique_id: energyzero_electricity_hour_price_2days
    resource: https://api.energyzero.nl/v1/energyprices
    unit_of_measurement: "EUR/kWh"
    scan_interval: 3600
    value_template: "{{ value_json.Prices[now().hour].price|float(0) }}"
    json_attributes:
      - Prices
    # Set start_date to 00:00:00 today and end_date to 23:59:59 tomorrow and convert to UTC
    params:
      fromDate: >
        {{ today_at().astimezone(utcnow().tzinfo).isoformat() | replace('+00:00', 'Z') }}
      tillDate: >
        {{ (today_at() + timedelta(days=2, seconds=-1)).astimezone(utcnow().tzinfo).isoformat() | replace('+00:00', 'Z') }}
      interval: 4
      usageType: 1
      inclBtw: true

After I added this parameter the error message disappeared and it worked properly.
I will also add the parameter time_key='readingDate' to reduce processing time.

Thank you very much for the time you spent to simplifying the rest sensor.
I assume that the summer/winter time changeover is also included?

If I have any questions regarding the changes or other comments, I will post them.
But for now, many thanks for the help.

Please try again late this afternoon (when rates for tomorrow are known).
I’m almost certain the issue will occur again.

UPDATE

v5.0.2

:sparkles: IMPROVEMENTS

  • Avoid unneeded use of attribute finder

:bug: BUG FIXES

  • fix issue with attribute finder for sensors with one attribute provide data for today and tomorrow
  • fix issue where macro would return a generic jinja error, instead of an error response provided by the macro

What’s Changed

Full Changelog: Comparing v5.0.1...v5.0.2 · TheFes/cheapest-energy-hours · GitHub

You were right, but it should be fixed now in v5.0.2

Although it’s still better to provide the attribute data and key data yourself, as I did in my last example :slight_smile:

Yes, of course I will, otherwise it would have been a waste of effort.

Thank you for the update.

Dear forum
Merry Christmas to You all! I would really like to use this integration, but apparently my lack of knowledge is limiting me. I’ve set up a template triggered sensor and I get the correct time of the cheapest hour, but adding any of the output modes results in errors. Probably because it’s kind of trial and error on my part.

I would appreciate if someone took the time to enlighten me. I’ve now read the documentation several times and I can’t find the link between the chapters “Advanced mode” and “Output modes”. Where do I add the output mode? Can I get the result of “mode = all” as attributes in a sensor?

Here is my sensor as it is right now.

template:
  - trigger:
      - platform: time_pattern
        minutes: "/1"
    sensor:
      - name: cheap_energy_2_15_today_tomorrow
        state: >
          {% from 'cheapest_energy_hours.jinja' import cheapest_energy_hours %}
          {% set output = cheapest_energy_hours (
          sensor = 'sensor.energi_data_service',
          attr_today = 'raw_today',
          attr_tomorrow = 'raw_tomorrow',
          time_key = 'hour',
          value_key = 'price',
          hours = 2.25,
          include_tomorrow = true,
          look_ahead = true
          ) %}
            {{ output }}

…and the result.

I’d appriciate any input to point me in the right direction.

You are now getting the start time for the cheapest consecutive block of 2.25 hours today or tomorrow for the times which are later than the current time. I don’t see any errors.

So if this is for example a dishwasher, which will run for 2.25 hours, it will be cheapest to turn it on at 1:45 this night.

If you want the results of mode='all' in an attribute, you will have to define that attribute as well in your template sensor.

BTW, there is no use for your current trigger here, you are just adding extra load to your system to run this every minute, it will not change the result. It will already change when the state of your source sensor changes.

I’ve now read the documentation several times and I can’t find the link between the chapters “Advanced mode” and “Output modes”. Where do I add the output mode? Can I get the result of “mode = all” as attributes in a sensor?

I don’t really understand what you mean here, the Advanced mode is for data input. It is used to add weights to your data. If your appliance uses very much power in the first and last half hour, but not so much during the 2 hours in between, you can add that information. It might use a bit higher price for the 2 hours in between, to have the most power usage in the least expensive hours.

The Output part defines what information you want to receive, do you want to have the start time, or the end time of the time-block, or the prices in that time block?

If you can tell me your goal, I can help you better :slight_smile:

BTW as raw_today and raw_tomorrow are used by default, you don’t have to set them in your template.

@TheFes Thanks. Yes I get this default result. My challange is that I don’t know where I should add “mode = all”. Adding it after “look_ahead” results in template error. This is also what I mean about my lack of understanding between the two chapters. I’ve been fighting with getting it to work and realised that maybe I didn’t get a result, because the input entity I am referring to only updates at 13:00 and 00:00.

For now my goal was just to get some information for a dashboard, but I’m working on an automation for charging my PV battery.

Does it also give an error with that output mode if you test it in developer tools > template?

Can you let me know if it works there, and if not, what the error is

Tried again to add “mode = average” after look_ahead. Got the correct value as state (my previous issue must have been triggering).
Adding mode = 'all'after look_ahead works in the Template. but gives me an “unknown” result in states. I realise state can only have a single value - so how do I go about adding all the values as attributes in a sensor?

template:
  - trigger:
      - platform: time_pattern
        minutes: "/1"
    sensor:
      - name: cheap_energy_2_15_today_tomorrow
        state: >
          {% from 'cheapest_energy_hours.jinja' import cheapest_energy_hours %}
          {% set output = cheapest_energy_hours (
          sensor = 'sensor.energi_data_service',
          attr_today = 'raw_today',
          attr_tomorrow = 'raw_tomorrow',
          time_key = 'hour',
          value_key = 'price',
          hours = 2.25,
          include_tomorrow = true,
          look_ahead = true,
          mode = 'all'
          ) %}
            {{ output }}

A state can be only 255 characters, and this will be more than that.

But again, what it your goal here. What are you trying to achieve?

First of all I’m trying to understand how to get information from the integration. I have a couple of use cases in mind at the moment. 1) Card in view with the one, two and three cheapest hours for today and tomorrow, with the average price for those timeslots. 2) Using it as a trigger in automation to charge PV battery under certain circumstances (SOC / consumption and PV forcast).

PS: The reason I mentioned that I can’t understand the documentation is because I don’t know how I get an output like the one in the example.