Commit f8a53820 authored by Sebastian Schwarz's avatar Sebastian Schwarz
Browse files

Merge development -> master

parent 66576884
<img src="./gitlab-utils/logos/pycity_scheduling.png" width="150"/>
<img src="https://fein-aachen.org/img/logos/pycity_scheduling.png" width="150"/>
# pycity_scheduling
......@@ -282,6 +282,8 @@ The pycity_scheduling package is released by the Institute for Automation of Com
## Contact
<img src="https://fein-aachen.org/img/logos/eonerc.png"/>
- Sebastian Schwarz, M.Sc. <sebastian.schwarz@eonerc.rwth-aachen.de>
- Sebastian Alexander Uerlich, B.Sc. <sebastian.uerlich@rwth-aachen.de>
- Univ.-Prof. Antonello Monti, Ph.D. <post_acs@eonerc.rwth-aachen.de>
......
......@@ -151,9 +151,9 @@
"source": [
"The following code finalizes the overall workflow of this illustrative code example by demonstrating different post-processing functionalities of the pycity_scheduling framework. For this purpose, in a first step we import the framework's post-processing utilities \"metric\", \"plot_schedules\", and \"write_schedules\" as shown in lines 41-43.\n",
"\n",
"In a second step, we call the CityDistrict's load_schedule function in line 46 to load the previously stored power schedules as tagged with the identifier \"optim_schedule\".\n",
"In a second step, we call the CityDistrict's load_schedule function in line 45 to load the previously stored power schedules as tagged with the identifier \"optim_schedule\".\n",
"\n",
"In a third step, we use the \"plot_entity\" functionality to plot the schedules of all optimization variables for the two objects of instance CityDistrict and Battery, where the schedules with the suffix \"p_el\" denote electrical power and \"e_el\" denote electrical energy, respectively. From the plots it becomes evident that the flexible battery device is scheduled in a way such that power is primarily imported from the energy spot market during cheap tariff periods, compare the price plot from the first part. This means that the battery unit is charged during these periods based on the defined energy cost minimization objective. Because of this behavior, low-cost electrical energy is temporarily stored inside the battery unit. Vice versa, the battery unit is discharged during expensive energy spot market tariff periods to supply the non-flexible building's electrical load locally during these periods. Moreover, one can see that the battery unit is also charged during time slots of high power penetration by the photovoltaic unit, compare the PV plot from the first part. This is because the locally generated photovoltaic energy is assumed to have zero energy costs, i.e., it can be perceived as free. The building's power self-consumption rate metric of approximately 67%, as evaluated in line 51, confirms this circumstance. The remaining 23% of photovoltaic power generation, however, cannot be consumed locally by the building, since the battery unit already operates at its physical charging power limit of 3.6kW. Finally and for further studies, we export the obtained schedules of the different multi-energy system assets into a JSON file named \"cost_otpim.json\" according to line 53.\n"
"In a third step, we use the \"plot_entity\" functionality to plot the schedules of all optimization variables for the two objects of instance CityDistrict and Battery, where the schedules with the suffix \"p_el\" denote electrical power and \"e_el\" denote electrical energy, respectively. From the plots it becomes evident that the flexible battery device is scheduled in a way such that power is primarily imported from the energy spot market during cheap tariff periods, compare the price plot from the first part. This means that the battery unit is charged during these periods based on the defined energy cost minimization objective. Because of this behavior, low-cost electrical energy is temporarily stored inside the battery unit. Vice versa, the battery unit is discharged during expensive energy spot market tariff periods to supply the non-flexible building's electrical load locally during these periods. Moreover, one can see that the battery unit is also charged during time slots of high power penetration by the photovoltaic unit, compare the PV plot from the first part. This is because the locally generated photovoltaic energy is assumed to have zero energy costs, i.e., it can be perceived as free. The building's power self-consumption rate metric of approximately 67%, as evaluated in line 50, confirms this circumstance. The remaining 23% of photovoltaic power generation, however, cannot be consumed locally by the building, since the battery unit already operates at its physical charging power limit of 3.6kW. Finally and for further studies, we export the obtained schedules of the different multi-energy system assets into a JSON file named \"cost_otpim.json\" according to line 52.\n"
]
},
{
......@@ -207,29 +207,21 @@
],
"metadata": {
"kernelspec": {
"display_name": "Octave",
"language": "octave",
"name": "octave"
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"file_extension": ".m",
"help_links": [
{
"text": "GNU Octave",
"url": "https://www.gnu.org/software/octave/support.html"
},
{
"text": "Octave Kernel",
"url": "https://github.com/Calysto/octave_kernel"
},
{
"text": "MetaKernel Magics",
"url": "https://metakernel.readthedocs.io/en/latest/source/README.html"
}
],
"mimetype": "text/x-octave",
"name": "octave",
"version": "4.2.2"
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.8"
}
},
"nbformat": 4,
......
import matplotlib.pyplot as plt
from pycity_scheduling.classes import *
from pycity_scheduling.algorithms import *
t = Timer(op_horizon=24, step_size=3600, initial_date=(2018, 3, 15), initial_time=(0, 0, 0))
w = Weather(timer=t, location=(50.76, 6.07))
p = Prices(timer=t)
e = Environment(timer=t, weather=w, prices=p)
fi = FixedLoad(environment=e, method=1, annual_demand=3000.0, profile_type="H0")
pv = Photovoltaic(environment=e, method=1, peak_power=6.0)
ba = Battery(environment=e, e_el_max=8.4, p_el_max_charge=3.6, p_el_max_discharge=3.6)
plot_time = list(range(t. timesteps_used_horizon))
fig, axs = plt.subplots(1, 3)
axs[0].plot(plot_time, p. da_prices, color="black")
axs[0].set_title("Day-ahead energy market prices [ct/kWh]")
axs[1].plot(plot_time, fi.p_el_schedule, color="black")
axs[1].set_title("Single-family house electrical load demand [kW]")
axs[2].plot(plot_time, pv.p_el_supply, color="black")
axs[2].set_title("Residential photovoltaics generation [kW]")
for ax in axs.flat:
ax.set(xlabel="Time [h]", xlim=[0, t.timesteps_used_horizon-1])
plt.grid()
plt.show()
import matplotlib.pyplot as plt
from pycity_scheduling.classes import *
from pycity_scheduling.algorithms import *
t = Timer(op_horizon=24, step_size=3600, initial_date=(2018, 3, 15), initial_time=(0, 0, 0))
w = Weather(timer=t, location=(50.76, 6.07))
p = Prices(timer=t)
e = Environment(timer=t, weather=w, prices=p)
fi = FixedLoad(environment=e, method=1, annual_demand=3000.0, profile_type="H0")
pv = Photovoltaic(environment=e, method=1, peak_power=6.0)
ba = Battery(environment=e, e_el_max=8.4, p_el_max_charge=3.6, p_el_max_discharge=3.6)
plot_time = list(range(t. timesteps_used_horizon))
fig, axs = plt.subplots(1, 3)
axs[0].plot(plot_time, p. da_prices, color="black")
axs[0].set_title("Day-ahead energy market prices [ct/kWh]")
axs[1].plot(plot_time, fi.p_el_schedule, color="black")
axs[1].set_title("Single-family house electrical load demand [kW]")
axs[2].plot(plot_time, pv.p_el_supply, color="black")
axs[2].set_title("Residential photovoltaics generation [kW]")
for ax in axs.flat:
ax.set(xlabel="Time [h]", xlim=[0, t.timesteps_used_horizon-1])
plt.grid()
plt.show()
bd = Building(environment=e, objective="none")
bes = BuildingEnergySystem(environment=e)
ap = Apartment(environment=e)
bd. addMultipleEntities(entities=[bes, ap])
bes . addDevice(objectInstance=pv)
ap. addMultipleEntities(entities=[fi, ba])
cd = CityDistrict(environment=e, objective="price")
cd. addEntity(bd, position=(0, 0))
opt = CentralOptimization(city_district=cd, mode="integer")
res = opt.solve()
cd.copy_schedule(dst="optim_schedule")
import matplotlib.pyplot as plt
from pycity_scheduling.classes import *
from pycity_scheduling.algorithms import *
t = Timer(op_horizon=24, step_size=3600, initial_date=(2018, 3, 15), initial_time=(0, 0, 0))
w = Weather(timer=t, location=(50.76, 6.07))
p = Prices(timer=t)
e = Environment(timer=t, weather=w, prices=p)
fi = FixedLoad(environment=e, method=1, annual_demand=3000.0, profile_type="H0")
pv = Photovoltaic(environment=e, method=1, peak_power=6.0)
ba = Battery(environment=e, e_el_max=8.4, p_el_max_charge=3.6, p_el_max_discharge=3.6)
plot_time = list(range(t. timesteps_used_horizon))
fig, axs = plt.subplots(1, 3)
axs[0].plot(plot_time, p. da_prices, color="black")
axs[0].set_title("Day-ahead energy market prices [ct/kWh]")
axs[1].plot(plot_time, fi.p_el_schedule, color="black")
axs[1].set_title("Single-family house electrical load demand [kW]")
axs[2].plot(plot_time, pv.p_el_supply, color="black")
axs[2].set_title("Residential photovoltaics generation [kW]")
for ax in axs.flat:
ax.set(xlabel="Time [h]", xlim=[0, t.timesteps_used_horizon-1])
plt.grid()
plt.show()
bd = Building(environment=e, objective="none")
bes = BuildingEnergySystem(environment=e)
ap = Apartment(environment=e)
bd. addMultipleEntities(entities=[bes, ap])
bes . addDevice(objectInstance=pv)
ap. addMultipleEntities(entities=[fi, ba])
cd = CityDistrict(environment=e, objective="price")
cd. addEntity(bd, position=(0, 0))
opt = CentralOptimization(city_district=cd, mode="integer")
res = opt.solve()
cd.copy_schedule(dst="optim_schedule")
from pycity_scheduling.util.metric import self_consumption
from pycity_scheduling.util.plot_schedules import plot_entity
from pycity_scheduling.util.write_schedules import schedule_to_json
cd.load_schedule(schedule="optim_schedule")
plot_entity(entity=cd, schedule=["optim_schedule"], title="City district - Cost-optimal schedules")
plot_entity(entity=ba, schedule=["optim_schedule"], title="Battery unit - Cost-optimal schedules")
print(self_consumption(entity=bd))
schedule_to_json(input_list=[fi, pv, ba], file_name="cost_optim.json", schedule=["optim_schedule"])
......@@ -27,13 +27,15 @@ import setuptools
os.chdir(os.path.dirname(os.path.realpath(__file__)))
with open('README.md') as f:
long_description = f.read()
setuptools.setup(
name="pycity_scheduling",
description="A Python framework for the development, testing, and assessment of optimization-based"
"power scheduling algorithms for multi-energy systems in city districts",
version="1.0.0",
author="Institute for Automation of Complex Power Systems,"
author="Institute for Automation of Complex Power Systems (ACS),"
"E.ON Energy Research Center (E.ON ERC),"
"RWTH Aachen University",
author_email="post_acs@eonerc.rwth-aachen.de",
......@@ -54,6 +56,8 @@ setuptools.setup(
"test": ["pytest"]
},
platforms="any",
long_description=long_description,
long_description_content_type='text/markdown',
classifiers=[
"Development Status :: 5 - Production/Stable",
"Operating System :: OS Independent",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment