FlexMeasures / flexmeasures

The intelligent & developer-friendly EMS to support real-time energy flexibility apps, rapidly and scalable.
https://flexmeasures.io
Apache License 2.0
147 stars 36 forks source link

The storage schedule can not optimize for self use #1232

Closed Ragnar-the-mighty closed 2 days ago

Ragnar-the-mighty commented 3 days ago

The storage schedule can not optimize for self use. I.e charge from battery instead or buying from grid and discharge for self use instead of selling to the grid. Here is an example showing that the storage schedule does not come up with the most economical schedule. Sorry, this is a long explanation.

Assumption We have a price difference between buy and sell prices We have local production We have have a battery We have a forecast for the grid connection.

Modify toy example 2 to show the issue Start with the toys account as described in the documentation Toy example Add sensors Buy energy price (we use the existing price sensor for sell price)

flexmeasures add sensor --name 'Buy price' --unit EUR/MWh --event-resolution PT1H --timezone 'Europe/Amsterdam' --asset 2

Grid connection

flexmeasures add sensor --name 'Grid' --unit MW --event-resolution PT1H --timezone 'Europe/Amsterdam' --asset 2 --attributes '{"capacity_in_mw": 0.5}'

Load data, sell prices

TOMORROW=$(date --date="next day" '+%Y-%m-%d')
echo "Hour,Price
${TOMORROW}T00:00:00,10
${TOMORROW}T01:00:00,11
${TOMORROW}T02:00:00,12
${TOMORROW}T03:00:00,15
${TOMORROW}T04:00:00,18
${TOMORROW}T05:00:00,17
${TOMORROW}T06:00:00,10.5
${TOMORROW}T07:00:00,9
${TOMORROW}T08:00:00,9.5
${TOMORROW}T09:00:00,9
${TOMORROW}T10:00:00,8.5
${TOMORROW}T11:00:00,10
${TOMORROW}T12:00:00,8
${TOMORROW}T13:00:00,5
${TOMORROW}T14:00:00,4
${TOMORROW}T15:00:00,4
${TOMORROW}T16:00:00,5.5
${TOMORROW}T17:00:00,8
${TOMORROW}T18:00:00,12
${TOMORROW}T19:00:00,13
${TOMORROW}T20:00:00,14
${TOMORROW}T21:00:00,12.5
${TOMORROW}T22:00:00,10
${TOMORROW}T23:00:00,7" > sell-prices-tomorrow.csv
flexmeasures add beliefs --sensor 1 --source toy-user sell-prices-tomorrow.csv --timezone Europe/Amsterdam

Load Buy prices:

TOMORROW=$(date --date="next day" '+%Y-%m-%d')
echo "Hour,Price
${TOMORROW}T00:00:00,15
${TOMORROW}T01:00:00,16
${TOMORROW}T02:00:00,17
${TOMORROW}T03:00:00,20
${TOMORROW}T04:00:00,23
${TOMORROW}T05:00:00,22
${TOMORROW}T06:00:00,15.5
${TOMORROW}T07:00:00,14
${TOMORROW}T08:00:00,14.5
${TOMORROW}T09:00:00,14
${TOMORROW}T10:00:00,13.5
${TOMORROW}T11:00:00,15
${TOMORROW}T12:00:00,13
${TOMORROW}T13:00:00,10
${TOMORROW}T14:00:00,9
${TOMORROW}T15:00:00,9
${TOMORROW}T16:00:00,10.5
${TOMORROW}T17:00:00,13
${TOMORROW}T18:00:00,17
${TOMORROW}T19:00:00,18
${TOMORROW}T20:00:00,19
${TOMORROW}T21:00:00,17.5
${TOMORROW}T22:00:00,15
${TOMORROW}T23:00:00,12" > buy-prices-tomorrow.csv

Use your buy sensor id in the command below

flexmeasures add beliefs --sensor <buy sensor_id> --source toy-user buy-prices-tomorrow.csv --timezone Europe/Amsterdam

Load Grid forecast

TOMORROW=$(date --date="next day" '+%Y-%m-%d')
echo "Hour,Power
${TOMORROW}T00:00:00,0.1
${TOMORROW}T01:00:00,0.1
${TOMORROW}T02:00:00,0.1
${TOMORROW}T03:00:00,0.1
${TOMORROW}T04:00:00,0.09
${TOMORROW}T05:00:00,0.07
${TOMORROW}T06:00:00,0.04
${TOMORROW}T07:00:00,0
${TOMORROW}T08:00:00,-0.04
${TOMORROW}T09:00:00,-0.07
${TOMORROW}T10:00:00,-0.09
${TOMORROW}T11:00:00,-0.11
${TOMORROW}T12:00:00,-0.12
${TOMORROW}T13:00:00,-0.11
${TOMORROW}T14:00:00,-0.09
${TOMORROW}T15:00:00,-0.07
${TOMORROW}T16:00:00,-0.04
${TOMORROW}T17:00:00,0
${TOMORROW}T18:00:00,0.04
${TOMORROW}T19:00:00,0.07
${TOMORROW}T20:00:00,0.09
${TOMORROW}T21:00:00,0.1
${TOMORROW}T22:00:00,0.1
${TOMORROW}T23:00:00,0.1" > grid-tomorrow.csv

Use your own grid sensor id in the command below

flexmeasures add beliefs --sensor <buy sensor_id> --source toy-user buy-prices-tomorrow.csv --timezone Europe/Amsterdam

Make a schedule, use your buy sensor id in the command below

flexmeasures add schedule for-storage --sensor 2 --consumption-price-sensor <buy price sensor> --production-price-sensor  1 \
    --start ${TOMORROW}T00:00+02:00 --duration PT24H \
    --soc-at-start 0% --roundtrip-efficiency 90%

You should now have a schedule like this Screenshot 2024-11-05 at 3 08 13 AM

Take a look at discharge at 02:00 notice that the buy prices at 01:00 and 03:00 are higher than the sell price at 02:00. Discharging the battery at 01:00 and 03:00 hours so we avoid buying is more economical than to discharge everything at 02:00. Result from current scheduler

Screenshot 2024-11-05 at 3 44 12 AM

The optimal schedule result should be

Screenshot 2024-11-05 at 3 44 26 AM

The same is true for the charging time period at 12:00. The optimal schedule should spread out the charging to take advantage of the solar production and avoid selling solar energy at low prices.

Flix6x commented 2 days ago

If you want the scheduler to take into account the opportunity of buying less from the grid, shouldn't you be telling the scheduler that it should take into account the forecasted inflexible consumption/production happening on your grid connection? That is, I was expecting to see the --inflexible-device-sensor option (like in Toy example II) set to the sensor ID that records the forecasted inflexible power on the grid connection.

Ragnar-the-mighty commented 2 days ago

@Flix6x , thank you. My understanding of --inflexible-device-sensor option was flawed and when I tested it I messed up. The grid sensor in my first comment in this thread was reversed.

With your comment got me to test the --inflexible-device-sensor option again and now it solves my problem. I will close this issues since your suggested solution solves my issues.