From 29a3c38de151e925198b9486b748ca426c898e6d Mon Sep 17 00:00:00 2001 From: Marius Staudt Date: Tue, 21 Jun 2022 18:03:51 +0200 Subject: [PATCH 01/13] Revising the data structure of the ElectricVehicle model. --- .../edu/ie3/mobsim/io/geodata/PoiEnums.scala | 26 ++++++++++++++++ .../mobsim/io/geodata/PointOfInterest.scala | 8 ++++- .../ie3/mobsim/model/ElectricVehicle.scala | 30 +++++------------- .../edu/ie3/mobsim/model/TripSimulation.scala | 12 ------- .../ie3/mobsim/io/geodata/PoiEnumsSpec.scala | 31 +++++++++++++++++++ .../ie3/mobsim/io/geodata/PoiTestData.scala | 20 ++++++++++-- .../mobsim/model/ElectricVehicleSpec.scala | 18 +++++------ .../model/ElectricVehicleTestData.scala | 7 ++++- .../ie3/mobsim/model/TripSimulationSpec.scala | 22 ++++++------- 9 files changed, 115 insertions(+), 59 deletions(-) diff --git a/src/main/scala/edu/ie3/mobsim/io/geodata/PoiEnums.scala b/src/main/scala/edu/ie3/mobsim/io/geodata/PoiEnums.scala index 67cfffbc..d0336d29 100644 --- a/src/main/scala/edu/ie3/mobsim/io/geodata/PoiEnums.scala +++ b/src/main/scala/edu/ie3/mobsim/io/geodata/PoiEnums.scala @@ -25,6 +25,32 @@ object PoiEnums { case _ => throw new RuntimeException("POI not known") } } + + def apply( + categoricalLocation: CategoricalLocationDictionary.Value + ): Value = { + categoricalLocation match { + case CategoricalLocationDictionary.HOME => HOME + case CategoricalLocationDictionary.WORK => WORK + case CategoricalLocationDictionary.SUPERMARKET => SHOPPING + case CategoricalLocationDictionary.SERVICES => SHOPPING + case CategoricalLocationDictionary.OTHER_SHOP => SHOPPING + case CategoricalLocationDictionary.RESTAURANT => LEISURE + case CategoricalLocationDictionary.CULTURE => LEISURE + case CategoricalLocationDictionary.SPORTS => LEISURE + case CategoricalLocationDictionary.RELIGIOUS => LEISURE + case CategoricalLocationDictionary.MEDICINAL => OTHER + case CategoricalLocationDictionary.BBPG => OTHER + case CategoricalLocationDictionary.CHARGING_HUB_TOWN => + CHARGING_HUB_TOWN + case CategoricalLocationDictionary.CHARGING_HUB_HIGHWAY => + CHARGING_HUB_HIGHWAY + case malformed => + throw new RuntimeException( + s"CategoricalLocation '$malformed' could not be applied to PoiTypeDictionary" + ) + } + } } object CategoricalLocationDictionary extends Enumeration { diff --git a/src/main/scala/edu/ie3/mobsim/io/geodata/PointOfInterest.scala b/src/main/scala/edu/ie3/mobsim/io/geodata/PointOfInterest.scala index bbbe2149..11a9c37c 100644 --- a/src/main/scala/edu/ie3/mobsim/io/geodata/PointOfInterest.scala +++ b/src/main/scala/edu/ie3/mobsim/io/geodata/PointOfInterest.scala @@ -8,7 +8,10 @@ package edu.ie3.mobsim.io.geodata import edu.ie3.datamodel.models.input.system.`type`.evcslocation.EvcsLocationType import edu.ie3.mobsim.exceptions.InitializationException -import edu.ie3.mobsim.io.geodata.PoiEnums.CategoricalLocationDictionary +import edu.ie3.mobsim.io.geodata.PoiEnums.{ + CategoricalLocationDictionary, + PoiTypeDictionary +} import edu.ie3.mobsim.model.ChargingStation import edu.ie3.util.geo.GeoUtils import org.locationtech.jts.geom.Coordinate @@ -43,6 +46,7 @@ import scala.jdk.CollectionConverters._ final case class PointOfInterest( uuid: UUID, id: String, + poiType: PoiTypeDictionary.Value, categoricalLocation: CategoricalLocationDictionary.Value, geoPosition: Coordinate, size: Double, @@ -206,6 +210,7 @@ case object PointOfInterest { val poi = PointOfInterest( uuid, identifier, + PoiTypeDictionary.apply(catLoc), catLoc, coordinate, sze, @@ -347,6 +352,7 @@ case object PointOfInterest { new PointOfInterest( uuid, identifier, + PoiTypeDictionary.apply(catLoc), catLoc, coordinate, sze, diff --git a/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala b/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala index 2b6636a4..d69a1035 100644 --- a/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala +++ b/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala @@ -47,15 +47,12 @@ case class ElectricVehicle( private val homePoi: PointOfInterest, private val workPoi: PointOfInterest, private var storedEnergy: ComparableQuantity[Energy], - private var destinationPoiType: PoiTypeDictionary.Value, - private var destinationCategoricalLocation: CategoricalLocationDictionary.Value, private var destinationPoi: PointOfInterest, private var parkingTimeStart: ZonedDateTime, private var departureTime: ZonedDateTime, private val chargingAtHomePossible: Boolean, private var chosenChargingStation: Option[UUID], private var chargingAtSimona: Boolean, - private var finalDestinationPoiType: Option[PoiTypeDictionary.Value], private var finalDestinationPoi: Option[PointOfInterest], private var remainingDistanceAfterChargingHub: Option[ ComparableQuantity[Length] @@ -84,10 +81,10 @@ case class ElectricVehicle( def getStoredEnergy: ComparableQuantity[Energy] = storedEnergy - def getDestinationPoiType: PoiTypeDictionary.Value = destinationPoiType + def getDestinationPoiType: PoiTypeDictionary.Value = destinationPoi.poiType def getDestinationCategoricalLocation: CategoricalLocationDictionary.Value = - destinationCategoricalLocation + destinationPoi.categoricalLocation def getDestinationPoi: PointOfInterest = destinationPoi @@ -101,8 +98,12 @@ case class ElectricVehicle( def isChargingAtSimona: Boolean = chargingAtSimona - def getFinalDestinationPoiType: Option[PoiTypeDictionary.Value] = - finalDestinationPoiType + def getFinalDestinationPoiType: Option[PoiTypeDictionary.Value] = { + getFinalDestinationPoi match { + case Some(poi) => Some(poi.poiType) + case None => None + } + } def getFinalDestinationPoi: Option[PointOfInterest] = finalDestinationPoi @@ -132,15 +133,11 @@ case class ElectricVehicle( */ def copyWith( storedEnergy: ComparableQuantity[Energy], - destinationPoiType: PoiTypeDictionary.Value, - destinationCategoricalLocation: CategoricalLocationDictionary.Value, destinationPoi: PointOfInterest, parkingTimeStart: ZonedDateTime, departureTime: ZonedDateTime ): ElectricVehicle = { this.storedEnergy = storedEnergy - this.destinationPoiType = destinationPoiType - this.destinationCategoricalLocation = destinationCategoricalLocation this.destinationPoi = destinationPoi this.parkingTimeStart = parkingTimeStart this.departureTime = departureTime @@ -155,12 +152,6 @@ case class ElectricVehicle( chargingAtSimona = isCharging } - def setFinalDestinationPoiType( - destinationPoiType: Option[PoiTypeDictionary.Value] - ): Unit = { - finalDestinationPoiType = destinationPoiType - } - def setFinalDestinationPoi(destinationPoi: Option[PointOfInterest]): Unit = { finalDestinationPoi = destinationPoi } @@ -461,10 +452,6 @@ case object ElectricVehicle extends LazyLogging { homePoi = homePoi, workPoi = workPoi, storedEnergy = evType.capacity, - destinationPoiType = - PoiTypeDictionary.HOME, // is updated when trip is sampled - destinationCategoricalLocation = - CategoricalLocationDictionary.HOME, // is updated when trip is sampled destinationPoi = homePoi, // is updated when trip is sampled parkingTimeStart = simulationStart, // EV starts parking at first tick departureTime = @@ -474,7 +461,6 @@ case object ElectricVehicle extends LazyLogging { chargingAtHomePossible = isChargingAtHomePossible, chosenChargingStation = None, chargingAtSimona = false, - finalDestinationPoiType = None, finalDestinationPoi = None, remainingDistanceAfterChargingHub = None, chargingPricesMemory = mutable.Queue[Double]() diff --git a/src/main/scala/edu/ie3/mobsim/model/TripSimulation.scala b/src/main/scala/edu/ie3/mobsim/model/TripSimulation.scala index 60f01364..b0de39a6 100644 --- a/src/main/scala/edu/ie3/mobsim/model/TripSimulation.scala +++ b/src/main/scala/edu/ie3/mobsim/model/TripSimulation.scala @@ -415,7 +415,6 @@ object TripSimulation extends LazyLogging { Some(remainingDistance) ) => /* Reset saved values */ - ev.setFinalDestinationPoiType(None) ev.setFinalDestinationPoi(None) ev.setRemainingDistanceAfterChargingHub(None) @@ -791,13 +790,10 @@ object TripSimulation extends LazyLogging { Some(plannedDrivingDistance.subtract(newDrivingDistance)) ) ev.setFinalDestinationPoi(Some(plannedDestinationPoi)) - ev.setFinalDestinationPoiType(Some(plannedDestinationPoiType)) /* Create updated EV */ ev.copyWith( newStoredEnergyEndOfTrip, - newDestinationPoiType, - newDestinationCategoricalLocation, newDestinationPoi, newParkingTimeStart, newDepartureTime @@ -907,13 +903,10 @@ object TripSimulation extends LazyLogging { Some(plannedDrivingDistance.subtract(newDrivingDistance)) ) ev.setFinalDestinationPoi(Some(plannedDestinationPoi)) - ev.setFinalDestinationPoiType(Some(plannedDestinationPoiType)) /* Create updated EV */ ev.copyWith( newStoredEnergyEndOfTrip, - newDestinationPoiType, - newDestinationCategoricalLocation, newDestinationPoi, newParkingTimeStart, newDepartureTime @@ -1026,7 +1019,6 @@ object TripSimulation extends LazyLogging { ): ElectricVehicle = { /* Because there is no stop at a charging hub, no trip values need to be saved */ - ev.setFinalDestinationPoiType(None) ev.setFinalDestinationPoi(None) ev.setRemainingDistanceAfterChargingHub(None) @@ -1045,8 +1037,6 @@ object TripSimulation extends LazyLogging { /* Create updated EV */ ev.copyWith( plannedStoredEnergyEndOfTrip, - plannedDestinationPoiType, - plannedDestinationCategoricalLocation, plannedDestinationPoi, plannedParkingTimeStart, plannedDepartureTime @@ -1107,8 +1097,6 @@ object TripSimulation extends LazyLogging { /* Create updated EV */ ev.copyWith( ev.getStoredEnergy, - ev.getDestinationPoiType, - ev.getDestinationCategoricalLocation, ev.getDestinationPoi, parkingTimeStart, departureTime diff --git a/src/test/scala/edu/ie3/mobsim/io/geodata/PoiEnumsSpec.scala b/src/test/scala/edu/ie3/mobsim/io/geodata/PoiEnumsSpec.scala index 4bbff510..3ccf3a65 100644 --- a/src/test/scala/edu/ie3/mobsim/io/geodata/PoiEnumsSpec.scala +++ b/src/test/scala/edu/ie3/mobsim/io/geodata/PoiEnumsSpec.scala @@ -47,6 +47,37 @@ class PoiEnumsSpec exception.getMessage shouldBe "POI not known" } + // testing PoiTypeDictionary.apply(categoricalLocation: CategoricalLocationDictionary.Value) + "convert CategoricalLocations to PoiTypeDictionary" in { + + val cases = Table( + ("categoricalLocation", "expectedResult"), + (CategoricalLocationDictionary.HOME, PoiTypeDictionary.HOME), + (CategoricalLocationDictionary.WORK, PoiTypeDictionary.WORK), + (CategoricalLocationDictionary.SUPERMARKET, PoiTypeDictionary.SHOPPING), + (CategoricalLocationDictionary.SERVICES, PoiTypeDictionary.SHOPPING), + (CategoricalLocationDictionary.OTHER_SHOP, PoiTypeDictionary.SHOPPING), + (CategoricalLocationDictionary.RESTAURANT, PoiTypeDictionary.LEISURE), + (CategoricalLocationDictionary.CULTURE, PoiTypeDictionary.LEISURE), + (CategoricalLocationDictionary.SPORTS, PoiTypeDictionary.LEISURE), + (CategoricalLocationDictionary.RELIGIOUS, PoiTypeDictionary.LEISURE), + (CategoricalLocationDictionary.MEDICINAL, PoiTypeDictionary.OTHER), + (CategoricalLocationDictionary.BBPG, PoiTypeDictionary.OTHER), + ( + CategoricalLocationDictionary.CHARGING_HUB_TOWN, + PoiTypeDictionary.CHARGING_HUB_TOWN + ), + ( + CategoricalLocationDictionary.CHARGING_HUB_HIGHWAY, + PoiTypeDictionary.CHARGING_HUB_HIGHWAY + ) + ) + + forAll(cases) { (categoricalLocation, expectedResult) => + PoiTypeDictionary.apply(categoricalLocation) shouldBe expectedResult + } + } + // testing CategoricalLocationDictionary.apply(token: String) "parse CategoricalLocation correctly" in { diff --git a/src/test/scala/edu/ie3/mobsim/io/geodata/PoiTestData.scala b/src/test/scala/edu/ie3/mobsim/io/geodata/PoiTestData.scala index d0bce013..58ca5c85 100644 --- a/src/test/scala/edu/ie3/mobsim/io/geodata/PoiTestData.scala +++ b/src/test/scala/edu/ie3/mobsim/io/geodata/PoiTestData.scala @@ -9,13 +9,16 @@ package edu.ie3.mobsim.io.geodata import edu.ie3.datamodel.models.ElectricCurrentType import edu.ie3.datamodel.models.input.system.`type`.chargingpoint.ChargingPointType import edu.ie3.datamodel.models.input.system.`type`.evcslocation.EvcsLocationType -import edu.ie3.mobsim.io.geodata.PoiEnums.CategoricalLocationDictionary +import edu.ie3.mobsim.io.geodata.PoiEnums.{ + CategoricalLocationDictionary, + PoiTypeDictionary +} import edu.ie3.mobsim.model.ChargingStation import edu.ie3.util.quantities.PowerSystemUnits import org.locationtech.jts.geom.Coordinate import tech.units.indriya.ComparableQuantity import tech.units.indriya.quantity.Quantities -import tech.units.indriya.unit.Units.METRE +import tech.units.indriya.unit.Units.{METRE, PASCAL, PERCENT} import java.util.UUID import javax.measure.quantity.Length @@ -93,6 +96,7 @@ trait PoiTestData { protected val poiHome: PointOfInterest = PointOfInterest( UUID.fromString("91b8a161-7e44-4363-aaa3-2d2adbaaab6d"), "POI_home_1", + PoiTypeDictionary.HOME, CategoricalLocationDictionary.HOME, new Coordinate(7.3201668, 51.5067774), 25.557183061784293, @@ -102,6 +106,7 @@ trait PoiTestData { protected val workPoi: PointOfInterest = PointOfInterest( UUID.fromString("a26b6850-c966-4b42-8ccf-762015bf19ba"), "work_617762273", + PoiTypeDictionary.WORK, CategoricalLocationDictionary.WORK, new Coordinate(7.4065593, 51.5491556), 1549.4886151800551, @@ -111,6 +116,7 @@ trait PoiTestData { protected val bbpgPoi: PointOfInterest = PointOfInterest( UUID.fromString("6e4e3fac-171c-471e-8ec7-cef0d172c39d"), "bbpg_88921333", + PoiTypeDictionary.OTHER, CategoricalLocationDictionary.BBPG, new Coordinate(7.4622403, 51.5491056), 2783.9202769435374, @@ -120,6 +126,7 @@ trait PoiTestData { protected val culturePoi: PointOfInterest = PointOfInterest( UUID.fromString("da6ffecd-301c-42cf-8985-402580985eae"), "culture_247900605", + PoiTypeDictionary.LEISURE, CategoricalLocationDictionary.CULTURE, new Coordinate(7.3339823, 51.5184387), 6721.140094154159, @@ -129,6 +136,7 @@ trait PoiTestData { protected val medicinalPoi: PointOfInterest = PointOfInterest( UUID.fromString("75f1f39a-28e5-44e4-85dd-c61e145b765f"), "medicinal_253820890", + PoiTypeDictionary.OTHER, CategoricalLocationDictionary.MEDICINAL, new Coordinate(7.5112704, 51.5178795), 4695.499976294351, @@ -138,6 +146,7 @@ trait PoiTestData { protected val other_shopPoi: PointOfInterest = PointOfInterest( UUID.fromString("dda899fb-e085-479d-b3a9-cba594770a2b"), "othershop_251193227", + PoiTypeDictionary.SHOPPING, CategoricalLocationDictionary.OTHER_SHOP, new Coordinate(7.3682537, 51.4935477), 1710.1059114060527, @@ -147,6 +156,7 @@ trait PoiTestData { protected val religiousPoi: PointOfInterest = PointOfInterest( UUID.fromString("bdac04c2-c3d6-4a6c-97fb-812b57b7e008"), "religious_8654674", + PoiTypeDictionary.LEISURE, CategoricalLocationDictionary.RELIGIOUS, new Coordinate(7.5366142, 51.4726591), 16984.79771274887, @@ -156,6 +166,7 @@ trait PoiTestData { protected val restaurantPoi: PointOfInterest = PointOfInterest( UUID.fromString("02851eae-8014-4f87-895c-21d2b653b199"), "restaurant_268555314", + PoiTypeDictionary.LEISURE, CategoricalLocationDictionary.RESTAURANT, new Coordinate(7.4411392, 51.5097096), 303.9431026, @@ -165,6 +176,7 @@ trait PoiTestData { protected val servicePoi: PointOfInterest = PointOfInterest( UUID.fromString("680df7d7-1c73-43ce-8eab-50d4a5105504"), "services_295406188", + PoiTypeDictionary.SHOPPING, CategoricalLocationDictionary.SERVICES, new Coordinate(7.5862309, 51.5012326), 548.2907601097887, @@ -174,6 +186,7 @@ trait PoiTestData { protected val sportsPoi: PointOfInterest = PointOfInterest( UUID.fromString("7d04dc33-3a53-4857-b75e-7391fe468048"), "sports_292612919", + PoiTypeDictionary.LEISURE, CategoricalLocationDictionary.SPORTS, new Coordinate(7.416975, 51.5009765), 12103.459075742423, @@ -183,6 +196,7 @@ trait PoiTestData { protected val supermarketPoi: PointOfInterest = PointOfInterest( UUID.fromString("63dd665f-ca0b-4556-a4a9-bebf32ecdaf8"), "supermarket_261717630", + PoiTypeDictionary.SHOPPING, CategoricalLocationDictionary.SUPERMARKET, new Coordinate(7.370586, 51.5234725), 1498.211731553507, @@ -192,6 +206,7 @@ trait PoiTestData { protected val charging_hub_townPoi: PointOfInterest = PointOfInterest( UUID.fromString("4df0614d-0c01-4b31-af94-804e299f2686"), "charging_hub_town_261344967", + PoiTypeDictionary.CHARGING_HUB_TOWN, CategoricalLocationDictionary.CHARGING_HUB_TOWN, new Coordinate(7.41153872, 51.4834271), 129.211731553507, @@ -200,6 +215,7 @@ trait PoiTestData { protected val charging_hub_highwayPoi: PointOfInterest = PointOfInterest( UUID.fromString("3ddc93c7-77fc-4187-be68-833b3db39809"), "charging_hub_highway_261347306", + PoiTypeDictionary.CHARGING_HUB_HIGHWAY, CategoricalLocationDictionary.CHARGING_HUB_HIGHWAY, new Coordinate(7.41153842, 51.4834251), 178.211731553507, diff --git a/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala b/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala index 5c79f2bc..780707e6 100644 --- a/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala +++ b/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala @@ -23,7 +23,7 @@ class ElectricVehicleSpec extends UnitSpec with ElectricVehicleTestData { "building the car models" should { "assign the correct properties" in { - ElectricVehicle.buildEv( + val ev: ElectricVehicle = ElectricVehicle.buildEv( "test_car", givenModel, givenHomePoi, @@ -31,10 +31,12 @@ class ElectricVehicleSpec extends UnitSpec with ElectricVehicleTestData { givenSimulationStart, givenFirstDeparture, true - ) match { + ) + + ev match { case ElectricVehicle( simulationStart, - _, + uuid, id, model, batteryCapacity, @@ -44,20 +46,18 @@ class ElectricVehicleSpec extends UnitSpec with ElectricVehicleTestData { homePoi, workPoi, storedEnergy, - destinationPoiType, - destinationCategoricalLocation, destinationPoi, parkingTimeStart, departureTime, chargingAtHomePossible, chosenChargingStation, chargingAtSimona, - finalDestinationPoiType, finalDestinationPoi, remainingDistanceAfterChargingHub, chargingPricesMemory ) => simulationStart shouldBe givenSimulationStart + uuid shouldBe ev.getUuid id shouldBe "test_car" model shouldBe "cool_producer cool_model" batteryCapacity shouldBe givenModel.capacity @@ -68,14 +68,14 @@ class ElectricVehicleSpec extends UnitSpec with ElectricVehicleTestData { workPoi shouldBe givenWorkPoi storedEnergy shouldBe givenModel.capacity chargingAtSimona shouldBe false - destinationPoiType shouldBe PoiTypeDictionary.HOME - destinationCategoricalLocation shouldBe CategoricalLocationDictionary.HOME + ev.getDestinationPoiType shouldBe PoiTypeDictionary.HOME + ev.getDestinationCategoricalLocation shouldBe CategoricalLocationDictionary.HOME destinationPoi shouldBe givenHomePoi parkingTimeStart shouldBe simulationStart departureTime shouldBe givenFirstDeparture chosenChargingStation shouldBe None chargingAtHomePossible shouldBe true - finalDestinationPoiType shouldBe None + ev.getFinalDestinationPoiType shouldBe None finalDestinationPoi shouldBe None remainingDistanceAfterChargingHub shouldBe None chargingPricesMemory shouldBe mutable.Queue[Double]() diff --git a/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleTestData.scala b/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleTestData.scala index a275fd31..708740d1 100644 --- a/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleTestData.scala +++ b/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleTestData.scala @@ -9,7 +9,10 @@ package edu.ie3.mobsim.model import edu.ie3.datamodel.models.ElectricCurrentType import edu.ie3.datamodel.models.input.system.`type`.chargingpoint.ChargingPointType import edu.ie3.datamodel.models.input.system.`type`.evcslocation.EvcsLocationType -import edu.ie3.mobsim.io.geodata.PoiEnums.CategoricalLocationDictionary +import edu.ie3.mobsim.io.geodata.PoiEnums.{ + CategoricalLocationDictionary, + PoiTypeDictionary +} import edu.ie3.mobsim.io.geodata.PointOfInterest import edu.ie3.mobsim.io.model.EvTypeInput import edu.ie3.mobsim.io.probabilities.{ @@ -42,6 +45,7 @@ trait ElectricVehicleTestData { protected val givenHomePoi: PointOfInterest = PointOfInterest( UUID.fromString("d40b4feb-fd57-42b5-9247-43eaad2dff4b"), "test", + PoiTypeDictionary.HOME, CategoricalLocationDictionary.HOME, new Coordinate(7.4116482, 51.4843281), 1.0, @@ -53,6 +57,7 @@ trait ElectricVehicleTestData { protected val givenWorkPoi: PointOfInterest = PointOfInterest( UUID.fromString("c34a031e-8568-4b59-99e4-1ad113bef6ea"), "test", + PoiTypeDictionary.WORK, CategoricalLocationDictionary.WORK, new Coordinate(7.4116482, 51.4843281), 1.0, diff --git a/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala b/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala index 1ebf3450..856802ed 100644 --- a/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala +++ b/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala @@ -50,15 +50,12 @@ class TripSimulationSpec homePoi, workPoi, storedEnergy, - destinationPoiType, - destinationCategoricalLocation, destinationPoi, parkingTimeStart, departureTime, chargingAtHomePossible, chosenChargingStation, chargingAtSimona, - finalDestinationPoiType, finalDestinationPoi, remainingDistanceAfterChargingHub, chargingPricesMemory @@ -75,14 +72,16 @@ class TripSimulationSpec workPoi shouldBe givenWorkPoi storedEnergy shouldBe storedEnergyValue chargingAtSimona shouldBe false - destinationPoiType shouldBe PoiTypeDictionary.CHARGING_HUB_TOWN - destinationCategoricalLocation shouldBe CategoricalLocationDictionary.CHARGING_HUB_TOWN + ev.getDestinationPoiType shouldBe PoiTypeDictionary.CHARGING_HUB_TOWN + ev.getDestinationCategoricalLocation shouldBe CategoricalLocationDictionary.CHARGING_HUB_TOWN destinationPoi shouldBe plannedDestinationPoi parkingTimeStart shouldBe simulationStart.plusMinutes(10) departureTime shouldBe simulationStart.plusHours(7).plusMinutes(26) chargingAtHomePossible shouldBe true chosenChargingStation shouldBe None - finalDestinationPoiType shouldBe Some(PoiTypeDictionary.WORK) + ev.getFinalDestinationPoiType shouldBe Some( + plannedDestinationPoi.poiType + ) finalDestinationPoi shouldBe Some(plannedDestinationPoi) remainingDistanceAfterChargingHub shouldBe Some( Quantities.getQuantity(-7000, METRE) @@ -118,15 +117,12 @@ class TripSimulationSpec homePoi, workPoi, storedEnergy, - destinationPoiType, - destinationCategoricalLocation, destinationPoi, parkingTimeStart, departureTime, chargingAtHomePossible, chosenChargingStation, chargingAtSimona, - finalDestinationPoiType, finalDestinationPoi, remainingDistanceAfterChargingHub, chargingPricesMemory @@ -143,14 +139,16 @@ class TripSimulationSpec workPoi shouldBe givenWorkPoi storedEnergy shouldBe storedEnergyValue chargingAtSimona shouldBe false - destinationPoiType shouldBe PoiTypeDictionary.CHARGING_HUB_TOWN - destinationCategoricalLocation shouldBe CategoricalLocationDictionary.CHARGING_HUB_TOWN + ev.getDestinationPoiType shouldBe PoiTypeDictionary.CHARGING_HUB_TOWN + ev.getDestinationCategoricalLocation shouldBe CategoricalLocationDictionary.CHARGING_HUB_TOWN destinationPoi shouldBe plannedDestinationPoi parkingTimeStart shouldBe simulationStart.plusMinutes(1) departureTime shouldBe simulationStart.plusHours(7).plusMinutes(17) chargingAtHomePossible shouldBe true chosenChargingStation shouldBe None - finalDestinationPoiType shouldBe Some(PoiTypeDictionary.WORK) + ev.getFinalDestinationPoiType shouldBe Some( + plannedDestinationPoi.poiType + ) finalDestinationPoi shouldBe Some(plannedDestinationPoi) remainingDistanceAfterChargingHub shouldBe Some( Quantities.getQuantity(10000, METRE) From 24fba9b44ad354601b0cda5c3f3df1028126ba21 Mon Sep 17 00:00:00 2001 From: Marius Staudt Date: Fri, 24 Jun 2022 14:29:35 +0200 Subject: [PATCH 02/13] Update --- .../ie3/mobsim/model/ElectricVehicle.scala | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala b/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala index d69a1035..1a2ba48f 100644 --- a/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala +++ b/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala @@ -46,7 +46,7 @@ case class ElectricVehicle( private val consumption: ComparableQuantity[SpecificEnergy], // kWh per km private val homePoi: PointOfInterest, private val workPoi: PointOfInterest, - private var storedEnergy: ComparableQuantity[Energy], + private val storedEnergy: ComparableQuantity[Energy], private var destinationPoi: PointOfInterest, private var parkingTimeStart: ZonedDateTime, private var departureTime: ZonedDateTime, @@ -98,12 +98,8 @@ case class ElectricVehicle( def isChargingAtSimona: Boolean = chargingAtSimona - def getFinalDestinationPoiType: Option[PoiTypeDictionary.Value] = { - getFinalDestinationPoi match { - case Some(poi) => Some(poi.poiType) - case None => None - } - } + def getFinalDestinationPoiType: Option[PoiTypeDictionary.Value] = + getFinalDestinationPoi.map(_.poiType) def getFinalDestinationPoi: Option[PointOfInterest] = finalDestinationPoi @@ -121,10 +117,8 @@ case class ElectricVehicle( * @return * a copy of this ElectricVehicle with given new stored energy / soc */ - def copyWith(storedEnergy: ComparableQuantity[Energy]): ElectricVehicle = { - this.storedEnergy = storedEnergy - this - } + def copyWith(storedEnergy: ComparableQuantity[Energy]): ElectricVehicle = + copy(storedEnergy = storedEnergy) /** @param storedEnergy * the new stored energy @@ -136,13 +130,13 @@ case class ElectricVehicle( destinationPoi: PointOfInterest, parkingTimeStart: ZonedDateTime, departureTime: ZonedDateTime - ): ElectricVehicle = { - this.storedEnergy = storedEnergy - this.destinationPoi = destinationPoi - this.parkingTimeStart = parkingTimeStart - this.departureTime = departureTime - this - } + ): ElectricVehicle = + copy( + storedEnergy = storedEnergy, + destinationPoi = destinationPoi, + parkingTimeStart = parkingTimeStart, + departureTime = departureTime + ) def setChosenChargingStation(chargingStation: Option[UUID]): Unit = { chosenChargingStation = chargingStation From 686159518125a2345e673bbe92b89ef429dc1493 Mon Sep 17 00:00:00 2001 From: Marius Staudt Date: Thu, 30 Jun 2022 08:45:20 +0200 Subject: [PATCH 03/13] Changing all mutable objects to immutable objects in ``ChargingStation`` and ``ElectricVehicle``. --- .../ie3/mobsim/model/ChargingStation.scala | 4 ++-- .../ie3/mobsim/model/ElectricVehicle.scala | 24 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/scala/edu/ie3/mobsim/model/ChargingStation.scala b/src/main/scala/edu/ie3/mobsim/model/ChargingStation.scala index 7d50b652..f0678d89 100644 --- a/src/main/scala/edu/ie3/mobsim/model/ChargingStation.scala +++ b/src/main/scala/edu/ie3/mobsim/model/ChargingStation.scala @@ -24,7 +24,7 @@ case class ChargingStation( private val evcsType: ChargingPointType, private val evcsLocationType: EvcsLocationType, private val chargingPoints: Int, - private var homeChargingStationAssignedToPOI: Boolean + private val homeChargingStationAssignedToPOI: Boolean ) { def getUuid: UUID = uuid @@ -36,7 +36,7 @@ case class ChargingStation( homeChargingStationAssignedToPOI def setHomeChargingStationAssignedToPOI(assigned: Boolean): Unit = { - homeChargingStationAssignedToPOI = assigned + copy(homeChargingStationAssignedToPOI = assigned) } } diff --git a/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala b/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala index 1a2ba48f..9fbd2486 100644 --- a/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala +++ b/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala @@ -47,17 +47,17 @@ case class ElectricVehicle( private val homePoi: PointOfInterest, private val workPoi: PointOfInterest, private val storedEnergy: ComparableQuantity[Energy], - private var destinationPoi: PointOfInterest, - private var parkingTimeStart: ZonedDateTime, - private var departureTime: ZonedDateTime, + private val destinationPoi: PointOfInterest, + private val parkingTimeStart: ZonedDateTime, + private val departureTime: ZonedDateTime, private val chargingAtHomePossible: Boolean, - private var chosenChargingStation: Option[UUID], - private var chargingAtSimona: Boolean, - private var finalDestinationPoi: Option[PointOfInterest], - private var remainingDistanceAfterChargingHub: Option[ + private val chosenChargingStation: Option[UUID], + private val chargingAtSimona: Boolean, + private val finalDestinationPoi: Option[PointOfInterest], + private val remainingDistanceAfterChargingHub: Option[ ComparableQuantity[Length] ], - private var chargingPricesMemory: mutable.Queue[Double] + private val chargingPricesMemory: mutable.Queue[Double] ) extends EvModel with Ordered[ElectricVehicle] { @@ -139,21 +139,21 @@ case class ElectricVehicle( ) def setChosenChargingStation(chargingStation: Option[UUID]): Unit = { - chosenChargingStation = chargingStation + copy(chosenChargingStation = chargingStation) } def setChargingAtSimona(isCharging: Boolean): Unit = { - chargingAtSimona = isCharging + copy(chargingAtSimona = isCharging) } def setFinalDestinationPoi(destinationPoi: Option[PointOfInterest]): Unit = { - finalDestinationPoi = destinationPoi + copy(finalDestinationPoi = destinationPoi) } def setRemainingDistanceAfterChargingHub( remainingDistance: Option[ComparableQuantity[Length]] ): Unit = { - remainingDistanceAfterChargingHub = remainingDistance + copy(remainingDistanceAfterChargingHub = remainingDistance) } def updateChargingPricesMemory(newPrice: Double): mutable.Queue[Double] = { From b98ccd685fa6a905b22789e176d98cf12f605d46 Mon Sep 17 00:00:00 2001 From: Marius Staudt Date: Thu, 30 Jun 2022 09:17:10 +0200 Subject: [PATCH 04/13] Fixing failing tests. --- .../edu/ie3/mobsim/model/TripSimulation.scala | 4 --- .../ie3/mobsim/model/TripSimulationSpec.scala | 28 +++++++------------ 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/src/main/scala/edu/ie3/mobsim/model/TripSimulation.scala b/src/main/scala/edu/ie3/mobsim/model/TripSimulation.scala index 88726262..c020af35 100644 --- a/src/main/scala/edu/ie3/mobsim/model/TripSimulation.scala +++ b/src/main/scala/edu/ie3/mobsim/model/TripSimulation.scala @@ -762,8 +762,6 @@ object TripSimulation extends LazyLogging { val newParkingTimeStart: ZonedDateTime = currentTime.plusMinutes(newDrivingTime) - val newDestinationPoiType: PoiTypeDictionary.Value = chargingHubPoiType - val newDestinationCategoricalLocation: CategoricalLocationDictionary.Value = PoiEnums.CategoricalLocationDictionary(chargingHubPoiType) /* Sample destination POI */ @@ -871,8 +869,6 @@ object TripSimulation extends LazyLogging { 1 ) - val newDestinationPoiType: PoiTypeDictionary.Value = chargingHubPoiType - val newDestinationCategoricalLocation: CategoricalLocationDictionary.Value = PoiEnums.CategoricalLocationDictionary(chargingHubPoiType) /* Sample destination POI */ diff --git a/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala b/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala index 856802ed..ef94e902 100644 --- a/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala +++ b/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala @@ -72,20 +72,16 @@ class TripSimulationSpec workPoi shouldBe givenWorkPoi storedEnergy shouldBe storedEnergyValue chargingAtSimona shouldBe false - ev.getDestinationPoiType shouldBe PoiTypeDictionary.CHARGING_HUB_TOWN - ev.getDestinationCategoricalLocation shouldBe CategoricalLocationDictionary.CHARGING_HUB_TOWN + destinationPoi.poiType shouldBe PoiTypeDictionary.CHARGING_HUB_TOWN + destinationPoi.categoricalLocation shouldBe CategoricalLocationDictionary.CHARGING_HUB_TOWN destinationPoi shouldBe plannedDestinationPoi parkingTimeStart shouldBe simulationStart.plusMinutes(10) departureTime shouldBe simulationStart.plusHours(7).plusMinutes(26) chargingAtHomePossible shouldBe true chosenChargingStation shouldBe None - ev.getFinalDestinationPoiType shouldBe Some( - plannedDestinationPoi.poiType - ) - finalDestinationPoi shouldBe Some(plannedDestinationPoi) - remainingDistanceAfterChargingHub shouldBe Some( - Quantities.getQuantity(-7000, METRE) - ) + finalDestinationPoi.map(_.poiType) shouldBe None + finalDestinationPoi shouldBe None + remainingDistanceAfterChargingHub shouldBe None chargingPricesMemory shouldBe mutable.Queue[Double]() } } @@ -139,20 +135,16 @@ class TripSimulationSpec workPoi shouldBe givenWorkPoi storedEnergy shouldBe storedEnergyValue chargingAtSimona shouldBe false - ev.getDestinationPoiType shouldBe PoiTypeDictionary.CHARGING_HUB_TOWN - ev.getDestinationCategoricalLocation shouldBe CategoricalLocationDictionary.CHARGING_HUB_TOWN + destinationPoi.poiType shouldBe PoiTypeDictionary.CHARGING_HUB_TOWN + destinationPoi.categoricalLocation shouldBe CategoricalLocationDictionary.CHARGING_HUB_TOWN destinationPoi shouldBe plannedDestinationPoi parkingTimeStart shouldBe simulationStart.plusMinutes(1) departureTime shouldBe simulationStart.plusHours(7).plusMinutes(17) chargingAtHomePossible shouldBe true chosenChargingStation shouldBe None - ev.getFinalDestinationPoiType shouldBe Some( - plannedDestinationPoi.poiType - ) - finalDestinationPoi shouldBe Some(plannedDestinationPoi) - remainingDistanceAfterChargingHub shouldBe Some( - Quantities.getQuantity(10000, METRE) - ) + finalDestinationPoi.map(_.poiType) shouldBe None + finalDestinationPoi shouldBe None + remainingDistanceAfterChargingHub shouldBe None chargingPricesMemory shouldBe mutable.Queue[Double]() } } From 42e066b56e6e955471ce03f89932e865df53b152 Mon Sep 17 00:00:00 2001 From: Marius Staudt Date: Thu, 30 Jun 2022 09:32:31 +0200 Subject: [PATCH 05/13] Removing unnecessary case in ``PoiEnums``. --- src/main/scala/edu/ie3/mobsim/io/geodata/PoiEnums.scala | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/scala/edu/ie3/mobsim/io/geodata/PoiEnums.scala b/src/main/scala/edu/ie3/mobsim/io/geodata/PoiEnums.scala index f443b06a..73e9b8ce 100644 --- a/src/main/scala/edu/ie3/mobsim/io/geodata/PoiEnums.scala +++ b/src/main/scala/edu/ie3/mobsim/io/geodata/PoiEnums.scala @@ -46,10 +46,6 @@ object PoiEnums { CHARGING_HUB_TOWN case CategoricalLocationDictionary.CHARGING_HUB_HIGHWAY => CHARGING_HUB_HIGHWAY - case malformed => - throw new RuntimeException( - s"CategoricalLocation '$malformed' could not be applied to PoiTypeDictionary" - ) } } } From c51f3cc377c92d9faf8edce12f1d2bdb070e3544 Mon Sep 17 00:00:00 2001 From: Marius Staudt Date: Thu, 30 Jun 2022 10:11:24 +0200 Subject: [PATCH 06/13] Adding some tests in ``ElectricVehicleSpec`` to cover recent changes with tests. --- .../ie3/mobsim/model/ElectricVehicle.scala | 8 +-- .../mobsim/model/ElectricVehicleSpec.scala | 52 +++++++++++++++---- .../model/ElectricVehicleTestData.scala | 19 +++++++ .../ie3/mobsim/model/TripSimulationSpec.scala | 7 ++- 4 files changed, 68 insertions(+), 18 deletions(-) diff --git a/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala b/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala index 9fbd2486..944c9190 100644 --- a/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala +++ b/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala @@ -138,21 +138,21 @@ case class ElectricVehicle( departureTime = departureTime ) - def setChosenChargingStation(chargingStation: Option[UUID]): Unit = { + def setChosenChargingStation(chargingStation: Option[UUID]): ElectricVehicle = { copy(chosenChargingStation = chargingStation) } - def setChargingAtSimona(isCharging: Boolean): Unit = { + def setChargingAtSimona(isCharging: Boolean): ElectricVehicle = { copy(chargingAtSimona = isCharging) } - def setFinalDestinationPoi(destinationPoi: Option[PointOfInterest]): Unit = { + def setFinalDestinationPoi(destinationPoi: Option[PointOfInterest]): ElectricVehicle = { copy(finalDestinationPoi = destinationPoi) } def setRemainingDistanceAfterChargingHub( remainingDistance: Option[ComparableQuantity[Length]] - ): Unit = { + ): ElectricVehicle = { copy(remainingDistanceAfterChargingHub = remainingDistance) } diff --git a/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala b/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala index 780707e6..19806b80 100644 --- a/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala +++ b/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala @@ -6,19 +6,18 @@ package edu.ie3.mobsim.model -import edu.ie3.mobsim.io.geodata.PoiEnums.{ - CategoricalLocationDictionary, - PoiTypeDictionary -} +import edu.ie3.mobsim.io.geodata.PoiEnums.{CategoricalLocationDictionary, PoiTypeDictionary} import edu.ie3.mobsim.io.probabilities.ProbabilityDensityFunction import edu.ie3.test.common.UnitSpec import edu.ie3.util.quantities.PowerSystemUnits +import tech.units.indriya.ComparableQuantity import tech.units.indriya.quantity.Quantities import tech.units.indriya.unit.Units +import javax.measure.quantity.Energy import scala.collection.mutable -class ElectricVehicleSpec extends UnitSpec with ElectricVehicleTestData { +class ElectricVehicleSpec extends UnitSpec with TripSimulationData { "Building and assigning evs" when { "building the car models" should { @@ -30,7 +29,7 @@ class ElectricVehicleSpec extends UnitSpec with ElectricVehicleTestData { givenWorkPoi, givenSimulationStart, givenFirstDeparture, - true + isChargingAtHomePossible = true ) ev match { @@ -64,8 +63,8 @@ class ElectricVehicleSpec extends UnitSpec with ElectricVehicleTestData { acChargingPower shouldBe givenModel.acPower dcChargingPower shouldBe givenModel.dcPower consumption shouldBe givenModel.consumption - homePoi shouldBe givenHomePoi - workPoi shouldBe givenWorkPoi + homePoi shouldBe ev.getHomePOI + workPoi shouldBe ev.getWorkPOI storedEnergy shouldBe givenModel.capacity chargingAtSimona shouldBe false ev.getDestinationPoiType shouldBe PoiTypeDictionary.HOME @@ -92,7 +91,7 @@ class ElectricVehicleSpec extends UnitSpec with ElectricVehicleTestData { givenWorkPoi, givenSimulationStart, givenFirstDeparture, - true + isChargingAtHomePossible = true ) match { case model: ElectricVehicle => model.getSRatedDC shouldBe givenModel.acPower @@ -107,7 +106,7 @@ class ElectricVehicleSpec extends UnitSpec with ElectricVehicleTestData { givenWorkPoi, givenSimulationStart, givenSimulationStart, - true + isChargingAtHomePossible = true ) match { case model: ElectricVehicle => model.getDepartureTime shouldBe givenSimulationStart.plusMinutes(1L) @@ -277,5 +276,38 @@ class ElectricVehicleSpec extends UnitSpec with ElectricVehicleTestData { } } } + + "An electricVehicle" should { + "check if home charging is possible" in { + evWithHomeCharging.isChargingAtHomePossible shouldBe true + evWithoutHomeCharging.isChargingAtHomePossible shouldBe false + } + + "copy object with new stored energy" in { + val evFull: ElectricVehicle = evWithHomeCharging.copyWith(evWithHomeCharging.getStoredEnergy) + evFull.getStoredEnergy shouldBe givenModel.capacity + + + val zero: ComparableQuantity[Energy] = Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR) + val evEmpty: ElectricVehicle = evWithHomeCharging.copyWith(zero) + evEmpty.getStoredEnergy shouldBe zero + } + + "copy object with new charging station" in { + val evChargingAtSimona: ElectricVehicle = evWithHomeCharging.setChargingAtSimona(true) + evChargingAtSimona.isChargingAtSimona shouldBe true + + val evNotChargingAtSimona: ElectricVehicle = evWithHomeCharging.setChargingAtSimona(false) + evNotChargingAtSimona.isChargingAtSimona shouldBe false + } + + "copy object with chosen charging station" in { + val evSetChargingStation: ElectricVehicle = evWithHomeCharging.setChosenChargingStation(Some(cs6.getUuid)) + evSetChargingStation.getChosenChargingStation shouldBe Some(cs6.getUuid) + + val evNoChargingStation: ElectricVehicle = evWithHomeCharging.setChosenChargingStation(None) + evNoChargingStation.getChosenChargingStation shouldBe None + } + } } } diff --git a/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleTestData.scala b/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleTestData.scala index 708740d1..52af7b59 100644 --- a/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleTestData.scala +++ b/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleTestData.scala @@ -92,4 +92,23 @@ trait ElectricVehicleTestData { 1, homeChargingStationAssignedToPOI = true ) + + val evWithHomeCharging: ElectricVehicle = ElectricVehicle.buildEv( + "test_car", + givenModel, + givenHomePoi, + givenWorkPoi, + givenSimulationStart, + givenFirstDeparture, + isChargingAtHomePossible = true + ) + val evWithoutHomeCharging: ElectricVehicle = ElectricVehicle.buildEv( + "test_car", + givenModel, + givenHomePoi, + givenWorkPoi, + givenSimulationStart, + givenFirstDeparture, + isChargingAtHomePossible = false + ) } diff --git a/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala b/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala index ef94e902..b881556d 100644 --- a/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala +++ b/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala @@ -18,7 +18,6 @@ import scala.collection.mutable class TripSimulationSpec extends UnitSpec - with ElectricVehicleTestData with TripSimulationData { "The TripSimulation" should { @@ -62,8 +61,8 @@ class TripSimulationSpec ) => simulationStart shouldBe givenSimulationStart uuid shouldBe ev.getUuid - id shouldBe "test_car" - model shouldBe "cool_producer cool_model" + id shouldBe ev.getId + model shouldBe ev.getModel batteryCapacity shouldBe givenModel.capacity acChargingPower shouldBe givenModel.acPower dcChargingPower shouldBe givenModel.dcPower @@ -81,7 +80,7 @@ class TripSimulationSpec chosenChargingStation shouldBe None finalDestinationPoi.map(_.poiType) shouldBe None finalDestinationPoi shouldBe None - remainingDistanceAfterChargingHub shouldBe None + remainingDistanceAfterChargingHub shouldBe ev.getRemainingDistanceAfterChargingHub chargingPricesMemory shouldBe mutable.Queue[Double]() } } From d0e1183173a612b8a7a3b63990166bdbc06fcc68 Mon Sep 17 00:00:00 2001 From: Marius Staudt Date: Thu, 30 Jun 2022 10:14:13 +0200 Subject: [PATCH 07/13] Fixing failing jenkins. --- .../ie3/mobsim/model/ElectricVehicle.scala | 8 +++++-- .../mobsim/model/ElectricVehicleSpec.scala | 24 ++++++++++++------- .../ie3/mobsim/model/TripSimulationSpec.scala | 4 +--- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala b/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala index 944c9190..e60ccb7c 100644 --- a/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala +++ b/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala @@ -138,7 +138,9 @@ case class ElectricVehicle( departureTime = departureTime ) - def setChosenChargingStation(chargingStation: Option[UUID]): ElectricVehicle = { + def setChosenChargingStation( + chargingStation: Option[UUID] + ): ElectricVehicle = { copy(chosenChargingStation = chargingStation) } @@ -146,7 +148,9 @@ case class ElectricVehicle( copy(chargingAtSimona = isCharging) } - def setFinalDestinationPoi(destinationPoi: Option[PointOfInterest]): ElectricVehicle = { + def setFinalDestinationPoi( + destinationPoi: Option[PointOfInterest] + ): ElectricVehicle = { copy(finalDestinationPoi = destinationPoi) } diff --git a/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala b/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala index 19806b80..b5400046 100644 --- a/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala +++ b/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala @@ -6,7 +6,10 @@ package edu.ie3.mobsim.model -import edu.ie3.mobsim.io.geodata.PoiEnums.{CategoricalLocationDictionary, PoiTypeDictionary} +import edu.ie3.mobsim.io.geodata.PoiEnums.{ + CategoricalLocationDictionary, + PoiTypeDictionary +} import edu.ie3.mobsim.io.probabilities.ProbabilityDensityFunction import edu.ie3.test.common.UnitSpec import edu.ie3.util.quantities.PowerSystemUnits @@ -284,28 +287,33 @@ class ElectricVehicleSpec extends UnitSpec with TripSimulationData { } "copy object with new stored energy" in { - val evFull: ElectricVehicle = evWithHomeCharging.copyWith(evWithHomeCharging.getStoredEnergy) + val evFull: ElectricVehicle = + evWithHomeCharging.copyWith(evWithHomeCharging.getStoredEnergy) evFull.getStoredEnergy shouldBe givenModel.capacity - - val zero: ComparableQuantity[Energy] = Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR) + val zero: ComparableQuantity[Energy] = + Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR) val evEmpty: ElectricVehicle = evWithHomeCharging.copyWith(zero) evEmpty.getStoredEnergy shouldBe zero } "copy object with new charging station" in { - val evChargingAtSimona: ElectricVehicle = evWithHomeCharging.setChargingAtSimona(true) + val evChargingAtSimona: ElectricVehicle = + evWithHomeCharging.setChargingAtSimona(true) evChargingAtSimona.isChargingAtSimona shouldBe true - val evNotChargingAtSimona: ElectricVehicle = evWithHomeCharging.setChargingAtSimona(false) + val evNotChargingAtSimona: ElectricVehicle = + evWithHomeCharging.setChargingAtSimona(false) evNotChargingAtSimona.isChargingAtSimona shouldBe false } "copy object with chosen charging station" in { - val evSetChargingStation: ElectricVehicle = evWithHomeCharging.setChosenChargingStation(Some(cs6.getUuid)) + val evSetChargingStation: ElectricVehicle = + evWithHomeCharging.setChosenChargingStation(Some(cs6.getUuid)) evSetChargingStation.getChosenChargingStation shouldBe Some(cs6.getUuid) - val evNoChargingStation: ElectricVehicle = evWithHomeCharging.setChosenChargingStation(None) + val evNoChargingStation: ElectricVehicle = + evWithHomeCharging.setChosenChargingStation(None) evNoChargingStation.getChosenChargingStation shouldBe None } } diff --git a/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala b/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala index b881556d..11b0ca63 100644 --- a/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala +++ b/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala @@ -16,9 +16,7 @@ import tech.units.indriya.unit.Units.METRE import scala.collection.mutable -class TripSimulationSpec - extends UnitSpec - with TripSimulationData { +class TripSimulationSpec extends UnitSpec with TripSimulationData { "The TripSimulation" should { // testing makeTripToChargingHub From 21bef07ba1da7fd3f6716a7008371ee309901da1 Mon Sep 17 00:00:00 2001 From: Marius Staudt Date: Thu, 30 Jun 2022 10:22:19 +0200 Subject: [PATCH 08/13] Fixing code smell in ``ElectricVehicle.setChargingAtSimona``. --- src/main/scala/edu/ie3/mobsim/MobilitySimulator.scala | 4 ++-- src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala | 8 ++++++-- .../scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala | 6 +++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/scala/edu/ie3/mobsim/MobilitySimulator.scala b/src/main/scala/edu/ie3/mobsim/MobilitySimulator.scala index 3ec9cec6..257af0bb 100644 --- a/src/main/scala/edu/ie3/mobsim/MobilitySimulator.scala +++ b/src/main/scala/edu/ie3/mobsim/MobilitySimulator.scala @@ -305,7 +305,7 @@ final class MobilitySimulator( cs -> movement } match { case result @ Some(_) => - ev.setChargingAtSimona(false) + ev.removeChargingAtSimona() ev.setChosenChargingStation(None) result case result @ None => @@ -424,7 +424,7 @@ final class MobilitySimulator( val availableChargingPointsAtStation: Integer = availableChargingPoints.getOrElse(cs, 0) if (availableChargingPointsAtStation > 0) { - ev.setChargingAtSimona(true) + ev.setChargingAtSimona() ev.setChosenChargingStation(Some(cs)) logger.debug( diff --git a/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala b/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala index e60ccb7c..b35b086c 100644 --- a/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala +++ b/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala @@ -144,8 +144,12 @@ case class ElectricVehicle( copy(chosenChargingStation = chargingStation) } - def setChargingAtSimona(isCharging: Boolean): ElectricVehicle = { - copy(chargingAtSimona = isCharging) + def setChargingAtSimona(): ElectricVehicle = { + copy(chargingAtSimona = true) + } + + def removeChargingAtSimona(): ElectricVehicle = { + copy(chargingAtSimona = false) } def setFinalDestinationPoi( diff --git a/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala b/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala index b5400046..e3911888 100644 --- a/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala +++ b/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala @@ -297,13 +297,13 @@ class ElectricVehicleSpec extends UnitSpec with TripSimulationData { evEmpty.getStoredEnergy shouldBe zero } - "copy object with new charging station" in { + "copy object with updated charging at simona information" in { val evChargingAtSimona: ElectricVehicle = - evWithHomeCharging.setChargingAtSimona(true) + evWithHomeCharging.setChargingAtSimona() evChargingAtSimona.isChargingAtSimona shouldBe true val evNotChargingAtSimona: ElectricVehicle = - evWithHomeCharging.setChargingAtSimona(false) + evWithHomeCharging.removeChargingAtSimona() evNotChargingAtSimona.isChargingAtSimona shouldBe false } From 445566e68e12f34044e6157816371f09ca6a99c2 Mon Sep 17 00:00:00 2001 From: Marius Staudt Date: Tue, 5 Jul 2022 17:40:47 +0200 Subject: [PATCH 09/13] - Fixing unhandled return values of setter methods. - Making ``ElectricVehicle`` a ``final case class``. - Replacing ``PointOfInterest.poiType`` with methode ``PointOfInterest#getPoiType``. --- .../edu/ie3/mobsim/MobilitySimulator.scala | 60 ++++++---- .../mobsim/io/geodata/PointOfInterest.scala | 6 +- .../ie3/mobsim/model/ChargingBehavior.scala | 38 +++--- .../ie3/mobsim/model/ElectricVehicle.scala | 106 ++++++----------- .../edu/ie3/mobsim/model/TripSimulation.scala | 111 ++++++++---------- .../scala/edu/ie3/mobsim/utils/IoUtils.scala | 22 ++-- .../ie3/mobsim/io/geodata/PoiTestData.scala | 18 +-- .../mobsim/model/ElectricVehicleSpec.scala | 26 ++-- .../model/ElectricVehicleTestData.scala | 7 +- .../ie3/mobsim/model/TripSimulationData.scala | 2 +- .../ie3/mobsim/model/TripSimulationSpec.scala | 40 ++++--- 11 files changed, 195 insertions(+), 241 deletions(-) diff --git a/src/main/scala/edu/ie3/mobsim/MobilitySimulator.scala b/src/main/scala/edu/ie3/mobsim/MobilitySimulator.scala index 257af0bb..21b462b0 100644 --- a/src/main/scala/edu/ie3/mobsim/MobilitySimulator.scala +++ b/src/main/scala/edu/ie3/mobsim/MobilitySimulator.scala @@ -176,8 +176,10 @@ final class MobilitySimulator( updatedChargingPoints, maxDistance ) - arrivals.foreach { case Movement(cs, ev) => - builder.addArrival(cs, ev) + arrivals.foreach { case Movement(cs, updatedEv) => + builder.addArrival(cs, updatedEv) + + updateElectricVehicle(Movement(cs, updatedEv)) } val finalTakenChargingPoints = updateFreeLots(updatedChargingPoints, takenChargingPoints) @@ -212,16 +214,15 @@ final class MobilitySimulator( evs: SortedSet[ElectricVehicle], currentTime: ZonedDateTime ): (SortedSet[ElectricVehicle], SortedSet[ElectricVehicle]) = { - val isParking = (ev: ElectricVehicle) => - ev.getParkingTimeStart == currentTime + val isParking = (ev: ElectricVehicle) => ev.parkingTimeStart == currentTime /* Relevant are only cars, that depart AND that are charging at a suitable charging station in SIMONA */ val isDeparting = (ev: ElectricVehicle) => - ev.getDepartureTime == currentTime && ev.isChargingAtSimona && ev.getChosenChargingStation.isDefined + ev.departureTime == currentTime && ev.chargingAtSimona && ev.chosenChargingStation.isDefined evs.par .filter { ev => isDeparting(ev) || isParking(ev) } - .partition(_.getParkingTimeStart == currentTime) match { + .partition(_.parkingTimeStart == currentTime) match { case (arrivals, departures) => (TreeSet.from(arrivals), TreeSet.from(departures)) } @@ -245,8 +246,10 @@ final class MobilitySimulator( ): Map[UUID, Integer] = { val (additionallyFreeChargingPoints, departures) = handleDepartingEvs(evs) - departures.foreach { case Movement(cs, ev) => - builder.addDeparture(cs, ev.getUuid) + departures.foreach { case Movement(cs, updatedEv) => + builder.addDeparture(cs, updatedEv.getUuid) + + updateElectricVehicle(Movement(cs, updatedEv)) } updateFreeLots(availableChargingPoints, additionallyFreeChargingPoints) } @@ -296,7 +299,7 @@ final class MobilitySimulator( ): Future[Option[(UUID, Movement)]] = Future { /* Determine the charging station, the car currently is connected to */ - ev.getChosenChargingStation.map { cs => + ev.chosenChargingStation.map { cs => /* Register departure */ val movement = MobilitySimulator.Movement(cs, ev) logger.debug( @@ -305,9 +308,12 @@ final class MobilitySimulator( cs -> movement } match { case result @ Some(_) => - ev.removeChargingAtSimona() - ev.setChosenChargingStation(None) - result + var updatedEv: ElectricVehicle = ev.removeChargingAtSimona() + updatedEv = updatedEv.setChosenChargingStation(None) + + val cs: UUID = result.value._1 + + Some(cs, MobilitySimulator.Movement(cs, updatedEv)) case result @ None => logger.warn( s"Ev '$ev' is meant to charge in SIMONA, but no charging station is set." @@ -424,17 +430,17 @@ final class MobilitySimulator( val availableChargingPointsAtStation: Integer = availableChargingPoints.getOrElse(cs, 0) if (availableChargingPointsAtStation > 0) { - ev.setChargingAtSimona() - ev.setChosenChargingStation(Some(cs)) + var updatedEv: ElectricVehicle = ev.setChargingAtSimona() + updatedEv = updatedEv.setChosenChargingStation(Some(cs)) logger.debug( s"${ev.getId} starts charging at $cs." ) - Some((cs, Movement(cs, ev))) + Some((cs, Movement(cs, updatedEv))) } else { logger.debug( - s"${ev.getId} could not be charged at destination ${ev.getDestinationPoi} " + + s"${ev.getId} could not be charged at destination ${ev.destinationPoi} " + s"(${ev.getDestinationPoiType}) because all charging points " + s"at $cs were taken." ) @@ -488,7 +494,7 @@ final class MobilitySimulator( ): Unit = { val allDepartedEvs: Set[UUID] = electricVehicles - .filter(_.getDepartureTime == currentTime) + .filter(_.departureTime == currentTime) .map(filteredEv => filteredEv.getUuid) electricVehicles = electricVehicles.map(ev => { @@ -544,18 +550,18 @@ final class MobilitySimulator( val nextEvent: ZonedDateTime = evs.foldLeft(currentTime.plusYears(1))( (earliestEvent: ZonedDateTime, ev: ElectricVehicle) => { - val earlierEvent = if (ev.getParkingTimeStart.isAfter(currentTime)) { + val earlierEvent = if (ev.parkingTimeStart.isAfter(currentTime)) { Seq( earliestEvent, - ev.getParkingTimeStart, - ev.getDepartureTime + ev.parkingTimeStart, + ev.departureTime ).minOption.getOrElse( throw new IllegalArgumentException( "Unable to determine the earlier time" ) ) } else { - Seq(earliestEvent, ev.getDepartureTime).minOption.getOrElse( + Seq(earliestEvent, ev.departureTime).minOption.getOrElse( throw new IllegalArgumentException( "Unable to determine the earlier time" ) @@ -574,6 +580,16 @@ final class MobilitySimulator( timeUntilNextEvent } + + private def updateElectricVehicle(movement: Movement): Unit = { + val updatedEv: ElectricVehicle = movement.ev + + electricVehicles.zipWithIndex.par.foreach { sortedEv => + if (sortedEv._1.uuid.equals(updatedEv.uuid)) { + electricVehicles.drop(sortedEv._2) + updatedEv + } + } + } } object MobilitySimulator @@ -755,7 +771,7 @@ object MobilitySimulator logger.info( s"Created ${evs.size} EVs in ${"%.2f" .format((System.currentTimeMillis() - start) / 1000d)} s, of which ${evs - .count(_.isChargingAtHomePossible)} can charge at home." + .count(_.chargingAtHomePossible)} can charge at home." ) /* Calculate and print total number of charging points at charging stations */ diff --git a/src/main/scala/edu/ie3/mobsim/io/geodata/PointOfInterest.scala b/src/main/scala/edu/ie3/mobsim/io/geodata/PointOfInterest.scala index 11a9c37c..d7bf4122 100644 --- a/src/main/scala/edu/ie3/mobsim/io/geodata/PointOfInterest.scala +++ b/src/main/scala/edu/ie3/mobsim/io/geodata/PointOfInterest.scala @@ -46,7 +46,6 @@ import scala.jdk.CollectionConverters._ final case class PointOfInterest( uuid: UUID, id: String, - poiType: PoiTypeDictionary.Value, categoricalLocation: CategoricalLocationDictionary.Value, geoPosition: Coordinate, size: Double, @@ -57,6 +56,9 @@ final case class PointOfInterest( else if (this.id > that.id) 1 else -1 } + + def getPoiType: PoiTypeDictionary.Value = + PoiTypeDictionary.apply(categoricalLocation) } case object PointOfInterest { @@ -210,7 +212,6 @@ case object PointOfInterest { val poi = PointOfInterest( uuid, identifier, - PoiTypeDictionary.apply(catLoc), catLoc, coordinate, sze, @@ -352,7 +353,6 @@ case object PointOfInterest { new PointOfInterest( uuid, identifier, - PoiTypeDictionary.apply(catLoc), catLoc, coordinate, sze, diff --git a/src/main/scala/edu/ie3/mobsim/model/ChargingBehavior.scala b/src/main/scala/edu/ie3/mobsim/model/ChargingBehavior.scala index 0159fb94..95598eef 100644 --- a/src/main/scala/edu/ie3/mobsim/model/ChargingBehavior.scala +++ b/src/main/scala/edu/ie3/mobsim/model/ChargingBehavior.scala @@ -17,7 +17,8 @@ import tech.units.indriya.quantity.Quantities.getQuantity import java.time.temporal.ChronoUnit import java.util.UUID -import javax.measure.quantity.{Energy, Length, Power} +import javax.measure.quantity.Length +import scala.collection.mutable import scala.collection.parallel.CollectionConverters.ImmutableIterableIsParallelizable import scala.math.Ordering.Implicits.infixOrderingOps import scala.util.Random @@ -65,7 +66,7 @@ object ChargingBehavior extends LazyLogging { maxDistance: ComparableQuantity[Length] ): Option[UUID] = { /* If there are charging stations nearby */ - if (ev.getDestinationPoi.nearestChargingStations.nonEmpty) { + if (ev.destinationPoi.nearestChargingStations.nonEmpty) { /* Always charge if the EV makes charging stop at charging hub */ if ( ev.getDestinationPoiType == PoiEnums.PoiTypeDictionary.CHARGING_HUB_TOWN @@ -74,15 +75,18 @@ object ChargingBehavior extends LazyLogging { logger.debug( s"${ev.getId} arrives at charging hub and wants to start charging." ) - ev.getDestinationPoi.nearestChargingStations.keys.headOption + ev.destinationPoi.nearestChargingStations.keys.headOption .map(_.getUuid) } else { /* Update charging prices memory of EV to have a reference for the prices of specific charging stations */ - ev.getDestinationPoi.nearestChargingStations.keys.foreach { cs => + val priceQueue: mutable.Queue[Double] = mutable.Queue.empty + + ev.destinationPoi.nearestChargingStations.keys.foreach { cs => currentPricesAtChargingStations .get(cs.getUuid) - .map(ev.updateChargingPricesMemory(_)) + .map(priceQueue += _) } + ev.updateChargingPricesMemory(priceQueue) /* If EV wants to charge, rank available charging stations and choose the best */ val evWantsToCharge = doesEvWantToCharge(ev, seed) @@ -120,18 +124,18 @@ object ChargingBehavior extends LazyLogging { * Decision as boolean, whether the EV wants to charge */ def doesEvWantToCharge(ev: ElectricVehicle, seed: Random): Boolean = { - val staysLongEnough = ev.getParkingTimeStart - .until(ev.getDepartureTime, ChronoUnit.MINUTES) >= 15 + val staysLongEnough = ev.parkingTimeStart + .until(ev.departureTime, ChronoUnit.MINUTES) >= 15 if (staysLongEnough) { val soc = ev.getStoredEnergy.divide(ev.getEStorage).getValue.doubleValue() /* Probability that the EV wants to charge based on its SoC. Distinguish between home and work and elsewhere for threshold for charging */ val (lowerThreshold, upperThreshold) = { - if (ev.isChargingAtHomePossible) { + if (ev.chargingAtHomePossible) { if ( - ev.getDestinationCategoricalLocation == CategoricalLocationDictionary.HOME - || ev.getDestinationCategoricalLocation == CategoricalLocationDictionary.WORK + ev.destinationPoi.categoricalLocation == CategoricalLocationDictionary.HOME + || ev.destinationPoi.categoricalLocation == CategoricalLocationDictionary.WORK ) { (0.4, 0.85) } else { @@ -139,8 +143,8 @@ object ChargingBehavior extends LazyLogging { } } else { if ( - ev.getDestinationCategoricalLocation == CategoricalLocationDictionary.HOME - || ev.getDestinationCategoricalLocation == CategoricalLocationDictionary.WORK + ev.destinationPoi.categoricalLocation == CategoricalLocationDictionary.HOME + || ev.destinationPoi.categoricalLocation == CategoricalLocationDictionary.WORK ) { (0.4, 0.85) } else { @@ -183,7 +187,7 @@ object ChargingBehavior extends LazyLogging { currentlyAvailableChargingPoints: Map[UUID, Integer], maxDistance: ComparableQuantity[Length] ): Map[UUID, Double] = - ev.getDestinationPoi.nearestChargingStations.par + ev.destinationPoi.nearestChargingStations.par .map { case (cs, distance) => /* Check if free charging spots are even available */ val freeSpots: Integer = @@ -233,8 +237,8 @@ object ChargingBehavior extends LazyLogging { ev.getSRatedDC.min(cs.getEvcsType.getsRated()).to(KILOWATT) } val parkingTime = - ev.getParkingTimeStart - .until(ev.getDepartureTime, ChronoUnit.MINUTES) + ev.parkingTimeStart + .until(ev.departureTime, ChronoUnit.MINUTES) val possibleChargeableEnergy = getQuantity( availableChargingPowerForEV @@ -257,8 +261,8 @@ object ChargingBehavior extends LazyLogging { currentPrices: Map[UUID, java.lang.Double] ): Double = currentPrices.get(cs.getUuid) match { case Some(price) => - ev.getChargingPricesMemory.maxOption.zip( - ev.getChargingPricesMemory.minOption + ev.chargingPricesMemory.maxOption.zip( + ev.chargingPricesMemory.minOption ) match { case Some((maxPrice, minPrice)) => if (math.abs(maxPrice - minPrice) < 0.001) diff --git a/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala b/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala index b35b086c..e4e7b9a0 100644 --- a/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala +++ b/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala @@ -9,16 +9,10 @@ package edu.ie3.mobsim.model import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.input.system.`type`.evcslocation.EvcsLocationType import edu.ie3.mobsim.exceptions.InitializationException -import edu.ie3.mobsim.io.geodata.PoiEnums.{ - CategoricalLocationDictionary, - PoiTypeDictionary -} +import edu.ie3.mobsim.io.geodata.PoiEnums.PoiTypeDictionary import edu.ie3.mobsim.io.geodata.PointOfInterest import edu.ie3.mobsim.io.model.EvTypeInput -import edu.ie3.mobsim.io.probabilities.{ - FirstDepartureOfDay, - ProbabilityDensityFunction -} +import edu.ie3.mobsim.io.probabilities.{FirstDepartureOfDay, ProbabilityDensityFunction} import edu.ie3.mobsim.utils.utils.toTick import edu.ie3.util.quantities.interfaces.SpecificEnergy import tech.units.indriya.ComparableQuantity @@ -32,32 +26,32 @@ import tech.units.indriya.quantity.Quantities import java.lang import javax.measure.quantity.{Energy, Length, Power} import scala.collection.immutable.SortedSet -import scala.collection.mutable +import scala.collection.{immutable, mutable} import scala.util.{Failure, Success, Try} -case class ElectricVehicle( - private val simulationStart: ZonedDateTime, - private val uuid: UUID, - private val id: String, - private val model: String, - private val batteryCapacity: ComparableQuantity[Energy], - private val acChargingPower: ComparableQuantity[Power], - private val dcChargingPower: ComparableQuantity[Power], - private val consumption: ComparableQuantity[SpecificEnergy], // kWh per km - private val homePoi: PointOfInterest, - private val workPoi: PointOfInterest, - private val storedEnergy: ComparableQuantity[Energy], - private val destinationPoi: PointOfInterest, - private val parkingTimeStart: ZonedDateTime, - private val departureTime: ZonedDateTime, - private val chargingAtHomePossible: Boolean, - private val chosenChargingStation: Option[UUID], - private val chargingAtSimona: Boolean, - private val finalDestinationPoi: Option[PointOfInterest], - private val remainingDistanceAfterChargingHub: Option[ +final case class ElectricVehicle( + simulationStart: ZonedDateTime, + uuid: UUID, + id: String, + model: String, + batteryCapacity: ComparableQuantity[Energy], + acChargingPower: ComparableQuantity[Power], + dcChargingPower: ComparableQuantity[Power], + consumption: ComparableQuantity[SpecificEnergy], // kWh per km + homePoi: PointOfInterest, + workPoi: PointOfInterest, + storedEnergy: ComparableQuantity[Energy], + destinationPoi: PointOfInterest, + parkingTimeStart: ZonedDateTime, + departureTime: ZonedDateTime, + chargingAtHomePossible: Boolean, + chosenChargingStation: Option[UUID], + chargingAtSimona: Boolean, + finalDestinationPoi: Option[PointOfInterest], + remainingDistanceAfterChargingHub: Option[ ComparableQuantity[Length] ], - private val chargingPricesMemory: mutable.Queue[Double] + chargingPricesMemory: immutable.Queue[Double] ) extends EvModel with Ordered[ElectricVehicle] { @@ -65,8 +59,6 @@ case class ElectricVehicle( def getId: String = id - def getModel: String = model - def getEStorage: ComparableQuantity[Energy] = batteryCapacity def getSRatedAC: ComparableQuantity[Power] = acChargingPower @@ -75,40 +67,12 @@ case class ElectricVehicle( def getConsumption: ComparableQuantity[SpecificEnergy] = consumption - def getHomePOI: PointOfInterest = homePoi - - def getWorkPOI: PointOfInterest = workPoi - def getStoredEnergy: ComparableQuantity[Energy] = storedEnergy - def getDestinationPoiType: PoiTypeDictionary.Value = destinationPoi.poiType - - def getDestinationCategoricalLocation: CategoricalLocationDictionary.Value = - destinationPoi.categoricalLocation - - def getDestinationPoi: PointOfInterest = destinationPoi - - def getParkingTimeStart: ZonedDateTime = parkingTimeStart - - def getDepartureTime: ZonedDateTime = departureTime - - def isChargingAtHomePossible: Boolean = chargingAtHomePossible - - def getChosenChargingStation: Option[UUID] = chosenChargingStation - - def isChargingAtSimona: Boolean = chargingAtSimona + def getDestinationPoiType: PoiTypeDictionary.Value = destinationPoi.getPoiType def getFinalDestinationPoiType: Option[PoiTypeDictionary.Value] = - getFinalDestinationPoi.map(_.poiType) - - def getFinalDestinationPoi: Option[PointOfInterest] = finalDestinationPoi - - def getRemainingDistanceAfterChargingHub - : Option[ComparableQuantity[Length]] = { - remainingDistanceAfterChargingHub - } - - def getChargingPricesMemory: mutable.Queue[Double] = chargingPricesMemory + finalDestinationPoi.map(_.getPoiType) def getDepartureTick: lang.Long = toTick(simulationStart, departureTime) @@ -164,12 +128,20 @@ case class ElectricVehicle( copy(remainingDistanceAfterChargingHub = remainingDistance) } - def updateChargingPricesMemory(newPrice: Double): mutable.Queue[Double] = { + def updateChargingPricesMemory( + newPrices: mutable.Queue[Double] + ): ElectricVehicle = { + val queue: mutable.Queue[Double] = mutable.Queue.empty + + queue.enqueueAll(chargingPricesMemory) + queue.enqueueAll(newPrices) + /* keep maximum of 20 last known prices */ - while (chargingPricesMemory.size >= 20) { - chargingPricesMemory.dequeue() + while (queue.size >= 20) { + queue.dequeue() } - chargingPricesMemory += newPrice + + copy(chargingPricesMemory = queue.asInstanceOf[immutable.Queue[Double]]) } def compare(that: ElectricVehicle): Int = { @@ -465,7 +437,7 @@ case object ElectricVehicle extends LazyLogging { chargingAtSimona = false, finalDestinationPoi = None, remainingDistanceAfterChargingHub = None, - chargingPricesMemory = mutable.Queue[Double]() + chargingPricesMemory = immutable.Queue[Double]() ) } diff --git a/src/main/scala/edu/ie3/mobsim/model/TripSimulation.scala b/src/main/scala/edu/ie3/mobsim/model/TripSimulation.scala index c020af35..8f6eb850 100644 --- a/src/main/scala/edu/ie3/mobsim/model/TripSimulation.scala +++ b/src/main/scala/edu/ie3/mobsim/model/TripSimulation.scala @@ -139,7 +139,7 @@ object TripSimulation extends LazyLogging { /* Check if SoC is < 10% at start of trip -> if yes, and EV could charge at its destination, do not depart */ else if ( socAtStartOfTrip < SOC_OF_10_PERCENT - && ev.getDestinationPoi.nearestChargingStations.nonEmpty + && ev.destinationPoi.nearestChargingStations.nonEmpty ) { // logger.info( s"${ev.getId} has SoC < 10% at planned departure, but EV could charged here. It stays until it can charge..." @@ -169,10 +169,10 @@ object TripSimulation extends LazyLogging { } /* Get planned POI information and distance for the trip */ val ( - plannedDestinationPoiType, plannedDestinationCategoricalLocation, plannedDestinationPoi, - plannedDrivingDistance + plannedDrivingDistance, + changedEv ) = getTargetProperties( ev, currentTime, @@ -182,12 +182,12 @@ object TripSimulation extends LazyLogging { tripDistance ) match { case TargetProperties( - poiType, categoricalLocation, poi, - distance + distance, + alteredEv ) => - (poiType, categoricalLocation, poi, distance) + (categoricalLocation, poi, distance, alteredEv) } /* Simulate the planned trip */ @@ -196,10 +196,10 @@ object TripSimulation extends LazyLogging { plannedParkingTimeStart, plannedDepartureTime ) = simulatePlannedTrip( - ev, + changedEv, currentTime, plannedDrivingDistance, - plannedDestinationPoiType, + plannedDestinationPoi.getPoiType, drivingSpeed, firstDepartureOfDay, lastTripOfDay, @@ -209,7 +209,7 @@ object TripSimulation extends LazyLogging { /* Decide whether EV makes a stop at a charging hub to recharge during the trip */ val (evWantsToChargeAtChargingHub, maybeSocAtArrival) = doesEvWantToChargeAtChargingHub( - ev, + changedEv, plannedStoredEnergyEndOfTrip, plannedDestinationCategoricalLocation, plannedParkingTimeStart, @@ -231,14 +231,13 @@ object TripSimulation extends LazyLogging { // ) makeTripToChargingHub( PoiTypeDictionary.CHARGING_HUB_TOWN, - ev, + changedEv, currentTime, poisWithSizes, socAtStartOfTrip, socAtArrival, plannedDrivingDistance, plannedDestinationPoi, - plannedDestinationPoiType, chargingStations, drivingSpeed ) @@ -247,9 +246,8 @@ object TripSimulation extends LazyLogging { s"${ev.getId} wants to charge at charging hub on a <50km trip, but keeps its original trip because there are no chargingHubTown." // ) keepOriginalTrip( - ev, + changedEv, plannedStoredEnergyEndOfTrip, - plannedDestinationPoiType, plannedDestinationCategoricalLocation, plannedDestinationPoi, plannedParkingTimeStart, @@ -261,14 +259,13 @@ object TripSimulation extends LazyLogging { // ) makeTripToChargingHub( PoiTypeDictionary.CHARGING_HUB_HIGHWAY, - ev, + changedEv, currentTime, poisWithSizes, socAtStartOfTrip, socAtArrival, plannedDrivingDistance, plannedDestinationPoi, - plannedDestinationPoiType, chargingStations, drivingSpeed ) @@ -279,13 +276,12 @@ object TripSimulation extends LazyLogging { // ) makeModifiedTripToChargingHub( PoiTypeDictionary.CHARGING_HUB_TOWN, - ev, + changedEv, currentTime, poisWithSizes, socAtArrival, plannedDrivingDistance, plannedDestinationPoi, - plannedDestinationPoiType, chargingStations, drivingSpeed ) @@ -294,9 +290,8 @@ object TripSimulation extends LazyLogging { s"${ev.getId} wants to charge at charging hub on a >50km trip, but keeps its original trip because there are no chargingHubs at all." // ) keepOriginalTrip( - ev, + changedEv, plannedStoredEnergyEndOfTrip, - plannedDestinationPoiType, plannedDestinationCategoricalLocation, plannedDestinationPoi, plannedParkingTimeStart, @@ -309,9 +304,8 @@ object TripSimulation extends LazyLogging { s"${ev.getId} makes its planned trip." // ) keepOriginalTrip( - ev, + changedEv, plannedStoredEnergyEndOfTrip, - plannedDestinationPoiType, plannedDestinationCategoricalLocation, plannedDestinationPoi, plannedParkingTimeStart, @@ -375,8 +369,6 @@ object TripSimulation extends LazyLogging { /** Properties of a target for a trip * - * @param poiType - * Type of the POI * @param categoricalLocation * Type of categorical location * @param poi @@ -385,10 +377,10 @@ object TripSimulation extends LazyLogging { * Distance to be driven */ private final case class TargetProperties( - poiType: PoiTypeDictionary.Value, categoricalLocation: CategoricalLocationDictionary.Value, poi: PointOfInterest, - distance: ComparableQuantity[Length] + distance: ComparableQuantity[Length], + updatedEv: ElectricVehicle ) /** If the vehicles has intermediately been charged at a charging hub, resume @@ -405,35 +397,29 @@ object TripSimulation extends LazyLogging { ev: ElectricVehicle ): TargetProperties = ( - ev.getFinalDestinationPoiType, - ev.getFinalDestinationPoi, - ev.getRemainingDistanceAfterChargingHub + ev.finalDestinationPoi, + ev.remainingDistanceAfterChargingHub ) match { case ( - Some(destinationPoiType), Some(destinationPoi), Some(remainingDistance) ) => /* Reset saved values */ - ev.setFinalDestinationPoi(None) - ev.setRemainingDistanceAfterChargingHub(None) + var updatedEv: ElectricVehicle = ev.setFinalDestinationPoi(None) + updatedEv = updatedEv.setRemainingDistanceAfterChargingHub(None) /* Return the determined values */ TargetProperties( - destinationPoiType, destinationPoi.categoricalLocation, destinationPoi, - remainingDistance + remainingDistance, + updatedEv ) - case (None, _, _) => - throw TripException( - "Cannot resume trip, as the previous destination POI type is unknown." - ) - case (Some(_), None, _) => + case (None, _) => throw TripException( "Cannot resume trip, as the previous destination POI is unknown." ) - case (Some(_), Some(_), None) => + case (Some(_), None) => throw TripException( "Cannot resume trip, as the remaining distance is unknown." ) @@ -480,8 +466,8 @@ object TripSimulation extends LazyLogging { sampleNextPoi( destinationPoiType, time, - ev.getHomePOI, - ev.getWorkPOI, + ev.homePoi, + ev.workPoi, categoricalLocation, categoricalLocationToPdf ) match { @@ -494,10 +480,10 @@ object TripSimulation extends LazyLogging { destinationPoiType ) TargetProperties( - destinationPoiType, categoricalLocation, poi, - drivingDistance + drivingDistance, + ev ) } } @@ -701,8 +687,6 @@ object TripSimulation extends LazyLogging { * planned trip distance * @param plannedDestinationPoi * planned destination POI - * @param plannedDestinationPoiType - * planned destination POI type * @param drivingSpeed * Meta-information to determine the next driving speed * @return @@ -720,7 +704,6 @@ object TripSimulation extends LazyLogging { socAtChargingHubArrival: Double, plannedDrivingDistance: ComparableQuantity[Length], plannedDestinationPoi: PointOfInterest, - plannedDestinationPoiType: PoiTypeDictionary.Value, chargingStations: Set[ChargingStation], drivingSpeed: DrivingSpeed ): ElectricVehicle = { @@ -784,18 +767,19 @@ object TripSimulation extends LazyLogging { newParkingTimeStart.plusMinutes(newParkingTime) /* Save parameters of the originally planned trip for the next trip simulation after charging */ - ev.setRemainingDistanceAfterChargingHub( + var updatedEv: ElectricVehicle = ev.setRemainingDistanceAfterChargingHub( Some(plannedDrivingDistance.subtract(newDrivingDistance)) ) - ev.setFinalDestinationPoi(Some(plannedDestinationPoi)) + updatedEv = updatedEv.setFinalDestinationPoi(Some(plannedDestinationPoi)) /* Create updated EV */ - ev.copyWith( + updatedEv = updatedEv.copyWith( newStoredEnergyEndOfTrip, newDestinationPoi, newParkingTimeStart, newDepartureTime ) + updatedEv } /** Change the planned trip and make a trip to a charging hub. The trip is @@ -818,8 +802,6 @@ object TripSimulation extends LazyLogging { * planned trip distance * @param plannedDestinationPoi * planned destination POI - * @param plannedDestinationPoiType - * planned destination POI type * @param drivingSpeed * Meta-information to determine the next driving speed * @return @@ -835,7 +817,6 @@ object TripSimulation extends LazyLogging { socAtChargingHubArrival: Double, plannedDrivingDistance: ComparableQuantity[Length], plannedDestinationPoi: PointOfInterest, - plannedDestinationPoiType: PoiTypeDictionary.Value, chargingStations: Set[ChargingStation], drivingSpeed: DrivingSpeed ): ElectricVehicle = { @@ -895,18 +876,19 @@ object TripSimulation extends LazyLogging { newParkingTimeStart.plusMinutes(newParkingTime) /* Save parameters of the originally planned trip for the next trip simulation after charging */ - ev.setRemainingDistanceAfterChargingHub( + var updatedEv: ElectricVehicle = ev.setRemainingDistanceAfterChargingHub( Some(plannedDrivingDistance.subtract(newDrivingDistance)) ) - ev.setFinalDestinationPoi(Some(plannedDestinationPoi)) + updatedEv = updatedEv.setFinalDestinationPoi(Some(plannedDestinationPoi)) /* Create updated EV */ - ev.copyWith( + updatedEv = updatedEv.copyWith( newStoredEnergyEndOfTrip, newDestinationPoi, newParkingTimeStart, newDepartureTime ) + updatedEv } /** Decide whether EV makes a stop at a charging hub to recharge during the @@ -949,7 +931,7 @@ object TripSimulation extends LazyLogging { /* EV can be sufficiently charged if the next destination is home, home charging is possible and EV stays for at least 3 hours */ val sufficientHomeChargingPossible: Boolean = (plannedDestinationCategoricalLocation == PoiEnums.CategoricalLocationDictionary.HOME - && ev.isChargingAtHomePossible + && ev.chargingAtHomePossible && plannedParkingTimeStart.until( plannedDepartureTime, ChronoUnit.MINUTES @@ -991,8 +973,6 @@ object TripSimulation extends LazyLogging { * The EV for which the trip shall be simulated * @param plannedStoredEnergyEndOfTrip * planned stored energy at end of the trip - * @param plannedDestinationPoiType - * planned destination POI type * @param plannedDestinationCategoricalLocation * planned destination categorical location * @param plannedDestinationPoi @@ -1006,7 +986,6 @@ object TripSimulation extends LazyLogging { def keepOriginalTrip( ev: ElectricVehicle, plannedStoredEnergyEndOfTrip: ComparableQuantity[Energy], - plannedDestinationPoiType: PoiTypeDictionary.Value, plannedDestinationCategoricalLocation: CategoricalLocationDictionary.Value, plannedDestinationPoi: PointOfInterest, plannedParkingTimeStart: ZonedDateTime, @@ -1014,8 +993,8 @@ object TripSimulation extends LazyLogging { ): ElectricVehicle = { /* Because there is no stop at a charging hub, no trip values need to be saved */ - ev.setFinalDestinationPoi(None) - ev.setRemainingDistanceAfterChargingHub(None) + var updatedEv: ElectricVehicle = ev.setFinalDestinationPoi(None) + updatedEv = updatedEv.setRemainingDistanceAfterChargingHub(None) if ( QuantityUtil.isEquivalentAbs( @@ -1030,12 +1009,13 @@ object TripSimulation extends LazyLogging { } /* Create updated EV */ - ev.copyWith( + updatedEv = updatedEv.copyWith( plannedStoredEnergyEndOfTrip, plannedDestinationPoi, plannedParkingTimeStart, plannedDepartureTime ) + updatedEv } /** Create updated EV for the case that the EV does not depart because its SoC @@ -1074,7 +1054,7 @@ object TripSimulation extends LazyLogging { parkingTimeStart.plusMinutes( calculateChargingTimeAtChargingHub( ev, - ev.getDestinationPoi, + ev.destinationPoi, ev.getStoredEnergy, chargingStations ) @@ -1090,12 +1070,13 @@ object TripSimulation extends LazyLogging { } /* Create updated EV */ - ev.copyWith( + val updatedEv: ElectricVehicle = ev.copyWith( ev.getStoredEnergy, - ev.getDestinationPoi, + ev.destinationPoi, parkingTimeStart, departureTime ) + updatedEv } /** Calculate stored energy at the end of the trip based on the trip distance. diff --git a/src/main/scala/edu/ie3/mobsim/utils/IoUtils.scala b/src/main/scala/edu/ie3/mobsim/utils/IoUtils.scala index 8daa2d4c..d6804af2 100644 --- a/src/main/scala/edu/ie3/mobsim/utils/IoUtils.scala +++ b/src/main/scala/edu/ie3/mobsim/utils/IoUtils.scala @@ -54,10 +54,10 @@ final case class IoUtils private ( "ev" -> ev.getUuid.toString, "status" -> status, "soc" -> (ev.getStoredEnergy.getValue.doubleValue / ev.getEStorage.getValue.doubleValue).toString, - "destination_poi" -> ev.getDestinationPoi.id, - "categorical_location" -> ev.getDestinationCategoricalLocation.toString, - "scheduled_departure" -> ev.getDepartureTime.toString, - "is_charging" -> ev.isChargingAtSimona.toString + "destination_poi" -> ev.destinationPoi.id, + "categorical_location" -> ev.destinationPoi.categoricalLocation.toString, + "scheduled_departure" -> ev.departureTime.toString, + "is_charging" -> ev.chargingAtSimona.toString ).asJava movementWriter.write(fieldData) @@ -74,7 +74,7 @@ final case class IoUtils private ( val fieldData = Map( "uuid" -> ev.getUuid.toString, "id" -> ev.getId, - "model" -> ev.getModel, + "model" -> ev.model, "battery_capacity" -> ev.getEStorage.to(KILOWATTHOUR).getValue.doubleValue().toString, "max_charging_power_ac" -> @@ -87,9 +87,9 @@ final case class IoUtils private ( .getValue .doubleValue() .toString, - "home_poi" -> ev.getHomePOI.id, - "work_poi" -> ev.getWorkPOI.id, - "is_home_charging_possible" -> ev.isChargingAtHomePossible.toString + "home_poi" -> ev.homePoi.id, + "work_poi" -> ev.workPoi.id, + "is_home_charging_possible" -> ev.chargingAtHomePossible.toString ).asJava evWriter.write(fieldData) @@ -166,12 +166,12 @@ final case class IoUtils private ( uuid: UUID = UUID.randomUUID() ): Unit = { val (location, destinationPoi) = - if (time.isBefore(ev.getParkingTimeStart)) { + if (time.isBefore(ev.parkingTimeStart)) { ("DRIVING", "") } else { ( - ev.getDestinationCategoricalLocation.toString, - ev.getDestinationPoi.toString + ev.destinationPoi.categoricalLocation.toString, + ev.destinationPoi.toString ) } diff --git a/src/test/scala/edu/ie3/mobsim/io/geodata/PoiTestData.scala b/src/test/scala/edu/ie3/mobsim/io/geodata/PoiTestData.scala index 98bcfe21..040f1253 100644 --- a/src/test/scala/edu/ie3/mobsim/io/geodata/PoiTestData.scala +++ b/src/test/scala/edu/ie3/mobsim/io/geodata/PoiTestData.scala @@ -9,10 +9,7 @@ package edu.ie3.mobsim.io.geodata import edu.ie3.datamodel.models.ElectricCurrentType import edu.ie3.datamodel.models.input.system.`type`.chargingpoint.ChargingPointType import edu.ie3.datamodel.models.input.system.`type`.evcslocation.EvcsLocationType -import edu.ie3.mobsim.io.geodata.PoiEnums.{ - CategoricalLocationDictionary, - PoiTypeDictionary -} +import edu.ie3.mobsim.io.geodata.PoiEnums.CategoricalLocationDictionary import edu.ie3.mobsim.model.ChargingStation import edu.ie3.util.quantities.PowerSystemUnits import org.locationtech.jts.geom.Coordinate @@ -96,7 +93,6 @@ trait PoiTestData { protected val poiHome: PointOfInterest = PointOfInterest( UUID.fromString("91b8a161-7e44-4363-aaa3-2d2adbaaab6d"), "POI_home_1", - PoiTypeDictionary.HOME, CategoricalLocationDictionary.HOME, new Coordinate(7.3201668, 51.5067774), 25.557183061784293, @@ -106,7 +102,6 @@ trait PoiTestData { protected val workPoi: PointOfInterest = PointOfInterest( UUID.fromString("a26b6850-c966-4b42-8ccf-762015bf19ba"), "work_617762273", - PoiTypeDictionary.WORK, CategoricalLocationDictionary.WORK, new Coordinate(7.4065593, 51.5491556), 1549.4886151800551, @@ -116,7 +111,6 @@ trait PoiTestData { protected val bbpgPoi: PointOfInterest = PointOfInterest( UUID.fromString("6e4e3fac-171c-471e-8ec7-cef0d172c39d"), "bbpg_88921333", - PoiTypeDictionary.OTHER, CategoricalLocationDictionary.BBPG, new Coordinate(7.4622403, 51.5491056), 2783.9202769435374, @@ -126,7 +120,6 @@ trait PoiTestData { protected val culturePoi: PointOfInterest = PointOfInterest( UUID.fromString("da6ffecd-301c-42cf-8985-402580985eae"), "culture_247900605", - PoiTypeDictionary.LEISURE, CategoricalLocationDictionary.CULTURE, new Coordinate(7.3339823, 51.5184387), 6721.140094154159, @@ -136,7 +129,6 @@ trait PoiTestData { protected val medicinalPoi: PointOfInterest = PointOfInterest( UUID.fromString("75f1f39a-28e5-44e4-85dd-c61e145b765f"), "medicinal_253820890", - PoiTypeDictionary.OTHER, CategoricalLocationDictionary.MEDICINAL, new Coordinate(7.5112704, 51.5178795), 4695.499976294351, @@ -146,7 +138,6 @@ trait PoiTestData { protected val other_shopPoi: PointOfInterest = PointOfInterest( UUID.fromString("dda899fb-e085-479d-b3a9-cba594770a2b"), "other_shop_251193227", - PoiTypeDictionary.SHOPPING, CategoricalLocationDictionary.OTHER_SHOP, new Coordinate(7.3682537, 51.4935477), 1710.1059114060527, @@ -156,7 +147,6 @@ trait PoiTestData { protected val religiousPoi: PointOfInterest = PointOfInterest( UUID.fromString("bdac04c2-c3d6-4a6c-97fb-812b57b7e008"), "religious_8654674", - PoiTypeDictionary.LEISURE, CategoricalLocationDictionary.RELIGIOUS, new Coordinate(7.5366142, 51.4726591), 16984.79771274887, @@ -166,7 +156,6 @@ trait PoiTestData { protected val restaurantPoi: PointOfInterest = PointOfInterest( UUID.fromString("02851eae-8014-4f87-895c-21d2b653b199"), "restaurant_268555314", - PoiTypeDictionary.LEISURE, CategoricalLocationDictionary.RESTAURANT, new Coordinate(7.4411392, 51.5097096), 303.9431026, @@ -176,7 +165,6 @@ trait PoiTestData { protected val servicePoi: PointOfInterest = PointOfInterest( UUID.fromString("680df7d7-1c73-43ce-8eab-50d4a5105504"), "services_295406188", - PoiTypeDictionary.SHOPPING, CategoricalLocationDictionary.SERVICES, new Coordinate(7.5862309, 51.5012326), 548.2907601097887, @@ -186,7 +174,6 @@ trait PoiTestData { protected val sportsPoi: PointOfInterest = PointOfInterest( UUID.fromString("7d04dc33-3a53-4857-b75e-7391fe468048"), "sports_292612919", - PoiTypeDictionary.LEISURE, CategoricalLocationDictionary.SPORTS, new Coordinate(7.416975, 51.5009765), 12103.459075742423, @@ -196,7 +183,6 @@ trait PoiTestData { protected val supermarketPoi: PointOfInterest = PointOfInterest( UUID.fromString("63dd665f-ca0b-4556-a4a9-bebf32ecdaf8"), "supermarket_261717630", - PoiTypeDictionary.SHOPPING, CategoricalLocationDictionary.SUPERMARKET, new Coordinate(7.370586, 51.5234725), 1498.211731553507, @@ -206,7 +192,6 @@ trait PoiTestData { protected val charging_hub_townPoi: PointOfInterest = PointOfInterest( UUID.fromString("4df0614d-0c01-4b31-af94-804e299f2686"), "charging_hub_town_261344967", - PoiTypeDictionary.CHARGING_HUB_TOWN, CategoricalLocationDictionary.CHARGING_HUB_TOWN, new Coordinate(7.41153872, 51.4834271), 129.211731553507, @@ -215,7 +200,6 @@ trait PoiTestData { protected val charging_hub_highwayPoi: PointOfInterest = PointOfInterest( UUID.fromString("3ddc93c7-77fc-4187-be68-833b3db39809"), "charging_hub_highway_261347306", - PoiTypeDictionary.CHARGING_HUB_HIGHWAY, CategoricalLocationDictionary.CHARGING_HUB_HIGHWAY, new Coordinate(7.41153842, 51.4834251), 178.211731553507, diff --git a/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala b/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala index e3911888..eaf2bcb5 100644 --- a/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala +++ b/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleSpec.scala @@ -66,12 +66,12 @@ class ElectricVehicleSpec extends UnitSpec with TripSimulationData { acChargingPower shouldBe givenModel.acPower dcChargingPower shouldBe givenModel.dcPower consumption shouldBe givenModel.consumption - homePoi shouldBe ev.getHomePOI - workPoi shouldBe ev.getWorkPOI + homePoi shouldBe ev.homePoi + workPoi shouldBe ev.workPoi storedEnergy shouldBe givenModel.capacity chargingAtSimona shouldBe false - ev.getDestinationPoiType shouldBe PoiTypeDictionary.HOME - ev.getDestinationCategoricalLocation shouldBe CategoricalLocationDictionary.HOME + ev.destinationPoi.getPoiType shouldBe PoiTypeDictionary.HOME + ev.destinationPoi.categoricalLocation shouldBe CategoricalLocationDictionary.HOME destinationPoi shouldBe givenHomePoi parkingTimeStart shouldBe simulationStart departureTime shouldBe givenFirstDeparture @@ -112,7 +112,7 @@ class ElectricVehicleSpec extends UnitSpec with TripSimulationData { isChargingAtHomePossible = true ) match { case model: ElectricVehicle => - model.getDepartureTime shouldBe givenSimulationStart.plusMinutes(1L) + model.departureTime shouldBe givenSimulationStart.plusMinutes(1L) } } } @@ -225,7 +225,7 @@ class ElectricVehicleSpec extends UnitSpec with TripSimulationData { additionalCars should have size expectedOverallAmount additionalCars.count( - _.isChargingAtHomePossible + _.chargingAtHomePossible ) shouldBe expectedHomeChargingAmount } } @@ -274,7 +274,7 @@ class ElectricVehicleSpec extends UnitSpec with TripSimulationData { evs should have size targetAmount evs.count( - _.isChargingAtHomePossible + _.chargingAtHomePossible ) shouldBe expectedAmountOfHomeCharging } } @@ -282,8 +282,8 @@ class ElectricVehicleSpec extends UnitSpec with TripSimulationData { "An electricVehicle" should { "check if home charging is possible" in { - evWithHomeCharging.isChargingAtHomePossible shouldBe true - evWithoutHomeCharging.isChargingAtHomePossible shouldBe false + evWithHomeCharging.chargingAtHomePossible shouldBe true + evWithoutHomeCharging.chargingAtHomePossible shouldBe false } "copy object with new stored energy" in { @@ -300,21 +300,21 @@ class ElectricVehicleSpec extends UnitSpec with TripSimulationData { "copy object with updated charging at simona information" in { val evChargingAtSimona: ElectricVehicle = evWithHomeCharging.setChargingAtSimona() - evChargingAtSimona.isChargingAtSimona shouldBe true + evChargingAtSimona.chargingAtSimona shouldBe true val evNotChargingAtSimona: ElectricVehicle = evWithHomeCharging.removeChargingAtSimona() - evNotChargingAtSimona.isChargingAtSimona shouldBe false + evNotChargingAtSimona.chargingAtSimona shouldBe false } "copy object with chosen charging station" in { val evSetChargingStation: ElectricVehicle = evWithHomeCharging.setChosenChargingStation(Some(cs6.getUuid)) - evSetChargingStation.getChosenChargingStation shouldBe Some(cs6.getUuid) + evSetChargingStation.chosenChargingStation shouldBe Some(cs6.getUuid) val evNoChargingStation: ElectricVehicle = evWithHomeCharging.setChosenChargingStation(None) - evNoChargingStation.getChosenChargingStation shouldBe None + evNoChargingStation.chosenChargingStation shouldBe None } } } diff --git a/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleTestData.scala b/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleTestData.scala index 52af7b59..cd4d770f 100644 --- a/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleTestData.scala +++ b/src/test/scala/edu/ie3/mobsim/model/ElectricVehicleTestData.scala @@ -9,10 +9,7 @@ package edu.ie3.mobsim.model import edu.ie3.datamodel.models.ElectricCurrentType import edu.ie3.datamodel.models.input.system.`type`.chargingpoint.ChargingPointType import edu.ie3.datamodel.models.input.system.`type`.evcslocation.EvcsLocationType -import edu.ie3.mobsim.io.geodata.PoiEnums.{ - CategoricalLocationDictionary, - PoiTypeDictionary -} +import edu.ie3.mobsim.io.geodata.PoiEnums.CategoricalLocationDictionary import edu.ie3.mobsim.io.geodata.PointOfInterest import edu.ie3.mobsim.io.model.EvTypeInput import edu.ie3.mobsim.io.probabilities.{ @@ -45,7 +42,6 @@ trait ElectricVehicleTestData { protected val givenHomePoi: PointOfInterest = PointOfInterest( UUID.fromString("d40b4feb-fd57-42b5-9247-43eaad2dff4b"), "test", - PoiTypeDictionary.HOME, CategoricalLocationDictionary.HOME, new Coordinate(7.4116482, 51.4843281), 1.0, @@ -57,7 +53,6 @@ trait ElectricVehicleTestData { protected val givenWorkPoi: PointOfInterest = PointOfInterest( UUID.fromString("c34a031e-8568-4b59-99e4-1ad113bef6ea"), "test", - PoiTypeDictionary.WORK, CategoricalLocationDictionary.WORK, new Coordinate(7.4116482, 51.4843281), 1.0, diff --git a/src/test/scala/edu/ie3/mobsim/model/TripSimulationData.scala b/src/test/scala/edu/ie3/mobsim/model/TripSimulationData.scala index 0197dfbb..6c374278 100644 --- a/src/test/scala/edu/ie3/mobsim/model/TripSimulationData.scala +++ b/src/test/scala/edu/ie3/mobsim/model/TripSimulationData.scala @@ -55,7 +55,7 @@ trait TripSimulationData extends ElectricVehicleTestData with PoiTestData { charging_hub_highwayPoi ) - protected val plannedDestinationPoi: PointOfInterest = poiData(11) + protected val plannedDestinationPoi: PointOfInterest = poiData(10) protected val pois: Set[PointOfInterest] = poiData.toSet diff --git a/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala b/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala index 11b0ca63..58739abc 100644 --- a/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala +++ b/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala @@ -22,7 +22,7 @@ class TripSimulationSpec extends UnitSpec with TripSimulationData { // testing makeTripToChargingHub "makeTripToChargingHub correctly" in { - TripSimulation.makeTripToChargingHub( + val updatedEv: ElectricVehicle = TripSimulation.makeTripToChargingHub( PoiTypeDictionary.CHARGING_HUB_TOWN, ev, givenSimulationStart, @@ -31,10 +31,11 @@ class TripSimulationSpec extends UnitSpec with TripSimulationData { 0.2, Quantities.getQuantity(1000, METRE), plannedDestinationPoi, - PoiTypeDictionary.WORK, chargingStations, speed - ) match { + ) + + updatedEv match { case ElectricVehicle( simulationStart, uuid, @@ -60,7 +61,7 @@ class TripSimulationSpec extends UnitSpec with TripSimulationData { simulationStart shouldBe givenSimulationStart uuid shouldBe ev.getUuid id shouldBe ev.getId - model shouldBe ev.getModel + model shouldBe ev.model batteryCapacity shouldBe givenModel.capacity acChargingPower shouldBe givenModel.acPower dcChargingPower shouldBe givenModel.dcPower @@ -69,16 +70,16 @@ class TripSimulationSpec extends UnitSpec with TripSimulationData { workPoi shouldBe givenWorkPoi storedEnergy shouldBe storedEnergyValue chargingAtSimona shouldBe false - destinationPoi.poiType shouldBe PoiTypeDictionary.CHARGING_HUB_TOWN + destinationPoi.getPoiType shouldBe PoiTypeDictionary.CHARGING_HUB_TOWN destinationPoi.categoricalLocation shouldBe CategoricalLocationDictionary.CHARGING_HUB_TOWN - destinationPoi shouldBe plannedDestinationPoi + destinationPoi shouldBe charging_hub_townPoi parkingTimeStart shouldBe simulationStart.plusMinutes(10) departureTime shouldBe simulationStart.plusHours(7).plusMinutes(26) chargingAtHomePossible shouldBe true chosenChargingStation shouldBe None - finalDestinationPoi.map(_.poiType) shouldBe None - finalDestinationPoi shouldBe None - remainingDistanceAfterChargingHub shouldBe ev.getRemainingDistanceAfterChargingHub + finalDestinationPoi.map(_.getPoiType) shouldBe Some(supermarketPoi.getPoiType) + finalDestinationPoi shouldBe Some(supermarketPoi) + remainingDistanceAfterChargingHub shouldBe Some(Quantities.getQuantity(-7000, METRE)) chargingPricesMemory shouldBe mutable.Queue[Double]() } } @@ -86,7 +87,7 @@ class TripSimulationSpec extends UnitSpec with TripSimulationData { // testing makeModifiedTripToChargingHub "makeModifiedTripToChargingHub correctly" in { - TripSimulation.makeModifiedTripToChargingHub( + val updatedEv: ElectricVehicle = TripSimulation.makeModifiedTripToChargingHub( PoiTypeDictionary.CHARGING_HUB_TOWN, ev, givenSimulationStart, @@ -94,10 +95,11 @@ class TripSimulationSpec extends UnitSpec with TripSimulationData { 0.2, Quantities.getQuantity(1000, METRE), plannedDestinationPoi, - PoiTypeDictionary.WORK, chargingStations, speed - ) match { + ) + + updatedEv match { case ElectricVehicle( simulationStart, uuid, @@ -122,8 +124,8 @@ class TripSimulationSpec extends UnitSpec with TripSimulationData { ) => simulationStart shouldBe givenSimulationStart uuid shouldBe ev.getUuid - id shouldBe "test_car" - model shouldBe "cool_producer cool_model" + id shouldBe ev.id + model shouldBe ev.model batteryCapacity shouldBe givenModel.capacity acChargingPower shouldBe givenModel.acPower dcChargingPower shouldBe givenModel.dcPower @@ -132,16 +134,16 @@ class TripSimulationSpec extends UnitSpec with TripSimulationData { workPoi shouldBe givenWorkPoi storedEnergy shouldBe storedEnergyValue chargingAtSimona shouldBe false - destinationPoi.poiType shouldBe PoiTypeDictionary.CHARGING_HUB_TOWN + destinationPoi.getPoiType shouldBe PoiTypeDictionary.CHARGING_HUB_TOWN destinationPoi.categoricalLocation shouldBe CategoricalLocationDictionary.CHARGING_HUB_TOWN - destinationPoi shouldBe plannedDestinationPoi + destinationPoi shouldBe charging_hub_townPoi parkingTimeStart shouldBe simulationStart.plusMinutes(1) departureTime shouldBe simulationStart.plusHours(7).plusMinutes(17) chargingAtHomePossible shouldBe true chosenChargingStation shouldBe None - finalDestinationPoi.map(_.poiType) shouldBe None - finalDestinationPoi shouldBe None - remainingDistanceAfterChargingHub shouldBe None + finalDestinationPoi.map(_.getPoiType) shouldBe Some(supermarketPoi.getPoiType) + finalDestinationPoi shouldBe Some(supermarketPoi) + remainingDistanceAfterChargingHub shouldBe Some(Quantities.getQuantity(10000, METRE)) chargingPricesMemory shouldBe mutable.Queue[Double]() } } From 7f33a7c1a9bdf7d939c00351a7ce959ba0230331 Mon Sep 17 00:00:00 2001 From: Marius Staudt Date: Tue, 5 Jul 2022 17:43:12 +0200 Subject: [PATCH 10/13] Fixing code format errors with ``spotless``. --- .../ie3/mobsim/model/ElectricVehicle.scala | 5 ++- .../ie3/mobsim/model/TripSimulationSpec.scala | 39 ++++++++++++------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala b/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala index e4e7b9a0..e25c188f 100644 --- a/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala +++ b/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala @@ -12,7 +12,10 @@ import edu.ie3.mobsim.exceptions.InitializationException import edu.ie3.mobsim.io.geodata.PoiEnums.PoiTypeDictionary import edu.ie3.mobsim.io.geodata.PointOfInterest import edu.ie3.mobsim.io.model.EvTypeInput -import edu.ie3.mobsim.io.probabilities.{FirstDepartureOfDay, ProbabilityDensityFunction} +import edu.ie3.mobsim.io.probabilities.{ + FirstDepartureOfDay, + ProbabilityDensityFunction +} import edu.ie3.mobsim.utils.utils.toTick import edu.ie3.util.quantities.interfaces.SpecificEnergy import tech.units.indriya.ComparableQuantity diff --git a/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala b/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala index 58739abc..99ce5c8c 100644 --- a/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala +++ b/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala @@ -77,9 +77,13 @@ class TripSimulationSpec extends UnitSpec with TripSimulationData { departureTime shouldBe simulationStart.plusHours(7).plusMinutes(26) chargingAtHomePossible shouldBe true chosenChargingStation shouldBe None - finalDestinationPoi.map(_.getPoiType) shouldBe Some(supermarketPoi.getPoiType) + finalDestinationPoi.map(_.getPoiType) shouldBe Some( + supermarketPoi.getPoiType + ) finalDestinationPoi shouldBe Some(supermarketPoi) - remainingDistanceAfterChargingHub shouldBe Some(Quantities.getQuantity(-7000, METRE)) + remainingDistanceAfterChargingHub shouldBe Some( + Quantities.getQuantity(-7000, METRE) + ) chargingPricesMemory shouldBe mutable.Queue[Double]() } } @@ -87,17 +91,18 @@ class TripSimulationSpec extends UnitSpec with TripSimulationData { // testing makeModifiedTripToChargingHub "makeModifiedTripToChargingHub correctly" in { - val updatedEv: ElectricVehicle = TripSimulation.makeModifiedTripToChargingHub( - PoiTypeDictionary.CHARGING_HUB_TOWN, - ev, - givenSimulationStart, - poisWithSizes, - 0.2, - Quantities.getQuantity(1000, METRE), - plannedDestinationPoi, - chargingStations, - speed - ) + val updatedEv: ElectricVehicle = + TripSimulation.makeModifiedTripToChargingHub( + PoiTypeDictionary.CHARGING_HUB_TOWN, + ev, + givenSimulationStart, + poisWithSizes, + 0.2, + Quantities.getQuantity(1000, METRE), + plannedDestinationPoi, + chargingStations, + speed + ) updatedEv match { case ElectricVehicle( @@ -141,9 +146,13 @@ class TripSimulationSpec extends UnitSpec with TripSimulationData { departureTime shouldBe simulationStart.plusHours(7).plusMinutes(17) chargingAtHomePossible shouldBe true chosenChargingStation shouldBe None - finalDestinationPoi.map(_.getPoiType) shouldBe Some(supermarketPoi.getPoiType) + finalDestinationPoi.map(_.getPoiType) shouldBe Some( + supermarketPoi.getPoiType + ) finalDestinationPoi shouldBe Some(supermarketPoi) - remainingDistanceAfterChargingHub shouldBe Some(Quantities.getQuantity(10000, METRE)) + remainingDistanceAfterChargingHub shouldBe Some( + Quantities.getQuantity(10000, METRE) + ) chargingPricesMemory shouldBe mutable.Queue[Double]() } } From d62fba00dca571c8d89ad1a5613c06325b5d9f9c Mon Sep 17 00:00:00 2001 From: Marius Staudt Date: Tue, 5 Jul 2022 17:56:29 +0200 Subject: [PATCH 11/13] Fixing code smells. --- .../scala/edu/ie3/mobsim/model/ChargingBehavior.scala | 11 +++++++---- .../scala/edu/ie3/mobsim/model/ElectricVehicle.scala | 3 ++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/scala/edu/ie3/mobsim/model/ChargingBehavior.scala b/src/main/scala/edu/ie3/mobsim/model/ChargingBehavior.scala index 95598eef..549533fe 100644 --- a/src/main/scala/edu/ie3/mobsim/model/ChargingBehavior.scala +++ b/src/main/scala/edu/ie3/mobsim/model/ChargingBehavior.scala @@ -132,10 +132,13 @@ object ChargingBehavior extends LazyLogging { /* Probability that the EV wants to charge based on its SoC. Distinguish between home and work and elsewhere for threshold for charging */ val (lowerThreshold, upperThreshold) = { + val categoricalLocation: CategoricalLocationDictionary.Value = + ev.destinationPoi.categoricalLocation + if (ev.chargingAtHomePossible) { if ( - ev.destinationPoi.categoricalLocation == CategoricalLocationDictionary.HOME - || ev.destinationPoi.categoricalLocation == CategoricalLocationDictionary.WORK + categoricalLocation == CategoricalLocationDictionary.HOME + || categoricalLocation == CategoricalLocationDictionary.WORK ) { (0.4, 0.85) } else { @@ -143,8 +146,8 @@ object ChargingBehavior extends LazyLogging { } } else { if ( - ev.destinationPoi.categoricalLocation == CategoricalLocationDictionary.HOME - || ev.destinationPoi.categoricalLocation == CategoricalLocationDictionary.WORK + categoricalLocation == CategoricalLocationDictionary.HOME + || categoricalLocation == CategoricalLocationDictionary.WORK ) { (0.4, 0.85) } else { diff --git a/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala b/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala index e25c188f..19968486 100644 --- a/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala +++ b/src/main/scala/edu/ie3/mobsim/model/ElectricVehicle.scala @@ -144,7 +144,8 @@ final case class ElectricVehicle( queue.dequeue() } - copy(chargingPricesMemory = queue.asInstanceOf[immutable.Queue[Double]]) + val newChargingPricesMemory: immutable.Queue[Double] = immutable.Queue.empty + copy(chargingPricesMemory = newChargingPricesMemory.enqueueAll(queue)) } def compare(that: ElectricVehicle): Int = { From 3b657379c15fd2590ca8e0b8fa2dfc565a818032 Mon Sep 17 00:00:00 2001 From: Marius Staudt Date: Tue, 5 Jul 2022 18:05:53 +0200 Subject: [PATCH 12/13] Fixing code smells. --- .../ie3/mobsim/model/ChargingBehavior.scala | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/main/scala/edu/ie3/mobsim/model/ChargingBehavior.scala b/src/main/scala/edu/ie3/mobsim/model/ChargingBehavior.scala index 549533fe..5e8137b0 100644 --- a/src/main/scala/edu/ie3/mobsim/model/ChargingBehavior.scala +++ b/src/main/scala/edu/ie3/mobsim/model/ChargingBehavior.scala @@ -135,24 +135,15 @@ object ChargingBehavior extends LazyLogging { val categoricalLocation: CategoricalLocationDictionary.Value = ev.destinationPoi.categoricalLocation - if (ev.chargingAtHomePossible) { - if ( - categoricalLocation == CategoricalLocationDictionary.HOME + ( + ev.chargingAtHomePossible, + categoricalLocation == CategoricalLocationDictionary.HOME || categoricalLocation == CategoricalLocationDictionary.WORK - ) { - (0.4, 0.85) - } else { - (0.3, 0.5) - } - } else { - if ( - categoricalLocation == CategoricalLocationDictionary.HOME - || categoricalLocation == CategoricalLocationDictionary.WORK - ) { - (0.4, 0.85) - } else { - (0.3, 0.75) - } + ) match { + case (true, true) => (0.4, 0.85) + case (true, false) => (0.3, 0.5) + case (false, true) => (0.4, 0.85) + case (false, false) => (0.3, 0.75) } } From 07f462134c0a845738fde4584f771c82f2a3e42f Mon Sep 17 00:00:00 2001 From: Marius Staudt Date: Thu, 7 Jul 2022 10:47:51 +0200 Subject: [PATCH 13/13] Adding some tests for ``IoUtils``. --- build.gradle | 2 +- .../model/ChargingBehaviorTestData.scala | 13 ++ .../ie3/mobsim/model/TripSimulationData.scala | 19 +- .../ie3/mobsim/model/TripSimulationSpec.scala | 16 +- .../edu/ie3/mobsim/utils/IoUtilsSpec.scala | 188 ++++++++++++++++++ .../ie3/mobsim/utils/IoUtilsTestData.scala | 48 +++++ 6 files changed, 275 insertions(+), 11 deletions(-) create mode 100644 src/test/scala/edu/ie3/mobsim/model/ChargingBehaviorTestData.scala create mode 100644 src/test/scala/edu/ie3/mobsim/utils/IoUtilsSpec.scala create mode 100644 src/test/scala/edu/ie3/mobsim/utils/IoUtilsTestData.scala diff --git a/build.gradle b/build.gradle index 546a47d6..749af2ab 100644 --- a/build.gradle +++ b/build.gradle @@ -45,7 +45,7 @@ dependencies { /* Exclude our own nested dependencies */ exclude group: 'com.github.ie3-institute' } - implementation('com.github.ie3-institute:PowerSystemDataModel:2.1.0') { + implementation('com.github.ie3-institute:PowerSystemDataModel:3.0-SNAPSHOT') { exclude group: 'org.apache.logging.log4j' exclude group: 'org.slf4j' /* Exclude our own nested dependencies */ diff --git a/src/test/scala/edu/ie3/mobsim/model/ChargingBehaviorTestData.scala b/src/test/scala/edu/ie3/mobsim/model/ChargingBehaviorTestData.scala new file mode 100644 index 00000000..36454d41 --- /dev/null +++ b/src/test/scala/edu/ie3/mobsim/model/ChargingBehaviorTestData.scala @@ -0,0 +1,13 @@ +package edu.ie3.mobsim.model + +import java.util.UUID + +trait ChargingBehaviorTestData extends TripSimulationData { + protected val currentlyAvailableChargingPoints: Map[UUID, Integer] = { + chargingStations.map { chargingStations => + chargingStations.getUuid -> Integer.valueOf( + chargingStations.getChargingPoints + ) + }.toMap + } +} diff --git a/src/test/scala/edu/ie3/mobsim/model/TripSimulationData.scala b/src/test/scala/edu/ie3/mobsim/model/TripSimulationData.scala index 6c374278..c38d8e3c 100644 --- a/src/test/scala/edu/ie3/mobsim/model/TripSimulationData.scala +++ b/src/test/scala/edu/ie3/mobsim/model/TripSimulationData.scala @@ -25,9 +25,14 @@ import tech.units.indriya.unit.Units.KILOMETRE_PER_HOUR import javax.measure.quantity.Energy trait TripSimulationData extends ElectricVehicleTestData with PoiTestData { + protected val zero: ComparableQuantity[Energy] = + Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR) + protected val half: ComparableQuantity[Energy] = + Quantities.getQuantity(50, PowerSystemUnits.KILOWATTHOUR) - val ev: ElectricVehicle = ElectricVehicle.buildEv( - "test_car", + + val ev1: ElectricVehicle = ElectricVehicle.buildEv( + "car_1", givenModel, givenHomePoi, givenWorkPoi, @@ -36,6 +41,16 @@ trait TripSimulationData extends ElectricVehicleTestData with PoiTestData { isChargingAtHomePossible = true ) + val ev2: ElectricVehicle = ElectricVehicle.buildEv( + "car_2", + givenModel, + givenHomePoi, + givenWorkPoi, + givenSimulationStart, + givenFirstDeparture, + isChargingAtHomePossible = false + ) + protected val chargingStations: Set[ChargingStation] = Set(cs0, cs1, cs2, cs3, cs4, cs5, cs6) diff --git a/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala b/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala index 99ce5c8c..c43c1e7b 100644 --- a/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala +++ b/src/test/scala/edu/ie3/mobsim/model/TripSimulationSpec.scala @@ -24,7 +24,7 @@ class TripSimulationSpec extends UnitSpec with TripSimulationData { val updatedEv: ElectricVehicle = TripSimulation.makeTripToChargingHub( PoiTypeDictionary.CHARGING_HUB_TOWN, - ev, + ev1, givenSimulationStart, poisWithSizes, 0.5, @@ -59,9 +59,9 @@ class TripSimulationSpec extends UnitSpec with TripSimulationData { chargingPricesMemory ) => simulationStart shouldBe givenSimulationStart - uuid shouldBe ev.getUuid - id shouldBe ev.getId - model shouldBe ev.model + uuid shouldBe ev1.getUuid + id shouldBe ev1.getId + model shouldBe ev1.model batteryCapacity shouldBe givenModel.capacity acChargingPower shouldBe givenModel.acPower dcChargingPower shouldBe givenModel.dcPower @@ -94,7 +94,7 @@ class TripSimulationSpec extends UnitSpec with TripSimulationData { val updatedEv: ElectricVehicle = TripSimulation.makeModifiedTripToChargingHub( PoiTypeDictionary.CHARGING_HUB_TOWN, - ev, + ev1, givenSimulationStart, poisWithSizes, 0.2, @@ -128,9 +128,9 @@ class TripSimulationSpec extends UnitSpec with TripSimulationData { chargingPricesMemory ) => simulationStart shouldBe givenSimulationStart - uuid shouldBe ev.getUuid - id shouldBe ev.id - model shouldBe ev.model + uuid shouldBe ev1.getUuid + id shouldBe ev1.id + model shouldBe ev1.model batteryCapacity shouldBe givenModel.capacity acChargingPower shouldBe givenModel.acPower dcChargingPower shouldBe givenModel.dcPower diff --git a/src/test/scala/edu/ie3/mobsim/utils/IoUtilsSpec.scala b/src/test/scala/edu/ie3/mobsim/utils/IoUtilsSpec.scala new file mode 100644 index 00000000..45519c68 --- /dev/null +++ b/src/test/scala/edu/ie3/mobsim/utils/IoUtilsSpec.scala @@ -0,0 +1,188 @@ +/* + * © 2022. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.mobsim.utils + +import edu.ie3.test.common.UnitSpec +import edu.ie3.util.quantities.PowerSystemUnits.{ + KILOWATT, + KILOWATTHOUR, + KILOWATTHOUR_PER_KILOMETRE +} + +import java.io.{BufferedReader, File, FileReader} +import java.util +import java.util.UUID + +class IoUtilsSpec extends UnitSpec with IoUtilsTestData { + "IoUtils" should { + "write movement correctly" in { + ioUtils.writeMovement( + firstEv, + currentTime, + status, + uuid + ) + + val data = new BufferedReader( + new FileReader(new File(outputFileFolder + "movements")) + ) + + val list: util.ArrayList[String] = new util.ArrayList[String]() + var line = data.readLine() + + while (line != null) { + list.add(line) + line = data.readLine() + } + + val compareString: String = (s"${uuid.toString}," + + s"${currentTime.toString}," + + s"${firstEv.uuid.toString},$status," + + s"${(firstEv.storedEnergy.getValue.doubleValue() / firstEv.batteryCapacity.getValue + .doubleValue()).toString}," + + s"${firstEv.destinationPoi.id}," + + s"${firstEv.destinationPoi.categoricalLocation.toString}," + + s"${firstEv.departureTime.toString}," + + s"${firstEv.chargingAtSimona.toString}").replaceAll(",", ";") + + list.get(list.size() - 1) shouldBe compareString + } + + "write evs correctly" in { + ioUtils.writeEvs(evSet) + + val data = new BufferedReader( + new FileReader(new File(outputFileFolder + "evs")) + ) + + val list: util.ArrayList[String] = new util.ArrayList[String]() + var line = data.readLine() + + while (line != null) { + list.add(line) + line = data.readLine() + } + + val firstEvString: String = (s"${firstEv.uuid.toString}," + + s"${firstEv.id}," + + s"${firstEv.model}," + + s"${firstEv.storedEnergy.to(KILOWATTHOUR).getValue.doubleValue().toString}," + + s"${firstEv.acChargingPower.to(KILOWATT).getValue.doubleValue().toString}," + + s"${firstEv.dcChargingPower.to(KILOWATT).getValue.doubleValue().toString}," + + s"${firstEv.consumption.to(KILOWATTHOUR_PER_KILOMETRE).getValue.doubleValue().toString}," + + s"${firstEv.homePoi.id}," + + s"${firstEv.workPoi.id}," + + s"${firstEv.chargingAtHomePossible.toString}").replaceAll(",", ";") + + val secondEvString: String = (s"${secondEv.uuid.toString}," + + s"${secondEv.id}," + + s"${secondEv.model}," + + s"${secondEv.storedEnergy.to(KILOWATTHOUR).getValue.doubleValue().toString}," + + s"${secondEv.acChargingPower.to(KILOWATT).getValue.doubleValue().toString}," + + s"${secondEv.dcChargingPower.to(KILOWATT).getValue.doubleValue().toString}," + + s"${secondEv.consumption.to(KILOWATTHOUR_PER_KILOMETRE).getValue.doubleValue().toString}," + + s"${secondEv.homePoi.id}," + + s"${secondEv.workPoi.id}," + + s"${secondEv.chargingAtHomePossible.toString}").replaceAll(",", ";") + + list.get(list.size() - 2) shouldBe firstEvString + list.get(list.size() - 1) shouldBe secondEvString + } + + "write electric vehicle charging stations correctly" in { + ioUtils.writeEvcs(cs6,currentlyAvailableChargingPoints,currentTime, uuid) + + val data = new BufferedReader( + new FileReader(new File(outputFileFolder + "evcs")) + ) + + val list: util.ArrayList[String] = new util.ArrayList[String]() + var line = data.readLine() + + while (line != null) { + list.add(line) + line = data.readLine() + } + + val chargingPoints: String = cs6.getChargingPoints.toString + val occupiedChargingPoints = (cs6.getChargingPoints - currentlyAvailableChargingPoints + .getOrElse(cs6.getUuid, 0) + .asInstanceOf[Integer]).toString + + val entry: String = (s"${uuid.toString}," + + s"${currentTime.toString}," + + s"${cs6.getUuid.toString}," + + s"$chargingPoints," + + s"$occupiedChargingPoints").replaceAll(",",";") + + + list.get(list.size()-1) shouldBe entry + } + + "write pois correctly" in { + ioUtils.writePois(poiMap) + + val data = new BufferedReader( + new FileReader(new File(outputFileFolder + "pois")) + ) + + val list: util.ArrayList[String] = new util.ArrayList[String]() + var line = data.readLine() + + while (line != null) { + list.add(line) + line = data.readLine() + } + + val string: String = + charging_hub_townPoi.nearestChargingStations.foreach { + case (evcsUuid, distance) => + evcsUuid.toString + "," + distance.getValue.doubleValue().toString + }.toString + + val entry: String = (s"${charging_hub_townPoi.id}," + + s"${charging_hub_townPoi.getPoiType.toString}," + + s"${charging_hub_townPoi.size.toString}," + + s"$string").replaceAll(",", ";") + + list.get(list.size() - 1) contains entry + } + + "write positions correctly" in { + ioUtils.writeEvPosition(firstEv, currentTime, uuid) + + val data = new BufferedReader( + new FileReader(new File(outputFileFolder + "positions")) + ) + + val list: util.ArrayList[String] = new util.ArrayList[String]() + var line = data.readLine() + + while (line != null) { + list.add(line) + line = data.readLine() + } + + val (location, destinationPoi) = + if (currentTime.isBefore(firstEv.parkingTimeStart)) { + ("DRIVING", "") + } else { + ( + firstEv.destinationPoi.categoricalLocation.toString, + firstEv.destinationPoi.toString + ) + } + + val entry: String = (s"$uuid," + + s"${firstEv.uuid.toString}," + + s"$location,").replaceAll(",", ";") + + s"$destinationPoi" + + list.get(list.size() - 1) shouldBe entry + } + } +} diff --git a/src/test/scala/edu/ie3/mobsim/utils/IoUtilsTestData.scala b/src/test/scala/edu/ie3/mobsim/utils/IoUtilsTestData.scala new file mode 100644 index 00000000..3016f0ab --- /dev/null +++ b/src/test/scala/edu/ie3/mobsim/utils/IoUtilsTestData.scala @@ -0,0 +1,48 @@ +/* + * © 2022. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.mobsim.utils + +import edu.ie3.mobsim.io.geodata.PoiEnums.CategoricalLocationDictionary +import edu.ie3.mobsim.io.geodata.PointOfInterest +import edu.ie3.mobsim.model.{ChargingBehaviorTestData, ElectricVehicle} + +import java.io.File +import java.time.ZonedDateTime +import java.util.UUID +import scala.collection.immutable.TreeSet + +trait IoUtilsTestData extends ChargingBehaviorTestData { + protected val outputFileFolder: String = new java.io.File( + "." + ).getCanonicalPath + File.separator + "out" + File.separator + + protected val ioUtils: IoUtils = IoUtils( + outputFileFolder, + "movements", + "evs", + "evcs", + "positions", + "pois" + ) + + protected val currentTime: ZonedDateTime = ZonedDateTime.now() + protected val status: String = "departure" + protected val uuid: UUID = UUID.randomUUID() + protected val firstEv: ElectricVehicle = ev1 + protected val secondEv: ElectricVehicle = ev2 + + protected val evSet: Set[ElectricVehicle] = Seq(firstEv, secondEv).toSet + + protected val poiMap + : Map[CategoricalLocationDictionary.Value, Set[PointOfInterest]] = { + val poiSet: Set[PointOfInterest] = Seq(charging_hub_townPoi).toSet + + poiSet.groupBy(_.categoricalLocation).map { case (catLoc, poi) => + catLoc -> TreeSet.from(poi) + } + } +}