-
Notifications
You must be signed in to change notification settings - Fork 38
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
Add VDI profiles based on lpagg #50
Draft
uvchik
wants to merge
25
commits into
v0.2dev
Choose a base branch
from
features/add-vdi-from-lpagg
base: v0.2dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
477c92e
Add lpagg code to demanlib
uvchik 4c63562
Add example for VDI profiles
uvchik 73480cd
Fix grammar
uvchik 6109b41
Add extra requirements for examples
uvchik d512612
Use black style
uvchik ea24008
Revise region module
uvchik 7b258b8
Make it possible to import Region from demandlib.vdi
uvchik ab21b5b
Add function to find TRY region by coordinates
uvchik 33a5964
Add geometry as extra requirements
uvchik 4160146
Add docstrings
uvchik a3660ae
Remove binary file from repository
uvchik 3785bc9
Do not read unused columns
uvchik b11468e
Fix style issues
uvchik 4eeed80
Fix style issues
uvchik ac2eb6c
Use new black style
uvchik d9e0d8d
Use temperature limits from config file
uvchik 31640f7
Add missing config import
uvchik 00e1114
Fix time stamp to left index
uvchik 2e205c9
Fix filepath for TRY data
uvchik f5a6e78
Remove blank line
uvchik 5d75001
Make VDI header clearer
uvchik 7cccf52
Temperature limit is part of the house data
uvchik a54ca63
Update src/demandlib/vdi/regions.py
uvchik 652ef05
Fix deprecated warning
b3fd0c4
Make it possible to fetch weather data by knowing the TRY region
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,103 @@ | ||||||
# -*- coding: utf-8 -*- | ||||||
""" | ||||||
Creating power demand profiles using bdew profiles. | ||||||
|
||||||
Installation requirements | ||||||
------------------------- | ||||||
This example requires at least version v0.1.4 of the oemof demandlib. Install | ||||||
by: | ||||||
pip install 'demandlib>=0.1.4,<0.2' | ||||||
Optional: | ||||||
pip install matplotlib | ||||||
|
||||||
SPDX-FileCopyrightText: Uwe Krien <krien@uni-bremen.de> | ||||||
|
||||||
SPDX-License-Identifier: MIT | ||||||
|
||||||
""" | ||||||
|
||||||
import datetime | ||||||
|
||||||
from matplotlib import pyplot as plt | ||||||
|
||||||
from demandlib import vdi | ||||||
|
||||||
# The following dictionary has been created by "workalendar" | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Maybe this is more clear. |
||||||
# pip3 install workalendar | ||||||
# from workalendar.europe import Germany | ||||||
# cal = Germany() | ||||||
# holidays = dict(cal.holidays(2017)) | ||||||
|
||||||
holidays = { | ||||||
datetime.date(2017, 1, 1): "New year", | ||||||
datetime.date(2017, 4, 14): "Good Friday", | ||||||
datetime.date(2017, 4, 17): "Easter Monday", | ||||||
datetime.date(2017, 5, 1): "Labour Day", | ||||||
datetime.date(2017, 5, 25): "Ascension Thursday", | ||||||
datetime.date(2017, 6, 5): "Whit Monday", | ||||||
datetime.date(2017, 10, 3): "Day of German Unity", | ||||||
datetime.date(2017, 10, 31): "Reformation Day", | ||||||
datetime.date(2017, 12, 25): "Christmas Day", | ||||||
datetime.date(2017, 12, 26): "Second Christmas Day", | ||||||
} | ||||||
p-snft marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
|
||||||
my_houses = [] | ||||||
for n in range(2): | ||||||
my_houses.append( | ||||||
{ | ||||||
"N_Pers": 3, | ||||||
"name": "EFH_{0}".format(n), | ||||||
"N_WE": 1, | ||||||
"Q_Heiz_a": 6000, | ||||||
"copies": 24, | ||||||
"house_type": "EFH", | ||||||
"Q_TWW_a": 1500, | ||||||
"W_a": 5250, | ||||||
"summer_temperature_limit": 15, | ||||||
"winter_temperature_limit": 5, | ||||||
} | ||||||
) | ||||||
my_houses.append( | ||||||
{ | ||||||
"N_Pers": 45, | ||||||
"name": "MFH_{0}".format(n), | ||||||
"N_WE": 15, | ||||||
"Q_Heiz_a": 60000, | ||||||
"copies": 24, | ||||||
"house_type": "MFH", | ||||||
"Q_TWW_a": 15000, | ||||||
"W_a": 45000, | ||||||
"summer_temperature_limit": 15, | ||||||
"winter_temperature_limit": 5, | ||||||
} | ||||||
) | ||||||
|
||||||
start = datetime.datetime.now() | ||||||
|
||||||
# To get the DWD TRY region from coordinates the geopandas package is needed. | ||||||
# pip3 install geopandas | ||||||
# try_region = vdi.find_try_region(13.42, 52.82) | ||||||
try_region = 4 | ||||||
|
||||||
# define the region | ||||||
my_region = vdi.Region( | ||||||
2017, | ||||||
holidays=holidays, | ||||||
try_region=try_region, | ||||||
houses=my_houses, | ||||||
resample_rule="15min", | ||||||
) | ||||||
|
||||||
# calculate load profiles | ||||||
lc = my_region.get_load_curve_houses() | ||||||
|
||||||
print(datetime.datetime.now() - start) | ||||||
lc = lc.groupby(level=[1, 2], axis=1).sum() | ||||||
lc = lc.rolling(15).mean() | ||||||
print(datetime.datetime.now() - start) | ||||||
print(lc) | ||||||
|
||||||
lc.plot() | ||||||
print(lc.sum()) | ||||||
plt.show() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
""" | ||
Adaptable config reader. | ||
|
||
By default the config file of the package is used. Each value can be | ||
overwritten with a user value with a custom config file in the $HOME directory | ||
or in the working directory. The name of the config file must be: | ||
demandlib.ini. If there is such a file in both locations the file in the | ||
working directory will overwrite the one in the home folder. | ||
|
||
SPDX-FileCopyrightText: Steffen - https://github.com/steffenGit | ||
SPDX-FileCopyrightText: 2016-2021 Uwe Krien <krien@uni-bremen.de> | ||
|
||
SPDX-License-Identifier: MIT | ||
""" | ||
|
||
__all__ = [ | ||
"get", | ||
"init", | ||
] | ||
|
||
|
||
import configparser as cp | ||
import os | ||
|
||
BLACKLIST = ["tox.ini"] | ||
|
||
cfg = cp.RawConfigParser() | ||
cfg.optionxform = str | ||
_loaded = False | ||
|
||
|
||
def get_ini_filenames(): | ||
"""Returns a list of ini files to use.""" | ||
paths = [] | ||
files = [] | ||
|
||
paths.append(os.path.join(os.path.dirname(__file__))) | ||
paths.append(os.path.join(os.path.expanduser("~"))) | ||
paths.append(os.getcwd()) | ||
|
||
for p in paths: | ||
if p == "": # Empty path string must be ignored | ||
continue | ||
for f in os.listdir(p): | ||
if f == "demandlib.ini": | ||
files.append(os.path.join(p, f)) | ||
return files | ||
|
||
|
||
def init(): | ||
"""Read config file(s).""" | ||
cfg.read(get_ini_filenames(), encoding="utf-8") | ||
global _loaded | ||
_loaded = True | ||
|
||
|
||
def load(): | ||
if not _loaded: | ||
init() | ||
|
||
|
||
def get(section, key): | ||
"""Returns the value of a given key in a given section.""" | ||
load() | ||
try: | ||
return cfg.getint(section, key) | ||
except ValueError: | ||
try: | ||
return cfg.getfloat(section, key) | ||
except ValueError: | ||
try: | ||
return cfg.getboolean(section, key) | ||
except ValueError: | ||
value = cfg.get(section, key) | ||
if value == "None": | ||
value = None | ||
return value |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from .dwd_try import find_try_region # noqa: F401 | ||
from .dwd_try import read_dwd_weather_file # noqa: F401 | ||
from .regions import Region # noqa: F401 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
Read DWD TRY (test reference year) data. | ||
|
||
SPDX-FileCopyrightText: Joris Zimmermann | ||
SPDX-FileCopyrightText: Uwe Krien | ||
|
||
SPDX-License-Identifier: MIT | ||
""" | ||
|
||
import os | ||
|
||
import pandas as pd | ||
|
||
try: | ||
import geopandas as gpd | ||
from shapely.geometry import Point | ||
except ModuleNotFoundError: | ||
pass | ||
|
||
|
||
def find_try_region(longitude, latitude): | ||
""" | ||
Find the DWD TRY region by coordinates. | ||
|
||
Notes | ||
----- | ||
The packages geopandas and shapely need to be installed to use this | ||
function. | ||
|
||
Parameters | ||
---------- | ||
longitude : float | ||
latitude : float | ||
|
||
Returns | ||
------- | ||
DWD TRY region. : int | ||
|
||
""" | ||
fn_try_map = os.path.join( | ||
os.path.dirname(__file__), "resources_weather", "TRY_polygons.geojson" | ||
) | ||
try_map = gpd.read_file(fn_try_map) | ||
my_point = Point(longitude, latitude) | ||
return int(try_map.loc[try_map.contains(my_point), "TRY_code"]) | ||
|
||
|
||
def read_dwd_weather_file(weather_file_path=None, try_region=None): | ||
"""Read and interpolate 'DWD Testreferenzjahr' files.""" | ||
if weather_file_path is None: | ||
weather_file_path = os.path.join( | ||
os.path.dirname(__file__), | ||
"resources_weather", | ||
"TRY2010_{:02d}_Jahr.dat".format(try_region), | ||
) | ||
# The comments in DWD files before the header are not commented out. | ||
# Thus we have to search for the line with the header information: | ||
header_row = None | ||
with open(weather_file_path, "r") as rows: | ||
for number, row in enumerate(rows, 1): | ||
# The header is the row before the appearance of '***' | ||
if "***" in row: | ||
header_row = number - 1 | ||
break | ||
|
||
# Plausibility check: | ||
if header_row is None: | ||
msg = ( | ||
"Error: Header row not found in weather file. " | ||
'Is the data type "DWD" correct? Exiting...\nFile is: ' | ||
+ weather_file_path | ||
) | ||
raise TypeError(msg) | ||
|
||
# Read the file and store it in a DataFrame | ||
weather_data = pd.read_csv( | ||
weather_file_path, | ||
delim_whitespace=True, | ||
skiprows=header_row - 1, | ||
index_col=["MM", "DD", "HH"], | ||
usecols=["MM", "DD", "HH", "t", "N"], | ||
comment="*", | ||
) | ||
|
||
# Rename the columns | ||
weather_data.rename( | ||
columns={ | ||
"t": "TAMB", | ||
"N": "CCOVER", | ||
}, | ||
inplace=True, | ||
) | ||
|
||
return weather_data |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a bit puzzled here. First, you write that the dictionary has been/ is created using
workalendar
but later you define the holidays yourself.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I am writing comments here... :-)
Since those lines are commented out, I think this is just to suggest how to use an alternative library, without creating a new dependency for the installation of demandlib. My only suggestion would be to also name https://pypi.org/project/holidays/ as another option. Personally, it took me much too long to stumble across it.