From 91bea33221fda8344c9736c0f3abc5899c8b63c9 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Mon, 26 Aug 2024 15:09:03 +0200 Subject: [PATCH] introduce DomesticHotWaterStorageResult --- .../factory/result/ThermalResultFactory.java | 20 ++++- .../result/ResultEntityProcessor.java | 2 + .../thermal/AbstractThermalStorageResult.java | 79 +++++++++++++++++++ .../thermal/CylindricalStorageResult.java | 59 +------------- .../DomesticHotWaterStorageResult.java | 26 ++++++ .../result/ThermalResultFactoryTest.groovy | 4 +- .../io/processor/ProcessorProviderTest.groovy | 4 +- .../result/ResultEntityProcessorTest.groovy | 27 ++++++- 8 files changed, 160 insertions(+), 61 deletions(-) create mode 100644 src/main/java/edu/ie3/datamodel/models/result/thermal/AbstractThermalStorageResult.java create mode 100644 src/main/java/edu/ie3/datamodel/models/result/thermal/DomesticHotWaterStorageResult.java 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 0ff9180d0..8bb06ba54 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 @@ -10,6 +10,7 @@ import edu.ie3.datamodel.models.Entity; import edu.ie3.datamodel.models.StandardUnits; import edu.ie3.datamodel.models.result.thermal.CylindricalStorageResult; +import edu.ie3.datamodel.models.result.thermal.DomesticHotWaterStorageResult; import edu.ie3.datamodel.models.result.thermal.ThermalHouseResult; import edu.ie3.datamodel.models.result.thermal.ThermalUnitResult; import java.time.ZonedDateTime; @@ -28,7 +29,10 @@ public class ThermalResultFactory extends ModelResultFactory private static final String FILL_LEVEL = "fillLevel"; public ThermalResultFactory() { - super(ThermalHouseResult.class, CylindricalStorageResult.class); + super( + ThermalHouseResult.class, + CylindricalStorageResult.class, + DomesticHotWaterStorageResult.class); } /** @@ -38,7 +42,11 @@ public ThermalResultFactory() { * @param dateTimeFormatter parse date time strings */ public ThermalResultFactory(DateTimeFormatter dateTimeFormatter) { - super(dateTimeFormatter, ThermalHouseResult.class, CylindricalStorageResult.class); + super( + dateTimeFormatter, + ThermalHouseResult.class, + CylindricalStorageResult.class, + DomesticHotWaterStorageResult.class); } @Override @@ -75,6 +83,14 @@ protected ThermalUnitResult buildModel(EntityData data) { return new CylindricalStorageResult( zdtTime, inputModelUuid, energyQuantity, qDotQuantity, fillLevelQuantity); + } else if (clazz.equals(DomesticHotWaterStorageResult.class)) { + ComparableQuantity energyQuantity = + data.getQuantity(ENERGY, StandardUnits.ENERGY_RESULT); + ComparableQuantity fillLevelQuantity = + data.getQuantity(FILL_LEVEL, StandardUnits.FILL_LEVEL); + + return new DomesticHotWaterStorageResult( + zdtTime, inputModelUuid, energyQuantity, qDotQuantity, fillLevelQuantity); } else { throw new FactoryException("Cannot process " + clazz.getSimpleName() + ".class."); } 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 0e347aa5f..224b75850 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 @@ -18,6 +18,7 @@ import edu.ie3.datamodel.models.result.connector.Transformer3WResult; import edu.ie3.datamodel.models.result.system.*; import edu.ie3.datamodel.models.result.thermal.CylindricalStorageResult; +import edu.ie3.datamodel.models.result.thermal.DomesticHotWaterStorageResult; import edu.ie3.datamodel.models.result.thermal.ThermalHouseResult; import edu.ie3.datamodel.utils.Try; import edu.ie3.datamodel.utils.Try.*; @@ -58,6 +59,7 @@ public class ResultEntityProcessor extends EntityProcessor { NodeResult.class, ThermalHouseResult.class, CylindricalStorageResult.class, + DomesticHotWaterStorageResult.class, EmResult.class, FlexOptionsResult.class, CongestionResult.class); diff --git a/src/main/java/edu/ie3/datamodel/models/result/thermal/AbstractThermalStorageResult.java b/src/main/java/edu/ie3/datamodel/models/result/thermal/AbstractThermalStorageResult.java new file mode 100644 index 000000000..a64d72b07 --- /dev/null +++ b/src/main/java/edu/ie3/datamodel/models/result/thermal/AbstractThermalStorageResult.java @@ -0,0 +1,79 @@ +/* + * © 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.thermal; + +import edu.ie3.datamodel.models.StandardUnits; +import java.time.ZonedDateTime; +import java.util.Objects; +import java.util.UUID; +import javax.measure.quantity.Dimensionless; +import javax.measure.quantity.Energy; +import javax.measure.quantity.Power; +import tech.units.indriya.ComparableQuantity; + +/** Abstract class representing the common results of different types of thermal storages */ +public abstract class AbstractThermalStorageResult extends ThermalStorageResult { + /** Fill level of the storage */ + private ComparableQuantity fillLevel; + + /** + * Constructs the result with + * + * @param time date and time when the result is produced + * @param inputModel uuid of the input model that produces the result + * @param energy Currently stored energy + * @param qDot Heat power flowing into (> 0) or coming from (< 0) the storage + * @param fillLevel Fill level of the storage + */ + public AbstractThermalStorageResult( + ZonedDateTime time, + UUID inputModel, + ComparableQuantity energy, + ComparableQuantity qDot, + ComparableQuantity fillLevel) { + super(time, inputModel, energy, qDot); + this.fillLevel = fillLevel.to(StandardUnits.FILL_LEVEL); + } + + public ComparableQuantity getFillLevel() { + return fillLevel; + } + + public void setFillLevel(ComparableQuantity fillLevel) { + this.fillLevel = fillLevel.to(StandardUnits.FILL_LEVEL); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + AbstractThermalStorageResult that = (AbstractThermalStorageResult) o; + return fillLevel.equals(that.fillLevel); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), fillLevel); + } + + @Override + public String toString() { + return getClass().getSimpleName() + + "{" + + "time=" + + getTime() + + ", inputModel=" + + getInputModel() + + ", qDot=" + + getqDot() + + ", energy=" + + getEnergy() + + ", fillLevel=" + + fillLevel + + '}'; + } +} diff --git a/src/main/java/edu/ie3/datamodel/models/result/thermal/CylindricalStorageResult.java b/src/main/java/edu/ie3/datamodel/models/result/thermal/CylindricalStorageResult.java index 40ab5bc1f..eeadc0bb8 100644 --- a/src/main/java/edu/ie3/datamodel/models/result/thermal/CylindricalStorageResult.java +++ b/src/main/java/edu/ie3/datamodel/models/result/thermal/CylindricalStorageResult.java @@ -5,75 +5,22 @@ */ package edu.ie3.datamodel.models.result.thermal; -import edu.ie3.datamodel.models.StandardUnits; -import edu.ie3.datamodel.models.input.thermal.CylindricalStorageInput; import java.time.ZonedDateTime; -import java.util.Objects; import java.util.UUID; import javax.measure.quantity.Dimensionless; import javax.measure.quantity.Energy; import javax.measure.quantity.Power; import tech.units.indriya.ComparableQuantity; -/** Respresents the results of {@link CylindricalStorageInput} */ -public class CylindricalStorageResult extends ThermalStorageResult { - /** Fill level of the storage */ - private ComparableQuantity fillLevel; +/** Represents the results of Cylindrical Storage */ +public class CylindricalStorageResult extends AbstractThermalStorageResult { - /** - * Constructs the result with - * - * @param time date and time when the result is produced - * @param inputModel uuid of the input model that produces the result - * @param energy Currently stored energy - * @param qDot Heat power flowing into (> 0) or coming from (< 0) the storage - * @param fillLevel Fill level of the storage - */ public CylindricalStorageResult( ZonedDateTime time, UUID inputModel, ComparableQuantity energy, ComparableQuantity qDot, ComparableQuantity fillLevel) { - super(time, inputModel, energy, qDot); - this.fillLevel = fillLevel.to(StandardUnits.FILL_LEVEL); - } - - public ComparableQuantity getFillLevel() { - return fillLevel; - } - - public void setFillLevel(ComparableQuantity fillLevel) { - this.fillLevel = fillLevel.to(StandardUnits.FILL_LEVEL); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - CylindricalStorageResult that = (CylindricalStorageResult) o; - return fillLevel.equals(that.fillLevel); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), fillLevel); - } - - @Override - public String toString() { - return "CylindricalStorageResult{" - + "time=" - + getTime() - + ", inputModel=" - + getInputModel() - + ", qDot=" - + getqDot() - + ", energy=" - + getEnergy() - + ", fillLevel=" - + fillLevel - + '}'; + super(time, inputModel, energy, qDot, fillLevel); } } diff --git a/src/main/java/edu/ie3/datamodel/models/result/thermal/DomesticHotWaterStorageResult.java b/src/main/java/edu/ie3/datamodel/models/result/thermal/DomesticHotWaterStorageResult.java new file mode 100644 index 000000000..cf604fe0e --- /dev/null +++ b/src/main/java/edu/ie3/datamodel/models/result/thermal/DomesticHotWaterStorageResult.java @@ -0,0 +1,26 @@ +/* + * © 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.thermal; + +import java.time.ZonedDateTime; +import java.util.UUID; +import javax.measure.quantity.Dimensionless; +import javax.measure.quantity.Energy; +import javax.measure.quantity.Power; +import tech.units.indriya.ComparableQuantity; + +/** Represents the results of Domestic Hot Water Storage */ +public class DomesticHotWaterStorageResult extends AbstractThermalStorageResult { + + public DomesticHotWaterStorageResult( + ZonedDateTime time, + UUID inputModel, + ComparableQuantity energy, + ComparableQuantity qDot, + ComparableQuantity fillLevel) { + super(time, inputModel, energy, qDot, fillLevel); + } +} diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/result/ThermalResultFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/result/ThermalResultFactoryTest.groovy index 9c64a97ec..1f22de467 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/result/ThermalResultFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/result/ThermalResultFactoryTest.groovy @@ -9,6 +9,7 @@ import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.io.factory.EntityData import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.result.thermal.CylindricalStorageResult +import edu.ie3.datamodel.models.result.thermal.DomesticHotWaterStorageResult import edu.ie3.datamodel.models.result.thermal.ThermalHouseResult import edu.ie3.datamodel.models.result.thermal.ThermalUnitResult import edu.ie3.datamodel.utils.Try @@ -23,7 +24,8 @@ class ThermalResultFactoryTest extends Specification implements FactoryTestHelpe def resultFactory = new ThermalResultFactory() def expectedClasses = [ ThermalHouseResult, - CylindricalStorageResult + CylindricalStorageResult, + DomesticHotWaterStorageResult ] expect: 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 257b8e33b..35f60261e 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/processor/ProcessorProviderTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/processor/ProcessorProviderTest.groovy @@ -35,6 +35,7 @@ import edu.ie3.datamodel.models.result.connector.Transformer2WResult import edu.ie3.datamodel.models.result.connector.Transformer3WResult import edu.ie3.datamodel.models.result.system.* import edu.ie3.datamodel.models.result.thermal.CylindricalStorageResult +import edu.ie3.datamodel.models.result.thermal.DomesticHotWaterStorageResult import edu.ie3.datamodel.models.result.thermal.ThermalHouseResult import edu.ie3.datamodel.models.timeseries.IntValue import edu.ie3.datamodel.models.timeseries.TimeSeries @@ -121,7 +122,8 @@ class ProcessorProviderTest extends Specification implements TimeSeriesTestData NodeResult, CongestionResult, ThermalHouseResult, - CylindricalStorageResult + CylindricalStorageResult, + DomesticHotWaterStorageResult ] // currently known processors 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 7bf12fbb9..12924e74a 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 @@ -15,6 +15,7 @@ import edu.ie3.datamodel.models.result.connector.Transformer2WResult import edu.ie3.datamodel.models.result.connector.Transformer3WResult import edu.ie3.datamodel.models.result.system.* import edu.ie3.datamodel.models.result.thermal.CylindricalStorageResult +import edu.ie3.datamodel.models.result.thermal.DomesticHotWaterStorageResult import edu.ie3.util.quantities.PowerSystemUnits import spock.lang.Shared import spock.lang.Specification @@ -252,6 +253,30 @@ class ResultEntityProcessorTest extends Specification { validProcessedElement == expectedResults } + def "A ResultEntityProcessor should serialize a DomesticHotWaterStorageResult correctly"() { + given: + def sysPartResProcessor = new ResultEntityProcessor(DomesticHotWaterStorageResult) + + Quantity qDot = Quantities.getQuantity(2, StandardUnits.Q_DOT_RESULT) + Quantity energy = Quantities.getQuantity(3, StandardUnits.ENERGY_RESULT) + Quantity fillLevel = Quantities.getQuantity(20, Units.PERCENT) + + def validResult = new DomesticHotWaterStorageResult(ZonedDateTime.parse("2020-01-30T17:26:44Z"), inputModel, energy, qDot, fillLevel) + + def expectedResults = [ + energy : '3.0', + fillLevel : '20.0', + inputModel: '22bea5fc-2cb2-4c61-beb9-b476e0107f52', + qDot : '2.0', + time : '2020-01-30T17:26:44Z'] + + when: + def validProcessedElement = sysPartResProcessor.handleEntity(validResult) + + then: + validProcessedElement == expectedResults + } + def "A ResultEntityProcessor should throw an EntityProcessorException when it receives an entity result that is not eligible"() { given: @@ -270,7 +295,7 @@ class ResultEntityProcessorTest extends Specification { def "The list of eligible entity classes for a ResultEntityProcessor should be valid"() { given: - int noOfElements = 20 // number of all currently implemented entity results + int noOfElements = 21 // number of all currently implemented entity results expect: ResultEntityProcessor.eligibleEntityClasses.size() == noOfElements