Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Combined version of optimisation task and comparison of the strategies. #231

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"rng_seed": 622414180
"rng_seed": 278718870
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
Time,load,pv,schedule
2016-01-01 00:00:00,0.011886246327641098,0.000517808433048365,-0.011368437894592734
2016-01-01 00:15:00,0.0410388447933982,0.0018173905721315046,-0.039221454221266695
2016-01-01 00:30:00,0.0406771589865564,0.0018788623941673238,-0.03879829659238907
2016-01-01 00:45:00,0.0405878697548583,0.0026125830560011706,-0.03797528669885713
2016-01-01 01:00:00,0.0408237818838657,0.007666088655028339,-0.03315769322883736
2016-01-01 01:15:00,0.0407177271612198,0.007786428245115456,-0.03293129891610434
2016-01-01 01:30:00,0.0155266774334944,0.015510455887296022,-1.622154619837675e-05
2016-01-01 01:45:00,0.0163007931439657,0.009280520350204874,-0.007020272793760827
2016-01-01 02:00:00,0.0322130119232581,0.024992648176070963,-0.007220363747187139
2016-01-01 02:15:00,0.0091297259677855,0.025210661520819418,0.01608093555303392
2016-01-01 02:30:00,0.0193711826356853,0.03305446941532318,0.013683286779637881
2016-01-01 02:45:00,0.028851808922693505,0.06424692281955591,0.0353951138968624
2016-01-01 03:00:00,0.0092306359903934,0.04001418894280702,0.03078355295241362
2016-01-01 03:15:00,0.021129578178791,0.09622432421329186,0.07509474603450086
2016-01-01 03:30:00,0.0261416596035054,0.10552542460550364,0.07938376500199824
2016-01-01 03:45:00,0.009300330445916,0.007356677947842775,-0.0019436524980732247
2016-01-01 04:00:00,0.0264843050659245,0.13987913288798656,0.11339482782206206
2016-01-01 04:15:00,0.0405926330346124,0.01505676975984138,-0.025535863274771017
2016-01-01 04:30:00,0.040739211280267,0.3217850817801391,0.28104587049987206
2016-01-01 04:45:00,0.0405072188688263,0.02317818073919563,-0.01732903812963067
2016-01-01 05:00:00,0.0364741472516811,0.06122328551108127,0.024749138259400172
2016-01-01 05:15:00,0.0093203889536746,0.22513915054135117,0.21581876158767657
2016-01-01 05:30:00,0.0255923848829077,0.2691584802761322,0.2435660953932245
2016-01-01 05:45:00,0.022564346575841502,0.03688942618358793,0.01432507960774643
2016-01-01 06:00:00,0.0093104882929739,0.18858470224978502,0.17927421395681112
2016-01-01 06:15:00,0.0288361838358345,0.12475466785699271,0.09591848402115821
2016-01-01 06:30:00,0.0174818311447777,0.05896052140999221,0.04147869026521451
2016-01-01 06:45:00,0.0095341104278976,1.0,0.9904658895721024
2016-01-01 00:00:00,0.011886246327641098,7.04546466156181e-05,-0.01181579168102548
2016-01-01 00:15:00,0.0410388447933982,0.0002472798864404,-0.040791564906957796
2016-01-01 00:30:00,0.0406771589865564,0.0002556439361969,-0.0404215150503595
2016-01-01 00:45:00,0.0405878697548583,0.00035547628083400007,-0.0402323934740243
2016-01-01 01:00:00,0.0408237818838657,0.0010430721723367,-0.039780709711529
2016-01-01 01:15:00,0.0407177271612198,0.0010594459560612,-0.039658281205158595
2016-01-01 01:30:00,0.0155266774334944,0.0021104014895109,-0.013416275943983499
2016-01-01 01:45:00,0.0163007931439657,0.0012627368346117,-0.015038056309354002
2016-01-01 02:00:00,0.0322130119232581,0.0034005784433972,-0.028812433479860903
2016-01-01 02:15:00,0.0091297259677855,0.0034302420258756,-0.005699483941909899
2016-01-01 02:30:00,0.0193711826356853,0.0044974952377916,-0.0148736873978937
2016-01-01 02:45:00,0.028851808922693505,0.0087416387113377,-0.020110170211355805
2016-01-01 03:00:00,0.0092306359903934,0.0054444566014102,-0.0037861793889832004
2016-01-01 03:15:00,0.021129578178791,0.0130925846811014,-0.008036993497689599
2016-01-01 03:30:00,0.0261416596035054,0.014358121701060402,-0.011783537902444997
2016-01-01 03:45:00,0.009300330445916,0.0010009727768025,-0.0082993576691135
2016-01-01 04:00:00,0.0264843050659245,0.0190323954720175,-0.007451909593907003
2016-01-01 04:15:00,0.0405926330346124,0.0020486715257943,-0.0385439615088181
2016-01-01 04:30:00,0.040739211280267,0.04378309192364951,0.003043880643382506
2016-01-01 04:45:00,0.0405072188688263,0.0031536962879483,-0.037353522580878
2016-01-01 05:00:00,0.0364741472516811,0.0083302330939972,-0.0281439141576839
2016-01-01 05:15:00,0.0093203889536746,0.0306331420625005,0.0213127531088259
2016-01-01 05:30:00,0.0255923848829077,0.036622550737176705,0.011030165854269004
2016-01-01 05:45:00,0.022564346575841502,0.0050192915366731,-0.0175450550391684
2016-01-01 06:00:00,0.0093104882929739,0.0256594286730729,0.016348940380099
2016-01-01 06:15:00,0.0288361838358345,0.0169745131143746,-0.0118616707214599
2016-01-01 06:30:00,0.0174818311447777,0.0080223542821783,-0.0094594768625994
2016-01-01 06:45:00,0.0095341104278976,0.1360631502288365,0.1265290398009389
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
Time,load,pv,schedule
2016-01-01 00:00:00,0.0183501135461672,0.000517808433048365,-0.017832305113118833
2016-01-01 00:15:00,0.0183276402096313,0.0018173905721315046,-0.016510249637499797
2016-01-01 00:30:00,0.0186881603411869,0.0018788623941673238,-0.016809297947019578
2016-01-01 00:45:00,0.0184871298585762,0.0026125830560011706,-0.01587454680257503
2016-01-01 01:00:00,0.0179609033250519,0.007666088655028339,-0.01029481467002356
2016-01-01 01:15:00,0.0183569591857021,0.007786428245115456,-0.010570530940586641
2016-01-01 01:30:00,0.0429906796923723,0.015510455887296022,-0.02748022380507628
2016-01-01 01:45:00,0.0468752880631146,0.009280520350204874,-0.037594767712909725
2016-01-01 02:00:00,0.0483995519556214,0.024992648176070963,-0.023406903779550438
2016-01-01 02:15:00,0.04895941513644,0.025210661520819418,-0.02374875361562058
2016-01-01 02:30:00,0.0448443403712756,0.03305446941532318,-0.011789870955952415
2016-01-01 02:45:00,0.0243064739511402,0.06424692281955591,0.039940448868415704
2016-01-01 03:00:00,0.0495014864417933,0.04001418894280702,-0.009487297498986282
2016-01-01 03:15:00,0.0493275564676503,0.09622432421329186,0.046896767745641554
2016-01-01 03:30:00,0.0503633213311156,0.10552542460550364,0.05516210327438804
2016-01-01 03:45:00,0.0499530098865384,0.007356677947842775,-0.04259633193869562
2016-01-01 04:00:00,0.0291384623307321,0.13987913288798656,0.11074067055725446
2016-01-01 04:15:00,0.0181229042056159,0.01505676975984138,-0.0030661344457745213
2016-01-01 04:30:00,0.0184295811072935,0.3217850817801391,0.3033555006728456
2016-01-01 04:45:00,0.0184305987280745,0.02317818073919563,0.004747582011121132
2016-01-01 05:00:00,0.0185237682294309,0.06122328551108127,0.04269951728165037
2016-01-01 05:15:00,0.0185859507615892,0.22513915054135117,0.20655319977976197
2016-01-01 05:30:00,0.0183005206430141,0.2691584802761322,0.2508579596331181
2016-01-01 05:45:00,0.08552167641729819,0.03688942618358793,-0.048632250233710254
2016-01-01 06:00:00,0.2606096659283621,0.18858470224978502,-0.07202496367857708
2016-01-01 06:15:00,0.0887413067346138,0.12475466785699271,0.036013361122378906
2016-01-01 06:30:00,0.046890415232898,0.05896052140999221,0.012070106177094211
2016-01-01 06:45:00,0.041905529810521,1.0,0.958094470189479
2016-01-01 00:00:00,0.0183501135461672,7.04546466156181e-05,-0.01827965889955158
2016-01-01 00:15:00,0.0183276402096313,0.0002472798864404,-0.0180803603231909
2016-01-01 00:30:00,0.0186881603411869,0.0002556439361969,-0.01843251640499
2016-01-01 00:45:00,0.0184871298585762,0.00035547628083400007,-0.018131653577742202
2016-01-01 01:00:00,0.0179609033250519,0.0010430721723367,-0.0169178311527152
2016-01-01 01:15:00,0.0183569591857021,0.0010594459560612,-0.017297513229640897
2016-01-01 01:30:00,0.0429906796923723,0.0021104014895109,-0.0408802782028614
2016-01-01 01:45:00,0.0468752880631146,0.0012627368346117,-0.0456125512285029
2016-01-01 02:00:00,0.0483995519556214,0.0034005784433972,-0.0449989735122242
2016-01-01 02:15:00,0.04895941513644,0.0034302420258756,-0.0455291731105644
2016-01-01 02:30:00,0.0448443403712756,0.0044974952377916,-0.040346845133483994
2016-01-01 02:45:00,0.0243064739511402,0.0087416387113377,-0.0155648352398025
2016-01-01 03:00:00,0.0495014864417933,0.0054444566014102,-0.0440570298403831
2016-01-01 03:15:00,0.0493275564676503,0.0130925846811014,-0.0362349717865489
2016-01-01 03:30:00,0.0503633213311156,0.014358121701060402,-0.036005199630055204
2016-01-01 03:45:00,0.0499530098865384,0.0010009727768025,-0.0489520371097359
2016-01-01 04:00:00,0.0291384623307321,0.0190323954720175,-0.0101060668587146
2016-01-01 04:15:00,0.0181229042056159,0.0020486715257943,-0.016074232679821603
2016-01-01 04:30:00,0.0184295811072935,0.04378309192364951,0.025353510816356006
2016-01-01 04:45:00,0.0184305987280745,0.0031536962879483,-0.0152769024401262
2016-01-01 05:00:00,0.0185237682294309,0.0083302330939972,-0.0101935351354337
2016-01-01 05:15:00,0.0185859507615892,0.0306331420625005,0.012047191300911302
2016-01-01 05:30:00,0.0183005206430141,0.036622550737176705,0.018322030094162604
2016-01-01 05:45:00,0.08552167641729819,0.0050192915366731,-0.08050238488062508
2016-01-01 06:00:00,0.2606096659283621,0.0256594286730729,-0.23495023725528918
2016-01-01 06:15:00,0.0887413067346138,0.0169745131143746,-0.0717667936202392
2016-01-01 06:30:00,0.046890415232898,0.0080223542821783,-0.03886806095071969
2016-01-01 06:45:00,0.041905529810521,0.1360631502288365,0.09415762041831549
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ pytest
pathlib
numpy
pydot
pyomo
20 changes: 20 additions & 0 deletions simply/actor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from simply.util import daily, gaussian_pv
import simply.config as cfg

