From 9eaf48867aa8bee660463700977b308e005e60f3 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 21 Feb 2025 16:45:32 +0100 Subject: [PATCH 1/3] Add Attributes housingType and numberInhabitants to ThermalHouses --- CHANGELOG.md | 1 + docs/readthedocs/io/ValidationUtils.md | 2 +- .../input/thermal/cylindricalstorage.md | 2 +- .../models/input/thermal/thermalhouse.md | 8 +++ .../main/input/ThermalDatamodelConcept.puml | 2 + .../input/ThermalHouseInputFactory.java | 16 ++++- .../input/thermal/ThermalHouseInput.java | 61 +++++++++++++++++-- .../validation/ThermalValidationUtils.java | 27 ++++++++ .../input/ThermalHouseInputFactoryTest.groovy | 7 ++- .../io/source/csv/CsvThermalSourceTest.groovy | 4 ++ .../thermal/ThermalHouseInputTest.groovy | 5 +- .../ThermalValidationUtilsTest.groovy | 28 +++++---- .../common/ThermalUnitInputTestData.groovy | 9 ++- .../datamodel/io/sink/_sql/input_entities.sql | 2 + .../csv/_thermal/thermal_house_input.csv | 4 +- 15 files changed, 150 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b35da38c7..6334f7c97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Enhance `TimeSeriesSource` with method to retrieve the previous value before a given key [#1182](https://github.com/ie3-institute/PowerSystemDataModel/issues/1182) - Added `BdewLoadProfileTimeSeries` [#1230](https://github.com/ie3-institute/PowerSystemDataModel/issues/1230) - Added `RandomLoadProfileTimeSeries` [#1232](https://github.com/ie3-institute/PowerSystemDataModel/issues/1232) +- Attributes `housingType` and `numberInhabitants` for `ThermalHouse`s [#1253](https://github.com/ie3-institute/PowerSystemDataModel/issues/1253) ### Fixed - Removing opened `SwitchInput` during connectivity check [#1221](https://github.com/ie3-institute/PowerSystemDataModel/issues/1221) diff --git a/docs/readthedocs/io/ValidationUtils.md b/docs/readthedocs/io/ValidationUtils.md index 7937ac204..4c2bf9194 100644 --- a/docs/readthedocs/io/ValidationUtils.md +++ b/docs/readthedocs/io/ValidationUtils.md @@ -74,7 +74,7 @@ The ValidationUtils include validation checks for... - HpTypeInput - StorageTypeInput - WecTypeInput -- ThermalUnitValidationUtils +- ThermalValidationUtils - ThermalUnitInput - ThermalSinkInput - ThermalHouseInput diff --git a/docs/readthedocs/models/input/thermal/cylindricalstorage.md b/docs/readthedocs/models/input/thermal/cylindricalstorage.md index 6e674f91b..ba25c5f5a 100644 --- a/docs/readthedocs/models/input/thermal/cylindricalstorage.md +++ b/docs/readthedocs/models/input/thermal/cylindricalstorage.md @@ -2,7 +2,7 @@ # Cylindrical Thermal Storage -Model of a cylindrical thermal storage using a fluent to store thermal energy. +Model of a cylindrical thermal storage using a fluid to store thermal energy. ## Attributes, Units and Remarks diff --git a/docs/readthedocs/models/input/thermal/thermalhouse.md b/docs/readthedocs/models/input/thermal/thermalhouse.md index 50837ee65..bcf0da11d 100644 --- a/docs/readthedocs/models/input/thermal/thermalhouse.md +++ b/docs/readthedocs/models/input/thermal/thermalhouse.md @@ -56,6 +56,14 @@ This reflects a simple shoe box with transmission losses * - lowerTemperatureLimit - °C - Lower temperature boundary + + * - housingType + - – + - Type of building can either be house or flat + + * - numberInhabititans + - – + - Number of people living in the house ``` diff --git a/docs/uml/main/input/ThermalDatamodelConcept.puml b/docs/uml/main/input/ThermalDatamodelConcept.puml index 3f275bc5b..466c4fdc0 100644 --- a/docs/uml/main/input/ThermalDatamodelConcept.puml +++ b/docs/uml/main/input/ThermalDatamodelConcept.puml @@ -107,6 +107,8 @@ package models { - targetTemperature: ComparableQuantity [°C] - upperTemperatureLimit: ComparableQuantity [°C] - lowerTemperatureLimit: ComparableQuantity [°C] + - houseType: String ['house' or 'flat'] + - numberInhabitants: Integer } ThermalHouseInput --|> ThermalSinkInput diff --git a/src/main/java/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactory.java b/src/main/java/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactory.java index 6fab0fc61..69533c930 100644 --- a/src/main/java/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactory.java +++ b/src/main/java/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactory.java @@ -23,6 +23,8 @@ public class ThermalHouseInputFactory private static final String TARGET_TEMPERATURE = "targetTemperature"; private static final String UPPER_TEMPERATURE_LIMIT = "upperTemperatureLimit"; private static final String LOWER_TEMPERATURE_LIMIT = "lowerTemperatureLimit"; + private static final String HOUSING_TYPE = "housingType"; + private static final String NUMBER_INHABITANTS = "numberInhabitants"; public ThermalHouseInputFactory() { super(ThermalHouseInput.class); @@ -31,7 +33,13 @@ public ThermalHouseInputFactory() { @Override protected String[] getAdditionalFields() { return new String[] { - ETH_LOSSES, ETH_CAPA, TARGET_TEMPERATURE, UPPER_TEMPERATURE_LIMIT, LOWER_TEMPERATURE_LIMIT + ETH_LOSSES, + ETH_CAPA, + TARGET_TEMPERATURE, + UPPER_TEMPERATURE_LIMIT, + LOWER_TEMPERATURE_LIMIT, + HOUSING_TYPE, + NUMBER_INHABITANTS }; } @@ -53,6 +61,8 @@ protected ThermalHouseInput buildModel( data.getQuantity(UPPER_TEMPERATURE_LIMIT, StandardUnits.TEMPERATURE); final ComparableQuantity lowerTemperatureLimit = data.getQuantity(LOWER_TEMPERATURE_LIMIT, StandardUnits.TEMPERATURE); + final String housingType = data.getField(HOUSING_TYPE); + final Integer numberInhabitants = data.getInt(NUMBER_INHABITANTS); return new ThermalHouseInput( uuid, id, @@ -63,6 +73,8 @@ protected ThermalHouseInput buildModel( ethCapa, targetTemperature, upperTemperatureLimit, - lowerTemperatureLimit); + lowerTemperatureLimit, + housingType, + numberInhabitants); } } diff --git a/src/main/java/edu/ie3/datamodel/models/input/thermal/ThermalHouseInput.java b/src/main/java/edu/ie3/datamodel/models/input/thermal/ThermalHouseInput.java index b0fbab0b6..e2a89a833 100644 --- a/src/main/java/edu/ie3/datamodel/models/input/thermal/ThermalHouseInput.java +++ b/src/main/java/edu/ie3/datamodel/models/input/thermal/ThermalHouseInput.java @@ -27,6 +27,10 @@ public class ThermalHouseInput extends ThermalSinkInput { private final ComparableQuantity upperTemperatureLimit; /** Lower boundary temperature of the thermal house model (typically in °C) */ private final ComparableQuantity lowerTemperatureLimit; + /** Type of the building, e.g. house or flat */ + private final String housingType; + /** Number of people living in the building, double to allow proper scaling */ + private final double numberInhabitants; /** * @param uuid Unique identifier of a thermal house model @@ -37,6 +41,8 @@ public class ThermalHouseInput extends ThermalSinkInput { * @param targetTemperature Desired target temperature of the thermal house model * @param upperTemperatureLimit Upper boundary temperature of the thermal house model * @param lowerTemperatureLimit Lower boundary temperature of the thermal house model + * @param housingType Type of the building: either house or flat + * @param numberInhabitants Number of inhabitants living in this house */ public ThermalHouseInput( UUID uuid, @@ -46,13 +52,17 @@ public ThermalHouseInput( ComparableQuantity ethCapa, ComparableQuantity targetTemperature, ComparableQuantity upperTemperatureLimit, - ComparableQuantity lowerTemperatureLimit) { + ComparableQuantity lowerTemperatureLimit, + String housingType, + double numberInhabitants) { super(uuid, id, bus); this.ethLosses = ethLosses.to(StandardUnits.THERMAL_TRANSMISSION); this.ethCapa = ethCapa.to(StandardUnits.HEAT_CAPACITY); this.targetTemperature = targetTemperature.to(StandardUnits.TEMPERATURE); this.upperTemperatureLimit = upperTemperatureLimit.to(StandardUnits.TEMPERATURE); this.lowerTemperatureLimit = lowerTemperatureLimit.to(StandardUnits.TEMPERATURE); + this.housingType = housingType; + this.numberInhabitants = numberInhabitants; } /** @@ -66,6 +76,8 @@ public ThermalHouseInput( * @param targetTemperature Desired target temperature of the thermal house model * @param upperTemperatureLimit Upper boundary temperature of the thermal house model * @param lowerTemperatureLimit Lower boundary temperature of the thermal house model + * @param housingType Type of the building: either house or flat + * @param numberInhabitants Number of inhabitants living in this house */ public ThermalHouseInput( UUID uuid, @@ -77,13 +89,17 @@ public ThermalHouseInput( ComparableQuantity ethCapa, ComparableQuantity targetTemperature, ComparableQuantity upperTemperatureLimit, - ComparableQuantity lowerTemperatureLimit) { + ComparableQuantity lowerTemperatureLimit, + String housingType, + double numberInhabitants) { super(uuid, id, operator, operationTime, bus); this.ethLosses = ethLosses.to(StandardUnits.THERMAL_TRANSMISSION); this.ethCapa = ethCapa.to(StandardUnits.HEAT_CAPACITY); this.targetTemperature = targetTemperature.to(StandardUnits.TEMPERATURE); this.upperTemperatureLimit = upperTemperatureLimit.to(StandardUnits.TEMPERATURE); this.lowerTemperatureLimit = lowerTemperatureLimit.to(StandardUnits.TEMPERATURE); + this.housingType = housingType; + this.numberInhabitants = numberInhabitants; } public ComparableQuantity getEthLosses() { @@ -106,6 +122,14 @@ public ComparableQuantity getLowerTemperatureLimit() { return lowerTemperatureLimit; } + public String getHousingType() { + return housingType; + } + + public double getNumberOfInhabitants() { + return numberInhabitants; + } + @Override public ThermalHouseInputCopyBuilder copy() { return new ThermalHouseInputCopyBuilder(this); @@ -120,7 +144,9 @@ public boolean equals(Object o) { && ethCapa.equals(that.ethCapa) && targetTemperature.equals(that.targetTemperature) && upperTemperatureLimit.equals(that.upperTemperatureLimit) - && lowerTemperatureLimit.equals(that.lowerTemperatureLimit); + && lowerTemperatureLimit.equals(that.lowerTemperatureLimit) + && Objects.equals(housingType, that.housingType) + && Objects.equals(numberInhabitants, that.numberInhabitants); } @Override @@ -131,7 +157,9 @@ public int hashCode() { ethCapa, targetTemperature, upperTemperatureLimit, - lowerTemperatureLimit); + lowerTemperatureLimit, + housingType, + numberInhabitants); } @Override @@ -157,6 +185,10 @@ public String toString() { + upperTemperatureLimit + ", lowerTemperatureLimit=" + lowerTemperatureLimit + + ", housingType=" + + housingType + + ", numberInhabitants=" + + numberInhabitants + '}'; } @@ -173,6 +205,8 @@ public static class ThermalHouseInputCopyBuilder private ComparableQuantity targetTemperature; private ComparableQuantity upperTemperatureLimit; private ComparableQuantity lowerTemperatureLimit; + private String housingType; + private double numberInhabitants; private ThermalHouseInputCopyBuilder(ThermalHouseInput entity) { super(entity); @@ -181,6 +215,8 @@ private ThermalHouseInputCopyBuilder(ThermalHouseInput entity) { this.targetTemperature = entity.getTargetTemperature(); this.upperTemperatureLimit = entity.getUpperTemperatureLimit(); this.lowerTemperatureLimit = entity.getLowerTemperatureLimit(); + this.housingType = entity.getHousingType(); + this.numberInhabitants = entity.getNumberOfInhabitants(); } public ThermalHouseInputCopyBuilder ethLosses( @@ -212,12 +248,23 @@ public ThermalHouseInputCopyBuilder lowerTemperatureLimit( return this; } + public ThermalHouseInputCopyBuilder housingType(String housingType) { + this.housingType = housingType; + return this; + } + + public ThermalHouseInputCopyBuilder numberInhabitants(double numberInhabitants) { + this.numberInhabitants = numberInhabitants; + return this; + } + @Override public ThermalHouseInputCopyBuilder scale(Double factor) { - // scale losses as well as capacity to keep equal + // scale losses as well as capacity and number of inhabitants to keep equal // the time needed to heat a scaled house ethLosses(ethLosses.multiply(factor)); ethCapa(ethCapa.multiply(factor)); + numberInhabitants(numberInhabitants * factor); return this; } @@ -233,7 +280,9 @@ public ThermalHouseInput build() { ethCapa, targetTemperature, upperTemperatureLimit, - lowerTemperatureLimit); + lowerTemperatureLimit, + housingType, + numberInhabitants); } @Override diff --git a/src/main/java/edu/ie3/datamodel/utils/validation/ThermalValidationUtils.java b/src/main/java/edu/ie3/datamodel/utils/validation/ThermalValidationUtils.java index 15cc20d2f..fc849a299 100644 --- a/src/main/java/edu/ie3/datamodel/utils/validation/ThermalValidationUtils.java +++ b/src/main/java/edu/ie3/datamodel/utils/validation/ThermalValidationUtils.java @@ -13,6 +13,7 @@ import edu.ie3.datamodel.utils.Try.Failure; import java.util.ArrayList; import java.util.List; +import java.util.Set; import javax.measure.Quantity; public class ThermalValidationUtils extends ValidationUtils { @@ -172,6 +173,8 @@ private ThermalValidationUtils() { *
  • its thermal capacity is positive *
  • its upper temperature limit is higher than the lower temperature limit *
  • its target temperature lies between the upper und lower limit temperatures + *
  • its housing type is either `house` or `flat` + *
  • its number of inhabitants is higher than zero * * * @param thermalHouseInput ThermalHouseInput to validate @@ -210,9 +213,33 @@ private static List> checkThermalHouse( thermalHouseInput))); } + if (!isValidHousingType(thermalHouseInput.getHousingType())) { + exceptions.add( + new Failure<>( + new InvalidEntityException( + "Housing type must be either 'house' or 'flat'", thermalHouseInput))); + } + + if (thermalHouseInput.getNumberOfInhabitants() <= 0) { + exceptions.add( + new Failure<>( + new InvalidEntityException( + "Number of inhabitants must be greater than zero", thermalHouseInput))); + } + return exceptions; } + /** + * Checks if the housing type is valid (either "house" or "flat"). + * + * @param housingType The housing type to check + * @return true if valid, false otherwise + */ + private static boolean isValidHousingType(String housingType) { + return Set.of("house", "flat").contains(housingType.toLowerCase()); + } + /** * Validates a cylindricalStorageInput if: * diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactoryTest.groovy index 82c0e7843..07f5794fd 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactoryTest.groovy @@ -35,7 +35,10 @@ class ThermalHouseInputFactoryTest extends Specification implements FactoryTestH "ethcapa" : "4", "targetTemperature" : "5", "upperTemperatureLimit": "6", - "lowerTemperatureLimit": "7" + "lowerTemperatureLimit": "7", + "housingType" : "flat", + "numberInhabitants" : "9", + ] def inputClass = ThermalHouseInput def thermalBusInput = Mock(ThermalBusInput) @@ -57,6 +60,8 @@ class ThermalHouseInputFactoryTest extends Specification implements FactoryTestH assert targetTemperature == getQuant(parameter["targetTemperature"], StandardUnits.TEMPERATURE) assert upperTemperatureLimit == getQuant(parameter["upperTemperatureLimit"], StandardUnits.TEMPERATURE) assert lowerTemperatureLimit == getQuant(parameter["lowerTemperatureLimit"], StandardUnits.TEMPERATURE) + assert housingType == parameter["housingType"] + assert numberInhabitants == parameter["numberInhabitants"].toInteger() } } } diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvThermalSourceTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvThermalSourceTest.groovy index 915046bb6..bdbfc2528 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvThermalSourceTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvThermalSourceTest.groovy @@ -114,6 +114,8 @@ class CsvThermalSourceTest extends Specification implements CsvTestDataMeta { targetTemperature == ThermalUnitInputTestData.thermalHouseInput.targetTemperature upperTemperatureLimit == ThermalUnitInputTestData.thermalHouseInput.upperTemperatureLimit lowerTemperatureLimit == ThermalUnitInputTestData.thermalHouseInput.lowerTemperatureLimit + housingType == ThermalUnitInputTestData.thermalHouseInput.housingType + numberOfInhabitants == ThermalUnitInputTestData.thermalHouseInput.numberOfInhabitants } //test method when operators and thermal buses are provided as constructor parameters @@ -134,6 +136,8 @@ class CsvThermalSourceTest extends Specification implements CsvTestDataMeta { targetTemperature == ThermalUnitInputTestData.thermalHouseInput.targetTemperature upperTemperatureLimit == ThermalUnitInputTestData.thermalHouseInput.upperTemperatureLimit lowerTemperatureLimit == ThermalUnitInputTestData.thermalHouseInput.lowerTemperatureLimit + housingType == ThermalUnitInputTestData.thermalHouseInput.housingType + numberOfInhabitants == ThermalUnitInputTestData.thermalHouseInput.numberOfInhabitants } } } \ No newline at end of file diff --git a/src/test/groovy/edu/ie3/datamodel/models/input/thermal/ThermalHouseInputTest.groovy b/src/test/groovy/edu/ie3/datamodel/models/input/thermal/ThermalHouseInputTest.groovy index d2f9c5afd..7f93dab21 100644 --- a/src/test/groovy/edu/ie3/datamodel/models/input/thermal/ThermalHouseInputTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/models/input/thermal/ThermalHouseInputTest.groovy @@ -67,7 +67,10 @@ class ThermalHouseInputTest extends Specification { Quantities.getQuantity(20, StandardUnits.HEAT_CAPACITY), Quantities.getQuantity(20, StandardUnits.TEMPERATURE), Quantities.getQuantity(25, StandardUnits.TEMPERATURE), - Quantities.getQuantity(15, StandardUnits.TEMPERATURE)) + Quantities.getQuantity(15, StandardUnits.TEMPERATURE), + "house", + 2 + ) expect: thermalHouseInput.targetTemperature == Quantities.getQuantity(20, StandardUnits.TEMPERATURE) diff --git a/src/test/groovy/edu/ie3/datamodel/utils/validation/ThermalValidationUtilsTest.groovy b/src/test/groovy/edu/ie3/datamodel/utils/validation/ThermalValidationUtilsTest.groovy index aee73fe73..3c017676c 100644 --- a/src/test/groovy/edu/ie3/datamodel/utils/validation/ThermalValidationUtilsTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/utils/validation/ThermalValidationUtilsTest.groovy @@ -44,6 +44,8 @@ class ThermalValidationUtilsTest extends Specification { private static final ComparableQuantity TARGET_TEMPERATURE = Quantities.getQuantity(20, StandardUnits.TEMPERATURE) private static final ComparableQuantity UPPER_TEMPERATURE_LIMIT = Quantities.getQuantity(25, StandardUnits.TEMPERATURE) private static final ComparableQuantity LOWER_TEMPERATURE_LIMIT = Quantities.getQuantity(15, StandardUnits.TEMPERATURE) + private static final String HOUSING_TYPE = "House" + private static final Integer NUMBER_INHABITANTS = 2.0 // Specific data for thermal cylindrical storage input private static final ComparableQuantity storageVolumeLvl = Quantities.getQuantity(100, StandardUnits.VOLUME) @@ -64,7 +66,7 @@ class ThermalValidationUtilsTest extends Specification { noExceptionThrown() } - def "ThermalUnitValidationUtils.checkThermalHouse() recognizes all potential errors for a thermal house"() { + def "ThermalValidationUtils.checkThermalHouse() recognizes all potential errors for a thermal house"() { when: List> exceptions = ThermalValidationUtils.check(invalidThermalHouse).stream().filter { it -> it.failure }.toList() @@ -75,13 +77,15 @@ class ThermalValidationUtilsTest extends Specification { ex.message == expectedException.message where: - invalidThermalHouse || expectedSize || expectedException - new ThermalHouseInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, Quantities.getQuantity(-10, StandardUnits.THERMAL_TRANSMISSION), ethCapa, TARGET_TEMPERATURE, UPPER_TEMPERATURE_LIMIT, LOWER_TEMPERATURE_LIMIT) || 1 || new InvalidEntityException("The following quantities have to be zero or positive: -10 kW/K", invalidThermalHouse) - new ThermalHouseInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, thermalConductance, Quantities.getQuantity(0, StandardUnits.HEAT_CAPACITY), TARGET_TEMPERATURE, UPPER_TEMPERATURE_LIMIT, LOWER_TEMPERATURE_LIMIT) || 1 || new InvalidEntityException("The following quantities have to be positive: 0 kWh/K", invalidThermalHouse) - new ThermalHouseInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, thermalConductance, ethCapa, Quantities.getQuantity(0, StandardUnits.TEMPERATURE), UPPER_TEMPERATURE_LIMIT, LOWER_TEMPERATURE_LIMIT) || 1 || new InvalidEntityException("Target temperature must be higher than lower temperature limit and lower than upper temperature limit", invalidThermalHouse) - new ThermalHouseInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, thermalConductance, ethCapa, TARGET_TEMPERATURE, Quantities.getQuantity(0, StandardUnits.TEMPERATURE), LOWER_TEMPERATURE_LIMIT) || 1 || new InvalidEntityException("Target temperature must be higher than lower temperature limit and lower than upper temperature limit", invalidThermalHouse) - new ThermalHouseInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, thermalConductance, ethCapa, TARGET_TEMPERATURE, UPPER_TEMPERATURE_LIMIT, Quantities.getQuantity(30, StandardUnits.TEMPERATURE)) || 1 || new InvalidEntityException("Target temperature must be higher than lower temperature limit and lower than upper temperature limit", invalidThermalHouse) - new ThermalHouseInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, thermalConductance, ethCapa, TARGET_TEMPERATURE, TARGET_TEMPERATURE, LOWER_TEMPERATURE_LIMIT) || 1 || new InvalidEntityException("Target temperature must be higher than lower temperature limit and lower than upper temperature limit", invalidThermalHouse) + invalidThermalHouse || expectedSize || expectedException + new ThermalHouseInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, Quantities.getQuantity(-10, StandardUnits.THERMAL_TRANSMISSION), ethCapa, TARGET_TEMPERATURE, UPPER_TEMPERATURE_LIMIT, LOWER_TEMPERATURE_LIMIT, HOUSING_TYPE, NUMBER_INHABITANTS) || 1 || new InvalidEntityException("The following quantities have to be zero or positive: -10 kW/K", invalidThermalHouse) + new ThermalHouseInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, thermalConductance, Quantities.getQuantity(0, StandardUnits.HEAT_CAPACITY), TARGET_TEMPERATURE, UPPER_TEMPERATURE_LIMIT, LOWER_TEMPERATURE_LIMIT, HOUSING_TYPE, NUMBER_INHABITANTS) || 1 || new InvalidEntityException("The following quantities have to be positive: 0 kWh/K", invalidThermalHouse) + new ThermalHouseInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, thermalConductance, ethCapa, Quantities.getQuantity(0, StandardUnits.TEMPERATURE), UPPER_TEMPERATURE_LIMIT, LOWER_TEMPERATURE_LIMIT, HOUSING_TYPE, NUMBER_INHABITANTS) || 1 || new InvalidEntityException("Target temperature must be higher than lower temperature limit and lower than upper temperature limit", invalidThermalHouse) + new ThermalHouseInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, thermalConductance, ethCapa, TARGET_TEMPERATURE, Quantities.getQuantity(0, StandardUnits.TEMPERATURE), LOWER_TEMPERATURE_LIMIT, HOUSING_TYPE, NUMBER_INHABITANTS) || 1 || new InvalidEntityException("Target temperature must be higher than lower temperature limit and lower than upper temperature limit", invalidThermalHouse) + new ThermalHouseInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, thermalConductance, ethCapa, TARGET_TEMPERATURE, UPPER_TEMPERATURE_LIMIT, Quantities.getQuantity(30, StandardUnits.TEMPERATURE), HOUSING_TYPE, NUMBER_INHABITANTS) || 1 || new InvalidEntityException("Target temperature must be higher than lower temperature limit and lower than upper temperature limit", invalidThermalHouse) + new ThermalHouseInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, thermalConductance, ethCapa, TARGET_TEMPERATURE, TARGET_TEMPERATURE, LOWER_TEMPERATURE_LIMIT, HOUSING_TYPE, NUMBER_INHABITANTS) || 1 || new InvalidEntityException("Target temperature must be higher than lower temperature limit and lower than upper temperature limit", invalidThermalHouse) + new ThermalHouseInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, thermalConductance, ethCapa, TARGET_TEMPERATURE, UPPER_TEMPERATURE_LIMIT, LOWER_TEMPERATURE_LIMIT, "someWrongType", NUMBER_INHABITANTS) || 1 || new InvalidEntityException("Housing type must be either 'house' or 'flat'", invalidThermalHouse) + new ThermalHouseInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, thermalConductance, ethCapa, TARGET_TEMPERATURE, UPPER_TEMPERATURE_LIMIT, LOWER_TEMPERATURE_LIMIT, HOUSING_TYPE, 0d) || 1 || new InvalidEntityException("Number of inhabitants must be greater than zero", invalidThermalHouse) } // Thermal Cylindrical Storage @@ -97,7 +101,7 @@ class ThermalValidationUtilsTest extends Specification { noExceptionThrown() } - def "ThermalUnitValidationUtils.checkCylindricalStorage() recognizes all potential errors for a thermal cylindrical storage"() { + def "ThermalValidationUtils.checkCylindricalStorage() recognizes all potential errors for a thermal cylindrical storage"() { when: List> exceptions = ThermalValidationUtils.check(invalidCylindricalStorage).stream().filter { it -> it.failure }.toList() @@ -114,7 +118,7 @@ class ThermalValidationUtilsTest extends Specification { new CylindricalStorageInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, Quantities.getQuantity(-100, StandardUnits.VOLUME), inletTemp, returnTemp, Quantities.getQuantity(-1.05, StandardUnits.SPECIFIC_HEAT_CAPACITY)) || 1 || new InvalidEntityException("The following quantities have to be positive: -100 ㎥, -1.05 kWh/K*m³", invalidCylindricalStorage) } - def "ThermalUnitValidationUtils.check() works for complete ThermalGrid as well"() { + def "ThermalValidationUtils.check() works for complete ThermalGrid as well"() { when: def thermalBus = ThermalUnitInputTestData.thermalBus def cylindricalStorageInput = [ @@ -135,7 +139,7 @@ class ThermalValidationUtilsTest extends Specification { where: - thermalHouse || expectedSize || expectedException - new ThermalHouseInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, thermalConductance, ethCapa, Quantities.getQuantity(0, StandardUnits.TEMPERATURE), UPPER_TEMPERATURE_LIMIT, LOWER_TEMPERATURE_LIMIT) || 1 || new InvalidEntityException("Target temperature must be higher than lower temperature limit and lower than upper temperature limit", thermalHouse) + thermalHouse || expectedSize || expectedException + new ThermalHouseInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, thermalConductance, ethCapa, Quantities.getQuantity(0, StandardUnits.TEMPERATURE), UPPER_TEMPERATURE_LIMIT, LOWER_TEMPERATURE_LIMIT, HOUSING_TYPE, NUMBER_INHABITANTS) || 1 || new InvalidEntityException("Target temperature must be higher than lower temperature limit and lower than upper temperature limit", thermalHouse) } } diff --git a/src/test/groovy/edu/ie3/test/common/ThermalUnitInputTestData.groovy b/src/test/groovy/edu/ie3/test/common/ThermalUnitInputTestData.groovy index bf3f6a521..ce12807e6 100644 --- a/src/test/groovy/edu/ie3/test/common/ThermalUnitInputTestData.groovy +++ b/src/test/groovy/edu/ie3/test/common/ThermalUnitInputTestData.groovy @@ -36,9 +36,12 @@ class ThermalUnitInputTestData extends SystemParticipantTestData { private static final ComparableQuantity TARGET_TEMPERATURE = Quantities.getQuantity(20, StandardUnits.TEMPERATURE) private static final ComparableQuantity UPPER_TEMPERATURE_LIMIT = Quantities.getQuantity(25, StandardUnits.TEMPERATURE) private static final ComparableQuantity LOWER_TEMPERATURE_LIMIT = Quantities.getQuantity(15, StandardUnits.TEMPERATURE) + private static final String HOUSING_TYPE = "house" + private static final double NUMBER_INHABITANTS = 2.0 + public static final thermalHouseInput = new ThermalHouseInput( thermalUnitUuid, - "test_thermalHouseInput", + "testThermalHouseInput", operator, operationTime, thermalBus, @@ -46,7 +49,9 @@ class ThermalUnitInputTestData extends SystemParticipantTestData { ethCapa, TARGET_TEMPERATURE, UPPER_TEMPERATURE_LIMIT, - LOWER_TEMPERATURE_LIMIT) + LOWER_TEMPERATURE_LIMIT, + HOUSING_TYPE, + NUMBER_INHABITANTS) // thermal cylindric storage input private static final ComparableQuantity storageVolumeLvl = Quantities.getQuantity(100, StandardUnits.VOLUME) diff --git a/src/test/resources/edu/ie3/datamodel/io/sink/_sql/input_entities.sql b/src/test/resources/edu/ie3/datamodel/io/sink/_sql/input_entities.sql index 6018e6f7c..5d7cb1a50 100644 --- a/src/test/resources/edu/ie3/datamodel/io/sink/_sql/input_entities.sql +++ b/src/test/resources/edu/ie3/datamodel/io/sink/_sql/input_entities.sql @@ -107,6 +107,8 @@ CREATE TABLE public.thermal_house_input target_temperature DOUBLE PRECISION NOT NULL, thermal_bus UUID NOT NULL, upper_temperature_limit DOUBLE PRECISION NOT NULL, + housing_type TEXT NOT NULL, + number_of_inhabitants TEXT NOT NULL, grid_uuid UUID NOT NULL REFERENCES grids(uuid) ) WITHOUT OIDS diff --git a/src/test/resources/edu/ie3/datamodel/io/source/csv/_thermal/thermal_house_input.csv b/src/test/resources/edu/ie3/datamodel/io/source/csv/_thermal/thermal_house_input.csv index a1a8cdbdc..87dcf4374 100644 --- a/src/test/resources/edu/ie3/datamodel/io/source/csv/_thermal/thermal_house_input.csv +++ b/src/test/resources/edu/ie3/datamodel/io/source/csv/_thermal/thermal_house_input.csv @@ -1,2 +1,2 @@ -uuid,id,operates_from,operates_until,operator,thermal_bus,eth_losses,eth_capa,target_temperature,upper_temperature_limit,lower_temperature_limit -717af017-cc69-406f-b452-e022d7fb516a,"test_thermalHouseInput",2020-03-24T15:11:31Z,2020-03-25T15:11:31Z,8f9682df-0744-4b58-a122-f0dc730f6510,0d95d7f2-49fb-4d49-8636-383a5220384e,10,20,20,25,15 \ No newline at end of file +uuid,id,operates_from,operates_until,operator,thermal_bus,eth_losses,eth_capa,target_temperature,upper_temperature_limit,lower_temperature_limit,housing_type,number_inhabitants +717af017-cc69-406f-b452-e022d7fb516a,"testThermalHouseInput",2020-03-24T15:11:31Z,2020-03-25T15:11:31Z,8f9682df-0744-4b58-a122-f0dc730f6510,0d95d7f2-49fb-4d49-8636-383a5220384e,10,20,20,25,15,"house",2 \ No newline at end of file From b1ddd42d1aab1f790da5bbafda7971cf1ba419a8 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 21 Feb 2025 17:21:16 +0100 Subject: [PATCH 2/3] include reviewers feedback --- docs/readthedocs/models/input/thermal/thermalhouse.md | 2 +- .../io/factory/input/ThermalHouseInputFactory.java | 2 +- .../datamodel/models/input/thermal/ThermalHouseInput.java | 2 +- .../io/factory/input/ThermalHouseInputFactoryTest.groovy | 2 +- .../models/input/thermal/ThermalHouseInputTest.groovy | 8 +++++++- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/docs/readthedocs/models/input/thermal/thermalhouse.md b/docs/readthedocs/models/input/thermal/thermalhouse.md index bcf0da11d..9120eb27f 100644 --- a/docs/readthedocs/models/input/thermal/thermalhouse.md +++ b/docs/readthedocs/models/input/thermal/thermalhouse.md @@ -63,7 +63,7 @@ This reflects a simple shoe box with transmission losses * - numberInhabititans - – - - Number of people living in the house + - Number of people living in the house. Double values to enable modeling based on statistical data sources. ``` diff --git a/src/main/java/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactory.java b/src/main/java/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactory.java index 69533c930..590dbcce1 100644 --- a/src/main/java/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactory.java +++ b/src/main/java/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactory.java @@ -62,7 +62,7 @@ protected ThermalHouseInput buildModel( final ComparableQuantity lowerTemperatureLimit = data.getQuantity(LOWER_TEMPERATURE_LIMIT, StandardUnits.TEMPERATURE); final String housingType = data.getField(HOUSING_TYPE); - final Integer numberInhabitants = data.getInt(NUMBER_INHABITANTS); + final Double numberInhabitants = data.getDouble(NUMBER_INHABITANTS); return new ThermalHouseInput( uuid, id, diff --git a/src/main/java/edu/ie3/datamodel/models/input/thermal/ThermalHouseInput.java b/src/main/java/edu/ie3/datamodel/models/input/thermal/ThermalHouseInput.java index e2a89a833..95af4144b 100644 --- a/src/main/java/edu/ie3/datamodel/models/input/thermal/ThermalHouseInput.java +++ b/src/main/java/edu/ie3/datamodel/models/input/thermal/ThermalHouseInput.java @@ -187,7 +187,7 @@ public String toString() { + lowerTemperatureLimit + ", housingType=" + housingType - + ", numberInhabitants=" + + ", #Inhabitants=" + numberInhabitants + '}'; } diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactoryTest.groovy index 07f5794fd..b2c1055c8 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactoryTest.groovy @@ -61,7 +61,7 @@ class ThermalHouseInputFactoryTest extends Specification implements FactoryTestH assert upperTemperatureLimit == getQuant(parameter["upperTemperatureLimit"], StandardUnits.TEMPERATURE) assert lowerTemperatureLimit == getQuant(parameter["lowerTemperatureLimit"], StandardUnits.TEMPERATURE) assert housingType == parameter["housingType"] - assert numberInhabitants == parameter["numberInhabitants"].toInteger() + assert numberInhabitants == parameter["numberInhabitants"].toDouble() } } } diff --git a/src/test/groovy/edu/ie3/datamodel/models/input/thermal/ThermalHouseInputTest.groovy b/src/test/groovy/edu/ie3/datamodel/models/input/thermal/ThermalHouseInputTest.groovy index 7f93dab21..739e8c1d6 100644 --- a/src/test/groovy/edu/ie3/datamodel/models/input/thermal/ThermalHouseInputTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/models/input/thermal/ThermalHouseInputTest.groovy @@ -38,6 +38,8 @@ class ThermalHouseInputTest extends Specification { assert targetTemperature == ThermalUnitInputTestData.TARGET_TEMPERATURE assert upperTemperatureLimit == ThermalUnitInputTestData.UPPER_TEMPERATURE_LIMIT assert lowerTemperatureLimit == ThermalUnitInputTestData.LOWER_TEMPERATURE_LIMIT + assert housingType == ThermalUnitInputTestData.HOUSING_TYPE + assert numberOfInhabitants == ThermalUnitInputTestData.NUMBER_INHABITANTS } } @@ -69,13 +71,15 @@ class ThermalHouseInputTest extends Specification { Quantities.getQuantity(25, StandardUnits.TEMPERATURE), Quantities.getQuantity(15, StandardUnits.TEMPERATURE), "house", - 2 + 2.0 ) expect: thermalHouseInput.targetTemperature == Quantities.getQuantity(20, StandardUnits.TEMPERATURE) thermalHouseInput.upperTemperatureLimit == Quantities.getQuantity(25, StandardUnits.TEMPERATURE) thermalHouseInput.lowerTemperatureLimit == Quantities.getQuantity(15, StandardUnits.TEMPERATURE) + thermalHouseInput.housingType == "house" + thermalHouseInput.numberOfInhabitants == 2.0 } def "Scaling a ThermalHouseInput via builder should work as expected"() { @@ -97,6 +101,8 @@ class ThermalHouseInputTest extends Specification { assert targetTemperature == thermalHouseInput.targetTemperature assert upperTemperatureLimit == thermalHouseInput.upperTemperatureLimit assert lowerTemperatureLimit == thermalHouseInput.lowerTemperatureLimit + assert housingType == thermalHouseInput.housingType + assert numberOfInhabitants == thermalHouseInput.numberOfInhabitants * 2d } } } From 8b867595a3871d42f13e5e8a8a4f9ce3f0a88744 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Mon, 24 Feb 2025 12:38:23 +0100 Subject: [PATCH 3/3] include reviewers feedback --- docs/uml/main/input/ThermalDatamodelConcept.puml | 2 +- .../datamodel/io/factory/input/ThermalHouseInputFactory.java | 2 +- .../ie3/datamodel/models/input/thermal/ThermalHouseInput.java | 2 +- .../resources/edu/ie3/datamodel/io/sink/_sql/input_entities.sql | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/uml/main/input/ThermalDatamodelConcept.puml b/docs/uml/main/input/ThermalDatamodelConcept.puml index 2df67bae6..11abcb7ac 100644 --- a/docs/uml/main/input/ThermalDatamodelConcept.puml +++ b/docs/uml/main/input/ThermalDatamodelConcept.puml @@ -108,7 +108,7 @@ package models { - upperTemperatureLimit: ComparableQuantity [°C] - lowerTemperatureLimit: ComparableQuantity [°C] - houseType: String ['house' or 'flat'] - - numberInhabitants: Integer + - numberInhabitants: Double } ThermalHouseInput --|> ThermalSinkInput diff --git a/src/main/java/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactory.java b/src/main/java/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactory.java index 590dbcce1..6972f99a0 100644 --- a/src/main/java/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactory.java +++ b/src/main/java/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactory.java @@ -62,7 +62,7 @@ protected ThermalHouseInput buildModel( final ComparableQuantity lowerTemperatureLimit = data.getQuantity(LOWER_TEMPERATURE_LIMIT, StandardUnits.TEMPERATURE); final String housingType = data.getField(HOUSING_TYPE); - final Double numberInhabitants = data.getDouble(NUMBER_INHABITANTS); + final double numberInhabitants = data.getDouble(NUMBER_INHABITANTS); return new ThermalHouseInput( uuid, id, diff --git a/src/main/java/edu/ie3/datamodel/models/input/thermal/ThermalHouseInput.java b/src/main/java/edu/ie3/datamodel/models/input/thermal/ThermalHouseInput.java index 95af4144b..e5ccfd342 100644 --- a/src/main/java/edu/ie3/datamodel/models/input/thermal/ThermalHouseInput.java +++ b/src/main/java/edu/ie3/datamodel/models/input/thermal/ThermalHouseInput.java @@ -187,7 +187,7 @@ public String toString() { + lowerTemperatureLimit + ", housingType=" + housingType - + ", #Inhabitants=" + + ", #inhabitants=" + numberInhabitants + '}'; } diff --git a/src/test/resources/edu/ie3/datamodel/io/sink/_sql/input_entities.sql b/src/test/resources/edu/ie3/datamodel/io/sink/_sql/input_entities.sql index adbfe4a9e..31464bae3 100644 --- a/src/test/resources/edu/ie3/datamodel/io/sink/_sql/input_entities.sql +++ b/src/test/resources/edu/ie3/datamodel/io/sink/_sql/input_entities.sql @@ -109,7 +109,7 @@ CREATE TABLE public.thermal_house_input thermal_bus UUID NOT NULL, upper_temperature_limit DOUBLE PRECISION NOT NULL, housing_type TEXT NOT NULL, - number_of_inhabitants TEXT NOT NULL, + number_of_inhabitants DOUBLE PRECISION NOT NULL, grid_uuid UUID NOT NULL REFERENCES grids(uuid) ) WITHOUT OIDS