Skip to content

Added support to provide the PSDM with custom LoadProfile #1363

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

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased/Snapshot]

## Added
- Added support to provide the PSDM with custom `LoadProfile` [#1362](https://github.com/ie3-institute/PowerSystemDataModel/issues/1362)

### Fixed
- Fixed handling of `CongestionResult.InputModelType` in `EntityProcessor` [#1325](https://github.com/ie3-institute/PowerSystemDataModel/issues/1325)
- -Fixed em fields in input models [#1331](https://github.com/ie3-institute/PowerSystemDataModel/issues/1331)
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ dependencies {
implementation 'org.jgrapht:jgrapht-core:1.5.2'

// Statistics (for random load model)
implementation 'de.lmu.ifi.dbs.elki:elki:0.7.5'
implementation 'de.lmu.ifi.dbs.elki:elki-core-math:0.7.5'

// testing
testImplementation "org.apache.groovy:groovy:$groovyBinaryVersion"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* © 2025. TU Dortmund University,
* Institute of Energy Systems, Energy Efficiency and Energy Economics,
* Research group Distribution grid planning and operation
*/
package edu.ie3.datamodel.io.provider;

import edu.ie3.datamodel.io.factory.timeseries.BdewLoadProfileFactory;
import edu.ie3.datamodel.io.factory.timeseries.LoadProfileFactory;
import edu.ie3.datamodel.io.factory.timeseries.RandomLoadProfileFactory;
import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile;
import edu.ie3.datamodel.models.profile.LoadProfile;
import edu.ie3.datamodel.models.profile.NbwTemperatureDependantLoadProfile;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/** Interface defining a provider for {@link LoadProfile}s and their {@link LoadProfileFactory}. */
public interface LoadProfileProvider {

/** A list of all {@link LoadProfile}, that are known. */
List<? extends LoadProfile> loadedProfiles =
ServiceLoader.load(LoadProfileProvider.class).stream()
.map(ServiceLoader.Provider::get)
.map(LoadProfileProvider::getProfiles)
.flatMap(Collection::stream)
.toList();

/** A map of all known {@link LoadProfile} to their {@link LoadProfileFactory}. */
Map<? extends LoadProfile, ? extends LoadProfileFactory<?, ?>> profileToFactories =

Check notice on line 30 in src/main/java/edu/ie3/datamodel/io/provider/LoadProfileProvider.java

View check run for this annotation

SonarQubeGithubPRChecks / SonarQube Code Analysis

src/main/java/edu/ie3/datamodel/io/provider/LoadProfileProvider.java#L30

Move "profileToFactories" to a class and lower its visibility
ServiceLoader.load(LoadProfileProvider.class).stream()
.map(ServiceLoader.Provider::get)
.map(LoadProfileProvider::getFactories)
.flatMap(map -> map.entrySet().stream())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

/** Returns a list of {@link LoadProfile}s. */
List<? extends LoadProfile> getProfiles();

/** Returns a map of {@link LoadProfile} to {@link LoadProfileFactory}. */
Map<LoadProfile, LoadProfileFactory<?, ?>> getFactories();

/**
* Default load profile provider. This class is used to provide the {@link LoadProfile}s defined
* in the PSDM.
*/
final class DefaultLoadProfileProvider implements LoadProfileProvider {

@Override
public List<? extends LoadProfile> getProfiles() {
return Stream.of(
BdewStandardLoadProfile.values(),
NbwTemperatureDependantLoadProfile.values(),
LoadProfile.RandomLoadProfile.values(),
LoadProfile.DefaultLoadProfiles.values())
.flatMap(Arrays::stream)
.toList();
}

@Override
public Map<LoadProfile, LoadProfileFactory<?, ?>> getFactories() {
BdewLoadProfileFactory bdewLoadProfileFactory = new BdewLoadProfileFactory();

Map<LoadProfile, LoadProfileFactory<?, ?>> factories = new HashMap<>();

Arrays.stream(BdewStandardLoadProfile.values())
.forEach(profile -> factories.put(profile, bdewLoadProfileFactory));

factories.put(
LoadProfile.RandomLoadProfile.RANDOM_LOAD_PROFILE, new RandomLoadProfileFactory());

return factories;
}
}
}
13 changes: 6 additions & 7 deletions src/main/java/edu/ie3/datamodel/models/profile/LoadProfile.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
package edu.ie3.datamodel.models.profile;

import edu.ie3.datamodel.exceptions.ParsingException;
import edu.ie3.datamodel.io.provider.LoadProfileProvider;
import java.io.Serializable;
import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public interface LoadProfile extends Serializable {
/** @return The identifying String */
Expand All @@ -28,13 +28,12 @@ static LoadProfile parse(String key) throws ParsingException {
return LoadProfile.getProfile(getAllProfiles(), key);
}

/**
* Returns all {@link LoadProfile}s, that are either provided by the PSDM or provided using the
* {@link LoadProfileProvider}.
*/
static LoadProfile[] getAllProfiles() {
return Stream.of(
BdewStandardLoadProfile.values(),
NbwTemperatureDependantLoadProfile.values(),
(LoadProfile[]) RandomLoadProfile.values())
.flatMap(Arrays::stream)
.toArray(LoadProfile[]::new);
return LoadProfileProvider.loadedProfiles.toArray(LoadProfile[]::new);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
edu.ie3.datamodel.io.provider.LoadProfileProvider$DefaultLoadProfileProvider
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,6 @@ class LoadProfileTest extends Specification {

then:
def e = thrown(ParsingException)
e.message == "No predefined load profile with key 'not_a_key' found. Please provide one of the following keys: h0, l0, l1, l2, g0, g1, g2, g3, g4, g5, g6, ep1, ez2, random"
e.message == "No predefined load profile with key 'not_a_key' found. Please provide one of the following keys: h0, l0, l1, l2, g0, g1, g2, g3, g4, g5, g6, ep1, ez2, random, No load profile assigned"
}
}