ottopaulsen / node-red-contrib-power-saver

A Node-RED node to saver money by turning off when the power is most expensive
Other
71 stars 17 forks source link

Force ps-strategy-lowest-price to only create schedules for the future #166

Closed corvy closed 1 year ago

corvy commented 1 year ago

Is there any way to stop the node from creating schedules for the past? Even if the past is cheaper? I am looking to use this node for charging EVs so I have created a logic to get the cheapest times to charge going forward. But sometimes the node selects times in the past, like today. If I set my time-window to 0 / 0 (e.g. disable) I get the following result:

image

This makes the charger set the following start and stop times:

image

Which is based on a time that has passed. The logic I have made takes the first suggested start and stop times and use those to program the chargers. I probably could create a logic to try and figure out if this in the past but I think that should not matter. I inject "hoursOn: 3" into the node and it is set to consecutive on-period.

Am I misunderstanding something? :)

corvy commented 1 year ago

Here is the full debug output from the node:

{
   "schedule":[
      {
         "time":"2023-04-27T00:00:00+02:00",
         "value":false,
         "countHours":14
      },
      {
         "time":"2023-04-27T14:00:00+02:00",
         "value":true,
         "countHours":3
      },
      {
         "time":"2023-04-27T17:00:00+02:00",
         "value":false,
         "countHours":9
      },
      {
         "time":"2023-04-28T02:00:00+02:00",
         "value":true,
         "countHours":3
      },
      {
         "time":"2023-04-28T05:00:00+02:00",
         "value":false,
         "countHours":19
      }
   ],
   "hours":[
      {
         "start":"2023-04-27T00:00:00+02:00",
         "price":2.0074,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T01:00:00+02:00",
         "price":1.9174,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T02:00:00+02:00",
         "price":1.8774,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T03:00:00+02:00",
         "price":1.8574,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T04:00:00+02:00",
         "price":1.8674,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T05:00:00+02:00",
         "price":1.9574,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T06:00:00+02:00",
         "price":2.1974,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T07:00:00+02:00",
         "price":2.5774,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T08:00:00+02:00",
         "price":2.4274,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T09:00:00+02:00",
         "price":2.0374,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T10:00:00+02:00",
         "price":1.8974,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T11:00:00+02:00",
         "price":1.8574,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T12:00:00+02:00",
         "price":1.8174,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T13:00:00+02:00",
         "price":1.8074,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T14:00:00+02:00",
         "price":1.8074,
         "onOff":true,
         "saving":null
      },
      {
         "start":"2023-04-27T15:00:00+02:00",
         "price":1.7874,
         "onOff":true,
         "saving":null
      },
      {
         "start":"2023-04-27T16:00:00+02:00",
         "price":1.7874,
         "onOff":true,
         "saving":null
      },
      {
         "start":"2023-04-27T17:00:00+02:00",
         "price":1.9174,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T18:00:00+02:00",
         "price":2.0874,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T19:00:00+02:00",
         "price":2.2674,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T20:00:00+02:00",
         "price":2.7574,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T21:00:00+02:00",
         "price":2.2274,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T22:00:00+02:00",
         "price":2.0774,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-27T23:00:00+02:00",
         "price":1.9374,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T00:00:00+02:00",
         "price":1.9274,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T01:00:00+02:00",
         "price":1.8174,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T02:00:00+02:00",
         "price":1.7774,
         "onOff":true,
         "saving":null
      },
      {
         "start":"2023-04-28T03:00:00+02:00",
         "price":1.8074,
         "onOff":true,
         "saving":null
      },
      {
         "start":"2023-04-28T04:00:00+02:00",
         "price":1.8174,
         "onOff":true,
         "saving":null
      },
      {
         "start":"2023-04-28T05:00:00+02:00",
         "price":1.8874,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T06:00:00+02:00",
         "price":2.0674,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T07:00:00+02:00",
         "price":2.2474,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T08:00:00+02:00",
         "price":2.2974,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T09:00:00+02:00",
         "price":2.2074,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T10:00:00+02:00",
         "price":2.0974,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T11:00:00+02:00",
         "price":2.0474,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T12:00:00+02:00",
         "price":1.9874,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T13:00:00+02:00",
         "price":1.8474,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T14:00:00+02:00",
         "price":1.8074,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T15:00:00+02:00",
         "price":1.7974,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T16:00:00+02:00",
         "price":1.8174,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T17:00:00+02:00",
         "price":1.9374,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T18:00:00+02:00",
         "price":2.0874,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T19:00:00+02:00",
         "price":2.1874,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T20:00:00+02:00",
         "price":2.2674,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T21:00:00+02:00",
         "price":2.2574,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T22:00:00+02:00",
         "price":2.1474,
         "onOff":false,
         "saving":null
      },
      {
         "start":"2023-04-28T23:00:00+02:00",
         "price":1.9874,
         "onOff":false,
         "saving":null
      }
   ],
   "config":{
      "fromTime":0,
      "toTime":0,
      "hoursOn":3,
      "maxPrice":null,
      "doNotSplit":true,
      "sendCurrentValueWhenRescheduling":true,
      "outputIfNoSchedule":false,
      "outputOutsidePeriod":false,
      "outputValueForOn":true,
      "outputValueForOff":true,
      "outputValueForOntype":"bool",
      "outputValueForOfftype":"bool",
      "override":"auto",
      "contextStorage":"memory",
      "hasChanged":true
   },
   "time":"2023-04-27T19:59:27.189+02:00",
   "version":"4.1.3",
   "strategyNodeId":"16a682dcba0d30b4",
   "current":false
}
ottopaulsen commented 1 year ago

