Control a water heater and ground source heat pump based on cheap hours of spot priced electricity

Because I am no coder I asked ChatGPT how to call the windchill calculator method. This is what it suggested:

I further asked it to add start and end times to the script. Here is what it suggested. Would this be what you expected @masipila?

// Import the InfluxDB client library
const Influx = require('influx');

// Create a new InfluxDB client instance
const influx = new Influx.InfluxDB({
    host: 'localhost',
    database: 'mydb',
});

// Define the start and end times for the import
const startTime = '2022-02-01T00:00:00Z'; // Replace with your start time
const endTime = '2022-02-28T23:59:59Z'; // Replace with your end time

// Define the query to fetch the temperature and windspeed data for the specified time range
const temperatureQuery = `
    SELECT "value"
    FROM "temperature"
    WHERE time >= '${startTime}' AND time <= '${endTime}'
`;
const windspeedQuery = `
    SELECT "value"
    FROM "windspeed"
    WHERE time >= '${startTime}' AND time <= '${endTime}'
`;

// Fetch the temperature data from InfluxDB
influx.query(temperatureQuery)
    .then(result => {
        // Create an array of temperature points
        let temperaturePoints = result.map(row => {
            return {
                datetime: row.time,
                value: row.value,
            };
        });

        // Fetch the windspeed data from InfluxDB
        return influx.query(windspeedQuery)
            .then(result => {
                // Create an array of windspeed points
                let windspeedPoints = result.map(row => {
                    return {
                        datetime: row.time,
                        value: row.value,
                    };
                });

                // Call the calculateWindChillTempPoints function with the fetched data
                let windChillTempPoints = calculateWindChillTempPoints(temperaturePoints, windspeedPoints);

                console.log(windChillTempPoints);
            });
    })
    .catch(error => {
        console.error(error);
    });

I’m literally laughing my lungs out!

I’ll put the kids to bed and try to stop laughing and will get back to you shortly.

Cheers,
Markus

@timo12357 the comment #13 now has the same version of the fmi.js that I’m using myself which has the methods for storing also other weather forecast measurements than just the temperature. It also has the method for calculating the wind chill compensated temperature.

Pay attention also to the updated script action for the rule that fetches the weather forecast from FMI API.

Cheers,
Markus

1 Like

Great @masipila, wind compensation seems to work now, even if I do 't really understand how.

I do not want to be a pain in the butt… but have you considered the solar thermal effect? Fissio.fi has a feature that reduces the needed heating hours on very sunny days. Do you have ideas how to implement that on this platform? Where does fissio.fi get the expected solar thermal power data from?

You are already now persisting Temperature,
WindSpeedMS from the FMI response XML.

If you read through the fmi.js and more specifically the row where the API call is made to the FMI API, you can see that were actually requesting for many other weather forecasts. The cloud coverqge is one of them. You can save that to your database exactly the same way as you do for the temperature and wind speed.

How you want to take the cloudiness into account in calculating the number of heating hours is purely up to you.

I haven’t even tried yet, even though its clear that it plays a significant factor now that the days are getting longer. We have 3.6 m x 3.6 m windows to South and the temperature in the living room bumps significantly on sunny days.

Markus

1 Like

Some reporting of how well the code now works.


Control 15.3.2023


Actual energy consumption from power company reporting system for 15.3.2023


Control 16.3.2023


Actual consumption 16.3.2023

One can see from the graphs that heating is the dominating energy consumption in our house and @masipila 's code succeeds nicely in controlling our heat pump to run only on the cheapest hours. Thanks Markus, this is great!

We buy our electricity from Oomi, that has hourly reporting on the consumption. I have not found an API that could be machine read, to plot the consumption values in the same graph with the control.

Can the data be extracted from the web content ( plots ) ?
Have you had a look into GitHub - sremes/oomi: Download electricity consumption data from Oomi and upload it into Google Firestore. ?

1 Like

Nice find! It seems to have InfluxDB support, too.

I’ll look into this.

1 Like

@masipila Seems like the transition to daylight saving time messed up the software. It does not calculate tomorrows heating as it only has 23 spot times.

