Skip to content
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Added weathersource documentation [#1390](https://github.com/ie3-institute/PowerSystemDataModel/issues/1390)
- Added standard asset parameter for `3wTransformer` in `ReadTheDocs` [#1417](https://github.com/ie3-institute/PowerSystemDataModel/issues/1417)
- Added abstraction for power value sources [#1438](https://github.com/ie3-institute/PowerSystemDataModel/issues/1438)

### Fixed
- Fixed small issues in tests [#1400](https://github.com/ie3-institute/PowerSystemDataModel/issues/1400)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,9 @@ public int hashCode() {
@Override
public String toString() {
return "CsvLoadProfileMetaInformation{"
+ "uuid='"
+ getUuid()
+ '\''
+ ", profile='"
+ "profile='"
+ getProfile()
+ '\''
+ "fullFilePath="
+ ", fullFilePath="
+ fullFilePath
+ '}';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

import edu.ie3.datamodel.exceptions.FactoryException;
import edu.ie3.datamodel.exceptions.ParsingException;
import edu.ie3.datamodel.io.naming.timeseries.LoadProfileMetaInformation;
import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile;
import edu.ie3.datamodel.models.timeseries.TimeSeriesEntry;
import edu.ie3.datamodel.models.timeseries.repetitive.BdewLoadProfileTimeSeries;
Expand Down Expand Up @@ -70,9 +69,7 @@ protected List<Set<String>> getFields(Class<?> entityClass) {

@Override
public BdewLoadProfileTimeSeries build(
LoadProfileMetaInformation metaInformation, Set<LoadProfileEntry<BdewLoadValues>> entries) {

BdewStandardLoadProfile profile = parseProfile(metaInformation.getProfile());
BdewStandardLoadProfile profile, Set<LoadProfileEntry<BdewLoadValues>> entries) {
ComparableQuantity<Power> maxPower = calculateMaxPower(profile, entries);
ComparableQuantity<Energy> profileEnergyScaling = getLoadProfileEnergyScaling(profile);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
package edu.ie3.datamodel.io.factory.timeseries;

import edu.ie3.datamodel.io.factory.Factory;
import edu.ie3.datamodel.io.naming.timeseries.LoadProfileMetaInformation;
import edu.ie3.datamodel.models.profile.LoadProfile;
import edu.ie3.datamodel.models.timeseries.repetitive.LoadProfileEntry;
import edu.ie3.datamodel.models.timeseries.repetitive.LoadProfileTimeSeries;
Expand Down Expand Up @@ -37,8 +36,7 @@ protected LoadProfileFactory(Class<? extends V>... valueClass) {
super(valueClass);
}

public abstract LoadProfileTimeSeries<P, V> build(
LoadProfileMetaInformation metaInformation, Set<LoadProfileEntry<V>> entries);
public abstract LoadProfileTimeSeries<P, V> build(P profile, Set<LoadProfileEntry<V>> entries);

public abstract P parseProfile(String profile);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import static edu.ie3.datamodel.models.profile.LoadProfile.RandomLoadProfile.RANDOM_LOAD_PROFILE;
import static tech.units.indriya.unit.Units.WATT;

import edu.ie3.datamodel.io.naming.timeseries.LoadProfileMetaInformation;
import edu.ie3.datamodel.models.profile.LoadProfile.RandomLoadProfile;
import edu.ie3.datamodel.models.timeseries.repetitive.LoadProfileEntry;
import edu.ie3.datamodel.models.timeseries.repetitive.RandomLoadProfileTimeSeries;
Expand Down Expand Up @@ -73,9 +72,7 @@ protected List<Set<String>> getFields(Class<?> entityClass) {

@Override
public RandomLoadProfileTimeSeries build(
LoadProfileMetaInformation metaInformation, Set<LoadProfileEntry<RandomLoadValues>> entries) {
RandomLoadProfile profile = RANDOM_LOAD_PROFILE;

RandomLoadProfile profile, Set<LoadProfileEntry<RandomLoadValues>> entries) {
ComparableQuantity<Power> maxPower = calculateMaxPower(profile, entries);
ComparableQuantity<Energy> profileEnergyScaling = getLoadProfileEnergyScaling(profile);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@ public LoadProfileMetaInformation(String profile) {
this.profile = profile;
}

public LoadProfileMetaInformation(UUID uuid, String profile) {
super(uuid);
this.profile = profile;
}

public String getProfile() {
return profile;
}
Expand All @@ -37,18 +32,11 @@ public boolean equals(Object o) {

@Override
public int hashCode() {
return Objects.hash(super.hashCode(), profile);
return Objects.hash(profile);
Copy link
Member

Choose a reason for hiding this comment

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

Wouldn't do this, especially because the equals method still relies on the super class

}

@Override
public String toString() {
return "LoadProfileTimeSeriesMetaInformation{"
+ "uuid='"
+ getUuid()
+ '\''
+ ", profile='"
+ profile
+ '\''
+ '}';
return "LoadProfileTimeSeriesMetaInformation{profile='" + profile + '}';
}
}
2 changes: 1 addition & 1 deletion src/main/java/edu/ie3/datamodel/io/sink/SqlSink.java
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ private <C extends Entity> void persistMixedList(List<C> entities, DbGridMetadat
void persistList(List<C> entities, Class<C> cls, DbGridMetadata identifier)
throws SQLException {
// Check if there are only elements of the same class
Class<?> firstClass = entities.get(0).getClass();
Class<?> firstClass = entities.getFirst().getClass();
boolean allSameClass = entities.stream().allMatch(e -> e.getClass() == firstClass);

if (allSameClass) {
Expand Down
54 changes: 20 additions & 34 deletions src/main/java/edu/ie3/datamodel/io/source/LoadProfileSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,36 @@
import edu.ie3.datamodel.io.factory.timeseries.LoadProfileData;
import edu.ie3.datamodel.io.factory.timeseries.LoadProfileFactory;
import edu.ie3.datamodel.io.factory.timeseries.RandomLoadProfileFactory;
import edu.ie3.datamodel.io.naming.timeseries.LoadProfileMetaInformation;
import edu.ie3.datamodel.io.source.csv.CsvDataSource;
import edu.ie3.datamodel.io.source.csv.CsvLoadProfileSource;
import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile;
import edu.ie3.datamodel.models.profile.LoadProfile;
import edu.ie3.datamodel.models.timeseries.repetitive.LoadProfileEntry;
import edu.ie3.datamodel.models.timeseries.repetitive.LoadProfileTimeSeries;
import edu.ie3.datamodel.models.timeseries.repetitive.RandomLoadProfileTimeSeries;
import edu.ie3.datamodel.models.value.PValue;
import edu.ie3.datamodel.models.value.Value;
import edu.ie3.datamodel.models.value.load.BdewLoadValues;
import edu.ie3.datamodel.models.value.load.LoadValues;
import edu.ie3.datamodel.models.value.load.RandomLoadValues;
import edu.ie3.datamodel.utils.Try;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.measure.quantity.Energy;
import javax.measure.quantity.Power;
import tech.units.indriya.ComparableQuantity;

public abstract class LoadProfileSource<P extends LoadProfile, V extends LoadValues<P>>
extends EntitySource {
extends EntitySource implements PowerValueSource.TimeSeriesBased {
protected final P profile;
protected final Class<V> entryClass;
protected final LoadProfileFactory<P, V> entryFactory;

protected LoadProfileSource(Class<V> entryClass, LoadProfileFactory<P, V> entryFactory) {
protected LoadProfileSource(
LoadProfileMetaInformation metaInformation,
Class<V> entryClass,
LoadProfileFactory<P, V> entryFactory) {
this.profile = entryFactory.parseProfile(metaInformation.getProfile());
this.entryClass = entryClass;
this.entryFactory = entryFactory;
}
Expand All @@ -60,33 +61,18 @@ protected Try<LoadProfileEntry<V>, FactoryException> createEntries(
return entryFactory.get(factoryData);
}

public abstract LoadProfileTimeSeries<P, V> getTimeSeries();
/** Returns the load profile entries as a set. */
public abstract Set<LoadProfileEntry<V>> getEntries();

/**
* Method to return all time keys after a given timestamp.
*
* @param time given time
* @return a list of time keys
*/
public abstract List<ZonedDateTime> getTimeKeysAfter(ZonedDateTime time);

/**
* Method to get the value for a given time.
*
* @param time for which a value is needed
* @return an optional
* @throws SourceException if an exception occurred
*/
public abstract Optional<PValue> getValue(ZonedDateTime time) throws SourceException;

/** Returns the load profile of this source. */
public abstract P getLoadProfile();

/** Returns the maximal power value of the time series */
public abstract Optional<ComparableQuantity<Power>> getMaxPower();
@Override
public P getProfile() {
return profile;
}

/** Returns the load profile energy scaling for this load profile time series. */
public abstract Optional<ComparableQuantity<Energy>> getLoadProfileEnergyScaling();
@Override
public Optional<ZonedDateTime> getNextTimeKey(ZonedDateTime time) {
return Optional.of(time.plusSeconds(getResolution(getProfile())));
}

/**
* Returns the resolution for the given {@link LoadProfile}.
Expand Down Expand Up @@ -125,7 +111,7 @@ public static long getResolution(LoadProfile loadProfile) {
metaInformation ->
new CsvLoadProfileSource<>(
buildInSource, metaInformation, BdewLoadValues.class, factory))
.collect(Collectors.toMap(CsvLoadProfileSource::getLoadProfile, Function.identity()));
.collect(Collectors.toMap(CsvLoadProfileSource::getProfile, Function.identity()));
}

/**
Expand Down
91 changes: 91 additions & 0 deletions src/main/java/edu/ie3/datamodel/io/source/PowerValueSource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* © 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.source;

import edu.ie3.datamodel.models.profile.LoadProfile;
import edu.ie3.datamodel.models.profile.PowerProfile;
import edu.ie3.datamodel.models.value.PValue;
import java.time.ZonedDateTime;
import java.util.Optional;
import java.util.function.Supplier;
import javax.measure.quantity.Energy;
import javax.measure.quantity.Power;
import tech.units.indriya.ComparableQuantity;

/** Interface defining base functionality for power value sources. */
public sealed interface PowerValueSource<
P extends PowerProfile, ID extends PowerValueSource.InputData>

Check notice on line 20 in src/main/java/edu/ie3/datamodel/io/source/PowerValueSource.java

View check run for this annotation

SonarQubeGithubPRChecks / SonarQube Code Analysis

src/main/java/edu/ie3/datamodel/io/source/PowerValueSource.java#L20

Rename this generic name to match the regular expression '^[A-Z][0-9]?$'.
Copy link
Member

Choose a reason for hiding this comment

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

Please check out the sonarqube issue

permits PowerValueSource.MarkovBased, PowerValueSource.TimeSeriesBased {

/** Returns the profile of this source. */
P getProfile();

/**
* Method to get the next power value based on the provided input data.
*
* @param data input data that is used to calculate the next power value.
* @return an option for the power value.
*/
Optional<PValue> getValue(ID data);
Comment on lines +26 to +32
Copy link
Member

Choose a reason for hiding this comment

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

I think this method now becomes obsolete with the addition of getValueSupplier. We can just use a supplier all the time, even if it always returns the same value.


/**
* Method to get a supplier for the next power value based on the provided input data. Depending
* on the implementation the supplier will either always return the same value or each time a
* random value. To return one constant value please use {@link #getValue(InputData)}.
*
* @param data input data that is used to calculate the next power value.
* @return A supplier for an option on the value at the given time step.
*/
Supplier<Optional<PValue>> getValueSupplier(ID data);

/**
* Method to determine the next timestamp for which data is present.
*
* @param time current time
* @return an option for the next timestamp or {@link Optional#empty()} if no timestamp was found.
*/
Optional<ZonedDateTime> getNextTimeKey(ZonedDateTime time);

/** Returns the maximal power that can be returned by this source. */
Optional<ComparableQuantity<Power>> getMaxPower();

/** Returns the energy scaling of this power source. */
Optional<ComparableQuantity<Energy>> getProfileEnergyScaling();

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// non-sealed implementations

/** Interface for time-series-based power value sources. */
non-sealed interface TimeSeriesBased
extends PowerValueSource<LoadProfile, TimeSeriesInputValue> {}

/** Interface for markov-chain-based power value sources. */
non-sealed interface MarkovBased extends PowerValueSource<PowerProfile, InputData> {}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// input data

/**
* Interface for the input data of {@link #getValue(InputData)}. The data is used to determine the
* next power.
*/
sealed interface InputData permits PowerValueSource.TimeSeriesInputValue {
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we can think about a different name for the interface here. InputData seems quite generic. Spontaneously I'd think of something that includes Identifier, maybe PowerValueIdentifier, or something better?

/** Returns the timestamp for which a power value is needed. */
ZonedDateTime getTime();
}

/**
* Input data for time-series-based power value sources.
*
* @param time
*/
record TimeSeriesInputValue(ZonedDateTime time) implements InputData {
@Override
public ZonedDateTime getTime() {
return time;
}
}
}
Loading