Negative TimeOfUse Prices demand inverse EFFICIENCY_FACTOR in Simulator
### Description
In the last few days I have noticed a weird behaviour of the Time of Use Controller. In multiple Simulations it favored to charge and discharge in Timeslots where the price stayed the same. As this is something I thought the `softConstraintViolations` and `modePreferencePenalty` should avoid, it had to be economically better in the simulation to charge and discharge.
```
Mai 02 08:14:55 openems java[6604]: OPTIMIZER Time BuyLimit Price Prod Cons MCons Ess Grid EssInitial
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 08:00 175000 73 0 76931 76931 0 76931 11205 BALANCING
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 08:15 175000 73 0 76931 76931 0 76931 11205 BALANCING
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 08:30 175000 73 0 76931 76931 0 76931 11205 BALANCING
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 08:45 175000 73 0 76931 76931 0 76931 11205 BALANCING
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 09:00 175000 6 0 75229 75229 0 75229 11205 BALANCING
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 09:15 175000 6 0 75229 75229 0 75229 11205 BALANCING
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 09:30 175000 6 0 75229 75229 0 75229 11205 BALANCING
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 09:45 175000 6 0 75229 75229 0 75229 11205 BALANCING
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 10:00 175000 -1 0 75168 75168 -99832 175000 11205 CHARGE_GRID
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 10:15 175000 -1 0 75168 75168 62668 12500 111037 BALANCING
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 10:30 175000 -1 0 75168 75168 37164 38004 48369 BALANCING
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 10:45 175000 -1 0 75168 75168 0 75168 11205 BALANCING
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 11:00 175000 -9 0 75104 75104 -99896 175000 11205 CHARGE_GRID
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 11:15 175000 -9 0 75104 75104 62604 12500 111101 BALANCING
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 11:30 175000 -9 0 75104 75104 37292 37812 48497 BALANCING
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 11:45 175000 -9 0 75104 75104 0 75104 11205 BALANCING
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 12:00 175000 -18 0 75057 75057 0 75057 11205 BALANCING
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 12:15 175000 -18 0 75057 75057 -99943 175000 11205 CHARGE_GRID
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 12:30 175000 -18 0 75057 75057 -99943 175000 111148 CHARGE_GRID
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 12:45 175000 -18 0 75057 75057 -99943 175000 211091 CHARGE_GRID
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 13:00 175000 -59 0 75000 75000 -100000 175000 311034 CHARGE_GRID
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 13:15 175000 -59 0 75000 75000 -100000 175000 411034 CHARGE_GRID
Mai 02 08:14:55 openems java[6604]: OPTIMIZER 13:30 175000 -59 0 75000 75000 -100000 175000 511034 CHARGE_GRID
...
Mai 02 08:14:55 openems java[6604]: OPTIMIZER totalNumberOfSimulations=113768726;totalNumberOfGenerations=20139343;fitness=Fitness{hardConstraintViolations=0, gridBuyCost=7.95814131213E7, gridSellRevenue=0.0, modePreferencePenalty=1016.5, softConstraintViolations=2}
```
I suspect the following Grid-Buy Cost Calculation to be the culprit.
```java
// Calculate Grid-Buy Cost
if (energyFlow.getGrid() > 0) {
int buyFromGrid = max(0, energyFlow.getGrid());
int chargeEss = max(0, -energyFlow.getEss());
int gridToEss = Math.min(buyFromGrid, chargeEss);
int gridToCons = buyFromGrid - gridToEss;
fitness.addGridBuyCost(
// Cost for direct Consumption
gridToCons * price
// Cost for future Consumption after storage
+ max(0, gridToEss) * price * EFFICIENCY_FACTOR);
}
```
where EFFICIENCY_FACTOR is 1.17
This makes sense for positive prices, as it it more costly to store energy for "later"
However for negative prices it results in more "negative Grid Buy Costs" or less Grid Buy Costs when stored in ESS even just for one time period.
Thats why I am proposing to add this line to the Grid-Buy Cost Calculation:
```java
double effectiveEfficiency = price >= 0 ? EFFICIENCY_FACTOR : (1.0 / EFFICIENCY_FACTOR);
fitness.addGridBuyCost(
// Cost for direct Consumption
gridToCons * price
// Cost for future Consumption after storage
+ max(0, gridToEss) * price * effectiveEfficiency);
```
### Screenshots
_No response_
### Operating System
Debian
### How to reproduce the Error?
Run a Simulation with negative Time of Use Prices with the Time of Use Controller.
关闭于 2026-05-11 1 条评论