Bringing electricity information from eloverblik.dk and energidataservice.dk into Openhab

Great work, and thanks for sharing.

I can add that I’m working on something similar - complimentary, not conflicting. :slight_smile: My first step was creating the dishwasher rule you mentioned - using the HTTP binding for fetching the data.

In last weekend I decided to take this a step further, so I started working on next step which is a binding for fetching the data. This is intended to replace the HTTP binding usage in my rule as well as the direct HTTP calls in your rules for Energi Data Service. This will have the following benefits (when completed):

  • Unified and reusable interface to the data to be consumed by rules.
  • Logic for making as few calls as possible and get data as fast as possible.
  • Error handling (retry policies).
  • Actions for common calculations to be used by rules.

The work can be tracked here:

I have also been playing with the eloverblik.dk API in Postman, and was able to pull interesting data like you have also shown here. I switched focus for a moment because my initial interest was getting electricity meter data, which I in the meantime found a better solution for:
https://techblog.vindvejr.dk/?p=523

However, with the new tariff models introduced this month, eloverblik.dk is again interesting and needed for calculating the gross cost taking everything into consideration. So when my current Energi Data Service is a little bit more evolved, I plan to proceed and create a similar binding for eloverblik.dk.

The next steps that could be interesting would be to have a look at openHAB itself and come up with a proposal for an energy API in core, so that bindings could implement external services and expose the data to core in a unified way, i.e. through some common interfaces.

This way rules could potentially interact with different underlying services in a common way. Similarly, common calculations could be implemented just once in core.

Obviously this require a good amount of work in order to discuss, design and implement this. Some initial thoughts can be found here:

2 Likes

Hi Jacob,

Excellent initiative and I’d gladly join you and attempt to help. I of course agree a binding is best. I actually struggled with the HTTP binding and some jython scripting before i realized their limitations and going for actions - i just could not figure out the handover of the access token for eloverblik without a variable to store into. My biggest issue is that i know very little java - python is much easier for me. I almost switched to HA because of that… I don’t know how useful i can be on the writing of the binding but i can test :).

I also saw your Omnipower solution - that is my priority No1 when i move to my new house on Feb 1st :slight_smile: . I think the only thing i don’t like about that solution is the ESP based bridge but i can see how that is just easy to implement so I’ll probably do the same as you. Any hints as to what to tell N1 would be welcome - last time i talked to them they did not know what i was talking about.

I will read the threads you posted and try the binding you have already to give you feedback. As initial thought i can say that I think you can stay with energidataservice.dk alone as i was able to map all data from eloverblik.dk to this dataset: ENERGI DATA SERVICE . The main issue is to get your filters right and eloverblik.dk has that for free. So from user point of view it will be either:

  • get 4-5 values for GLN/tarif type etc and use only energidataservice.dk
    OR
  • use eloverblik.dk with token and metering point for the state and local network company charges (as i did in my scripts) and then spot prices from energidataservice.dk as you have also done.

The main reason to connect to eloverblik.dk beyond the filtered charges is the metering data. I checked Grafana and there you can actually store a variable key and handover the access token. So for just pulling data and displaying (like in watts.dk) grafana would be fine i think - have not actually implemented it yet. The binding would be needed for all the calculations, which i cannot currently see an easy way to implement in grafana.

Finally on the topic of core/openhab feature - i know nothing about that - i trust you will come up with something meaningful. :slight_smile: Just keep in mind I might be putting solar panels next summer :slight_smile: .

Cheers

Curious, which problem do you see in the ESP-based solution?

You can use this form:

You need to provide your meter number and mention that you need the GPK 60 and GPK 61 keys, and probably also that you’ll be needing push, so this should be activated on your meter. They will usually get back to you within a few working days. I believe it was only in December that N1 became capable of providing these keys and activating push. I don’t know all the details, perhaps they needed to update the firmware, or maybe that were just not internally ready to handle this.