from simply.optimisation import optimize_schedule

Order = namedtuple("Order", ("type", "time", "actor_id", "cluster", "energy", "price"))
Order.__doc__ = """
Struct to hold order
Expand Down Expand Up @@ -188,6 +190,20 @@ def __init__(self, id, df, environment=None, battery=None, csv=None, ls=1, ps=1,
self.args = {"id": id, "df": df.to_json(), "csv": csv, "ls": ls, "ps": ps,
"pm": pm}

def strategy_with_optimisation(self):#change the name of the func
# Use the optimization library to implement the new strategy

objective, df_results = optimize_schedule(self.pred, self.mm_buy_prices, self.mm_sell_prices)

# Process the results as needed
# For example:
print("Optimization objective:", objective)
print("Optimization results:")
print(df_results)

market_schedule = df_results["to_grid"]
return market_schedule

def set_var_battery(self, capacity, soc_initial, df, available=0, max_c_rate=4,
refresh=True):
"""
Expand Down Expand Up @@ -274,6 +290,10 @@ def get_market_schedule(self, strategy=None):
f"without planning instead.")
strategy = self.strategy

if strategy == 4:
self.market_schedule = self.strategy_with_optimisation()
return self.market_schedule

if strategy == 0:
self.market_schedule = self.get_default_market_schedule()
# overwrite the current value of the market schedule if the soc would surpass 1
Expand Down
148 changes: 148 additions & 0 deletions simply/optimisation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# REQUIREMENTS# pyomo package needs to be installed
# a solver needs to be installed: CBC or GLPK are open source; for CBC
# coppy cbc_solver in the directory where the repo clone is

