Skip to content

Enhance ValidationUtils for load profile #1358

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 4 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Updated dependabot workflow and added CODEOWNERS [#1328](https://github.com/ie3-institute/PowerSystemDataModel/issues/1328)
- Extend azimuth angle range to [-180°, 180°] for PV inputs [#1330](https://github.com/ie3-institute/PowerSystemDataModel/issues/1330)
- Enhanced `ValidationUtils` for `LoadModel` to check for correct profile naming [#1357](https://github.com/ie3-institute/PowerSystemDataModel/issues/1357)

## [7.0.0] - 2025-05-08

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@
*/
package edu.ie3.datamodel.utils.validation;

import static edu.ie3.datamodel.models.StandardUnits.*;
import static edu.ie3.datamodel.models.StandardUnits.AZIMUTH;
import static edu.ie3.datamodel.models.StandardUnits.SOLAR_ELEVATION_ANGLE;

import edu.ie3.datamodel.exceptions.InvalidEntityException;
import edu.ie3.datamodel.exceptions.TryException;
import edu.ie3.datamodel.models.input.UniqueInputEntity;
import edu.ie3.datamodel.models.input.system.*;
import edu.ie3.datamodel.models.input.system.type.*;
import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile;
import edu.ie3.datamodel.models.profile.LoadProfile;
import edu.ie3.datamodel.models.profile.NbwTemperatureDependantLoadProfile;
import edu.ie3.datamodel.utils.Try;
import edu.ie3.datamodel.utils.Try.Failure;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.measure.Quantity;
import javax.measure.quantity.Dimensionless;
Expand Down Expand Up @@ -356,6 +361,7 @@ private static Try<Void, InvalidEntityException> checkHpType(HpTypeInput hpTypeI
*
* <ul>
* <li>its standard load profile is not null
* <li>its standard load profile matches the supported types / profile names
* <li>its rated apparent power is not negative
* <li>its annual energy consumption is not negative
* <li>its rated power factor is between 0 and 1
Expand All @@ -375,6 +381,36 @@ private static List<Try<Void, InvalidEntityException>> checkLoad(LoadInput loadI
new InvalidEntityException(
"No standard load profile defined for load", loadInput)));

if (loadInput.getLoadProfile() != null) {
LoadProfile profile = loadInput.getLoadProfile();

// Validate if the profile is one of the allowed profiles
exceptions.add(
Try.ofVoid(
!(profile.equals(LoadProfile.DefaultLoadProfiles.NO_LOAD_PROFILE)
|| profile.equals(LoadProfile.RandomLoadProfile.RANDOM_LOAD_PROFILE)
|| Arrays.asList(
BdewStandardLoadProfile.H0,
BdewStandardLoadProfile.G0,
BdewStandardLoadProfile.G1,
BdewStandardLoadProfile.G2,
BdewStandardLoadProfile.G3,
BdewStandardLoadProfile.G4,
BdewStandardLoadProfile.G5,
BdewStandardLoadProfile.G6,
BdewStandardLoadProfile.L0,
BdewStandardLoadProfile.L1,
BdewStandardLoadProfile.L2,
NbwTemperatureDependantLoadProfile.EP1,
NbwTemperatureDependantLoadProfile.EZ2)
.contains(profile)),
() ->
new InvalidEntityException(
"Load profile must contain at least one valid entry: h0, g[0-6], l[0-2], ep1, ez2, random, or LoadProfile#NO_LOAD_PROFILE.",
loadInput)));
}

// Check negative quantities and power factor
exceptions.addAll(
Try.ofVoid(
InvalidEntityException.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import edu.ie3.datamodel.exceptions.InvalidEntityException
import edu.ie3.datamodel.models.input.system.characteristic.WecCharacteristicInput
import edu.ie3.datamodel.models.input.system.type.*
import edu.ie3.datamodel.models.input.system.type.chargingpoint.ChargingPointType
import edu.ie3.datamodel.models.profile.StandardLoadProfile
import edu.ie3.datamodel.utils.Try
import edu.ie3.test.common.SystemParticipantTestData
import edu.ie3.util.quantities.interfaces.Currency
Expand Down Expand Up @@ -336,6 +337,38 @@ class SystemParticipantValidationUtilsTest extends Specification {
SystemParticipantTestData.loadInput.copy().loadprofile(null).build() || 1 || new InvalidEntityException("No standard load profile defined for load", invalidLoad)
SystemParticipantTestData.loadInput.copy().sRated(Quantities.getQuantity(-25d, ACTIVE_POWER_IN)).eConsAnnual(Quantities.getQuantity(-4000, ENERGY_IN)).build() || 1 || new InvalidEntityException("The following quantities have to be zero or positive: -25 kVA, -4000 kWh", invalidLoad)
SystemParticipantTestData.loadInput.copy().cosPhiRated(2).build() || 1 || new InvalidEntityException("Rated power factor of LoadInput must be between 0 and 1", invalidLoad)
SystemParticipantTestData.loadInput.copy().loadprofile(createInvalidStandardLoadProfile("h1")).build() || 1 || new InvalidEntityException("Load profile must contain at least one valid entry: h0, g[0-6], l[0-2], ep1, ez2, random, or LoadProfile#NO_LOAD_PROFILE.", invalidLoad)
SystemParticipantTestData.loadInput.copy().loadprofile(createInvalidStandardLoadProfile("g7")).build() || 1 || new InvalidEntityException("Load profile must contain at least one valid entry: h0, g[0-6], l[0-2], ep1, ez2, random, or LoadProfile#NO_LOAD_PROFILE.", invalidLoad)
SystemParticipantTestData.loadInput.copy().loadprofile(createInvalidStandardLoadProfile("l3")).build() || 1 || new InvalidEntityException("Load profile must contain at least one valid entry: h0, g[0-6], l[0-2], ep1, ez2, random, or LoadProfile#NO_LOAD_PROFILE.", invalidLoad)
SystemParticipantTestData.loadInput.copy().loadprofile(createInvalidStandardLoadProfile("invalid")).build() || 1 || new InvalidEntityException("Load profile must contain at least one valid entry: h0, g[0-6], l[0-2], ep1, ez2, random, or LoadProfile#NO_LOAD_PROFILE.", invalidLoad)
}

// Helper method to create invalid standard load profiles for testing
private static StandardLoadProfile createInvalidStandardLoadProfile(String profileName) {
return new StandardLoadProfile() {
@Override
String getKey() {
return profileName
}

@Override
String toString() {
return profileName
}

@Override
boolean equals(Object obj) {
if (obj instanceof String) {
return obj == "Simona"
}
return false
}

@Override
int hashCode() {
return profileName.hashCode()
}
}
}

// PV
Expand Down