It’s wireless (in general i prefer cable for everything) and judging by the few other ESPs i have in the house not a very reliable one. I also run tasmota on few and i keep having issues. I know it is not a popular opinion but it is my experience. I am not a pro but i am also not a complete newby so if it does take an absolute pro to get them to be reliable then they are not for me. But i do recognize the enormous community around them and the many projects they enable so more power to them - if i can avoid them i will but if not then so be it - i will use them.

Thanks a lot! Did you investigate the now discontinued Kamstrup HAN module?

I also prefer cabling in general. In this case I can live with a Wi-Fi solution, since it’s very low bandwidth and it’s close to my access point and packet loss is not critical since data is sent every 10 seconds. It also saves some power by not using a port on my switch. :slight_smile:

So far the solution seems very stable and reliable, I haven’t experience any issues.

No.

A small update on the Energi Data Service binding: During the last week the work has progressed a lot. There are now channels for all prices, so I think it can now replace some of your rules. I also backported it to Java 11 and openHAB 3.4, so it can be tested in production.

Nice work!

You might be interested to check this solution for some inspiration:

I optimized our house heating and hot water heating based on the spot prices so that it’s done during the cheap hours of the day. I’ve managed to save 400€ between August and December with this solution so far.

Markus

2 Likes

I use HTTP binding to poll raw data from NordPool, and then in my rules I add a fees (currently hard-coded) and VAT on top. Currently I use this to schedule charging my car. However I’m interested to pull usage data from eloverblik, thanks a lot for sharing!

Hi @somy ,

This is now a deprecated solution as far as I can tell. You should check the evolution of Jacobs binding, which I believe has far surpassed the functionality here.

Cheers

Hi @katerica ,

Thank you for your reply! I’m a bit confused about what data is provided by which websites, and I’m not reading Danish which makes things a little harder for me. Initially I thought eloverblik.dk only provides usage data, but it sounds like it also can provide tax and fees for calculating final price - does it take into consideration of el provider (not grid provider) which also can add a margin on top of raw price?
I have never tried https://www.energidataservice.dk/, what data do they provide?
I ask because today I poll raw price from NordPool (simple HTTP binding works reliably), and I created some rules to calculate full price based on formula I find here: https://elspotpris.dk/
This solution seems to work reliably for me, and the good thing is I know el price tomorrow from 13:00 everyday. Does eloverblik and energidataservice also can tell future prices?

Many thanks all for the good discussion and suggestions!

No, that part is a jungle. They would then need to know your exact contract with your electricity supplier. As an example, I was recently in contact with my supplier Vindstød, asking if the 0,063 øre/kWh I’m paying for the “LokalVind” subscription is including or excluding VAT, because that wasn’t declared at their webpage. It turned out I had an older subscription to “LokalVind” which was more expensive. So they switched me to “LokalVind” (the new one) where I had to pay 0,05 øre/kWh excl. VAT, i.e. 0,0625 øre, which rounded up resembled my original assumption.

You would need to go there and look around. They provide tons of datasets! For electricity, the most interesting ones for you as a private consumer would probably be Elspotprices and DatahubPricelist. These are also the two datasets implemented in the Energi Data Service binding.

They would prefer that you didn’t do that. :slightly_smiling_face: At least I’ve heard that they would prefer end users querying other services rather than everyone going directly to the “root”.

Yes, both of them. I believe you can simplify your setup and have an even more robust querying by using the Energi Data Service binding, which should be available for you to install directly from Community Marketplace (the pull request is waiting for review). The documentation is here.

With this binding you will also get future prices around 13:00, and it’s easy to set up a group item with the total costs - in combination with the VAT transformation that you can also install from Community Marketplace.

1 Like

Hi @laursen
Thank you for your reply with lots of useful info, very much appreciated. Regarding the el provider I took the offer from elforbundet and the margin is 0 as I read.
I will definitely try the binding as I don’t particularly like to hard code all the fees and tax in rules - they’re not static and can change from month to month.
I learned a lot from this post, I will now also use the el price to turn on/off Nilan central heating and hot water production depends on el price (inspired by @masipila ) The only concern I have is whether frequent turn on/off heating and hot water has any impact to the heat pump. I’m aware that I shouldn’t turn off ventilation as condensation can build up in the pipes.

Hi @laursen