import pyomo.environ as pyo
import pandas as pd


def optimize_schedule(df_actor, buy_prices, sell_prices, capacity=10, max_c_rate=1, soc_initial=0.5):
# parametrisation of battery specified in simply/battery.py
# capacity=10, max_c_rate=1, soc_initial=0.5
# TODO battery-efficiency ?
# TODO electric vehicle parameter

# single time series vectors
t = list(range(len(df_actor)))
load = df_actor[["load"]].to_list()
pv = df_actor[["pv"]].to_list()
buy_prices = buy_prices.to_list()
sell_prices = sell_prices.to_list()

# TODO add electric vehicle
ev_avail = [1] * len(buy_prices)
ev_demand = [0] * len(buy_prices)

# other parameters
# TODO minutes per time step can be obtained using datetime functions from input csv-files
time_interval = 15 # minutes per time step
# TODO grid fee for buying electricity, see config.cfg
grid_fee = 0.0 # 0.09
# TODO if no upper bound is provided the problem turns out to be unbounded
grid_connection_capacity = 20

# PYOMO OPTIMISATION MODEL
model = pyo.ConcreteModel()
model.charging_power = pyo.Var(t, bounds=(0, capacity * max_c_rate))
model.discharging_power = pyo.Var(t, bounds=(0, capacity * max_c_rate))
model.stored_energy = pyo.Var(t, bounds=(0, capacity))
# 0/ 1 for distinguishing between charging / discharging
model.bi_charge = pyo.Var(t, within=pyo.Binary)
model.power_from_grid = pyo.Var(t, bounds=(0, grid_connection_capacity))
model.power_to_grid = pyo.Var(t, bounds=(0, grid_connection_capacity))
model.cash_flow = pyo.Var(t)

# energy balance for the system
model.energy_balance_system = pyo.ConstraintList()
for i in range(len(t) - 1):
model.energy_balance_system.add(
0 ==
model.power_from_grid[i] + pv[i] + model.discharging_power[i]
- load[i] - model.power_to_grid[i] - model.charging_power[i])

# component energy storage
model.energy_balance_storage = pyo.ConstraintList()
for i in range(len(t) - 1):
# constraint
model.energy_balance_storage.add(
model.stored_energy[i+1] - model.stored_energy[i] ==
(model.charging_power[i] - model.discharging_power[i]) * time_interval/60)

model.start_storage = pyo.Constraint(
expr=model.stored_energy[0] ==
soc_initial * capacity)

# optional: equal soc at first and last time step
model.start_end_storage = pyo.Constraint(
expr=model.stored_energy[0] == model.stored_energy[len(t)-1])

# needed in order to not have a discharge that affects the timestep after the last considered
model.end_no_discharge_storage = pyo.Constraint(
expr=0 == model.discharging_power[len(t)-1])

# binary variable to separate charging and discharging timesteps in order to
# exclude having both at the same time
model.binary_charge_storage = pyo.ConstraintList()
for i in t:
model.binary_charge_storage.add(
model.charging_power[i] <= model.bi_charge[i] * capacity * max_c_rate)

