node-red-contrib-power-saver icon indicating copy to clipboard operation
node-red-contrib-power-saver copied to clipboard

Bug: strategy-heat-capacitor-functions.js

Open volkmarnissen opened this issue 1 year ago • 5 comments

Hi,

I am working on a test case to evaluate the heat-capacitor strategy. It uses the temperature data of my own heat pump.

The idea behind it: I'd like to use the strategy to load the hot water tank at cheapest tibber prices. So, the complete configuration for the strategy will be set before starting a calculation, because the configuration data is dependent on the tank temperature and the current consumption of hot water.

My test case executes the same procedure for different values. The output will be validated against the expected reaction. This is still in progress.

However, when testing it, I came across the following issue:

strategy-heat-capacitor-functions.js:22 If pattern.length == 0, the reduce() call of the dot() function will throw an exception

19  const dot = (a, b) => a.map((x, i) => a[i] * b[i]).reduce((m, n) => m + n);
20 const procurementOpportunities = Array(prices.length * 60 - pattern.length + 1);
21  for (let i = 0; i < procurementOpportunities.length; i++) {
22    procurementOpportunities[i] = dot(weightedPattern, tempPrice.slice(i, i + pattern.length));
23 }
24  return procurementOpportunities;

you can repdroduce this using the source code at https://github.com/volkmarnissen/node-red-contrib-power-saver/tree/heat-capacitor-hot-water

The test case "ps-strategy-heat-capacitor hot water" will fail when processing the 5th set of data. msg.payload.time == '2021-10-11T00:30:00.004+02:00

volkmarnissen avatar Sep 25 '24 15:09 volkmarnissen

I needed to change a little of the code in src/strategy-heat-capacitor.js. The component used Date.now() instead of msg.payload.time. The test case use the time field to identify the test data.

volkmarnissen avatar Sep 25 '24 15:09 volkmarnissen

I assume, it will help to add the pattern.length > 0 to the for loop

21  for (let i = 0; i < procurementOpportunities.length && pattern.length > 0; i++) {

and add buyLength to the condition of the while loop

  let i = 0;
35  while (buyLength > 0 && i < priceBuy.length - 1) {
    // Find Local Minima

volkmarnissen avatar Sep 25 '24 15:09 volkmarnissen

If you agree, I can create a pull request to do these changes easily.

volkmarnissen avatar Sep 25 '24 15:09 volkmarnissen

@TomTorger

ottopaulsen avatar Jan 08 '25 19:01 ottopaulsen

Hmm... From what I can remember, the pattern is the shape of the power procurement. That is, if one wants to use this for charging a car, one could add a charging curve. Here, it is simply put to a constant load on line 242.

const buyDuration = Math.round(timeHeat1C * maxTempAdjustment * 2); const sellDuration = Math.round(timeCool1C * maxTempAdjustment * 2); const buyPattern = Array(buyDuration).fill(1); const sellPattern = Array(sellDuration).fill(1);

This will only have a length of zero if the "buyDuration" is zero... Then there is something strange going on with the input parameters timeHeat1C or timeCool1C...

TomTorger avatar Jan 09 '25 11:01 TomTorger