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

Implement various improvements to VDI feature #76

Open
wants to merge 8 commits into
base: dev
Choose a base branch
from

Conversation

jnettels
Copy link
Contributor

@jnettels jnettels commented Mar 3, 2025

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 existing from_try_data() now uses internally

  • Remove 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.

@jnettels jnettels self-assigned this Mar 3, 2025
@jnettels jnettels marked this pull request as ready for review March 3, 2025 12:40
@jnettels jnettels requested review from uvchik and p-snft March 3, 2025 12:40
Copy link
Member

@uvchik uvchik left a 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"))

Copy link
Member

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),
)
Copy link
Member

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
Copy link
Member

Choose a reason for hiding this comment

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

See comment above.

@jnettels
Copy link
Contributor Author

jnettels commented Mar 7, 2025

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 data

I 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.
However, I do not know how to generate those energy factors. From what I can read, the norm does not give any indication how those were actually generated. I assume it is a part of fitting real measurement data into the 'typical day' style. A user who is able to replicate this does not need the norm.

Please correct me, but I only see two outcomes:

  1. A user cannot create energy factors: This prevents them from using custom weather data
  2. A user digs into the source code to see how the official energy factors are loaded and writes their own function for creating a Climate object with the daily mean values of their weather data and the official energy factors

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 Climate().from_file() just puts an easy to use wrapper around the option 2 above, instead of forcing users to implement it themselves. What I should definitely improve is to add a note or warning to the function docstring to explain that it is not part of the official VDI usage.

Building options

You raise a valid point and I totally agree that it would be annoying to never notice that a setting for e.g. summer_temperature_limit was not in effect because of a typo.
Region().add_houses() already performs a check for valid house types (EFH, MFH). It would be straightforward to also test the houses for invalid arguments. Don't you think this would be far simpler to implement than switching to a new logic with a Building class? In any case there should always be a convenience function to create all the houses from e.g. a DataFrame or a list of dicts, where those tests for valid arguments would be necessary anyway.

I can offer to implement a check in Region().add_houses(), but I am not sure if I can write a class implementation that matches your vision.

@uvchik
Copy link
Member

uvchik commented Mar 10, 2025

Custom weather data

We 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 options

In the first step you can see the Building() class as a container, which is nothing more than a dictionary with given keys. In a second step you could add checks or methods if needed. In the docstring of this class you can clearly discribe the parameters. That makes it easier to use than discribing a dictionary that has to have to following keys... In a class you could even check the input if you want.
Furthermore, you could add the option to implement a MultiHouse that works like a singel hous but each parameter is a Series a not just a single value.

@jnettels
Copy link
Contributor Author

I implemented some changes as suggestions.

Custom weather data

  • I renamed the function to from_dwd_weather_file() to make the required file type obvious (you raised a valid point there)
  • I added quite a bit of notes to the docstring and the documentation to clarify that this is not the usage intended by the norm
  • I considered marking it as private _from_dwd_weather_file(), but it felt wrong to then mention it in the documentation, which I would still prefer

But all of this may not solve the fundamental problem:

Don't you think that people will be able to handle their own weather data and extract the temperature and cloud covererage?

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.
So it seems obvious to provide a convenience function for what is, from my point of view, the primary way to use this implementation. Of course, anyone with enough time and knowledge could implement what is now from_dwd_weather_file() for themselves, but I would prefer to have a well documented function that explains the caveats.
Also we are still talking about standardized profiles. They are never "correct" and always a rough estimation for cases where you cannot use e.g. measurement data or simulated load profiles. That is why I think the "error" introduced by using the "wrong" energy factors can be acceptable, if you are aware of them.

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 options

As a first step, I added checks for required and unsupported parameters to add_houses(). This is what I consider the actually required functionality. Can we agree on that?
Moving it to a new class could become a new step when I find more time, maybe in a separate PR?

@uvchik
Copy link
Member

uvchik commented Mar 14, 2025

Isn't it just easy to set a specific Parameter to None or 0?

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 def _load_weather_file(fn_weather, hoy) and def _load_energy_factors(try_region). In that case you could use these two functions to combine weather files with any data row of the energy factors but I would not announce that in the documentation or in the docstring.

@uvchik
Copy link
Member

uvchik commented Mar 14, 2025

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants