Hourly electricity prices Netherlands

Ah, yes! Thanks

Small rewrite as the one posted above is in legacy notation. See Template - Home Assistant Great work though!

template:
  - sensor:
      - name: "ANWB all in electricity price"
        unit_of_measurement: "€/kWh"
        device_class: energy
        state: "{{ (states('sensor.energyzero_today_energy_current_hour_price') | float) + 0.17364 | round(4) }}"
  - sensor:
      - name: "ANWB all in gas price" 
        unit_of_measurement: "€/m³"
        device_class: energy
        state: "{{ (states('sensor.energyzero_today_gas_current_hour_price') | float) + 0.67541 | round(4) }}"

Hey,

does this mean that I could adjust all my sensors better?

like these:

  - platform: template
    sensors:
      energy_import_totaal_dag_kwh:
        unique_id: energy_in_total_daily_kwh
        friendly_name: "kWh afgenomen dag "
        value_template: "{{ (states('sensor.energy_import_t1_dag')|float + states('sensor.energy_import_t2_dag')|float)|round(3) }}"
        unit_of_measurement: "kWh"
  - platform: template
    sensors:
      energy_export_totaal_dag_kwh:
        unique_id: energy_out_total_daily_kwh
        friendly_name: "kWh geleverd dag"
        value_template: "{{ (states('sensor.energy_export_t1_dag')|float + states('sensor.energy_export_t2_dag')|float)|round(3) }}"
        unit_of_measurement: "kWh"

As far as I know, the rates provided by energyZero are in only 2 decimal places. It then makes no sense to add amounts with 5 decimal places and then round them to 4 decimal places.

I’m considering changing the way of querying data for gas in the python package. The code is designed to switch between retrieving old or new data on 06:00, but in practice it appears that this data is often online much later (for the range I defined).

If I change it, it would request data again from 00:00 to 23:59, but this may still not solve the problem. At midnight you only see the data until 06:00, if they are late publishing the new data and you request the data at 07:30, this would still cause problems because there is no new data for the rest of the day.

@klaasnicolaas, thanks for the integration, works like a charm!

Since I loved the apex graph, decided to make one with the rest api.
Problem arose to do the in line calculation of the total cost from the json.
Came up with the idea to use Node-Red to calculate the values and present it in json thus using it as a sort of proxy for the public api.

Result:

Should anyone want the node-red flow, let me know!

1 Like

Yes please :grinning:, the node-red flow would be very welcome.

At the moment, the data for actual gas prices is missing, this is going on for 2 days now. It’s also missing on the website of energyzero.nl. I have sent them a message, asking them to repair this.

Yes, it is a bit worthless that that data is not online, just like the gas data every morning. That is really a problem that could be improved on their side :thinking:

1 Like

yes please …interested.
thanks in advance

Right now I cannot use the generated data because they represent numbers that do not go near actual costs (that include taxes & ‘inkoopkosten’):

  • sensor.energyzero_today_energy_average_price plus all of the 24 attributes
  • sensor.energyzero_today_energy_current_hour_price
  • sensor.energyzero_today_energy_percentage_of_max
  • sensor.energyzero_today_energy_max_price
  • sensor.energyzero_today_energy_min_price
  • sensor.energyzero_today_energy_next_hour_price
  • sensor.energyzero_today_gas_current_hour_price
  • sensor.energyzero_today_gas_next_hour_price
    (and the same thing for the gas entities)

So I would have to create approx. 16 template sensors to get real values, values that can be used to in charts, energy dashboards, etc. One of the entities contains 24 attributes that also need to be updated, which is quite difficult.

Right now I’m still using the EntsoE plugin which has a has a price modifier modifier field in the configuration, containing:

{% set s = {"taxes": 0.143454} %}{{(current_price + s.taxes) | float}}

(tax value is without VAT)

Such a solution (or similar) would be great to see in the future. Keep up the good work!

What I have done myself is to add the additional costs in the data generator of apexcharts (with regard to the attributes data), with many entities that you mention I do not think it is necessary to make a template sensor for that. For example, that percentage entity probably won’t change :wink:

The percentage sensor is not in my list, even though that does make a difference:
With plugin data : current € 0.20, max € 0.40 = 50% of max
With taxes added: current € 0.38, max € 0.58 = 66% of max

a max price of €0.05 or €0.40 sounds very different from €0.23 or €0.58. This also applies to the current/next_hour prizes but also to the averages and min/max prizes.

But then, everyone uses data for different things :slight_smile:

Yes please, would be much appreciated

Sorry, took me a while to post it all:

  • Home Assistant uses a rest sensor to trigger the api lookup.
  • NodeRed edits the URL and uses gas or kwh lookup.
  • With the REST sensor the current taxes are provided to add to the lookup.
  • All values are stored in Influx DB and retreived by a grafana dashboard.

Same result as the apex chart but with taxes, current time, energieplafond (NL) and 48 hours lookup.
Based on these data I am now creating my own energy dashboard based on the usages of my devices on hourly, daily and monthly base. To bad the data is not available via HA, but this works for me.

Using this data, my wife and I receive a push notification each day telling me what the best hours are (5 minimum) and actionable notification to set the dishwasher and EV car to charge on these hours. Saves me a lot of money at the moment on my gas bill.

--- NodeRed
 
[{"id":"59ff2a1.fa600d4","type":"http in","z":"aae8250a.3fe838","name":"","url":"/anwbapi/","method":"get","upload":false,"swaggerDoc":"","x":120,"y":880,"wires":[["7da96eed0cd16c82","0fa651f42942cf5b"]]},{"id":"7da96eed0cd16c82","type":"change","z":"aae8250a.3fe838","name":"Set URL","rules":[{"t":"set","p":"url","pt":"msg","to":"\"https://api.energyzero.nl/v1/energyprices?fromDate=\"&payload.fromDate&\"&tillDate=\"&payload.tillDate&\"&interval=4&usageType=\"&payload.usageType&\"&inclBtw=true\"","tot":"jsonata"},{"t":"set","p":"cost","pt":"msg","to":"$number(payload.costs_to_add)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":840,"wires":[["818723db759e79d7"]]},{"id":"0fa651f42942cf5b","type":"debug","z":"aae8250a.3fe838","name":"debug 13","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":330,"y":920,"wires":[]},{"id":"818723db759e79d7","type":"http request","z":"aae8250a.3fe838","name":"Fetch prices","method":"GET","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":340,"y":880,"wires":[["c645058ec963fa50"]]},{"id":"c645058ec963fa50","type":"change","z":"aae8250a.3fe838","name":"Change Payload","rules":[{"t":"set","p":"payload_old","pt":"msg","to":"payload","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"payload.Prices","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":570,"y":800,"wires":[["ee7507ab1d6157b8"]]},{"id":"ee7507ab1d6157b8","type":"split","z":"aae8250a.3fe838","name":"Split Prices","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":790,"y":800,"wires":[["a15ac1021fc737e3"]]},{"id":"a15ac1021fc737e3","type":"change","z":"aae8250a.3fe838","name":"Add taxes and costs","rules":[{"t":"set","p":"payload.cost","pt":"msg","to":"payload.price","tot":"msg"},{"t":"set","p":"payload.price","pt":"msg","to":"payload.price+cost","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":590,"y":840,"wires":[["26562fbd38774ac6","cca5cff7d007aaa8"]]},{"id":"26562fbd38774ac6","type":"join","z":"aae8250a.3fe838","name":"Join Prices","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":560,"y":880,"wires":[["a00230546c6b7291"]]},{"id":"cca5cff7d007aaa8","type":"switch","z":"aae8250a.3fe838","name":"","property":"req.query.usageType","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"str"},{"t":"eq","v":"3","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":810,"y":840,"wires":[["da27a7ab5dbde5a4"],["2cd8ba88f3721334"]],"outputLabels":["stroom","gas"]},{"id":"a00230546c6b7291","type":"change","z":"aae8250a.3fe838","name":"Fix Payload","rules":[{"t":"move","p":"payload","pt":"msg","to":"payload.Prices","tot":"msg"},{"t":"move","p":"payload_old.intervalType","pt":"msg","to":"payload.intervalType","tot":"msg"},{"t":"move","p":"payload_old.fromDate","pt":"msg","to":"payload.fromDate","tot":"msg"},{"t":"move","p":"payload_old.tillDate","pt":"msg","to":"payload.tillDate","tot":"msg"},{"t":"delete","p":"payload_old","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":790,"y":880,"wires":[["d8445f2710e5c3a9"]]},{"id":"da27a7ab5dbde5a4","type":"change","z":"aae8250a.3fe838","name":"Create Influx Data","rules":[{"t":"set","p":"influx","pt":"msg","to":"[\t   [\t       {\t           \"cost\":$.payload.cost,\t           \"all_in\":$.payload.price,\t           \"time\":$toMillis($.payload.readingDate)\t       },\t       {\t           \"type\":\"contractprices\",\t           \"energytype\":\"kwh\",\t           \"supplier\":\"anwb\"\t       }\t   ]\t]","tot":"jsonata"},{"t":"delete","p":"payload","pt":"msg"},{"t":"set","p":"payload","pt":"msg","to":"influx","tot":"msg"},{"t":"set","p":"measurement","pt":"msg","to":"energy_prices","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":990,"y":800,"wires":[["fb833f72d3de149e","7f948dbac71fe0c9"]]},{"id":"2cd8ba88f3721334","type":"change","z":"aae8250a.3fe838","name":"Create Influx Data","rules":[{"t":"set","p":"influx","pt":"msg","to":"[\t   [\t       {\t           \"cost\":$.payload.cost,\t           \"all_in\":$.payload.price,\t           \"time\":$toMillis($.payload.readingDate)\t       },\t       {\t            \"type\":\"contractprices\",\t           \"energytype\":\"m3\",\t           \"supplier\":\"anwb\"\t       }\t   ]\t]","tot":"jsonata"},{"t":"delete","p":"payload","pt":"msg"},{"t":"set","p":"payload","pt":"msg","to":"influx","tot":"msg"},{"t":"set","p":"measurement","pt":"msg","to":"energy_prices","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":990,"y":840,"wires":[["fb833f72d3de149e","7f948dbac71fe0c9"]]},{"id":"d8445f2710e5c3a9","type":"http response","z":"aae8250a.3fe838","name":"Return Payload","statusCode":"","headers":{},"x":1000,"y":880,"wires":[]},{"id":"fb833f72d3de149e","type":"debug","z":"aae8250a.3fe838","name":"debug 12","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1220,"y":880,"wires":[]},{"id":"7f948dbac71fe0c9","type":"influxdb out","z":"aae8250a.3fe838","influxdb":"bffeb7df.cd3218","name":"Store data in Energie bucket","measurement":"","precision":"","retentionPolicy":"","database":"database","precisionV18FluxV20":"ms","retentionPolicyV18Flux":"","org":"Doverau","bucket":"Energie","x":1310,"y":810,"wires":[]},{"id":"bffeb7df.cd3218","type":"influxdb","hostname":"127.0.0.1","port":"8086","protocol":"http","database":"database","name":"InfluxDB","usetls":false,"tls":"","influxdbVersion":"2.0","url":"http://xxx:8086","rejectUnauthorized":false}]
 
--- Home Assistant
 
sensor:
- platform: rest
  unique_id: energyzero_prices_rest
  name: Gasprijs per uur 
  resource: http://xxx:1880/anwbapi
  scan_interval: 7200
  unit_of_measurement: "EUR/m³"
  value_template: >
     {{value_json.Prices[(now()+timedelta(hours=-1)).hour].price}}
  params:
    fromDate: >
      {{((now()- timedelta(days=2)).strftime('%Y-%m-%d')|as_datetime).isoformat()}}Z
    tillDate: >
      {{((now()+ timedelta(days=2)).strftime('%Y-%m-%d')|as_datetime).isoformat()}}Z
    interval: 4
    costs_to_add: >
      {{ ((states('input_number.nrg_m3_cost') | float/100) | round(5))+((states('input_number.nrg_m3_tax') | float/100) | round(5)) }}
    usageType: 3
    inclBtw: true
  json_attributes:
      - Prices
      - readingDate
- platform: rest
  unique_id: energyzero_powerprices_rest
  name: Stroomprijs per uur 
  resource: http://xxx:1880/anwbapi
  scan_interval: 7200
  unit_of_measurement: "EUR/kWh"
  value_template: >
      {{value_json.Prices[(now()+timedelta(hours=-1)).hour].price}}
  params:
    fromDate: >
      {{((now()- timedelta(days=2)).strftime('%Y-%m-%d')|as_datetime).isoformat()}}Z
    tillDate: >
      {{((now()+ timedelta(days=2)).strftime('%Y-%m-%d')|as_datetime).isoformat()}}Z
    interval: 4
    costs_to_add: >
      {{ ((states('input_number.nrg_kw_cost') | float/100) | round(5))+((states('input_number.nrg_kw_tax') | float/100) | round(5)) }}
    usageType: 1
    inclBtw: true
  json_attributes:
      - Prices
      - readingDate
 
--- Grafana
import "date"
from(bucket: "Energie")
  |> range(start: date.add(d:-24h,to:today()), stop: date.add(d:48h,to:today()))
  |> filter(fn: (r) => r["_measurement"] == "energy_prices")
  |> filter(fn: (r) => r["energytype"] == "kwh")
  |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)
  |> yield(name: "last")

3 Likes

Hello Ceriel, Can you tell me and others how to get the ANWB API for energy? address or link or email address.
you wrote: http://xxx:1880/anwbapi

I will try to make this work,
thanks,
Nico

I think that points to a local NodeRed (https://nodered.org/) instance, see config in first part of the code.

Sorry, totally missed the post. But yes, it is the local endpoint of NodeRed, the flow is the first line of my code block. You can import it and use it :).

I just installed the EnergyZero plugin as I’ll get ANWB energy soon.

A noob question: How do I change the “energyzero_today_energy_lowest_price_time” sensor so that is only shows the hours and minutes (not the day)? I’d like to use it in different cards / notifications.

I got this to work in Developer Tools Templates, but doesn’t work when I add it to my templates.yaml. Any idea what I’m doing wrong? Or is there a simpler way to achieve what I want?

- name: EnergyZero Low Price Time Fix
    unique_id: energyzero_lowprice_timefix
    icon: mdi:clock-in
    unit_of_measurement: "hours"
    state_class: measurement
    state: >
        {{ as_timestamp(states("sensor.energyzero_today_energy_lowest_price_time")) | timestamp_custom('%H:%M')  }}

Solve this problem by removing unit_of_measuerment and state_class