The schedule is created for the whole period that it gets data for, normally including the current day from 00:00. When you set from 0 to 0, it is searching for the cheapest period during the whole day. One trick could be to set from 23:00 to 07:00, as you often want to charge during the night, and that is often when the prices are lowest. If you do that, I think it will not plan for the current day, since the period includes one hour from yesterday. It will only plan for the following night, and of course only after it has received prices for tomorrow.

However, I think the best solution would be to filter out passed schedules before you use them, since you obviously are using the schedule, and not output 1 and 2.

By the way, for charging an EV, I guess you do not have to use consecutive hours on, but you may have other reasons for that.

corvy commented 1 year ago

Thanks Otto. I agree that consecutive is not really needed for EV charging, but I kind of need that to "keep it simple" in this phase. Multiple schedules could be an option for next round. I think for now the best solution is to filter out the passed schedules like you say, and use the schedule that is in the future.

I will do some more thinking about this, thanks for replying!

corvy commented 1 year ago

Created the following filter-node to get only future schedules.

// Get the input array from msg.payload
const inputArray = msg.payload.schedule;

// Filter the array items based on schedule.time being in the future
const filteredArray = inputArray.filter((item, index) => {
    // Exclude the first item from the filter
    if (index === 0) {
        return false;
    }

    // Check if schedule.time is in the future
    const time = new Date(item.time).getTime();
    const currentTime = Date.now();
    return time > currentTime;
});

// Set the filtered array as the output to msg.payload
msg.payload = filteredArray;

// Send the modified message to the next node
return msg;

Also I greated a simple logic around the time-target. If it is disabled (e.g. put to 0) I just ask it to set a schedule between now and 0 o'clock. That seems to work good.

var x = msg.payload;

const d = new Date();

var now = d.getHours(); var target = parseInt(x.slice(0, 2));

if ( target == 0 ) { // if target i 0 disable
        msg = {
            "payload": {
                "config": {
                    "fromTime": now,
                    "toTime": 0
                }
            }
        } 
} else { // else set targettime for charge between now and target
    msg = {
        "payload": {
            "config": {
                "fromTime": now + 1,
                "toTime": target
            }
        }
    }
} 

Will keep monitoring this to see what happens but for now this seems to be a better logic.

In this screenshot you can see that the nissan came up with two schedules (since I had not updated the time-window node for that charger) but still it selects the correct window.

image