model.binary_discharge_storage = pyo.ConstraintList()
for i in t:
model.binary_discharge_storage.add(
model.discharging_power[i] <= (1 - model.bi_charge[i]) * capacity * max_c_rate)

# costs to be used in objective function
model.cash_flow_equation = pyo.ConstraintList()
for i in t:
model.cash_flow_equation.add(
model.cash_flow[i] ==
sell_prices[i] * model.power_to_grid[i] * time_interval/60
- (buy_prices[i] + grid_fee) * model.power_from_grid[i] * time_interval/60)

model.obj = pyo.Objective(
expr=sum(model.cash_flow[i] for i in t), sense=pyo.maximize)

# chose solver and solver-specific options
# opt = pyo.SolverFactory('glpk')
# opt.options['mipgap'] = 1e-3 # solver option for GLPK: relative gap, default: 0.0
# opt.options['tmlim'] = 60*30 # solver option for GLPK: timelimit in seconds
opt = pyo.SolverFactory('cbc')
opt.options['seconds'] = 60*30 # solver option for CBC: timelimit in seconds

_ = opt.solve(model, tee=True) # solve the problem
# model.pprint() # print results in run terminal

# RESULTS
# calculate objective for result output
objective = sum(model.cash_flow[i].value for i in t)
return objective, pd.DataFrame({
"Time": [df_actor.iat[i, 0] for i in t],
"load": load,
"pv": pv,
"sell_prices": sell_prices,
"buy_prices": buy_prices,
"from_grid": [model.power_from_grid[i].value for i in t],
"to_grid": [model.power_to_grid[i].value for i in t],
"charge": [model.charging_power[i].value for i in t],
"discharge": [model.discharging_power[i].value for i in t],
"soc": [model.stored_energy[i].value / capacity for i in t],
})


if __name__ == "__main__":
# INPUT DATA
# read input data from csv nad write to df
# just as one example
df_input_data_actor = pd.read_csv('/home/bedirhan/simply/projects/example_projects/example_project/scenario/actor_residential_1.csv')
load = df_input_data_actor.loc[:, "load"]
pv = df_input_data_actor.loc[:, "pv"]
df_input_data_prices = pd.read_csv('/home/bedirhan/simply/projects/example_projects/example_project/scenario/MarketMaker.csv')
buy_prices = df_input_data_prices.loc[:, "all_buy_prices"]
sell_prices = df_input_data_prices.loc[:, "all_sell_prices"]
objective, df_results = optimize_schedule(df_input_data_actor, load, pv, buy_prices, sell_prices)
# PRINTS
print("RESULTS:")
print("Objective:", objective)
pd.set_option('display.max_columns', None)
print(df_results)

import matplotlib.pyplot as plt
f, axs = plt.subplots(3)
energy_cols = ["load", "pv", "from_grid", "to_grid", "charge", "discharge"]
df_results[energy_cols].plot(ax=axs[0])
bat_cols = ["soc"]
df_results[bat_cols].plot(ax=axs[1])
price_cols = ["buy_prices"]
df_results[price_cols].plot(ax=axs[2])
plt.show()
4 changes: 4 additions & 0 deletions simply/scenario.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
import pandas as pd
import numpy as np
import random
#import matplotlib.pyplot as plt
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt

import simply.config as cfg
from simply import actor, market_maker
from simply import power_network
Expand Down
Loading