Car Charger - On Cheapest Hours From connecting time to preset run time

Hi HA Community.

I just connected my EV Charger to the system, and now i need it to charge only the cheapest hours a day, but it need to charge also if the price is below 3.5 DKK, then its still cheaper than gassoil.

In my setup i have created a sensor called " sensor.electricity_cost" where i have the attributes from nordpool incl. VAT, Tarrifs, elafgift, etc.

here i can see my attributes for every hour for today and tomorrow (tomorrow after 12:30).

then i have created five sensors for telling me if its:

  • Meget Dyrt (Very Expensive)
  • Dyrt (Expensive)
  • Normal (Normal)
  • Billigt (Cheap)
  • Meget Billigt (Very Cheap)

What i would suggest is to create a counter to tell me how many of the hours is “Meget Billigt”, “Billigt” and “Normal” between plug in and next day 06:00. then if there is four hours with “Meget Billigt” it only turns on when “Meget Billigt”, if there is not enough hours when “Meget Billigt” it has to use the hours where “Billigt” and so on.

How do i do create three sensors counting the three sensors between plug in time and 06:00 next day ?

here is my five sensors for which telling me the arrays of price:

here is a picture of the attributes and the main sensor for electricity price:

Here is my chart telling me the prices for today and tomorrow (tomorrow only after today 12:30)

Hope anyone here can help me out with this one.

BR
/Mike

To help us get you a solution and to save lots of typing, could you put this into Developer Tools / Template, and paste the result properly formatted as code please?

{{ state_attr('sensor.electricity_cost', 'today') }}
{{ state_attr('sensor.electricity_cost', 'tomorrow') }}

Of Course.

this:

{{ state_attr('sensor.electricity_cost', 'today') }}
{{ state_attr('sensor.electricity_cost', 'tomorrow') }}

make this list (Tomorrow is not there yet, but will apply at 12:30 today for tomorrow):

[
  [
    1676588400,
    1.54028125
  ],
  [
    1676592000,
    1.4852812499999999
  ],
  [
    1676595600,
    1.43228125
  ],
  [
    1676599200,
    1.37228125
  ],
  [
    1676602800,
    1.31528125
  ],
  [
    1676606400,
    1.37128125
  ],
  [
    1676610000,
    1.3982812500000001
  ],
  [
    1676613600,
    1.4462812500000002
  ],
  [
    1676617200,
    1.4462812500000002
  ],
  [
    1676620800,
    1.39928125
  ],
  [
    1676624400,
    1.38528125
  ],
  [
    1676628000,
    1.37128125
  ],
  [
    1676631600,
    1.37128125
  ],
  [
    1676635200,
    1.2002812500000002
  ],
  [
    1676638800,
    0.91228125
  ],
  [
    1676642400,
    0.88428125
  ],
  [
    1676646000,
    1.21928125
  ],
  [
    1676649600,
    2.0952375
  ],
  [
    1676653200,
    2.1942375
  ],
  [
    1676656800,
    2.1432374999999997
  ],
  [
    1676660400,
    1.12928125
  ],
  [
    1676664000,
    1.0072812500000001
  ],
  [
    1676667600,
    0.9792812500000001
  ],
  [
    1676671200,
    0.77728125
  ]
]

thank you

i dont know how, but if its possible to find the four chepest prices from plug in to X time.
that maybe would be better, but im new in this part of HA, so hope you can help me out i some way, to make the best charging by price of my electrical vhiecle.

BR
/Mike

Thanks for the data. What you want is possible — you just need to think through exactly what you’re trying to achieve, ask you have asked for lots of slightly different things. Have a play in Developer Tools / Template: here’s a starting point. I’ve copied in your data into the cl variable: you can substitute in state_attr('sensor.electricity_cost', 'today').

{% set cl = [[1676588400,1.54028125],[1676592000,1.4852812499999999],[1676595600,1.43228125],[1676599200,1.37228125],[1676602800,1.31528125],[1676606400,1.37128125],[1676610000,1.3982812500000001],[1676613600,1.4462812500000002],[1676617200,1.4462812500000002],[1676620800,1.39928125],[1676624400,1.38528125],[1676628000,1.37128125],[1676631600,1.37128125],[1676635200,1.2002812500000002],[1676638800,0.91228125],[1676642400,0.88428125],[1676646000,1.21928125],[1676649600,2.0952375],[1676653200,2.1942375],[1676656800,2.1432374999999997],[1676660400,1.12928125],[1676664000,1.0072812500000001],[1676667600,0.9792812500000001],[1676671200,0.77728125]] %}
{% set tom6 = (now().date()+timedelta(days=1))|as_timestamp+21600 %}
{{ cl|selectattr(0,'<=',tom6)|selectattr(1,'<=',0.918)|sort(attribute=1) }}

