diff --git a/CHANGELOG.md b/CHANGELOG.md index 4883a5291..609e6327c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Enhancing `VoltageLevel` with `equals` method [#1063](https://github.com/ie3-institute/PowerSystemDataModel/issues/1063) - `ConnectorValidationUtils` checks if parallel devices is > 0 [#1077](https://github.com/ie3-institute/PowerSystemDataModel/issues/1077) - `GridContainerValidationUtils` checks the connectivity for all defined operation time intervals [#1091](https://github.com/ie3-institute/PowerSystemDataModel/issues/1091) +- Implemented a `CongestionResult` [#1097](https://github.com/ie3-institute/PowerSystemDataModel/issues/1097) ### Fixed - Fixed `MappingEntryies` not getting processed by adding `Getter` methods for record fields [#1084](https://github.com/ie3-institute/PowerSystemDataModel/issues/1084) diff --git a/docs/readthedocs/models/models.md b/docs/readthedocs/models/models.md index c28fbc6f7..56c314ac9 100644 --- a/docs/readthedocs/models/models.md +++ b/docs/readthedocs/models/models.md @@ -185,6 +185,7 @@ result/grid/switch result/grid/transformer result/grid/transformer2w result/grid/transformer3w +result/grid/congestion ``` ### Participant Related Models diff --git a/docs/readthedocs/models/result/grid/congestion.md b/docs/readthedocs/models/result/grid/congestion.md new file mode 100644 index 000000000..f55886613 --- /dev/null +++ b/docs/readthedocs/models/result/grid/congestion.md @@ -0,0 +1,51 @@ +(congestion-result)= + +# Congestion + +Representation of a congestion result for a given subnet. + +## Attributes, Units and Remarks + +```{eval-rst} +.. list-table:: + :widths: 33 33 33 + :header-rows: 1 + + + * - Attribute + - Unit + - Remarks + + * - time + - ZonedDateTime + - date and time for the produced result + + * - subgrid + - -- + - Sub grid number + + * - vMin + - p.u. + - minimal voltage of the subnet + + * - vMax + - p.u. + - maximal voltage of the subnet + + * - voltage + - -- + - Boolean indicator, if a voltage congestion occurred + + * - line + - -- + - Boolean indicator, if a line congestion occurred + + * - transformer + - -- + - Boolean indicator, if a transformer congestion occurred +``` + +## Caveats + +Nothing - at least not known. +If you found something, please contact us! diff --git a/src/main/java/edu/ie3/datamodel/io/factory/result/CongestionResultFactory.java b/src/main/java/edu/ie3/datamodel/io/factory/result/CongestionResultFactory.java new file mode 100644 index 000000000..9950a3eaf --- /dev/null +++ b/src/main/java/edu/ie3/datamodel/io/factory/result/CongestionResultFactory.java @@ -0,0 +1,52 @@ +/* + * © 2024. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation +*/ +package edu.ie3.datamodel.io.factory.result; + +import static edu.ie3.util.quantities.PowerSystemUnits.PU; + +import edu.ie3.datamodel.io.factory.EntityData; +import edu.ie3.datamodel.models.result.CongestionResult; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Set; +import javax.measure.quantity.Dimensionless; +import tech.units.indriya.ComparableQuantity; + +public class CongestionResultFactory extends ResultEntityFactory { + private static final String SUBGRID = "subgrid"; + private static final String VMIN = "vMin"; + private static final String VMAX = "vMax"; + private static final String VOLTAGE = "voltage"; + private static final String LINE = "line"; + private static final String TRANSFORMER = "transformer"; + + public CongestionResultFactory() { + super(CongestionResult.class); + } + + public CongestionResultFactory(DateTimeFormatter dateTimeFormatter) { + super(dateTimeFormatter, CongestionResult.class); + } + + @Override + protected List> getFields(Class entityClass) { + return List.of(newSet(TIME, SUBGRID, VMIN, VMAX, VOLTAGE, LINE, TRANSFORMER)); + } + + @Override + protected CongestionResult buildModel(EntityData data) { + ZonedDateTime zdtTime = timeUtil.toZonedDateTime(data.getField(TIME)); + int subgrid = data.getInt(SUBGRID); + ComparableQuantity vMin = data.getQuantity(VMIN, PU); + ComparableQuantity vMax = data.getQuantity(VMAX, PU); + boolean voltage = data.getBoolean(VOLTAGE); + boolean line = data.getBoolean(LINE); + boolean transformer = data.getBoolean(TRANSFORMER); + + return new CongestionResult(zdtTime, subgrid, vMin, vMax, voltage, line, transformer); + } +} diff --git a/src/main/java/edu/ie3/datamodel/io/factory/result/ConnectorResultFactory.java b/src/main/java/edu/ie3/datamodel/io/factory/result/ConnectorResultFactory.java index 495ee9bb9..d211528ef 100644 --- a/src/main/java/edu/ie3/datamodel/io/factory/result/ConnectorResultFactory.java +++ b/src/main/java/edu/ie3/datamodel/io/factory/result/ConnectorResultFactory.java @@ -20,7 +20,7 @@ import javax.measure.quantity.ElectricCurrent; import tech.units.indriya.ComparableQuantity; -public class ConnectorResultFactory extends ResultEntityFactory { +public class ConnectorResultFactory extends ModelResultFactory { private static final String IAMAG = "iAMag"; private static final String IAANG = "iAAng"; diff --git a/src/main/java/edu/ie3/datamodel/io/factory/result/FlexOptionsResultFactory.java b/src/main/java/edu/ie3/datamodel/io/factory/result/FlexOptionsResultFactory.java index 1c31ea9db..d3d63af84 100644 --- a/src/main/java/edu/ie3/datamodel/io/factory/result/FlexOptionsResultFactory.java +++ b/src/main/java/edu/ie3/datamodel/io/factory/result/FlexOptionsResultFactory.java @@ -14,7 +14,7 @@ import javax.measure.quantity.Power; import tech.units.indriya.ComparableQuantity; -public class FlexOptionsResultFactory extends ResultEntityFactory { +public class FlexOptionsResultFactory extends ModelResultFactory { private static final String P_REF = "pRef"; private static final String P_MIN = "pMin"; diff --git a/src/main/java/edu/ie3/datamodel/io/factory/result/ModelResultFactory.java b/src/main/java/edu/ie3/datamodel/io/factory/result/ModelResultFactory.java new file mode 100644 index 000000000..c888b7ee5 --- /dev/null +++ b/src/main/java/edu/ie3/datamodel/io/factory/result/ModelResultFactory.java @@ -0,0 +1,23 @@ +/* + * © 2024. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation +*/ +package edu.ie3.datamodel.io.factory.result; + +import edu.ie3.datamodel.models.result.ModelResultEntity; +import java.time.format.DateTimeFormatter; + +public abstract class ModelResultFactory + extends ResultEntityFactory { + protected static final String INPUT_MODEL = "inputModel"; + + protected ModelResultFactory(Class... allowedClasses) { + super(allowedClasses); + } + + protected ModelResultFactory( + DateTimeFormatter dateTimeFormatter, Class... allowedClasses) { + super(dateTimeFormatter, allowedClasses); + } +} diff --git a/src/main/java/edu/ie3/datamodel/io/factory/result/NodeResultFactory.java b/src/main/java/edu/ie3/datamodel/io/factory/result/NodeResultFactory.java index e7cbf1ea9..858480fbd 100644 --- a/src/main/java/edu/ie3/datamodel/io/factory/result/NodeResultFactory.java +++ b/src/main/java/edu/ie3/datamodel/io/factory/result/NodeResultFactory.java @@ -15,7 +15,7 @@ import javax.measure.quantity.Dimensionless; import tech.units.indriya.ComparableQuantity; -public class NodeResultFactory extends ResultEntityFactory { +public class NodeResultFactory extends ModelResultFactory { private static final String VMAG = "vMag"; private static final String VANG = "vAng"; diff --git a/src/main/java/edu/ie3/datamodel/io/factory/result/ResultEntityFactory.java b/src/main/java/edu/ie3/datamodel/io/factory/result/ResultEntityFactory.java index f1c1d0495..3f3346aae 100644 --- a/src/main/java/edu/ie3/datamodel/io/factory/result/ResultEntityFactory.java +++ b/src/main/java/edu/ie3/datamodel/io/factory/result/ResultEntityFactory.java @@ -21,7 +21,6 @@ abstract class ResultEntityFactory extends EntityFactory { protected static final String TIME = "time"; - protected static final String INPUT_MODEL = "inputModel"; protected final TimeUtil timeUtil; diff --git a/src/main/java/edu/ie3/datamodel/io/factory/result/SwitchResultFactory.java b/src/main/java/edu/ie3/datamodel/io/factory/result/SwitchResultFactory.java index 0db6a14dc..039928148 100644 --- a/src/main/java/edu/ie3/datamodel/io/factory/result/SwitchResultFactory.java +++ b/src/main/java/edu/ie3/datamodel/io/factory/result/SwitchResultFactory.java @@ -11,7 +11,7 @@ import java.time.format.DateTimeFormatter; import java.util.*; -public class SwitchResultFactory extends ResultEntityFactory { +public class SwitchResultFactory extends ModelResultFactory { private static final String CLOSED = "closed"; diff --git a/src/main/java/edu/ie3/datamodel/io/factory/result/SystemParticipantResultFactory.java b/src/main/java/edu/ie3/datamodel/io/factory/result/SystemParticipantResultFactory.java index 1d819be4e..68243f438 100644 --- a/src/main/java/edu/ie3/datamodel/io/factory/result/SystemParticipantResultFactory.java +++ b/src/main/java/edu/ie3/datamodel/io/factory/result/SystemParticipantResultFactory.java @@ -23,7 +23,7 @@ * Factory class for creating {@link SystemParticipantResult} entities from provided {@link * EntityData} data objects. */ -public class SystemParticipantResultFactory extends ResultEntityFactory { +public class SystemParticipantResultFactory extends ModelResultFactory { private static final String POWER = "p"; private static final String REACTIVE_POWER = "q"; diff --git a/src/main/java/edu/ie3/datamodel/io/factory/result/ThermalResultFactory.java b/src/main/java/edu/ie3/datamodel/io/factory/result/ThermalResultFactory.java index 6a84b6d73..0ff9180d0 100644 --- a/src/main/java/edu/ie3/datamodel/io/factory/result/ThermalResultFactory.java +++ b/src/main/java/edu/ie3/datamodel/io/factory/result/ThermalResultFactory.java @@ -21,7 +21,7 @@ import javax.measure.quantity.Temperature; import tech.units.indriya.ComparableQuantity; -public class ThermalResultFactory extends ResultEntityFactory { +public class ThermalResultFactory extends ModelResultFactory { private static final String Q_DOT = "qDot"; private static final String INDOOR_TEMPERATURE = "indoorTemperature"; private static final String ENERGY = "energy"; diff --git a/src/main/java/edu/ie3/datamodel/io/processor/result/ResultEntityProcessor.java b/src/main/java/edu/ie3/datamodel/io/processor/result/ResultEntityProcessor.java index 177ed1909..0e347aa5f 100644 --- a/src/main/java/edu/ie3/datamodel/io/processor/result/ResultEntityProcessor.java +++ b/src/main/java/edu/ie3/datamodel/io/processor/result/ResultEntityProcessor.java @@ -9,6 +9,7 @@ import edu.ie3.datamodel.io.factory.result.SystemParticipantResultFactory; import edu.ie3.datamodel.io.processor.EntityProcessor; import edu.ie3.datamodel.models.StandardUnits; +import edu.ie3.datamodel.models.result.CongestionResult; import edu.ie3.datamodel.models.result.NodeResult; import edu.ie3.datamodel.models.result.ResultEntity; import edu.ie3.datamodel.models.result.connector.LineResult; @@ -58,7 +59,8 @@ public class ResultEntityProcessor extends EntityProcessor { ThermalHouseResult.class, CylindricalStorageResult.class, EmResult.class, - FlexOptionsResult.class); + FlexOptionsResult.class, + CongestionResult.class); public ResultEntityProcessor(Class registeredClass) throws EntityProcessorException { diff --git a/src/main/java/edu/ie3/datamodel/io/source/ResultEntitySource.java b/src/main/java/edu/ie3/datamodel/io/source/ResultEntitySource.java index b5fbd6baa..2a9eba45b 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/ResultEntitySource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/ResultEntitySource.java @@ -11,6 +11,7 @@ import edu.ie3.datamodel.io.factory.EntityData; import edu.ie3.datamodel.io.factory.EntityFactory; import edu.ie3.datamodel.io.factory.result.*; +import edu.ie3.datamodel.models.result.CongestionResult; import edu.ie3.datamodel.models.result.NodeResult; import edu.ie3.datamodel.models.result.ResultEntity; import edu.ie3.datamodel.models.result.connector.LineResult; @@ -41,6 +42,7 @@ public class ResultEntitySource extends EntitySource { private final SwitchResultFactory switchResultFactory; private final NodeResultFactory nodeResultFactory; private final ConnectorResultFactory connectorResultFactory; + private final CongestionResultFactory congestionResultFactory; private final FlexOptionsResultFactory flexOptionsResultFactory; public ResultEntitySource(DataSource dataSource) { @@ -52,6 +54,7 @@ public ResultEntitySource(DataSource dataSource) { this.switchResultFactory = new SwitchResultFactory(); this.nodeResultFactory = new NodeResultFactory(); this.connectorResultFactory = new ConnectorResultFactory(); + this.congestionResultFactory = new CongestionResultFactory(); this.flexOptionsResultFactory = new FlexOptionsResultFactory(); } @@ -64,6 +67,7 @@ public ResultEntitySource(DataSource dataSource, DateTimeFormatter dateTimeForma this.switchResultFactory = new SwitchResultFactory(); this.nodeResultFactory = new NodeResultFactory(); this.connectorResultFactory = new ConnectorResultFactory(); + this.congestionResultFactory = new CongestionResultFactory(); this.flexOptionsResultFactory = new FlexOptionsResultFactory(); } @@ -95,7 +99,8 @@ public void validate() throws ValidationException { validate(LineResult.class, connectorResultFactory), validate(Transformer2WResult.class, connectorResultFactory), validate(Transformer3WResult.class, connectorResultFactory), - validate(FlexOptionsResult.class, flexOptionsResultFactory))); + validate(FlexOptionsResult.class, flexOptionsResultFactory), + validate(CongestionResult.class, congestionResultFactory))); Try.scanCollection(participantResults, Void.class) .transformF(FailedValidationException::new) @@ -357,6 +362,15 @@ public Set getEmResults() throws SourceException { return getResultEntities(EmResult.class, systemParticipantResultFactory); } + /** + * Returns a unique set of {@link CongestionResult} instances. + * + * @return a set of object and subgrid unique {@link CongestionResult} entities + */ + public Set getCongestionResults() throws SourceException { + return getResultEntities(CongestionResult.class, congestionResultFactory); + } + // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- /** diff --git a/src/main/java/edu/ie3/datamodel/models/result/CongestionResult.java b/src/main/java/edu/ie3/datamodel/models/result/CongestionResult.java new file mode 100644 index 000000000..61db3fb62 --- /dev/null +++ b/src/main/java/edu/ie3/datamodel/models/result/CongestionResult.java @@ -0,0 +1,113 @@ +/* + * © 2024. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation +*/ +package edu.ie3.datamodel.models.result; + +import java.time.ZonedDateTime; +import java.util.Objects; +import javax.measure.quantity.Dimensionless; +import tech.units.indriya.ComparableQuantity; + +public class CongestionResult extends ResultEntity { + /** Values */ + private final Integer subgrid; + + private final ComparableQuantity vMin; + private final ComparableQuantity vMax; + private final boolean voltage; + private final boolean line; + private final boolean transformer; + + /** + * Standard constructor which includes auto generation of the resulting output models uuid. + * + * @param time date and time when the result is produced + * @param subgrid the subgrid + * @param vMin minimum voltage in pu + * @param vMax maximal voltage in pu + * @param voltage {@code true} if a voltage congestion occurred in the subnet + * @param line {@code true} if a line congestion occurred in the subnet + * @param transformer {@code true} if a transformer congestion occurred in the subnet + */ + public CongestionResult( + ZonedDateTime time, + int subgrid, + ComparableQuantity vMin, + ComparableQuantity vMax, + boolean voltage, + boolean line, + boolean transformer) { + super(time); + this.subgrid = subgrid; + this.vMin = vMin; + this.vMax = vMax; + this.voltage = voltage; + this.line = line; + this.transformer = transformer; + } + + public int getSubgrid() { + return subgrid; + } + + public boolean getVoltage() { + return voltage; + } + + public boolean getLine() { + return line; + } + + public boolean getTransformer() { + return transformer; + } + + public ComparableQuantity getVMin() { + return vMin; + } + + public ComparableQuantity getVMax() { + return vMax; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CongestionResult that = (CongestionResult) o; + return getTime().equals(that.getTime()) + && Objects.equals(subgrid, that.subgrid) + && vMin.equals(that.vMin) + && vMax.equals(that.vMax) + && voltage == that.voltage + && line == that.line + && transformer == that.transformer; + } + + @Override + public int hashCode() { + return Objects.hash( + super.hashCode(), getTime(), subgrid, vMin, vMax, voltage, line, transformer); + } + + @Override + public String toString() { + return "InputResultEntity{time=" + + getTime() + + ", subgrid=" + + subgrid + + ", vMin=" + + vMin + + ", vMan=" + + vMax + + ", voltage=" + + voltage + + ", line=" + + line + + ", transformer=" + + transformer + + '}'; + } +} diff --git a/src/main/java/edu/ie3/datamodel/models/result/ModelResultEntity.java b/src/main/java/edu/ie3/datamodel/models/result/ModelResultEntity.java new file mode 100644 index 000000000..abc90cec4 --- /dev/null +++ b/src/main/java/edu/ie3/datamodel/models/result/ModelResultEntity.java @@ -0,0 +1,54 @@ +/* + * © 2024. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation +*/ +package edu.ie3.datamodel.models.result; + +import java.time.ZonedDateTime; +import java.util.Objects; +import java.util.UUID; + +/** Abstract class to hold all mappings common to all input result models */ +public abstract class ModelResultEntity extends ResultEntity { + + /** uuid of the input model that produces the result */ + private UUID inputModel; + + /** + * Standard constructor which includes auto generation of the resulting output models uuid. + * + * @param time date and time when the result is produced + * @param inputModel uuid of the input model that produces the result + */ + protected ModelResultEntity(ZonedDateTime time, UUID inputModel) { + super(time); + this.inputModel = inputModel; + } + + public UUID getInputModel() { + return inputModel; + } + + public void setInputModel(UUID inputID) { + inputModel = inputID; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ModelResultEntity that = (ModelResultEntity) o; + return getTime().equals(that.getTime()) && inputModel.equals(that.inputModel); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), getTime(), inputModel); + } + + @Override + public String toString() { + return "InputResultEntity{time=" + getTime() + ", inputModel=" + inputModel + '}'; + } +} diff --git a/src/main/java/edu/ie3/datamodel/models/result/NodeResult.java b/src/main/java/edu/ie3/datamodel/models/result/NodeResult.java index 0724a8344..f0db14df3 100644 --- a/src/main/java/edu/ie3/datamodel/models/result/NodeResult.java +++ b/src/main/java/edu/ie3/datamodel/models/result/NodeResult.java @@ -13,7 +13,7 @@ import tech.units.indriya.ComparableQuantity; /** Represents calculation results of a {@link edu.ie3.datamodel.models.input.NodeInput} */ -public class NodeResult extends ResultEntity { +public class NodeResult extends ModelResultEntity { /** Voltage magnitude @ this node in p.u. */ private ComparableQuantity vMag; diff --git a/src/main/java/edu/ie3/datamodel/models/result/ResultEntity.java b/src/main/java/edu/ie3/datamodel/models/result/ResultEntity.java index 09ac36ea7..ba4dd58af 100644 --- a/src/main/java/edu/ie3/datamodel/models/result/ResultEntity.java +++ b/src/main/java/edu/ie3/datamodel/models/result/ResultEntity.java @@ -8,33 +8,20 @@ import edu.ie3.datamodel.models.Entity; import java.time.ZonedDateTime; import java.util.Objects; -import java.util.UUID; /** Abstract class to hold all mappings common to all result models */ public abstract class ResultEntity implements Entity { /** date and time of the produced result */ private ZonedDateTime time; - /** uuid of the input model that produces the result */ - private UUID inputModel; /** * Standard constructor which includes auto generation of the resulting output models uuid. * * @param time date and time when the result is produced - * @param inputModel uuid of the input model that produces the result */ - protected ResultEntity(ZonedDateTime time, UUID inputModel) { + protected ResultEntity(ZonedDateTime time) { this.time = time; - this.inputModel = inputModel; - } - - public UUID getInputModel() { - return inputModel; - } - - public void setInputModel(UUID inputID) { - inputModel = inputID; } public ZonedDateTime getTime() { @@ -50,16 +37,16 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ResultEntity that = (ResultEntity) o; - return time.equals(that.time) && inputModel.equals(that.inputModel); + return time.equals(that.time); } @Override public int hashCode() { - return Objects.hash(super.hashCode(), time, inputModel); + return Objects.hash(super.hashCode(), time); } @Override public String toString() { - return "ResultEntity{time=" + time + ", inputModel=" + inputModel + '}'; + return "ResultEntity{time=" + time + '}'; } } diff --git a/src/main/java/edu/ie3/datamodel/models/result/connector/ConnectorResult.java b/src/main/java/edu/ie3/datamodel/models/result/connector/ConnectorResult.java index c5d9b99cd..187a27fc0 100644 --- a/src/main/java/edu/ie3/datamodel/models/result/connector/ConnectorResult.java +++ b/src/main/java/edu/ie3/datamodel/models/result/connector/ConnectorResult.java @@ -5,7 +5,7 @@ */ package edu.ie3.datamodel.models.result.connector; -import edu.ie3.datamodel.models.result.ResultEntity; +import edu.ie3.datamodel.models.result.ModelResultEntity; import java.time.ZonedDateTime; import java.util.Objects; import java.util.UUID; @@ -14,7 +14,7 @@ import tech.units.indriya.ComparableQuantity; /** Abstract class to hold most 'ElectricCurrent and Angle'-mappings common to all connectors */ -public abstract class ConnectorResult extends ResultEntity { +public abstract class ConnectorResult extends ModelResultEntity { /** Electric current magnitude @ port A, normally provided in Ampere */ private ComparableQuantity iAMag; diff --git a/src/main/java/edu/ie3/datamodel/models/result/connector/SwitchResult.java b/src/main/java/edu/ie3/datamodel/models/result/connector/SwitchResult.java index 7b5c15c5b..c0b650558 100644 --- a/src/main/java/edu/ie3/datamodel/models/result/connector/SwitchResult.java +++ b/src/main/java/edu/ie3/datamodel/models/result/connector/SwitchResult.java @@ -5,7 +5,7 @@ */ package edu.ie3.datamodel.models.result.connector; -import edu.ie3.datamodel.models.result.ResultEntity; +import edu.ie3.datamodel.models.result.ModelResultEntity; import java.time.ZonedDateTime; import java.util.Objects; import java.util.UUID; @@ -13,7 +13,7 @@ /** * Represents calculation results of a {@link edu.ie3.datamodel.models.input.connector.SwitchInput} */ -public class SwitchResult extends ResultEntity { +public class SwitchResult extends ModelResultEntity { /** is the switching state 'closed'? */ private boolean closed; diff --git a/src/main/java/edu/ie3/datamodel/models/result/system/FlexOptionsResult.java b/src/main/java/edu/ie3/datamodel/models/result/system/FlexOptionsResult.java index 210bc761b..ea85fc554 100644 --- a/src/main/java/edu/ie3/datamodel/models/result/system/FlexOptionsResult.java +++ b/src/main/java/edu/ie3/datamodel/models/result/system/FlexOptionsResult.java @@ -5,7 +5,7 @@ */ package edu.ie3.datamodel.models.result.system; -import edu.ie3.datamodel.models.result.ResultEntity; +import edu.ie3.datamodel.models.result.ModelResultEntity; import java.time.ZonedDateTime; import java.util.Objects; import java.util.UUID; @@ -13,7 +13,7 @@ import tech.units.indriya.ComparableQuantity; /** Represents results of flexibility request */ -public class FlexOptionsResult extends ResultEntity { +public class FlexOptionsResult extends ModelResultEntity { /** * Active power (might be negative, thus feed-in) that was suggested for regular usage by the diff --git a/src/main/java/edu/ie3/datamodel/models/result/system/SystemParticipantResult.java b/src/main/java/edu/ie3/datamodel/models/result/system/SystemParticipantResult.java index 4b5067896..225833777 100644 --- a/src/main/java/edu/ie3/datamodel/models/result/system/SystemParticipantResult.java +++ b/src/main/java/edu/ie3/datamodel/models/result/system/SystemParticipantResult.java @@ -5,7 +5,7 @@ */ package edu.ie3.datamodel.models.result.system; -import edu.ie3.datamodel.models.result.ResultEntity; +import edu.ie3.datamodel.models.result.ModelResultEntity; import java.time.ZonedDateTime; import java.util.Objects; import java.util.UUID; @@ -13,7 +13,7 @@ import tech.units.indriya.ComparableQuantity; /** Abstract class that holds values common to all other result entities */ -public abstract class SystemParticipantResult extends ResultEntity { +public abstract class SystemParticipantResult extends ModelResultEntity { /** active power output normally provided in MW */ private ComparableQuantity p; diff --git a/src/main/java/edu/ie3/datamodel/models/result/thermal/ThermalUnitResult.java b/src/main/java/edu/ie3/datamodel/models/result/thermal/ThermalUnitResult.java index 07ba81913..d3265bbae 100644 --- a/src/main/java/edu/ie3/datamodel/models/result/thermal/ThermalUnitResult.java +++ b/src/main/java/edu/ie3/datamodel/models/result/thermal/ThermalUnitResult.java @@ -6,7 +6,7 @@ package edu.ie3.datamodel.models.result.thermal; import edu.ie3.datamodel.models.StandardUnits; -import edu.ie3.datamodel.models.result.ResultEntity; +import edu.ie3.datamodel.models.result.ModelResultEntity; import java.time.ZonedDateTime; import java.util.Objects; import java.util.UUID; @@ -14,7 +14,7 @@ import tech.units.indriya.ComparableQuantity; /** Representation of a result with regard to a thermal unit */ -public abstract class ThermalUnitResult extends ResultEntity { +public abstract class ThermalUnitResult extends ModelResultEntity { /** * Average thermal power flowing into the thermal unit (+: Power flowing into unit, -: Power diff --git a/src/main/java/edu/ie3/datamodel/utils/validation/UniquenessValidationUtils.java b/src/main/java/edu/ie3/datamodel/utils/validation/UniquenessValidationUtils.java index 10ba0b91e..86be3c060 100644 --- a/src/main/java/edu/ie3/datamodel/utils/validation/UniquenessValidationUtils.java +++ b/src/main/java/edu/ie3/datamodel/utils/validation/UniquenessValidationUtils.java @@ -11,7 +11,8 @@ import edu.ie3.datamodel.models.UniqueEntity; import edu.ie3.datamodel.models.input.AssetInput; import edu.ie3.datamodel.models.input.IdCoordinateInput; -import edu.ie3.datamodel.models.result.ResultEntity; +import edu.ie3.datamodel.models.result.CongestionResult; +import edu.ie3.datamodel.models.result.ModelResultEntity; import edu.ie3.datamodel.models.timeseries.individual.TimeBasedValue; import edu.ie3.datamodel.models.value.WeatherValue; import edu.ie3.datamodel.utils.Try; @@ -27,8 +28,10 @@ public class UniquenessValidationUtils extends ValidationUtils { protected static final FieldSetSupplier uuidFieldSupplier = entity -> Set.of(entity.getUuid()); protected static final FieldSetSupplier idFieldSupplier = e -> Set.of(e.getId()); - protected static final FieldSetSupplier resultFieldSupplier = + protected static final FieldSetSupplier modelResultFieldSupplier = entity -> Set.of(entity.getTime(), entity.getInputModel()); + protected static final FieldSetSupplier congestionResultFieldSupplier = + entity -> Set.of(entity.getTime(), entity.getSubgrid()); protected static final FieldSetSupplier mappingFieldSupplier = entity -> Set.of(entity.participant()); protected static final FieldSetSupplier idCoordinateSupplier = @@ -69,14 +72,25 @@ public static void checkAssetUniqueness(Collection entitie } /** - * Checks the uniqueness of a collection of {@link ResultEntity}. + * Checks the uniqueness of a collection of {@link CongestionResult}. * * @param entities to be checked * @throws DuplicateEntitiesException if uniqueness is violated */ - public static void checkResultUniqueness(Collection entities) + public static void checkCongestionResultUniqueness( + Collection entities) throws DuplicateEntitiesException { + checkUniqueness(entities, congestionResultFieldSupplier).getOrThrow(); + } + + /** + * Checks the uniqueness of a collection of {@link ModelResultEntity}. + * + * @param entities to be checked + * @throws DuplicateEntitiesException if uniqueness is violated + */ + public static void checkModelResultUniqueness(Collection entities) throws DuplicateEntitiesException { - checkUniqueness(entities, resultFieldSupplier).getOrThrow(); + checkUniqueness(entities, modelResultFieldSupplier).getOrThrow(); } /** diff --git a/src/test/groovy/edu/ie3/datamodel/io/processor/ProcessorProviderTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/processor/ProcessorProviderTest.groovy index b9ed42a8e..b5e145799 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/processor/ProcessorProviderTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/processor/ProcessorProviderTest.groovy @@ -11,12 +11,7 @@ import edu.ie3.datamodel.io.processor.timeseries.TimeSeriesProcessor import edu.ie3.datamodel.io.processor.timeseries.TimeSeriesProcessorKey import edu.ie3.datamodel.io.source.TimeSeriesMappingSource import edu.ie3.datamodel.models.StandardUnits -import edu.ie3.datamodel.models.input.EmInput -import edu.ie3.datamodel.models.input.IdCoordinateInput -import edu.ie3.datamodel.models.input.MeasurementUnitInput -import edu.ie3.datamodel.models.input.NodeInput -import edu.ie3.datamodel.models.input.OperatorInput -import edu.ie3.datamodel.models.input.RandomLoadParameters +import edu.ie3.datamodel.models.input.* import edu.ie3.datamodel.models.input.connector.LineInput import edu.ie3.datamodel.models.input.connector.SwitchInput import edu.ie3.datamodel.models.input.connector.Transformer2WInput @@ -31,6 +26,7 @@ import edu.ie3.datamodel.models.input.system.type.* import edu.ie3.datamodel.models.input.thermal.CylindricalStorageInput import edu.ie3.datamodel.models.input.thermal.ThermalBusInput import edu.ie3.datamodel.models.input.thermal.ThermalHouseInput +import edu.ie3.datamodel.models.result.CongestionResult import edu.ie3.datamodel.models.result.NodeResult import edu.ie3.datamodel.models.result.connector.LineResult import edu.ie3.datamodel.models.result.connector.SwitchResult @@ -121,6 +117,7 @@ class ProcessorProviderTest extends Specification implements TimeSeriesTestData LoadResult, SwitchResult, NodeResult, + CongestionResult, ThermalHouseResult, CylindricalStorageResult ] diff --git a/src/test/groovy/edu/ie3/datamodel/io/processor/result/ResultEntityProcessorTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/processor/result/ResultEntityProcessorTest.groovy index 80e17345f..7bf12fbb9 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/processor/result/ResultEntityProcessorTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/processor/result/ResultEntityProcessorTest.groovy @@ -7,8 +7,8 @@ package edu.ie3.datamodel.io.processor.result import edu.ie3.datamodel.exceptions.EntityProcessorException import edu.ie3.datamodel.models.StandardUnits +import edu.ie3.datamodel.models.result.ModelResultEntity import edu.ie3.datamodel.models.result.NodeResult -import edu.ie3.datamodel.models.result.ResultEntity import edu.ie3.datamodel.models.result.connector.LineResult import edu.ie3.datamodel.models.result.connector.SwitchResult import edu.ie3.datamodel.models.result.connector.Transformer2WResult @@ -270,7 +270,7 @@ class ResultEntityProcessorTest extends Specification { def "The list of eligible entity classes for a ResultEntityProcessor should be valid"() { given: - int noOfElements = 19 // number of all currently implemented entity results + int noOfElements = 20 // number of all currently implemented entity results expect: ResultEntityProcessor.eligibleEntityClasses.size() == noOfElements @@ -285,7 +285,7 @@ class ResultEntityProcessorTest extends Specification { thrown(EntityProcessorException) } - private static class InvalidTestResult extends ResultEntity { + private static class InvalidTestResult extends ModelResultEntity { InvalidTestResult(ZonedDateTime time, UUID inputModel) { super(time, inputModel) diff --git a/src/test/groovy/edu/ie3/datamodel/utils/validation/UniquenessValidationUtilsTest.groovy b/src/test/groovy/edu/ie3/datamodel/utils/validation/UniquenessValidationUtilsTest.groovy index 3d8f71edd..d33502cb1 100644 --- a/src/test/groovy/edu/ie3/datamodel/utils/validation/UniquenessValidationUtilsTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/utils/validation/UniquenessValidationUtilsTest.groovy @@ -15,8 +15,9 @@ import edu.ie3.datamodel.exceptions.DuplicateEntitiesException import edu.ie3.datamodel.io.source.TimeSeriesMappingSource import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.AssetInput +import edu.ie3.datamodel.models.result.CongestionResult +import edu.ie3.datamodel.models.result.ModelResultEntity import edu.ie3.datamodel.models.result.NodeResult -import edu.ie3.datamodel.models.result.ResultEntity import edu.ie3.datamodel.models.timeseries.individual.TimeBasedValue import edu.ie3.datamodel.models.value.SolarIrradianceValue import edu.ie3.datamodel.models.value.TemperatureValue @@ -105,19 +106,19 @@ class UniquenessValidationUtilsTest extends Specification { Quantity vMag = Quantities.getQuantity(0.95, PU) Quantity vAng = Quantities.getQuantity(45, StandardUnits.VOLTAGE_ANGLE) - Set uniqueResults = [ + Set uniqueResults = [ new NodeResult(time, uuid, vMag, vAng), new NodeResult(time.plusHours(1), uuid, vMag, vAng) ] when: - checkResultUniqueness(uniqueResults) + checkModelResultUniqueness(uniqueResults) then: noExceptionThrown() } - def "Duplicates in result inputs lead to an exception"() { + def "Duplicates in model result inputs lead to an exception"() { given: ZonedDateTime time = ZonedDateTime.parse("2024-02-15T13:49:44+01:00[Europe/Berlin]") UUID uuid1 = UUID.fromString("4f7938ad-3d8f-4d56-a76c-525f2362e8b6") @@ -125,7 +126,7 @@ class UniquenessValidationUtilsTest extends Specification { Quantity vMag = Quantities.getQuantity(0.95, PU) Quantity vAng = Quantities.getQuantity(45, StandardUnits.VOLTAGE_ANGLE) - Set notUniqueResults = [ + Set notUniqueResults = [ new NodeResult(time, uuid1, vMag, vAng), new NodeResult(time, uuid1, vMag, vAng), new NodeResult(time.plusHours(1), uuid2, vMag, vAng), @@ -133,13 +134,36 @@ class UniquenessValidationUtilsTest extends Specification { ] when: - checkResultUniqueness(notUniqueResults) + checkModelResultUniqueness(notUniqueResults) then: DuplicateEntitiesException de = thrown() de.message.startsWith("'NodeResult' entities with duplicated") } + def "Duplicates in congestion result inputs lead to an exception"() { + given: + ZonedDateTime time = ZonedDateTime.parse("2024-02-15T13:49:44+01:00[Europe/Berlin]") + int subgrid1 = 1 + int subgrid2 = 2 + Quantity vMin = Quantities.getQuantity(0.9, PU) + Quantity vMax = Quantities.getQuantity(1.1, PU) + + Set notUniqueResults = [ + new CongestionResult(time, subgrid1, vMin, vMax, false, false, false), + new CongestionResult(time, subgrid1, vMin, vMax, false, true, false), + new CongestionResult(time.plusHours(1), subgrid1, vMin, vMax, false, false, false), + new CongestionResult(time.plusHours(1), subgrid2, vMin, vMax, false, true, false), + ] + + when: + checkCongestionResultUniqueness(notUniqueResults) + + then: + DuplicateEntitiesException de = thrown() + de.message.startsWith("'CongestionResult' entities with duplicated") + } + def "Checking if mapping entries are unique"() { given: UUID timeSeries = UUID.randomUUID()