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

Hi @laursen Thank you for your reply!
Indeed the following trigger and cron expression at midnight will work for me:

Channel 'energidataservice:service:energidataservice:electricity#price-event' triggered 'SPOT'

So the trigger will be available in 4.2 I assume? Looking forward to try it!

Blockquote
I think you can do all of this using Persistence Extensions. For example, you could use <item>.averageBetween(ZonedDateTime, ZonedDateTime) - example

I kind of need a time series of time series - in my uses case I keep avg prices between 17-21 in an item (group AVG function), and then I have a history of avg prices between 17-21 in the past days, I then compare if today/tomorrow is more/less expensive to the previous week (so avg of avg prices in the past 7 days). I think even with the time series support, I still need to persist the avg prices, or do I misunderstand how it works?

Many thanks for your help!

I wanted to check with you first that this solution would be viable. It seems so, so I will then publish the PR soon and would expect it to be included with 4.2.

In order to be able to access prices for the past 7 days, InMemory persistence will not be sufficient. The binding only fetches and publishes the last 24 hours. However, with another persistence service such as MySQL, you would be able to accomplish exactly that. Not only will it allow you to access the historic and future prices, but it can also calculate average prices for you within requested periods as shown in my example above.

Hi.
I’m looking for some advice on how to calculate if and when it’s a good idea to charge my house battery during the night, I hope this thread is a good place for that.

Currently I’m doing this at 22:00 every evening:

actions.calculateCheapestPeriod(now.toInstant(), now.plusHours(10).toInstant(), java.time.Duration.ofMinutes(60))

…and on the cheapest hour that I get back, I charge my battery (depending also on values returned from solarforecast). This often works very good, since the prices are higher in the morning, so the battery will be charged when the prices are at the lowest. Some days however the prices look something like this:
Screenshot_20240706_075535_Tibber
…which means I’m effectualy charging my battery at one price and then the prices get even lower the next hour. What do I do about this? I mean, I could of course ask for the lowest price the entire next day, but no matter which time period I chose I’ll be risking that the period will be ending with falling prices and the hours after it will be even cheaper. Am I thinking this wrong? How do you others do about things like this?

I think what I’m really trying to achieve is: Get the cheapest hour in this 10 hour period. But only if the hours directly after the period are more expensive. Guess that couldn’t be that hard to achieve…

Could the problem be as simple as this: You are looking for the cheapest hour within the next 10 hours (second argument in your rule), so at 22:00 you are only checking prices until 08:00 the next morning?

Yep, that’s correct. And as I said, this mostly works fine, but sometimes (like in the day in my screenshot) the price is going down after 08:00 which makes this problematic. Maybe I need to first check when it’s cheapest (like I’m already doing), then check the exact price for that hour and then check if that price is actually lower than the price between say 8 and 12 oclock…

I guess I don’t fully understand what you are trying to accomplish then. If you really want to find the cheapest hour, even if after 8:00 the next day, you should simply extend your search, e.g.:

actions.calculateCheapestPeriod(now.toInstant(), now.plusHours(24).toInstant(), java.time.Duration.ofMinutes(60))

I guess you also need to know how long time it takes to charge your battery, unless you can always do that within one hour?

Yep, ended up doing something like that. So it it’s even cheaper some time between 8:00 and 11:00 I’ll simply abort the rule completely. Hope this logic will hold.

It’s funny, I thought this would be something that everyone with a house battery would want to do, optimize things like night charging, but I struggle to find any good design patterns for it. Guess it differs so much from user to user that it would be hard to do…

Hi @laursen :

Sorry to bother you again but I’m struggling with lots of warnings in my log after upgrading to 4.2. I understand there has been some persistency API changes in 4.2 (good thing I suppose), however I can’t seem to figure out how to workaround the problem.
It looks like the issue is triggered by the following in my rules:

        var double stdDeviationWeek = (gEnergiDataServiceTomorrow.deviationSince(now.plusDays(-7)) as Number).doubleValue
        var double avgWeek = (gEnergiDataServiceTomorrow.averageSince(now.plusDays(-7)) as Number).doubleValue
        var double avgDayPrice = (gEnergiDataServiceTomorrow.state as Number).doubleValue

As I understand it reads all historic states from the persistency service, and the error I have received looks like the following (I have thousands of them when this particular rule is triggered):

2024-07-25 13:00:32.101 [WARN ] [nce.extensions.PersistenceExtensions] - Item gEnergiDataServiceTomorrow is QuantityType but state 1.872597290395115 at time 2024-07-20T22:22+02:00[Europe/Copenhagen] retrieved from persistence has no unit

I have recently (more than a couple of weeks ago) added QuantityType for energy price, however it didn’t give me any issue in OH 4.1. And the definition of gEnergiDataServiceTomorrow is average price of all it’s members:

Group:Number:EnergyPrice:AVG    gEnergiDataServiceTomorrow    "Avg Price Tomorrow [%.2f %unit%]"                <price>    (gEnergiDataService)
Group:Number:EnergyPrice:AVG    gAvgPrice00_06Tomorrow        "Avg Price Tomorrow 00:00-06:00 [%.2f %unit%]"    <price>    (gEnergiDataServiceTomorrow)
Number:EnergyPrice              PriceAt00Tomorrow             "El Price Tomorrow at 00:00 [%.2f %unit%]"        <price>    (gAvgPrice00_06Tomorrow, gEnergiDataServiceTomorrow)
Number:EnergyPrice              PriceAt01Tomorrow             "El Price Tomorrow at 01:00 [%.2f %unit%]"        <price>    (gAvgPrice00_06Tomorrow, gEnergiDataServiceTomorrow)
Number:EnergyPrice              PriceAt02Tomorrow             "El Price Tomorrow at 02:00 [%.2f %unit%]"        <price>    (gAvgPrice00_06Tomorrow, gEnergiDataServiceTomorrow)
Number:EnergyPrice              PriceAt03Tomorrow             "El Price Tomorrow at 03:00 [%.2f %unit%]"        <price>    (gAvgPrice00_06Tomorrow, gEnergiDataServiceTomorrow)
Number:EnergyPrice              PriceAt04Tomorrow             "El Price Tomorrow at 04:00 [%.2f %unit%]"        <price>    (gAvgPrice00_06Tomorrow, gEnergiDataServiceTomorrow)
Number:EnergyPrice              PriceAt05Tomorrow             "El Price Tomorrow at 05:00 [%.2f %unit%]"        <price>    (gAvgPrice00_06Tomorrow, gEnergiDataServiceTomorrow)
......
......

If I understand correctly, the warning basically says I’m trying to read historic state from a QuantityType (EnergyPrice), however all values in persistency store are without unit.
The question is: I can’t go back in history to change the values, but is there any way to workaround this issue so I don’t receive tons of warnings?
Many thanks in advance!

Are you using rrd4j? Looks like: Retrieved from persistence has no unit since 4.2

1 Like

Sorry I missed that post, yeah that’s exactly the issue I have. Looks like it will be solved in next version :slight_smile:

Anybody saw the error like below:

COMMUNICATION_ERROR

java.util.concurrent.ExecutionException: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Looks like the Thing is OFFLINE, and I have noticed it happened 2 times last month (I have a script that alerts me if Thing goes OFFLINE), and it took a long time for it to come back.
Also I don’t seem to have prices for tomorrow, maybe the site is down?

It seems there is some planned maintenance going on currently:

Technical optimizations are scheduled for the 19th of August 2024. You might experience operational disturbances on this date, affecting both the client and the API service. We expect the changes to run smoothly, affecting usage as little as possible.

I noticed this change for the Home Assistant integration, which looks related:
https://github.com/MTrab/energidataservice/pull/565

I don’t think this is a good idea, and I’m wondering if it was created in panic without checking the news/status of the service.

I should have checked that, sorry to bother you!
It’s a bit strange that maintenance is done during the normal working hours though, will report if the Thing doesn’t get back online

I just checked their new certificate with various tools online, and it seems there might be an issue with incomplete certificate chain, see for example SSL Server Test: api.energidataservice.dk (Powered by Qualys SSL Labs).

I’m not an expert in this area. The best temporary solution might be adding the GlobalSign root certificate to a Jetty config, if that’s possible. Another solution might be to add it to the OS level certificate store. I don’t know how to do either, and I’m not sure who to ask.

Perhaps @wborn knows something regarding Jetty, or @mstormi might know something about how to ā€œfixā€ this on OS level (openHABian)?

This might not be the best solution, but it’s the only idea I have for now.

First, get the certificate:

openssl s_client -showcerts -connect api.energidataservice.dk:443

Copy the certificate into a file (start with and including the line -----BEGIN CERTIFICATE----- and until -----END CERTIFICATE-----), e.g. ~/energidataservice.crt.

Import it into the keystore (password is changeit):

sudo keytool -import -alias energidataservice-cert -file ~/energidataservice.crt -keystore /etc/ssl/certs/java/cacerts

This is the keystore used by Java:

ll /usr/lib/jvm/java-17-openjdk-arm64/lib/security/cacerts
lrwxrwxrwx 1 root root 27 Jul 31 17:55 /usr/lib/jvm/java-17-openjdk-arm64/lib/security/cacerts -> /etc/ssl/certs/java/cacerts

And finally restart openHAB.

To remove it again when the root cause is fixed, I believe something like this can be done:

sudo keytool -delete -alias energidataservice-cert -keystore /etc/ssl/certs/java/cacerts

Hi,
I’m also not expert in this but recall if client complains about certificate there is a way to make https without checking certificate, or am I missing something?
Looking at what HA changed?

Edit find below discussion to override trust manager in Java to skip ssl certificate check:
https://stackoverflow.com/questions/4663147/is-there-a-java-setting-for-disabling-certificate-validation

That is not a solution, at the best it’s a quick workaround to get it working. Not providing the intermediate cert is not good practice and one would hope that they’re working on it and that it will work again soon. I sent them a mail asking about it, might get an answer :slight_smile:

1 Like

Thanks hope they fix the issue. In the meantime I will try the workaround by Jacob. I’m running it on Docker hope it works :slight_smile: (obviously it won’t work next upgrade).

@laursen : I know it’s a hacky solution but would it be possible to add an advance setting in the binding to ignore ssl error for non techy users?

Edit: ok I (almost) made it work - now they banned me due to too many requests. Will report if the issue is solved :slight_smile:

COMMUNICATION_ERROR
Too Many Requests

For those who run on Docker, this is the command I used:

docker exec -it <container> keytool -import -alias energidataservice-cert -file /openhab/conf/cert/EnergiDataService.cert -keystore /etc/ssl/certs/java/cacerts

The issue is now resolved according to:
https://github.com/MTrab/energidataservice/pull/565#issuecomment-2298742419

And I can confirm by this test that it’s now trusted:

That is strange. They allow 50 requests per minute, so I can’t imagine how you surpassed that. The binding will wait one hour IIRC correctly after HTTP code 429 (Too many requests).

1 Like

I can confirm it works for me now :slight_smile:
Thanks a lot for looking into it!

1 Like