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

I created a bucket called “autogen”. Do I need to add data to it using some of these options?
image

No, the openhab scripts will enter the data.

Now it seems the OpenHab script creates “spot_price” measurement to the bucket “autogen” but there are no values. I have updated the Entsoe token to the OpenHab script FetchSpotPrices. Also the debug info says “influx.js: Preparing to write 24 points to the database for spot_price” and “influx.js: Points successfully saved for measurement spot_price”.

If you have the measurement, you also have data in it. infkuxdb only creates the measurement when it writes the first measurement point for it.

The default time frame in the influx data explorer is “past 1h” if my memory serves me well. You need to change this to see tomorrow’s prices because they are in the future.

Cheers,
Markus

That was it, thank you Markus! I just needed to change the time frame. My new Raspberry is coming next week :smiley:

1 Like

I have been running this great solution for a couple of month controlling my water heater :blush:

I have an idea trying to visualize for the rest of the family when the spot price is “high” or “low” using a led matrix.

My goal is to have the matrix:

Spot_price above average day = Red Light
Spot_price below average day = Green Light

Can anyone point me in any direction to achieve this, can I simply modify existing code?

Create a new rule that runs every full hour (because that when the price changes).

That rule would run a new script action that would read the spot_price measurement points from your influxDB in the same way as you do when you calculated the on/off hours for your waterheater, calculate if the current hour is above or below the daily average and then sen the command to your lights.

Based on my own experience, the red/green indocator is not very helpful though because if it’s red right now, the obvious follow-up question is “well when is it going to be green then”.

One option is to have a cheap but nice looking tablet as a wall display, and have the daily spot prices visually available over there.

My system has now been up and running without problems for about one month. No changes has been made but today the entsoe.js script didn’t run correctly and no spot prices where added to the influx db. The error message is,

2022-10-24 19:45:28.785 [ERROR] [nhab.automation.script.ui.d023cfcc23] - entsoe.js: Exception parsing spot prices: Cannot read property "period.timeInterval" from undefined

Has anyone else encountered this? Any ideas about what is going wrong?

Entso-E platform has some issues and tomorrow’s prices are not available there, not even their web user interface, see

https://m-transparency.entsoe.eu/transmission-domain/r2/dayAheadPrices/show?name=&defaultValue=false&viewType=GRAPH&areaType=BZN&atch=false&dateTime.dateTime=25.10.2022+00:00|EET|DAY&dateTime.timezone=EET_EEST&dateTime.timezone_input=EET+(UTC+2)+/+EEST+(UTC+3)&biddingZone.values=CTY|10YAL-KESH-----5!BZN|10YAL-KESH-----5&resolution.values=PT60M

Hi all since yesterday data is present in api response for 25th oct for swwden se3 atleast.

Hi,

For information,

Since end of October 2022 the FMI HIRLAM weather forecasting model is no longer in use. The fmi.js script must be updated to get the weather forecast from the HARMONIE forecasts. See info received from FMI below,

Hi,

Thank you for your feedback! The use of the HIRLAM weather forecasting model at the Finnish Meteorological Institute has been ended in the end of October 2022, after which its forecasts are not available through the open data services. HARMONIE (MEPS) forecasts are available through our open data services.

Here you can read more about the changes: The use of the HIRLAM weather forecast model will end in October - Finnish Meteorological Institute

More information on our open data services: Open data - Finnish Meteorological Institute

Best Regards,

…………………….

Nina Kaitemo
Communications

Finnish meteorological institute
Erik Palménin aukio 1, 00560 Helsinki
PL 503, 00101 Helsinki
www.ilmatieteenlaitos.fi

Thanks for sharing the root cause, I was wondering where my weather forecast are but this explains…

I remember that parsing the weather forecast XML was the most painful part of this whole exercise but I now need to redo this part. Let’s see when I will have time for it. I’ll publish a new version of the weather forecast script unless somebody else is faster than me.

Markus

Hi,

I already upgraded the script so you can have it here…

/**
 * Javascript module for reading weather data from FMI API - HARMONIE.
 *
 * Copyright (c) 2022 Markus Sipilä, Updated for HARMONIE Rainer Keto
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/**
 * Exports.
 */
module.exports = {
    getForecast: getForecast,
};

/**
 * Reads the weather forecase from FMI API.
 *
 * @param string place
 *   Place recoginzed by FMI API.
 *
 * @return string
 *   XML response from FMI API.
 */
function getForecast(place) {
    const xml = makeApiCall(place);
    const points = preparePoints(xml);
    return points;
}

/**
 * Makes an API call to the Finnish Meteorology Institute.
 *
 * @param string place
 *   Place recoginzed by FMI API.
 *
 * @return string
 *   XML response from FMI API.
 */
function makeApiCall(place) {
    const http = Java.type("org.openhab.core.model.script.actions.HTTP");
    console.log('fmi.js: Making an API call to FMI API...');
    const url = 'http://opendata.fmi.fi/wfs?service=WFS&version=2.0.0&request=getFeature&storedquery_id=fmi::forecast::harmonie::surface::point::simple&place=' + place + '&parameters=temperature';
    const xml = http.sendHttpGetRequest(url, 10000);
    return xml;
}

/**
 * Parses the forecasted temperatures from the XML response.
 *
 * @param string xml
 *   FMI response in XML format.
 *
 * @return array
 *   Array of point objects.
 */
function preparePoints(xml) {
    console.log('fmi.js: transforming XML to JSON and parsing temperatures...');
    const transformation = Java.type("org.openhab.core.transform.actions.Transformation");
    let tempPoints = [];

    // Early exit in case XML is null.
    if (xml == null) {
	console.error('fmi.js: XML empty, parsing aborted.')
	return tempPoints;
    }
    try {
	const jsObject = JSON.parse(transformation.transform('XSLT', 'xml2json.xsl', xml));
	const members = jsObject['wfs:FeatureCollection']['wfs:member'];
	for (let i = 0; i < members.length; i++) {
		    let point = {
			datetime: members[i]['BsWfs:BsWfsElement']['BsWfs:Time'],
			value: members[i]['BsWfs:BsWfsElement']['BsWfs:ParameterValue']
		    };
		    tempPoints.push(point);
	}
	console.log('fmi.js: Temperatures parsed!');
    }
    catch (exception) {
	console.error('fmi.js: Exception parsing temperatures: ' + exception.message);
    }

    return tempPoints;
}
1 Like

Thank you @ruxu ! I also updated this to the comment #13 which is marked as the solution for this thread.

Thank your for your effort! I got mine working a couple of days ago and today I had the control connected to the physical layer of house 'lectrics.

Quick info for others regarding the setup I have: I’m running OH 3.3 branch, have the same relay board from Waveshare as Markus with RPi 4B+ on it and have OH running on a separate server. If you make identical steps and as per the guide, you will get it to work out of the box.
Just for the info if you are thinking of using the same relay board with BananaPi, it doesn’t work out of the box as the pigpio and wiringpi are not compatible and would require coding skills to get it to work.
At first I wanted to use the Banana as it has better mass storage than RPi and was aiming to have the OH on it, but after I realized I have to use the RPi already in my possession, because lack of coding skills and understanding, I opted to have the OH running on a ProxMox VM installed in my x3950M4 server to “never” having to worry about sufficient IO capabilities or storage corruption, so I could of just went witha Denkovi ethernet relay or a similar product.


Anyway, now that I have it running, I wondered if you could help me just a bit so I could have my generator started when the spot price is high enough.
I looked for the waterheater.js for a couple of hours and compared it with the rule script to make adjustments and get it done - but it seems like that period of time was similar to a pig watching a satellite trying to understand it…

But still, in case you don’t have the time or interest, thank you again for the effort and making it public. It sure is helpful for many!

Do you mean that you want to start the generator if the hourly spot price is above some threshold?

Or do you want to start it every day for the most expensive hours?

When do you want to stop it?

Markus

Start when price threshold is reached and stop after price decreases below the threshold.

I think there could be a percentage value regarding the shutdown, hence 100% would be the threshold price and if set to 80%, the generator would stop after the price is 0,8*spot price. I’m collecting the heat generated by the exhaust and water jacket so it’s not necessary to stop immediately after the price goes under the set threshold value.

Min running time can be one hour. Other scheduling / start limitations can be set with time based rules for running the script, I think. I have a machine shop and the idea is to cap the peak prices during working hours.

You don’t need to read, clone or modify the waterheater.js that you were wondering earlier.

All you need to do is to create an hourly executed rule with a script action, similar what we now have for the “does the waterheater_control have value 1 for the current hour.”

Conceptually the only change in the script action is that you don’t read waterheater_control, but you read spot_price value for the current hour. And them you don’t compare if it is 1 or 0, you compare it to the price threshold of your choice.

Hope this helps,
Markus

1 Like

I made some major updates to comment #13 as a Christmas present for the community. It is now giving more more guidance to new openHab users who are learning the basic openHab concepts at the same time.

3 Likes

Is there a bug in influx.js.txt ?

Line 41: bucket: autogen’,
Shouldn’t this be
bucket: ‘autogen’,

?