Skip to content

Extend Validation to EnergyManagement Systems #1359

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

Merged
merged 5 commits into from
Jul 9, 2025
Merged
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
- Extend Validation to EnergyManagement Systems. [#1356](https://github.com/ie3-institute/PowerSystemDataModel/issues/1356)

### 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* © 2021. TU Dortmund University,
* Institute of Energy Systems, Energy Efficiency and Energy Economics,
* Research group Distribution grid planning and operation
*/
package edu.ie3.datamodel.utils.validation;

import edu.ie3.datamodel.exceptions.InvalidEntityException;
import edu.ie3.datamodel.exceptions.ValidationException;
import edu.ie3.datamodel.models.input.EmInput;
import edu.ie3.datamodel.utils.Try;
import java.util.ArrayList;
import java.util.List;

public class EnergyManagementValidationUtils extends ValidationUtils {

/** Private Constructor as this class is not meant to be instantiated */
private EnergyManagementValidationUtils() {
throw new IllegalStateException("Don't try and instantiate a Utility class.");
}

/**
* Validates a energy management unit if:
*
* <ul>
* <li>its control strategy is not null
* </ul>
*
* A "distribution" method, that forwards the check request to specific implementations to fulfill
* the checking task, based on the class of the given object.
*
* @param energyManagement EmInput to validate
* @return a list of try objects either containing an {@link ValidationException} or an empty
* Success
*/
protected static List<Try<Void, ? extends ValidationException>> check(EmInput energyManagement) {
List<Try<Void, ? extends ValidationException>> exceptions = new ArrayList<>();

exceptions.add(
Try.ofVoid(
energyManagement.getControlStrategy() == null,
() ->
new InvalidEntityException(
"No control strategy of energy management defined for", energyManagement)));

return exceptions;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
*/
package edu.ie3.datamodel.utils.validation;

import edu.ie3.datamodel.exceptions.*;
import edu.ie3.datamodel.exceptions.FailedValidationException;
import edu.ie3.datamodel.exceptions.InvalidEntityException;
import edu.ie3.datamodel.exceptions.UnsafeEntityException;
import edu.ie3.datamodel.exceptions.ValidationException;
import edu.ie3.datamodel.models.UniqueEntity;
import edu.ie3.datamodel.models.input.AssetInput;
import edu.ie3.datamodel.models.input.AssetTypeInput;
import edu.ie3.datamodel.models.input.MeasurementUnitInput;
import edu.ie3.datamodel.models.input.NodeInput;
import edu.ie3.datamodel.models.input.*;
import edu.ie3.datamodel.models.input.connector.ConnectorInput;
import edu.ie3.datamodel.models.input.connector.type.LineTypeInput;
import edu.ie3.datamodel.models.input.connector.type.Transformer2WTypeInput;
Expand All @@ -22,8 +22,11 @@
import edu.ie3.datamodel.models.input.system.type.SystemParticipantTypeInput;
import edu.ie3.datamodel.models.input.thermal.ThermalUnitInput;
import edu.ie3.datamodel.utils.Try;
import edu.ie3.datamodel.utils.Try.*;
import java.util.*;
import edu.ie3.datamodel.utils.Try.Failure;
import edu.ie3.datamodel.utils.Try.Success;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import javax.measure.Quantity;
Expand Down Expand Up @@ -101,7 +104,7 @@
* @return a list of try objects either containing a {@link ValidationException} or an empty
* Success
*/
private static List<Try<Void, ? extends ValidationException>> checkAsset(AssetInput assetInput) {

Check failure on line 107 in src/main/java/edu/ie3/datamodel/utils/validation/ValidationUtils.java

View check run for this annotation

SonarQubeGithubPRChecks / SonarQube Code Analysis

src/main/java/edu/ie3/datamodel/utils/validation/ValidationUtils.java#L107

Refactor this method to reduce its Cognitive Complexity from 18 to the 15 allowed.
Try<Void, InvalidEntityException> isNull = checkNonNull(assetInput, "an asset");

if (isNull.isFailure()) {
Expand Down Expand Up @@ -157,6 +160,8 @@
exceptions.addAll(ThermalValidationUtils.check((ThermalUnitInput) assetInput));
else if (ThermalGrid.class.isAssignableFrom(assetInput.getClass()))
exceptions.addAll(ThermalValidationUtils.check((ThermalUnitInput) assetInput));
else if (EmInput.class.isAssignableFrom(assetInput.getClass()))
exceptions.addAll(EnergyManagementValidationUtils.check((EmInput) assetInput));
else {
logNotImplemented(assetInput);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* © 2025. TU Dortmund University,
* Institute of Energy Systems, Energy Efficiency and Energy Economics,
* Research group Distribution grid planning and operation
*/
package edu.ie3.datamodel.utils.validation

import edu.ie3.datamodel.exceptions.InvalidEntityException
import edu.ie3.datamodel.exceptions.ValidationException
import edu.ie3.datamodel.utils.Try
import edu.ie3.test.common.GridTestData
import spock.lang.Specification

class EmValidationUtilsTest extends Specification {

def "Smoke Test: Correct energy management system throws no exception"() {
given:
def em = GridTestData.energyManagementInput

when:
List<Try<Void, ? extends ValidationException>> tries = EnergyManagementValidationUtils.check(em)

then:
tries.every { it.success }
}

def "The check method recognizes all potential errors for an energy management input"() {
when:
List<Try<Void, ? extends ValidationException>> exceptions = EnergyManagementValidationUtils.check(invalidEm).stream().filter { it -> it.failure }.toList()

then:
exceptions.size() == expectedSize
Exception ex = exceptions.get(0).exception.get()
ex.class == expectedException.class
ex.message == expectedException.message

where:
invalidEm || expectedSize || expectedException
GridTestData.energyManagementInput.copy().controlStrategy(null).build() || 1 || new InvalidEntityException("No control strategy of energy management defined for", invalidEm)
}
}
10 changes: 10 additions & 0 deletions src/test/groovy/edu/ie3/test/common/GridTestData.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import static edu.ie3.datamodel.models.StandardUnits.*
import static edu.ie3.util.quantities.PowerSystemUnits.*

import edu.ie3.datamodel.models.OperationTime
import edu.ie3.datamodel.models.input.EmInput
import edu.ie3.datamodel.models.input.MeasurementUnitInput
import edu.ie3.datamodel.models.input.NodeInput
import edu.ie3.datamodel.models.input.OperatorInput
Expand Down Expand Up @@ -387,4 +388,13 @@ class GridTestData {
true,
true
)

public static final EmInput energyManagementInput = new EmInput(
UUID.fromString("4bef6955-5e31-4283-8920-5e4cae267a23"),
"test_energyManagement",
profBroccoli,
defaultOperationTime,
"PRIORITIZED",
null,
)
}