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

Feature/usability: Allow input of precalculated time series and different SAM SI modules #317

Open
wants to merge 40 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
ed56c0a
allow own weather data
Piranias May 25, 2021
845bf11
add_weather_file and add_sam_si_module
Piranias May 25, 2021
15baa84
add_demand_timeseries
Piranias May 25, 2021
b23e4cf
add_demand_timeseries
Piranias May 25, 2021
49b5dd6
add docstrings for add_sam_si_module
Piranias May 25, 2021
c54e199
add more description for main function
Piranias May 25, 2021
cde4945
allow add pv timeseries
Piranias May 25, 2021
751725c
add docstring to new function
Piranias May 25, 2021
892d911
add changelog
Piranias May 25, 2021
e5295d5
apply black
Piranias May 25, 2021
9bf257d
add sam_si_module to nominal value
Piranias May 25, 2021
1a77703
add tests for new features to test_main()
Piranias May 25, 2021
d034425
add predefined timeseries to test data
Piranias May 25, 2021
5641840
adjust tests
Piranias May 25, 2021
be58676
fix tests and docstrings
Piranias May 26, 2021
edc6046
add decription of new features in docs
Piranias May 26, 2021
10dd843
adapt doctring
Piranias May 26, 2021
a2c9983
add energy system grapg to finish #165
Piranias May 26, 2021
392adbe
Update pvcompare/main.py
Piranias May 26, 2021
d3603e8
Update pvcompare/main.py
Piranias May 26, 2021
7d568ac
Merge branch 'dev' into feature/usability
Piranias May 26, 2021
bbcbe6d
Update CHANGELOG.md
Piranias May 28, 2021
d44bca4
Update docs/basic_usage.rst
Piranias May 28, 2021
07ac732
Update docs/basic_usage.rst
Piranias May 28, 2021
6a7f11e
Update docs/basic_usage.rst
Piranias May 28, 2021
d2dd2c4
Update docs/basic_usage.rst
Piranias May 28, 2021
809c09a
Update pvcompare/pv_feedin.py
Piranias May 28, 2021
fc6615d
Update pvcompare/pv_feedin.py
Piranias May 28, 2021
e5a0d00
Merge branch 'dev' into feature/usability
Piranias May 28, 2021
141c221
fix heat demand if file does not exist
Piranias May 28, 2021
c3524fc
add energy system graph
Piranias May 28, 2021
e932149
update name of graph
Piranias May 28, 2021
2b82251
Update docs/basic_usage.rst
Piranias May 28, 2021
972b697
Update docs/basic_usage.rst
Piranias May 28, 2021
8e959fe
Apply suggestions from code review
Piranias May 28, 2021
4a9d7d7
update docstrings
Piranias May 28, 2021
c3c7742
remove dots
Piranias May 28, 2021
50a9242
fix raise error and further tests
Piranias May 28, 2021
ff31feb
Merge branch 'dev' into feature/usability
Piranias May 28, 2021
b6cc633
apply black
Piranias May 30, 2021
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Here is a template for new release sections
- Add info on energy systems consisting of more than one node in RTD section "scope and limitations" (#293)
- Added description of the implementation of the stratified thermal storage in pvcompare with a description of the possibilities modeling it (#291)
- Dokumentation: Update on 'basic_usage', 'parameter description' and 'model assumptions' (#302)
- Usability: allow the user to provide their own weather data, demand time series, pv time series and SAM SI modules (#317)
Piranias marked this conversation as resolved.
Show resolved Hide resolved

### Changed
- The inlet temperatures of the heat pump and the stratified thermal storage have been revised in the pvcompare input parameters, adapting them in order to fit typical temperatures of the heating system. Also the pvcompare input parameters of the stratified thermal storage have been revised (#272)
Expand Down
92 changes: 69 additions & 23 deletions pvcompare/demand.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ def calculate_load_profiles(
static_inputs_directory=None,
user_inputs_pvcompare_directory=None,
user_inputs_mvs_directory=None,
add_electricity_demand=None,
add_heat_demand=None,
):
"""
Calculates electricity and heat load profiles and saves them to csv.
Expand All @@ -81,6 +83,12 @@ def calculate_load_profiles(
Default: None.
user_inputs_mvs_directory : str or None
Path to mvs input directory. If None: DEFAULT_USER_INPUTS_MVS_DIRECTORY. Default: None.
add_electricity_demand: str
Piranias marked this conversation as resolved.
Show resolved Hide resolved
Path to precalculated hourly electricity demand time series for one year (or the same period
of a precalculated PV timeseries)
add_heat_demand: str
Path to precalculated hourly heat demand time series for one year (or the same period
of a precalculated PV timeseries)

Returns
------
Expand All @@ -105,28 +113,66 @@ def calculate_load_profiles(
for column in energyConsumption:
if column != "unit":
if energyConsumption.at["energyVector", column] == "Heat":
calculate_heat_demand(
country=country,
lat=lat,
lon=lon,
storeys=storeys,
year=year,
weather=weather,
static_inputs_directory=static_inputs_directory,
user_inputs_pvcompare_directory=user_inputs_pvcompare_directory,
user_inputs_mvs_directory=user_inputs_mvs_directory,
column=column,
)

if add_heat_demand is not None:
# check if file exists
if os.path.isfile(add_heat_demand):
# save the file name of the time series
# mvs_inputs/elements/csv/energyProduction.csv
check_inputs.add_file_name_to_energy_consumption_file(
column=column,
ts_filename=add_heat_demand,
user_inputs_mvs_directory=user_inputs_mvs_directory,
)
else:
logging.warning(
Piranias marked this conversation as resolved.
Show resolved Hide resolved
"The heat demand time series"
" you have entered does not exist. It is"
" thus calculated according to the default"
" method of pvcompare."
)
else:
calculate_heat_demand(
country=country,
lat=lat,
lon=lon,
storeys=storeys,
year=year,
weather=weather,
static_inputs_directory=static_inputs_directory,
user_inputs_pvcompare_directory=user_inputs_pvcompare_directory,
user_inputs_mvs_directory=user_inputs_mvs_directory,
column=column,
)
elif energyConsumption.at["energyVector", column] == "Electricity":
calculate_power_demand(
country=country,
storeys=storeys,
year=year,
static_inputs_directory=static_inputs_directory,
user_inputs_pvcompare_directory=user_inputs_pvcompare_directory,
user_inputs_mvs_directory=user_inputs_mvs_directory,
column=column,
)

if add_electricity_demand is not None:

if os.path.isfile(add_electricity_demand):
# save the file name of the time series
# mvs_inputs/elements/csv/energyProduction.csv
check_inputs.add_file_name_to_energy_consumption_file(
column=column,
ts_filename=add_electricity_demand,
user_inputs_mvs_directory=user_inputs_mvs_directory,
)
else:
logging.warning(
"The electricity demand time series"
Piranias marked this conversation as resolved.
Show resolved Hide resolved
" you have entered does not exist. It is"
" thus calculated according to the default"
" method of pvcompare."
)
else:
calculate_power_demand(
country=country,
storeys=storeys,
year=year,
static_inputs_directory=static_inputs_directory,
user_inputs_pvcompare_directory=user_inputs_pvcompare_directory,
user_inputs_mvs_directory=user_inputs_mvs_directory,
column=column,
)
else:
logging.warning(
"the given energyVector in energyConsumption.csv "
Expand Down Expand Up @@ -300,7 +346,7 @@ def calculate_power_demand(
filename = os.path.join(timeseries_directory, el_demand_csv)
shifted_elec_demand.to_csv(filename, index=False)

# save the file name of the time series and the nominal value to
# save the file name of the time series
# mvs_inputs/elements/csv/energyProduction.csv
check_inputs.add_file_name_to_energy_consumption_file(
column=column,
Expand Down Expand Up @@ -502,7 +548,7 @@ def calculate_heat_demand(
filename = os.path.join(timeseries_directory, h_demand_csv)

shifted_heat_demand.to_csv(filename, index=False)
# save the file name of the time series and the nominal value to
# save the file name of the time series
# mvs_inputs/elements/csv/energyProduction.csv
check_inputs.add_file_name_to_energy_consumption_file(
column=column,
Expand Down
141 changes: 105 additions & 36 deletions pvcompare/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ def apply_pvcompare(
overwrite_grid_parameters=True,
overwrite_pv_parameters=True,
overwrite_heat_parameters=True,
add_weather_file=None,
add_sam_si_module=None,
add_electricity_demand=None,
add_heat_demand=None,
add_pv_timeseries=None,
):
"""
Runs the main functionalities of pvcompare.
Expand Down Expand Up @@ -92,6 +97,37 @@ def apply_pvcompare(
overwritten with calculated time series of COP and existing fixed thermal losses
absolute and relative will be overwritten with calculated time series of fixed thermal
losses relative and absolute.
add_weather_data: str or None
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have suggested adaptions to this docstring in a PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which PR?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Path to hourly csv weather time series with columns: [time, latitude, longitude
Piranias marked this conversation as resolved.
Show resolved Hide resolved
,ghi, wind_speed, temp_air, precipitable_water, dni, dhi]
Default: None. If None, the ERA5 data is used instead.
add_sam_si_module: dict or None
Dictionary with library (’CECMod’ or "SandiaMod") as key and module name as value.
E.g. {"cecmod":'Canadian_Solar_Inc__CS5P_220M'}.
Note that the SI module is only considered if there is the technology "SI" in
'user_inputs/mvs_inputs/pvcompare_inputs/pv_setup.csv'
add_electricity_demand: str or None
Path to precalculated hourly electricity demand time series for one year (or the same period
of a precalculated PV timeseries)
Note that that the demand is only considered is a column "Electricity demand" is added to
Piranias marked this conversation as resolved.
Show resolved Hide resolved
'user_inputs/mvs_inputs/csv_elements/energyConsumption.csv'
add_heat_demand: str or None
Path to precalculated hourly heat demand time series for one year (or the same period
of a precalculated PV timeseries)
Note that that the demand is only considered is a column "Heat demand" is added to
'user_inputs/mvs_inputs/csv_elements/energyConsumption.csv'
add_pv_timeseries: dict or None
Dictionary with {"PV1" : ["filename": >path_to_time_series< , "module_size": >module_size in m²<,
"module_peak_power": >peak power of the module in kWp<, "surface_type": >surface_type for PV installation<],
"PV2" : [...], ...}. If you want to consider more PV time series, more PV keys can be added.
The PV time series itself needs to be be an normalized hourly time series in kW/kWp
(normalized by the peak power of the module). The facades can be one of: [
"flat_roof", "gable_roof", "south_facade", "east_facade", "west_facade"].
Note that you need to add more specific PV parameters of your module (name, costs, lifetime etc.) in
'user_inputs/mvs_inputs/csv_elements/energyProduction.csv'. The columns in energyProduction.csv
should be named "PV"+ key (e.g. "PV SI1")
When providing your own time series, overwrite_pv_parameters should be
set to false. When add_pv_timeseries is used, the pv_setup.csv is disregarded.

Returns
-------
Expand Down Expand Up @@ -130,39 +166,55 @@ def apply_pvcompare(
user_inputs_mvs_directory=user_inputs_mvs_directory,
)

# check if weather data already exists
weather_file = os.path.join(
static_inputs_directory, f"weatherdata_{latitude}_{longitude}_{year}.csv"
)
if os.path.isfile(weather_file):
weather = pd.read_csv(weather_file, index_col=0,)
if add_weather_file is not None:
weather = pd.read_csv(add_weather_file, index_col=0,)
else:
# if era5 import works this line can be used
weather = era5.load_era5_weatherdata(lat=latitude, lon=longitude, year=year)
weather.to_csv(weather_file)
# check if weather data already exists
weather_file = os.path.join(
static_inputs_directory, f"weatherdata_{latitude}_{longitude}_{year}.csv"
)
if os.path.isfile(weather_file):
weather = pd.read_csv(weather_file, index_col=0,)
else:
# download ERA5 weather data
weather = era5.load_era5_weatherdata(lat=latitude, lon=longitude, year=year)
# save to csv
weather.to_csv(weather_file)
# add datetimeindex
weather.index = pd.to_datetime(weather.index)

# check energyProduction.csv file for the correct pv technology
check_inputs.overwrite_mvs_energy_production_file(
pv_setup=pv_setup,
user_inputs_mvs_directory=user_inputs_mvs_directory,
user_inputs_pvcompare_directory=user_inputs_pvcompare_directory,
collections_mvs_inputs_directory=collections_mvs_inputs_directory,
overwrite_pv_parameters=overwrite_pv_parameters,
)
pv_feedin.create_pv_components(
lat=latitude,
lon=longitude,
weather=weather,
storeys=storeys,
pv_setup=pv_setup,
plot=plot,
user_inputs_pvcompare_directory=user_inputs_pvcompare_directory,
user_inputs_mvs_directory=user_inputs_mvs_directory,
year=year,
normalization=True,
)
# check if add_pv_time_series is True
Piranias marked this conversation as resolved.
Show resolved Hide resolved
if add_pv_timeseries is not None:
pv_feedin.add_pv_timeseries(
add_pv_timeseries=add_pv_timeseries,
storeys=storeys,
user_inputs_mvs_directory=user_inputs_mvs_directory,
user_inputs_pvcompare_directory=user_inputs_pvcompare_directory,
)

else:
# check energyProduction.csv file for the correct pv technology
check_inputs.overwrite_mvs_energy_production_file(
pv_setup=pv_setup,
user_inputs_mvs_directory=user_inputs_mvs_directory,
user_inputs_pvcompare_directory=user_inputs_pvcompare_directory,
collections_mvs_inputs_directory=collections_mvs_inputs_directory,
overwrite_pv_parameters=overwrite_pv_parameters,
)

pv_feedin.create_pv_components(
lat=latitude,
lon=longitude,
weather=weather,
storeys=storeys,
pv_setup=pv_setup,
plot=plot,
user_inputs_pvcompare_directory=user_inputs_pvcompare_directory,
user_inputs_mvs_directory=user_inputs_mvs_directory,
year=year,
normalization=True,
add_sam_si_module=add_sam_si_module,
)

# add sector coupling in case heat pump or chiller exists in energyConversion.csv
# note: chiller was not tested, yet.
Expand All @@ -185,6 +237,8 @@ def apply_pvcompare(
user_inputs_pvcompare_directory=user_inputs_pvcompare_directory,
user_inputs_mvs_directory=user_inputs_mvs_directory,
weather=weather,
add_electricity_demand=add_electricity_demand,
add_heat_demand=add_heat_demand,
)

stratified_thermal_storage.add_strat_tes(
Expand Down Expand Up @@ -276,18 +330,33 @@ def apply_mvs(
year = 2018
SabineHaas marked this conversation as resolved.
Show resolved Hide resolved
storeys = 5
country = "Spain"
scenario_name = "Scenario_B2"
scenario_name = "Scenario_TEST_weatherdata"

apply_pvcompare(
latitude=latitude,
longitude=longitude,
year=year,
storeys=storeys,
country=country,
# add_pv_timeseries={
# "PV1": {
# "filename": "/home/inia/Dokumente/greco_env/pvcompare/pvcompare/data/user_inputs/mvs_inputs/time_series/cpv_90_0_2013_40.416775_-3.70379.csv",
# "module_size": 1,
# "module_peak_power": 50,
# "surface_type": "flat_roof",
# },
# "PV2": {
# "filename": "/home/inia/Dokumente/greco_env/pvcompare/pvcompare/data/user_inputs/mvs_inputs/time_series/cpv_90_0_2013_40.416775_-3.70379.csv",
# "module_size": 1,
# "module_peak_power": 50,
# "surface_type": "flat_roof",
# },
# },
add_sam_si_module={"cecmod": "Advance_Solar_Hydro_Wind_Power_API_180"},
)

# apply_mvs(
# scenario_name=scenario_name,
# outputs_directory=None,
# user_inputs_mvs_directory=None,
# )
# 'Canadian_Solar_CS5P_220M___2009_']
# apply_mvs(
# scenario_name=scenario_name,
# outputs_directory=None,
# user_inputs_mvs_directory=None,
# )
Loading