-
Notifications
You must be signed in to change notification settings - Fork 39
Implement various improvements to VDI feature #76
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
base: dev
Are you sure you want to change the base?
Conversation
Heating, hot water and electrical demand are now optional parameters. If they are not provided, the respective time series will be returned with all NaNs.
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.
Thank you for improving the documentation.
The possibility to upload other weather data is okay for me. What is important to me is that matching energy factors must be uploaded at the same time so that users realise that the two are directly related. You can't upload new weather data if you don't have the matching energy factors.
A dictionary is already a problematic construct for providing input data. If other problems arise now, we should make a separate building class out of it.
q_tww_a = house["Q_TWW_a"] | ||
q_heiz_a = house.get("Q_Heiz_a", float("NaN")) | ||
w_a = house.get("W_a", float("NaN")) | ||
q_tww_a = house.get("Q_TWW_a", float("NaN")) | ||
|
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 do not agree with this behaviour. This will also happen if there is a typo in the parameter. I think the best way to deal with this ist to introduce a Building()
class where we can define what will happen with any of the parameters.
summer=house["summer_temperature_limit"], | ||
winter=house["winter_temperature_limit"], | ||
summer=house.get("summer_temperature_limit", 15), | ||
winter=house.get("winter_temperature_limit", 5), | ||
) |
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.
See acomment above.
@@ -632,7 +649,7 @@ def get_load_curve_houses(self): | |||
# The typical day calculation inherently does not add up to the | |||
# desired total energy demand of the full year. Here we fix that: | |||
for column in load_curve_house.columns: | |||
q_a = house[column.replace("TT", "a")] | |||
q_a = house.get(column.replace("TT", "a"), float("NaN")) | |||
sum_ = load_curve_house[column].sum() | |||
if sum_ > 0: # Would produce NaN otherwise |
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.
See comment above.
Thanks for your comments. I did not realize this would be so controversial, so maybe it would be better to remove this PR and create one for "custom weather data" and one for "updated building options" (and a third to update the example and docs after both are merged). Would you prefer that? In the mean time we should separate the following two discussions: Custom weather dataI guess your sentiment is that by using custom weather data we leave the defined use case of the norm? The energy factor matrix was fitted to each of the 15 weather regions and weather data specifically. Combining custom weather data with the existing energy factors can be considered inappropriate. Requiring users to provide energy factors that match their weather data is the logical conclusion. Please correct me, but I only see two outcomes:
I think it should be each user's responsibility to decide weather they stick to the norm and the official weather data, or prefer using their own weather data at the cost of some minor "error" in the way the typical days are scaled relative to each other. Using the wrong weather data might be the worse decision in many cases. My proposed function Building optionsYou raise a valid point and I totally agree that it would be annoying to never notice that a setting for e.g. I can offer to implement a check in |
Custom weather dataWe could make the method private, making it clear that you should not use it. In fact, in Python you can use it anyway: def _from_file(self, fn_weather, try_region, hoy=8760):
pass However, you expect the user to have a very specific weather file. Most users will have csv files. Your method suggests that it is possible to load custom weather files, but in fact you can only load a very specific formatted weather file. Why not leave it up to the user. Anyone is free to use the following function: weather = dwd_try.read_dwd_weather_file(fn_weather) Don't you think that people will be able to handle their own weather data and extract the temperature and cloud covererage? There are no other energy factors at the moment, but there may be in the future. People just have to add three parameters and if they know what they are doing, they can just do it. A convenient method that returns a wrong combination does not seem useful to me. Building optionsIn the first step you can see the |
I implemented some changes as suggestions. Custom weather data
But all of this may not solve the fundamental problem:
I do expect users to be able to handle their own weather data and extract the temperature and cloud coverage. But that is beside the point, because I cannot expect them to come up with their own energy factors. This prohibits the usage of custom weather data. Let's look at it this way: In the projects I am involved, it is quite common to use the current DWD TRY weather data. On the other hand, the 2010 DWD weather should arguably not be used anymore, because it is out of date and even contains errors (specifically in the radiation data). Also, no one would want use different weather data for different parts of a project. Also I think it is fair to assume that most users who want to use VDI profiles are from Germany. If you cannot agree with that, would making the function private be an acceptable compromise? Would we have to remove it from the documentation then? Building optionsAs a first step, I added checks for required and unsupported parameters to |
Isn't it just easy to set a specific Parameter to 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": None,
"summer_temperature_limit": 15,
"winter_temperature_limit": 5,
}
) When I find time, I could add a Building class. Actually there is already a building class and we should bring both approaches as close together as possible. Adding your own weather data and using the VDI energy factors is just wrong and I would not provide a function to do wrong things. If you want we could internally provide a |
BTW: It might save time if you do not implent everthing diretly but first discuss what you want to do. It feels strange to me if you provide many lines of code and I have to say, that I do not agree with the general approach. |
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.
Thank you for your effort. Honestly, I am not really deep into standard heat demand curves, however, I can comment this from a software design perspective.
To hopefully solve the discussion on custom weather: We currently allow to define custom seasons in the BDEW SLP, which is also not to standard. Thus, it might be consistent to also allow some more freedom here. Also, we have the class vdi.Region(temperature, cloud_coverage, energy_factors)
, which already allows to give user-defined energy factors.
However, if the standard defines specific regions and according TRYs, we should explicitly state that it's not up to standard if these numbers are changed. (The same is true for the BDEW electricity SLPs from 2000. We should state that "custom seasons" violate the standard, if they do.)
* ``Q_Heiz_a``: Annual heating demand in kWh | ||
* ``Q_TWW_a``: Annual hot water demand in kWh | ||
* ``W_a``: Annual electricity demand in kWh |
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 would always require these inputs. If you do not want to have TWW, you can simply give 0.
summer=house.get("summer_temperature_limit", 15), | ||
winter=house.get("winter_temperature_limit", 5), |
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.
Aren't these temperatures in the norm? If so, I think it's okay to set them as defaults.
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.
Correct, these are the values used per default in the norm.
It makes me think my suggestions through and allows me to test them. Also I feel like sometimes just writing the code is the most precise form of communicating a suggestion. Custom weather dataI think I cannot add anything new to the discussion. Thanks for chiming in, @p-snft. You ask for a specific disclaimer in case of deviations from the standard. This is the disclaimer I already included in the function
To answer this comment:
If we cannot agree on anything else, this would be a useful addition, yes. Building optionsYou both agree that all three energy values should be required arguments. But I'd like to make some distinctions: Allowing If |
Now, I see the point why you want to have the values undefined. However, creating garbage data (NaN) would not be the expected result of that. You will have endless columns of NaN which isn't any better than 0. It consumes the same memory and even computations are executed. When I put None as an input, I would expect None as an output, not NaN.
I feel the same. For bigger changes I try to draft and discuss them beforehand, but sometimes an implementation is the fastest way specify something. (Following this approach, however, also means that suggested changes will be rejected, as implementation and rejection are part of the discussion process.) |
I just didn't want you to write a lot of code that might get deleted, but if that's okay with you, it's okay with me.
I would go the other way round and change the API for BDEW SLP.
This is missleading. If you have a method as described above it is totally fine, but this is not what we have here. We have something like this: my_dict= {
"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": None,
"summer_temperature_limit": 15,
"winter_temperature_limit": 5,
}
)
class Building:
def __init__(self, q_heiz_a=None, q_tww_a=None, w_a=None):
self.q_heiz_a = q_heiz_a
self.q_tww_a = q_tww_a
self.w_a = w_a The code would look like this: my_building = Building(q_heiz_a=5000, q_tww_a=1000, w_a=2000)
make_me_some_profiles_plz(my_building) Now it works as @jnettels intended and EDIT: It does not have to be a Building class it could also be a Region class or whatever name. |
I found several possible improvements for the VDI4655 feature. I considered opening a PR for each of them, but I think that would be too much effort to review. The commits are cleanly separated, except for the changes to the documentation (which is affected by most of the changes).
Make parameters 'summer_temperature_limit' and 'winter_temperature_limit' actually optional
Allow skipping any energy type: Heating, hot water and electrical demand are now optional parameters. If they are not provided, the respective time series will be returned with all NaNs.
Allow custom DWD weather data by exposing a new function
from_file()
, which the existingfrom_try_data()
now uses internallyRemove unused parameter 'copies' from example and reorder parameters
Adapt VDI documentation to latest changes
I hope this is fine, if necessary I will separate e.g. the weather data commit into a new PR.