Any good ideas are welcome. Nordpool Energy Price per hour

Not really 100 procent my self yet, working progress :grinning: and learning my self on how to (also new to HA)

Thank you for replying! Then we might cooperate to make something good of it! I’m also pretty new to the more advanced programming of this type of functions. If you are OK with it, please share what you have this far and maybe I can continue to build on it and share back in turn :slight_smile:

Hi there

The only thing I have so far is that I shall have a look at state based templates Template - Home Assistant

And that I can do a call that trigger to set values:

- service: input_number.set_value
	data:
	  entity_id: input_number.ev_car
	  value: Mustang
      entity_id: input_number.ev_charge_to
	  value: 90
      entity_id: input_number.ev_bat_size
	  value: 89

And then I can set tresholds from lovelance

And from here I’m lost

Thank you for the additional information! “Fun” fact: when changing from normal time to daylight saving time as we do tonight, the template script wont work as there are no price for electricity for hour 3 tomorrow… I will continue to experiment when we have valid data to work with again :slight_smile:

Made this, think it works, it will only use price for tomorrow if valid:

          {% if state_attr('nordpool_kwh_dk1_dkk_2_095_025', 'tomorrow') == none %}
            {% set interval_end_tomorrow = 0 -%}
            {% set interval_end_hour = 23 -%}
          {% else %}
            {% set interval_end_tomorrow = 1 -%}
            {% set interval_end_hour = states('input_number.mini_charger_ready_tomorrow') | int  -%}

And the use a helper to set the time when it must be ready to morrow (made in configuration.yaml)

input_number:
  mini_charger_ready_tomorrow:
    name: Mini klar kl 
    icon: mdi:clock-check
    mode: slider
    initial: 7
    step: 1
    min: 5
    max: 23
    unit_of_measurement: Kl

I also created a automation there starts the charger when power is under a certan cheap price, and sends a notify if the car is home and not plugedin. This automation waits 55 minutes if second car is low (under 70%). We have 2 EV car’s one with 33kWh and one with 89kWh battery and loadbalancing on the chargers. 1 car chargning = 11kW, 2 cars 5.5kW each

alias: EV MUSTANG - kWh < "input_number.ev_charge_start_always" kr start ladning.
description: ''
trigger:
  - platform: numeric_state
    entity_id: sensor.nordpool_kwh_dk1_dkk_2_095_025
    below: input_number.ev_charge_start_always
condition: []
action:
  - wait_for_trigger:
      - platform: numeric_state
        entity_id: sensor.cooper_se_charging_level_hv
        above: '70'
    timeout: '00:55:00'
  - choose:
      - conditions:
          - condition: state
            entity_id: sensor.mustang_gt_easee_status
            state: disconnected
          - condition: device
            device_id: 364f4a1d24de696091ae6d4f79a873d8
            domain: device_tracker
            entity_id: device_tracker.fordpass_tracker
            type: is_home
        sequence:
          - device_id: 7ceb2dfb14ec52a79e1eef4d4540ce9c
            domain: mobile_app
            type: notify
            message: >-
              Sæt ladekabel i, der er billig strøm nu, du har {{
              states('sensor.ford_hv_battery_percent') }}% batteri, kWh koster:
              {{ states('sensor.nordpool_kwh_dk1_dkk_2_095_025') }} kr.
            title: Kastanily - Mustang
      - conditions:
          - condition: state
            entity_id: sensor.mustang_gt_easee_status
            state: awaiting_start
        sequence:
          - device_id: 7ceb2dfb14ec52a79e1eef4d4540ce9c
            domain: mobile_app
            type: notify
            message: >-
              Lader nu: {{ states('sensor.ford_hv_battery_percent') }}% batteri
              og kWh koster: {{ states('sensor.nordpool_kwh_dk1_dkk_2_095_025')
              }} kr.
            title: Kastaniely - Mustang
    default: []
  - service: easee.resume
    data:
      charger_id: XXXXXXX
  - service: input_boolean.turn_on
    data: {}
    target:
      entity_id: input_boolean.mustang_charger_status_charge
mode: restart

And then the car is pluged in