That sets the tom6 variable to tomorrow 06:00, and outputs any items from the list that is at or before that time and at or less than 0.918 cost, sorted by cost. I’ve hard-coded in the 0.918 number, but you can put states('sensor.meget_billigt')|float(0) or whatever you’ve called it.

That shows the sort of thing that’s possible. Experiment, and if you get stuck do ask for help here.

Okay, thank you !
I will try some different things.

But where do I have to add the date/time stamp for where I plugged in the cable for the car ?

BR
/Mike

You may be able to read that from your charger: I can certainly get it from my Pod Point. If you have to enter it manually, you can then add it to the selection template, such as:

{{ cl|selectattr(0,'>',state_attr('input_datetime.plugged_in','timestamp')
     |selectattr(0,'<=',tom6)
     |selectattr(1,'<=',0.918)
     |sort(attribute=1) }}

Linebreaks added for readability: template will work like that. In words, that template says:

Look through all items in the list
Select those with the first element (time) after your input time thing
Select those with the first element (time) before 0600 tomorrow
Select those with the second element (cost) less than or equal to 0.918
Sort by price

It returns a list of list items which you can then count.

Similar topic:

I will try this out and return on a solution :handshake:
Or if I run in to trouble, ask for more help.

Thank you

1 Like

So im a little struggeling again
here is my code from cheap and very cheap.

{% set el_price_today = state_attr('sensor.electricity_cost', 'today') %}
{% set tomorrow_6 = (now().date()+timedelta(days=1))|as_timestamp+21600 %}
{% set el_price_very_cheap = float(states('sensor.electricity_price_level_nordpool_very_cheap_day_avg')) %}
{{ el_price_today|selectattr(0,'<=',tomorrow_6)|selectattr(1,'<=',el_price_very_cheap)|sort(attribute=1) }}

{% set el_price_today = state_attr('sensor.electricity_cost', 'today') %}
{% set tomorrow_6 = (now().date()+timedelta(days=1))|as_timestamp+21600 %}
{% set el_price_cheap = float(states('sensor.electricity_price_level_nordpool_cheap_day_avg')) %}
{{ el_price_today|selectattr(0,'<=',tomorrow_6)|selectattr(1,'<=',el_price_cheap)|sort(attribute=1) }}

{% set time_connection = as_timestamp(states('sensor.charger_timestamp_config_response')) | timestamp_custom('%d %m %Y %H:%M') %}
{{time_connection}}

{% set el_price_today = state_attr('sensor.electricity_cost_ev_charger', 'today') %}
{% set tomorrow_6 = (time_connection) %}
{% set el_price_cheap = float(states('sensor.electricity_price_level_nordpool_very_cheap_day_avg')) %}
{{ el_price_today|selectattr(0,'<=',tomorrow_6)|selectattr(1,'<=',el_price_very_cheap)|sort(attribute=1) }}

output:

[[1676671200, 0.77728125], [1676642400, 0.88428125], [1676638800, 0.91228125]]




[[1676671200, 0.77728125], [1676642400, 0.88428125], [1676638800, 0.91228125], [1676667600, 0.9792812500000001], [1676664000, 1.0072812500000001], [1676660400, 1.12928125], [1676635200, 1.2002812500000002], [1676646000, 1.21928125]]


17 02 2023 21:37




[]

but i have now tried to change the format to string for the date/time as i need it to be showed readable.
how do i add the delta for 1 day and also add to be 6 am tomorrow ?

{% set el_price_today = state_attr('sensor.electricity_cost_ev_charger', 'today') %}
{% set tomorrow_6 = (time_connection) %}   **>-----------<**
{% set el_price_cheap = float(states('sensor.electricity_price_level_nordpool_very_cheap_day_avg')) %}
{{ el_price_today|selectattr(0,'<=',tomorrow_6)|selectattr(1,'<=',el_price_very_cheap)|sort(attribute=1) }}

then i think the start is good to go, then i need to know how can i add the four lowest values, to a sensor?

hope you can give me a little more to work with.

BR
/Mike

Okay. so now i have played a little more with the date time function and also set the whole price list as one.

BUT now im stuck. I need to create the list for the “cheapest_price_list_sorted” i just get empty square bracekts [].

and i also need to find a solution for the time. As it is right now, when we get to 00:00 then it will create a new list reasoned to calculated next day.

my code:

{% set now_time = as_timestamp(now()) | timestamp_custom("%d %m %Y %H %M") %}
{% set now_time_unix = as_timestamp(now()) %}
Now Time
{{ now_time }} #string format datetime
{{ now_time_unix }} #unix format datetime


{% set time_connection = as_timestamp(states('input_datetime.datetime_charger_change')) | timestamp_custom('%d %m %Y %H:%M') %}
{% set time_connection_unix = ((as_timestamp(time_connection[6:10] ~ "-" ~ time_connection[3:5] ~ "-" ~ time_connection[0:2] ~ time_connection[10:16]))) | round(0) %}
Time Connection
{{ time_connection }} #string format datetime
{{ time_connection_unix }} #unix format datetime

{% set hour_morning_next_day = '06:00' %}
{% set next_day = as_timestamp(now()+timedelta(days=1)) | timestamp_custom("%d %m %Y") %}
{% set next_day_and_hour = next_day + " " + hour_morning_next_day %}
{% set next_day_and_hour_unix = ((as_timestamp(next_day_and_hour[6:10] ~ "-" ~ next_day_and_hour[3:5] ~ "-" ~ next_day_and_hour[0:2] ~ next_day_and_hour[10:16]))) | round(0) %}
Tomorrow Time
{{ next_day }} #string format date
{{ hour_morning_next_day }} #string format time
{{ next_day_and_hour }} #string format datetime
{{ next_day_and_hour_unix }} #unix format datetime

{% set price_today = state_attr('sensor.electricity_cost', 'today') %}
{% set price_tomorrow = state_attr('sensor.electricity_cost', 'tomorrow') %}
{% set price_list = price_today + price_tomorrow %}

{% set cheapest_price_list = price_list|selectattr(0,'>=',time_connection_unix)|selectattr(0,'<=',next_day_and_hour_unix)|selectattr(1,'<=',3.5)|sort(attribute=1) %}
{{cheapest_price_list}}

{% set cheapest_price_list_sorted = namespace(prices=[]) %}
{% for i in cheapest_price_list %}
{{ cheapest_price_list_sorted.prices }}
{% endfor %}

result:

**Now Time**
19 02 2023 21 01 #string format datetime
1676836860.473437 #unix format datetime

**Time Connection**
19 02 2023 16:48 #string format datetime
1676821680 #unix format datetime

**Tomorrow Time**
20 02 2023 #string format date
06:00 #string format time
20 02 2023 06:00 #string format datetime
1676869200 #unix format datetime

**Cheapest List**
[[1676862000, 0.8422812500000001], [1676858400, 0.88728125], [1676865600, 0.9262812500000001], [1676854800, 1.02528125], [1676851200, 1.04628125], [1676869200, 1.24328125], [1676847600, 1.3052812500000002], [1676844000, 1.3782812500000001], [1676840400, 1.39528125], [1676836800, 1.45128125], [1676833200, 1.46828125], [1676829600, 2.2902375], [1676822400, 2.3292374999999996], [1676826000, 2.3442375]]

**Cheapest List Sorted**

[]

[]

[]

[]

[]

[]

[]

[]

[]

[]

[]

[]

[]

[]

hope you can help me out

BR
/Mike

Could you please show me the content of this price_list variable?

Code:

{% set price_today = state_attr('sensor.electricity_cost', 'today') %}
{% set price_tomorrow = state_attr('sensor.electricity_cost', 'tomorrow') %}
{% set price_list = price_today + price_tomorrow %}
{{ price_list }}

Result:

[[1676761200, 1.58528125], [1676764800, 1.54028125], [1676768400, 1.49728125], [1676772000, 1.43628125], [1676775600, 1.43228125], [1676779200, 1.4812812499999999], [1676782800, 1.48728125], [1676786400, 1.57428125], [1676790000, 1.6302812500000001], [1676793600, 1.67228125], [1676797200, 1.54728125], [1676800800, 1.51028125], [1676804400, 1.46528125], [1676808000, 1.38928125], [1676811600, 1.37928125], [1676815200, 1.42328125], [1676818800, 1.47628125], [1676822400, 2.3292374999999996], [1676826000, 2.3442375], [1676829600, 2.2902375], [1676833200, 1.46828125], [1676836800, 1.45128125], [1676840400, 1.39528125], [1676844000, 1.3782812500000001], [1676847600, 1.3052812500000002], [1676851200, 1.04628125], [1676854800, 1.02528125], [1676858400, 0.88728125], [1676862000, 0.8422812500000001], [1676865600, 0.9262812500000001], [1676869200, 1.24328125], [1676872800, 1.29828125], [1676876400, 1.27628125], [1676880000, 1.0352812500000002], [1676883600, 0.9612812500000001], [1676887200, 0.79328125], [1676890800, 0.79228125], [1676894400, 0.77528125], [1676898000, 0.9572812500000001], [1676901600, 1.05828125], [1676905200, 1.10228125], [1676908800, 2.2352375], [1676912400, 2.1862375], [1676916000, 2.1552375], [1676919600, 1.36528125], [1676923200, 1.33928125], [1676926800, 1.3562812499999999], [1676930400, 1.20928125]]

Is this a template sensor? Could you please share it’s yaml?

You are loosing the key names somewhere, I’m trying to find out, so your life will be much easier.

Sure.

here it is:

- sensor:
    - name: "Electricity Cost"
      unique_id: electricity_cost
      device_class: monetary
      unit_of_measurement: "DKK"
      state: >
        {{ (1.25 * float(states('sensor.eloverblik_tariff_sum'))) + float(states('sensor.nordpool_kwh_dk1_dkk_3_10_025')) }}
      attributes:
        today: >
          {%- if state_attr('sensor.eloverblik_tariff_sum', 'hourly') and state_attr('sensor.nordpool_kwh_dk1_dkk_3_10_025', 'raw_today') -%}
            {%- set ns = namespace (prices=[]) -%}
            {%- for item in state_attr('sensor.nordpool_kwh_dk1_dkk_3_10_025', 'raw_today') if item is defined -%}
              {%- set tarif = 1.25 * float(state_attr('sensor.eloverblik_tariff_sum', 'hourly')[loop.index0]) -%}
              {%- set price = item.value + tarif -%}
              {%- set hour = as_timestamp(item.start) | int -%}
              {%- set ns.prices = ns.prices + [[hour, price]] -%}
            {%- endfor -%}
            {{ ns.prices }}
          {%- endif -%}
        tomorrow: >
          {%- if state_attr('sensor.eloverblik_tariff_sum', 'hourly') and state_attr('sensor.nordpool_kwh_dk1_dkk_3_10_025', 'raw_tomorrow') -%}
            {%- set ns = namespace (prices=[]) -%}
            {%- for item in state_attr('sensor.nordpool_kwh_dk1_dkk_3_10_025', 'raw_tomorrow') if item is defined -%}
              {%- set tarif = 1.25 * float(state_attr('sensor.eloverblik_tariff_sum', 'hourly')[loop.index0]) -%}
              {%- set price = item.value + tarif -%}
              {%- set hour = as_timestamp(item.start) | int -%}
              {%- set ns.prices = ns.prices + [[hour, price]] -%}
            {%- endfor -%}
            {{ ns.prices }}
          {%- endif %}

What is this sensor?

In Denmark we pay for different extra cost to get the electricty distributed, and this is what we call nettariff so I need this one added to the nordpool prices to get the right price

1 Like

This should work:

{{ cheapest_price_list | sort(1) }}

But again, by losing the key names you make your coding much harder to understand and maybe more fragile for changes in the data format…

I will take a look later on a way to improve the electricity cost sensor in order to keep the keys, ok?

i dont get it ?
how do i get the list by:

{{ cheapest_price_list | sort(1) }}

result:

[[1676869200, 1.24328125], [1676865600, 0.9262812500000001], [1676862000, 0.8422812500000001], [1676858400, 0.88728125], [1676854800, 1.02528125], [1676851200, 1.04628125], [1676847600, 1.3052812500000002], [1676844000, 1.3782812500000001], [1676840400, 1.39528125], [1676836800, 1.45128125], [1676833200, 1.46828125], [1676829600, 2.2902375], [1676826000, 2.3442375], [1676822400, 2.3292374999999996]]

what i need to know is the cheapest hours from plugged in to next morning 6.
so i can create a trigger for my charger to start at the hours. when the battery is not full.

so for now i just need to create sensors or varibles for every hours ( 4 hors for now as my car take 4 hours to fully charge).

how do i make four sensors ? out of this list ?

Take a look at this an maybe you can play with yourself in order to make your keys on the electricity price sensor, so you can use key names instead of column numbers in your filters:

{%- set raw_today = state_attr('sensor.nordpool_kwh_dk1_dkk_3_10_025', 'raw_today') %}
Original prices: {{ raw_today | map(attribute='value') | list }}
{%- set ns = namespace(prices=[]) %}
{%- for item in raw_today %}
  {%- set new_entry = {
    'start': item.start,
    'value': item.value,
    'new_value': (item.value * 1.25) | round(3) }
  %}
  {%- set ns.prices = ns.prices + [ new_entry ] %} 
{%- endfor %}
New prices: {{ ns.prices | map(attribute='new_value') | list }}