2023-03-26 17:47:00.339 [INFO ] [nhab.automation.script.ui.00b077135e] - nibe.js: Calculating forecasted average temperature...
2023-03-26 17:47:00.384 [INFO ] [nhab.automation.script.ui.00b077135e] - nibe.js: average temperature: -8.295833333333334
2023-03-26 17:47:00.387 [INFO ] [nhab.automation.script.ui.00b077135e] - nibe.js: Calculating number of ON hours for Nibe...
2023-03-26 17:47:00.391 [INFO ] [nhab.automation.script.ui.00b077135e] - nibe.js: Number of needed hours: 8.994074074074074
2023-03-26 17:47:00.393 [INFO ] [nhab.automation.script.ui.00b077135e] - control-point-optimizer-slicing.js: Searching for cheapest hours...
2023-03-26 17:47:00.396 [INFO ] [nhab.automation.script.ui.00b077135e] - influx.js: Reading spot prices from the database...
2023-03-26 17:47:00.432 [ERROR] [nhab.automation.script.ui.00b077135e] - control-point-optimizer-slicing.js: Not enough spot prices! Expected 24 but found 23
2023-03-26 17:47:00.435 [INFO ] [nhab.automation.script.ui.00b077135e] - influx.js: Preparing to write 0 points to the database for nibe_control
2023-03-26 17:47:00.437 [INFO ] [nhab.automation.script.ui.00b077135e] - influx.js: Points successfully saved for measurement nibe_control

I got this circumvented by editing row 132 of nibe.js like so:

    const duration = (Math.abs(stop-start) / (60*60*1000))-1;

After this the software agreed to calculate heating hours for tomorrow. This cludge is not a good solution, but at least gives one more day time to find a real solution to the problem.

I finally managed to understand (read: reverse engineer) the logic behind the Entso-E API and it’s input paramaters.

The root of all evil is that Entso-E does not respect the ISO8601 standard in the periodStart and periodEnd input arguments which are implicitly assumed to be CET/CEST. Their API responses are properly respecting ISO8601.

In addition to this, the periodStart and periodEnd arguments are NOT the start and end times for which we will get data back, and I had previously never fully understood how their API works when it comes to periodStart and periodEnd. Now I finally know, after experimenting their API for a couple of hours with different dates. They will always return full days worth of spot prices and they will all the days that are are at least partially between periodStart and periodEnd.

Because of my previous “I-wonder-how-the-f*ck-does-this-work-since-they-don’t-respect-ISO8601” I had made incorrect assumptions and as a result, I had a bug in my own code that parses their responses. I’ll need to clean it up still before I publish a new version.

To avoid these errors I replaced the stock Influxdb add on with this:

https://docs.smarthomej.org/3.2.16/org.smarthomej.persistence.influxdb.html

The errors went away, and everything worked for a couple of days. I had to tweak some of the graphs to work ok. However, now I have random starts of the pump. Is this a random error or related to the smarthomej influxdb add on?

If you have connected your hardware connections so that the compressor is blocked when the relay pulls, then a compressor start means that at that time your relay has not pulled.

If your Raspberry was offline or rebooting, that would be one possible explanation why the relay did not pull.

If the unexpected compressor start was occurring on full hour when your hourly rule runs, then there is another possible explanation. The script is designed so that when the script does not find a control value for the current hour that just begun, then value 1 is assumed as a failsafe so that your house doesn’t freeze.

I have no idea what your error message means, I’ve never seen that. And I don’t know about your renegade influx instance either.

Is the Entso-E service down? My system stopped getting spot price values yesterday. This is my log:

2023-04-15 07:08:11.500 [INFO ] [nhab.automation.script.ui.00b077135e] - entsoe.js: Making an API call to Entso-E API...
2023-04-15 07:08:11.959 [INFO ] [nhab.automation.script.ui.00b077135e] - entsoe.js: transforming XML to JSON and parsing prices...
2023-04-15 07:08:12.144 [ERROR] [nhab.automation.script.ui.00b077135e] - entsoe.js: Exception parsing spot prices: Cannot read property "period.timeInterval" from undefined
2023-04-15 07:08:12.150 [INFO ] [nhab.automation.script.ui.00b077135e] - influx.js: Preparing to write 0 points to the database for spot_price
2023-04-15 07:08:12.156 [INFO ] [nhab.automation.script.ui.00b077135e] - influx.js: Points successfully saved for measurement spot_price
2023-04-15 07:08:27.899 [INFO ] [nhab.automation.script.ui.00b077135e] - waterheater.js: Starting to calculate on/off hours for the waterheater...4
2023-04-15 07:08:27.902 [INFO ] [nhab.automation.script.ui.00b077135e] - influx.js: Reading spot prices from the database...
2023-04-15 07:08:27.969 [INFO ] [nhab.automation.script.ui.00b077135e] - influx.js: Preparing to write 1 points to the database for waterheater_control
2023-04-15 07:08:27.993 [INFO ] [nhab.automation.script.ui.00b077135e] - influx.js: Points successfully saved for measurement waterheater_control
2023-04-15 07:08:42.855 [INFO ] [nhab.automation.script.ui.00b077135e] - nibe.js: Calculating forecasted average temperature...
2023-04-15 07:08:42.921 [INFO ] [nhab.automation.script.ui.00b077135e] - nibe.js: average temperature: 2.391666666666666
2023-04-15 07:08:42.924 [INFO ] [nhab.automation.script.ui.00b077135e] - nibe.js: Calculating number of ON hours for Nibe...
2023-04-15 07:08:42.930 [INFO ] [nhab.automation.script.ui.00b077135e] - nibe.js: Number of needed hours: 5.3121212121212125
2023-04-15 07:08:42.933 [INFO ] [nhab.automation.script.ui.00b077135e] - control-point-optimizer-slicing.js: Searching for cheapest hours...
2023-04-15 07:08:42.936 [INFO ] [nhab.automation.script.ui.00b077135e] - influx.js: Reading spot prices from the database...
2023-04-15 07:08:42.984 [ERROR] [nhab.automation.script.ui.00b077135e] - control-point-optimizer-slicing.js: Not enough spot prices! Expected 24 but found 1
2023-04-15 07:08:42.988 [INFO ] [nhab.automation.script.ui.00b077135e] - influx.js: Preparing to write 0 points to the database for nibe_control
2023-04-15 07:08:42.991 [INFO ] [nhab.automation.script.ui.00b077135e] - influx.js: Points successfully saved for measurement nibe_control

Or has my system got corrupted?

Entso-E is not completely down, but have not been able to publish today’s prices. See the link below and observe that prices are there for Apr 14 but not for Apr 15.

If you’re using the scripts unmodified, all hours are allowed and your real world devices should be operating on their own logic.

Markus

https://transparency.entsoe.eu/transmission-domain/r2/dayAheadPrices/show?name=&defaultValue=false&viewType=GRAPH&areaType=BZN&atch=false&dateTime.dateTime=14.04.2023+00:00|CET|DAY&biddingZone.values=CTY|10YFI-1--------U!BZN|10YFI-1--------U&resolution.values=PT15M&resolution.values=PT30M&resolution.values=PT60M&dateTime.timezone=CET_CEST&dateTime.timezone_input=CET+(UTC+1)+/+CEST+(UTC+2)

1 Like

@masipila. Entso-E is not your product or responsibility and you still help! Thanks a lot!

Hello. I know you @masipila from the Fission portal. I promised to try OpenHAB and your scripts. What can I say, work like the famous train toilet, thanks a lot for your effort and for sharing these with others !!! I have semi-reserving electric heating and night/day electricity rates in transmission, so I modified your scripts to take into account cheaper transmission rate between 22:00…07:00. I use a Shelly pro 2 relay for controls and a tiny PC and Rocky Linux instead of Raspberry.

2 Likes

Glad to hear that it works well for you!

Now that I have been running my own version of this software concept, I noticed it’s somewhat suboptimal at times.
Say I don’t heat during the n most expensive hours, and one of those n is at 23:00 (which is not uncommon) so I don’t heat by then.
But now what if next day prices are overall higher than today’s … I will start heating at 0:00 because that’s among 24 - n cheapest of the next day but that hour it is more expensive than it was the hour before so reversing those would have been the cheaper choice in total.

Ok we don’t obtain prices more than 1 day in advance, but by 13:00 or so they are there.
I now came to think that instead of doing the calculation on a static 0:00-23:00 basis, we should better be using a rolling window of the next 24 hours (or as few or as many as we have prices available).
If looking to cover a fixed period of 24h, we might need to estimate prices, say it’s 12:00 and we haven’t received next day price info yet, we would need to generate a value to calculate with for the hours 13 (= 00:00 next day) to 24.

wdyt?

1 Like