I have tried your binding and it’s smooth to set up and works great except for one little issue. I don’t seem to get value for the below item, it says “UNDEF”:

Number NetTariff "Current Net Tariff" <price> (TotalPrice) { channel="energidataservice:service:energidataservice:electricity#net-tariff" [profile="transform:VAT"] }

Same in HourlyPrices I don’t see Net Tariff:

{"hourStart":"2023-05-10T19:00:00Z","spotPrice":0.229600006,"spotPriceCurrency":"DKK","systemTariff":0.054000,"electricityTax":0.008000,"transmissionNetTariff":0.058000}

My things configuration below:

Thing energidataservice:service:energidataservice "Energi Data Service" [ priceArea="DK2", currencyCode="DKK", gridCompanyGLN="5790000705689" ] {
    Channels:
        Number : electricity#net-tariff [ chargeTypeCodes="DT_C_01", start="StartOfMonth" ]}

The Data feed looks like the following:

ChargeOwner GLN_Number ChargeType ChargeTypeCode Note Description ValidFrom ValidTo VATClass Price1 Price2 Price3 Price4 Price5 Price6 Price7 Price8 Price9 Price10 Price11 Price12 Price13 Price14 Price15 Price16 Price17 Price18 Price19 Price20 Price21 Price22 Price23 Price24 TransparentInvoicing TaxIndicator ResolutionDuration
Radius Elnet A/S 5790000705689 D03 DT_C_01 Nettarif C time Nettarif C time 01/10/2024 D02 0,1509 0,1509 0,1509 0,1509 0,1509 0,1509 0,4528 0,4528 0,4528 0,4528 0,4528 0,4528 0,4528 0,4528 0,4528 0,4528 0,4528 1,3584 1,3584 1,3584 1,3584 0,4528 0,4528 0,4528 0 0 PT1H
Radius Elnet A/S 5790000705689 D03 DT_C_01 Nettarif C time Nettarif C time 01/04/2024 01/10/2024 D02 0,1509 0,1509 0,1509 0,1509 0,1509 0,1509 0,2264 0,2264 0,2264 0,2264 0,2264 0,2264 0,2264 0,2264 0,2264 0,2264 0,2264 0,5887 0,5887 0,5887 0,5887 0,2264 0,2264 0,2264 0 0 PT1H

A potential feature request if you don’t mind: today I created 48 items grouped in Today and Tomorrow groups, and I update total prices when they become available. Then every night I copy Tomorrow prices to Today and set Tomorrow price to empty (please see the screenshot below). In the current binding looks like all hourly prices are stored in Json, I think it’ll be more convenient to provide channels for each hour (like TotalPrice but for 48 hours) instead so that the data is more structured and easy to validate.

Many thanks in advance!

Edit: I found out how to configure the filter however doesn’t seem to work, attached the raw data for Radius

You do not need to configure this filter manually, the binding comes with pre-configured filters, also for Radius. If you remove the channel configuration, it should work. The start parameter is wrong since it will exclude records still valid, but starting before the beginning of current month. The pre-configured filter has 2023-01-01 as cutoff date.

You can also see this in the records you receive - they are only valid in the future:

I would need to understand your use-case to comment on that. What I can say is that having this amount of items is bad design and will not be implemented in the binding. Most likely this was “invented” to work around the lack of timestamped states. In 2025 we should start receiving spot prices in intervals of 15 minutes. Then what - 192 items that will be rotated every 15 minutes? :slightly_smiling_face: I can’t even wrap my head around how to use that for calculations.

This pull request will probably pave some of the way:

I recently renamed all channels to prepare for supporting time series (e.g. from current-spot-price to just spot-price).

For now, instead of using the serialized JSON content, you could also simply use the thing action getPrices for retrieving all the prices in a rule. This will also perform much better.

Perhaps some of the thing actions could be helpful for some of your use-cases, for example if you need to calculate periods with lowest prices.

1 Like

Thanks a lot, it works after removing the channels :slight_smile:

My use-cases are:

  1. To show hourly prices in a table like what https://elspotpris.dk shows. What is would be the best way to show those prices with hourly or 3-hourly intervals?
  2. To calculate when cheapest to charge the car, but I think the action calculateCheapestPeriod you have implemented works much better. In my current rules I have a nested for loop to go hour by hour to find our when to start charging, and it won’t work when the price is updated every 15mins.

Best regards

Notice the timestamps are Instant, based on print out looks like it’s in GMT time:

  1. How can I check if Instant is today in local time
  2. and how to get local hour HH (2 digits) from Instant

Edit: found the issue please ignore the original post.

Did you also solve the problem of iterating the Map? If you could post your solution here, it could possibly help others finding this topic - and I might also be able to use it for improving the documentation.

EDIT: Okay, I just tested iterating - previously I only did key lookups in my rules:

val actions = getActions("energidataservice", "energidataservice:service:energidataservice");
var priceMap = actions.getPrices(null)
priceMap.forEach[ key, value | logInfo(key.toString, value.toString) ]

Hi, thanks for the reply!
The error message was misleading, it initially look like array out of bound. But it was because I only have one parameter when I logInfo, so iteration works perfectly fine. I’m now struggling to find out how to handle Instant, so far I have the following code (which is ugly I know), I will keep updating it:

    val actions = getActions("energidataservice", "energidataservice:service:energidataservice")
    var priceMap = actions.getPrices(null)
    var hourStart = now.toInstant().truncatedTo(ChronoUnit.HOURS)
    var String currentDate = new DateTimeType().format("%1$tY-%1$tm-%1$td")
    priceMap.forEach[ key, value | 
        logInfo("TEST", key.toString)
        var LocalDateTime ldt = LocalDateTime.ofInstant(key, ZoneOffset.systemDefault())
        var DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        var DateTimeFormatter hourFormatter = DateTimeFormatter.ofPattern("HH");
        var String date = ldt.format(dateFormatter)
        var String hour = ldt.format(hourFormatter)
        if (hour.length < 2){
            hour = "0" + hour
        }
       var String itemName = "ElectricityPriceAt" + hour
        if(date != currentDate) {
  			gEnergiDataServiceTomorrow.members.findFirst[name.equals(itemName+"Tomorrow")].postUpdate(value)
        }
        else {
            gEnergiDataServiceToday.members.findFirst[name.equals(itemName+"Today")].postUpdate(value)
        }
    ]

The idea is to find the item called ElectricityPriceAtHHToday/Tomorrow and update with the value of the map

1 Like
  1. What kind of heating system is this Nilan device you’re planning to control? I have a Nibe F-1226 ground source heat pump which is NOT a so called inverter pump like most modern heat pumps are.

In other words, my heat pump is a traditional on/off pump whereas modern inverter pumps adjust the speed instead of toggling the compressor on/off.

There are different opinions/schools in the heat pump forums. One quite popular opinion related to on/off pumps is that trying to minimize the nimber of compressor starts will make it last longer. In other words, longer consequtive heating periods is preferred over many short periods.

  1. Regarding the ventilation: I don’t recommend you to interfere with this. The benefit of that is not worth it in my opinion compared to the downsides (decreased quality of the air, messed up humidity etc).

Cheers,
Markus

P.s. you might want to open a separate thread for heat pump control strategies, since that is easily a topic of its own. You can ping me there and I’ll be happy to share what I’ve learnt about heat pumps.

Looks good. :+1:

I’m wondering now if you need more history to fill out all hours for Today? Currently I populate prices only 12 hours back in time, but that’s an arbitrary number I selected just to have some kind of restriction/boundary. My own use-case for keeping historic prices at all is to be able to show the total price when the tumble dryer has finished: Dishwasher price calculation automation - #5 by laursen

My rule triggers when HourlyPrice changes, so I think it will catch the older prices if it updates frequently. How often does it update (or what event triggers an update)?
I’m trying to add VAT to my items with format already, the following doesn’t seem to work, I guess I misunderstand how to use it, any suggestion?

Number    ElectricityPriceAt01Today       "Price Today at 01:00 [VAT(25):%.2f kr]"       (gEnergiDataServiceToday)