alias: EV MUSTANG - Ladekabel sat i
description: ''
trigger:
  - platform: state
    entity_id: sensor.mustang_gt_easee_status
    from: disconnected
    for:
      hours: 0
      minutes: 0
      seconds: 0
condition: []
action:
  - choose:
      - conditions:
          - condition: state
            entity_id: input_boolean.mustang_charger_status_charge
            state: 'off'
        sequence:
          - service: easee.pause
            data:
              charger_id: XXXXXX
    default:
      - device_id: 7ceb2dfb14ec52a79e1eef4d4540ce9c
        domain: mobile_app
        type: notify
        message: Ladekabel i
mode: restart

So when the car is plugedin the script puts the charger into pause if it has not been told to charge from the “EV MUSTANG - kWh < “input_number.ev_charge_start_always” kr start ladning” (by using a helper to keep track of charge on or off

and then eletricity prices gets above helper value it stops charge and sends notification:

alias: EV MUSTANG - KWh > "input_number.ev_charge_start_always" kr stop ladning
description: ''
trigger:
  - platform: numeric_state
    entity_id: sensor.nordpool_kwh_dk1_dkk_2_095_025
    above: input_number.ev_charge_start_always
condition:
  - condition: state
    entity_id: sensor.mustang_gt_easee_status
    state: charging
action:
  - device_id: 7ceb2dfb14ec52a79e1eef4d4540ce9c
    domain: mobile_app
    type: notify
    message: >-
      Stopper ladning, kWh kr: {{
      states.sensor.nordpool_kwh_dk1_dkk_2_095_025.attributes.current_price
      }}kr, ladet til: {{ states('sensor.ford_hv_battery_percent')  }}%
    title: Kastaniely - Mustang
  - service: easee.pause
    data:
      charger_id: XXXXXX
  - service: input_boolean.turn_off
    data: {}
    target:
      entity_id: input_boolean.mustang_charger_status_charge
mode: restart

The above makes sure that when electrity is cheap we charge, no matter what nedded

Now I have also made some template sensors that constant gives me these information:

Those are I planing to use from automation

in pseudocode:

if mustang < AA% and kWh awg price is < xx charge to BB%
if mustang < CC% and kWh awg price is < yy charge to DD%
if mustang < EE% and kWh awg price is < zz charge to EE%

Next look into my calender to morrow and se how far do I have to go and then make sure there is enough power for that (I work out from home)

So basicly I want to charge, under these conditions:
CAR 1:
!. Eletricity price cheap
2. If not enough charge for what I have to drive to morrow

CAR 2:
!. Eletricity price cheap
2. If not enough charge for what I have to drive to morrow

Also needs to think in load sharing in the Easee charger if both have to charge same day…

So I have a long way to go yet:-)

2 Likes

Run into a problem:

How do i write to a helper from template?

        {# Car and charger settings #}
        {% set ev_car_battery_size =  89 -%}
        {% set interval_end_hour = (states('input_number.mustang_charger_ready_tomorrow') | int) -%}
        {% set ev_car_end_charge_level  = (states('input_number.mustang_charger_stop_state') | int)-%}
        {% set ev_car_chargestate = (states('sensor.ford_hv_battery_percent') | float)  %}
        {# define charge spped (11kW or 5.5kW in my setup, if both cars is chargning #}
        {% set ev_car_battery_charge_speed = (states('input_number.mustang_charger_speed') | float) %}
        {# Nordpool eletricity price settings #}
        {% set today_price = states.sensor.nordpool_kwh_dk1_dkk_2_095_025.attributes.today %}
        {% set tomorrow_price = states.sensor.nordpool_kwh_dk1_dkk_2_095_025.attributes.tomorrow %}
        {# Charger efficinty 90% in my case#}
        {% set ev_car_battery_charge_speed = ev_car_battery_charge_speed * 0.9 %}
        {% set today_price_from_now = today_price[now().hour:] -%} 
        {% set all_price = today_price + tomorrow_price -%}

        {% set interval_start_tomorrow = 0 -%}
        {% set interval_start_hour =  now().hour + 1 -%}
        {% set interval_end_tomorrow = 1 -%}
        {# test if valid prices tomorrow? #}
        {% if tomorrow_price[0] == None %}
          {% set interval_end_tomorrow = 0 -%}
          {% set interval_end_hour = 23 -%}
        {% endif %}

        {% if ev_car_end_charge_level >= ev_car_chargestate -%}
          {% set ev_car_charge_kwh = (ev_car_battery_size / 100 * (ev_car_end_charge_level - ev_car_chargestate))  %}
          {% set ev_car_charge_time_min = ((ev_car_charge_kwh / ev_car_battery_charge_speed) * 60) | round(0) -%}
          {% set ev_car_charge_time_hour = (ev_car_charge_time_min / 60) |  round(0, 'ceil') %}
          {% set low_interval_length = ev_car_charge_time_hour -%}
          {% set interval_price = all_price[interval_start_hour + 24 * interval_start_tomorrow : interval_end_hour + 24 * interval_end_tomorrow] -%}
          {% set last_considered_interval_index = (interval_price | length) - low_interval_length + 1 -%}
          {% set ns = namespace(current_best_average=1000, current_best_index=-1) -%}  
          {% for price in interval_price[:last_considered_interval_index] -%}
            {% set current_average =  interval_price[loop.index0:loop.index0+low_interval_length] | average -%}
            {% if current_average < ns.current_best_average -%}
              {%-set ns.current_best_average = current_average -%}
              {% set ns.current_best_index = loop.index0 -%}
            {% endif -%}
          {% endfor -%}
          {%- set start_index = ns.current_best_index %}
          {%- set best_interval_price = interval_price[start_index:start_index + low_interval_length] %}
          {% set best_interval_start_hour =  24 * interval_start_tomorrow + interval_start_hour + start_index -%}
          {%- set best_interval_price = interval_price[start_index:start_index + low_interval_length] %}
          {% set ev_car_start_charge_datetime =  (now() + timedelta(hours=best_interval_start_hour - now().hour)) - timedelta(minutes = now().minute) %}
          {% set ev_car_stop_charge_datetime =  ev_car_start_charge_datetime + timedelta(minutes=ev_car_charge_time_min + 15) %}

        start_charger: {{ ev_car_start_charge_datetime.strftime('%Y-%m-%dT%H:%M') }}
        stop_charger : {{ ev_car_stop_charge_datetime.strftime('%Y-%m-%dT%H:%M') }}
        charge_time  : {{ ev_car_charge_time_hour - 1 }} time(r) og {{ ev_car_charge_time_min  % 60 }} min
        kWh_needed   : {{ ev_car_charge_kwh | round(1) }} kWh
        charge_price : {{ (ev_car_charge_kwh * (best_interval_price| average))| round(0, 'ceil') }} kr
        kwh_avg_price: {{ (best_interval_price| average)| round(2) }} kr
        {% else -%}
          0
        {% endif -%}

I want to set this helper to the load balancer from my charger?:

'input_number.mustang_charger_speed'
  - type: custom:config-template-card
    variables:
      threshold: states['sensor.electricity_price'].attributes.peak
      min_price: states['sensor.electricity_price'].attributes.min - 0.5
      max_price: states['sensor.electricity_price'].attributes.max
    entities:
      - sensor.electricity_price
    card:
        type: custom:apexcharts-card
        graph_span: 24h
        span:
          start: day
        all_series_config:
          stroke_width: 2
        header:
          show: true
          title: Electricity Price
          show_states: true
          colorize_states: true
        now:
          show: true
          color: white
          label: NOW
        experimental:
          color_threshold: true
        yaxis: # only 1 yaxis, no need for id or yaxis_id
          - min: ${min_price}
            # if the sensor doesn't go above 50, the max of the axis will be 50
            # else the max will be the maximum value of the sensor
            max: ${max_price}
            apex_config:
              tickAmount: 4
        series:
          - entity: sensor.electricity_price
            color: "#e57300"
            color_threshold:
              - value: 0
                color: "00cc00"
              - value: 2.8
                color: "#e57300"
            show:
              in_header: after_now
            data_generator: | 
              return entity.attributes.raw_today.map((entry) => {
                return [new Date(entry.start), entry.value];
              });  
            type: column
            offset: -30min

for future reference with the config template card, you can achive dynamic threshold

Are there any way to easily display average monthly prices on Nordpool?

2 Likes

So it seems that Nordpool changed something.

The webpage i have as a bookmark now says

Oops!

That page doesn’t seem to exist! Try to use the search bar at the top bar to find content you are looking for.

Also the integration says “Import error”

Maybe the nordpool integration needs a bit of love :slight_smile:

I’ve got an interesting situation.

I have 2 separate systems under same local network. Raspberry Pi 4 4GBs with HAOS + all the latest updates. Both have Norpool component installed from HACS and corresponding definitions in configuration.yaml. I believe there is also a graphical way of setting up them, but since I needed to do some testing with variables (mainky additional costs, precision etc.), I took the yaml route.

The 2 systems are coonnected with remote home asistant -integration.

Now, it seems that when both systems initialize during restart, they of course run the settings from the yaml. It looks like that running the yaml from either machine has an effect on the other one as well, that is, when restarting the other, the other one also initializes. I can see this from the fact that the entity (nordpool_kwh_fi_eur_4_095_024) set by Nordpool goes for brief to undefined or null etc. ( I do not recall what exatcly)

Also, the system does not seem to alwyas know, how it should apply the additional costs -setting.

When looking at core.config_entries at /config/.storage folder of Pi, I can see that it differs to config I have in yaml, most dominantly the additional cocts, which in configuration.yaml is

additional_costs: 0.0756372

but in core.config_entries it has the default setting:

            {
                "entry_id": "xxxxxxxxxxxxxxxxxxxxxxxxx",
                "version": 1,
                "domain": "nordpool",
                "title": "Nordpool",
                "data": {
                    "region": "FI",
                    "currency": "EUR",
                    "VAT": true,
                    "precision": 4,
                    "low_price_cutoff": 0.95,
                    "price_in_cents": true,
                    "price_type": "kWh",
                    "additional_costs": "{{0.0|float}}"
                },
                "options": {},
                "pref_disable_new_entities": false,
                "pref_disable_polling": false,
                "source": "user",
                "unique_id": null,
                "disabled_by": null
            },

I have in general not been messing around manually with core.config_entries due to it’s nature as a system -type of file

Q1: Is there a problem, when 2 separate systems from the same ip connects with the Nordpool component to their system? Can it cause some kind of confusion?

Q2: Should I do something (what?) with the obvious conflict between configyration.yaml and core.config_entries described above?

I am using this but today I updated apexcharts to version 2.0.1 and there is an error:

/// apexcharts-card version 2.0.1 
/// value.series[0] is not a ChartCardSeriesExternalConfig value.series[0].extend_to_end is extraneous value.series[0].extend_to_end is extraneous

any one an idea how to fix this?

Apexcharts changes: extend_to_end replaced by extend_to: , possible values are now and end.
Best, JR

Thanks Foxy. I change it to code below and I can see the graph again:

type: custom:apexcharts-card
hours_12: false
header:
  show: true
  title: Nordpool Prize -> 48 hours
  show_states: true
now:
  show: true
  color: '#ff0000'
  label: Now
graph_span: 2d
span:
  start: day
series:
  - entity: sensor.nordpool_kwh_oslo_nok_2_10_025
    name: Today
    unit: øre/kWh
    data_generator: |
      return entity.attributes.raw_today.map((entry) => {
        return [new Date(entry.start), entry.value * 100];
      });
    type: column
    show:
      legend_value: false
      in_header: false
    extend_to: end
  - entity: sensor.nordpool_kwh_oslo_nok_2_10_025
    name: Tomorrow
    unit: øre/kWh
    data_generator: |
      return entity.attributes.raw_tomorrow.map((entry) => {
        return [new Date(entry.start), entry.value * 100];
      });
    type: column
    show:
      legend_value: false
      in_header: false
3 Likes

Why did you update apexcards ?

Asking because in the last days my apexcharts with Nordpool prices for today and tomorrow has been very spotty.

Today i only have the price from 00-01 and on the card for tomorrow i have no prices at all.

If you experienced something similar and upgraded because of this i am very interested in knowing.

There are some issues with Nordpool, causing the next day not to be visible once in a while (restarting HA will get the correct prices but that is only a work around). This has nothing to do the the apexcards. I updated the apexcards because there was a new release, no other reason.

I have that problem also, did it resolve the issue with not showing the next day prices. ?

Nevermind, it seems there was probably some error in 2022.5, that they fixed in 2202.5.1, all is working again.

After updating to the latest May release Nordpool integration fails here.

Setup failed for custom integration nordpool: Unable to import component: cannot import name ‘EVENT_TIME_CHANGED’ from ‘homeassistant.const’ (/usr/src/homeassistant/homeassistant/const.py)

If anybody interested, I used some code from here and adjusted a bit for a better Apex Chart: [Question] Is it possible to get all 48 price values into one graph? · Issue #19 · custom-components/nordpool · GitHub

type: custom:apexcharts-card
graph_span: 48h
span:
  start: day
  offset: +0H
header:
  title: Electricity Price
  show: true
  show_states: false
  colorize_states: true
hours_12: false
stacked: false
experimental:
  color_threshold: true
all_series_config:
  show:
    legend_value: false
    datalabels: false
    extremas: true
    in_brush: true
  float_precision: 3
  type: area
  invert: false
  fill_raw: last
  color_threshold:
    - value: -1
      color: 1E90FF
    - value: 0.06
      color: '008000'
    - value: 0.19
      color: DAA520
    - value: 0.25
      color: FF0000
now:
  show: true
  label: Now
  color: red
series:
  - entity: sensor.nordpool_kwh_ee_eur_3_05_02
    name: Current day
    opacity: 0.7
    extend_to: false
    data_generator: |
      return entity.attributes.raw_today.map((start, index) => {
        return [new Date(start["start"]).getTime(), entity.attributes.raw_today[index]["value"]];
      });
  - entity: sensor.nordpool_kwh_ee_eur_3_05_02
    name: Tomorrow
    opacity: 0.5
    data_generator: |
      return entity.attributes.raw_tomorrow.map((start, index) => {

        return [new Date(start["start"]).getTime(), entity.attributes.raw_tomorrow[index]["value"]];

      });
apex_config:
  chart:
    height: 400px
    animations:
      enabled: true
      easing: easeinout
      speed: 800
      animateGradually:
        enabled: true
        delay: 150
  zoom:
    enabled: true
    type: x
    autoScaleYaxis: true
    zoomedArea:
      fill:
        color: '#90CAF9'
        opacity: 0.4
      stroke:
        color: '#0D47A1'
        opacity: 0.4
        width: 1
  legend:
    show: false
    floating: true
    offsetY: 25
  yaxis:
    opposite: false
    reversed: false
    logarithmic: false
    decimalsInFloat: 2
    labels:
      show: true
    tooltip:
      enabled: true
    crosshairs:
      show: true
  xaxis:
    labels:
      show: true
      rotate: -45
      rotateAlways: true
    logarithmic: true
  stroke:
    show: true
    curve: stepline
    lineCap: butt
    colors: undefined
  plotOptions:
    candlestick:
      colors:
        upward: '#00B746'
        downward: '#EF403C'
      wick:
        useFillColor: true
  markers:
    size: 1
  grid:
    show: true
    strokeDashArray: 1
    position: front
    xaxis:
      lines:
        show: true

Change the entity and play with color threshhold values to suit you.

20 Likes

thanks for this!

1 Like

Taking now a closer look on costs side of things.

From the component description:

   # The price result of the additional_costs template expects this additional cost to be in kWh and not cents as a float

Can someone please clarify, what this sentence means?

“…additional costs to be in kWh” means in other words that the units of currency and energy are the same (“currency = kWh”), which of course cannot be.

“…and not cents as a float” ???

Basically I need to to know, whether additionals costs are per kWhs or are they per hour type of things? The senttence above probably takes some position in that, but I don’t undestand the sentence at all.

I also need to insert both kWh -based and hour -based fixed costs, so how is this done?