eflips-depot 4.15.1__tar.gz → 4.15.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/PKG-INFO +2 -2
  2. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/README.md +1 -1
  3. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/api/__init__.py +3 -1
  4. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/api/private/consumption.py +24 -21
  5. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/api/private/depot.py +39 -31
  6. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/api/private/results_to_database.py +10 -4
  7. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/api/private/util.py +1 -0
  8. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/processes.py +19 -3
  9. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/rating.py +1 -1
  10. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/simple_vehicle.py +12 -1
  11. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/pyproject.toml +1 -1
  12. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/LICENSE.md +0 -0
  13. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/__init__.py +0 -0
  14. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/api/defaults/default_settings.json +0 -0
  15. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/api/private/__init__.py +0 -0
  16. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/configuration.py +0 -0
  17. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/depot.py +0 -0
  18. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/evaluation.py +0 -0
  19. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/filters.py +0 -0
  20. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/input_epex_power_price.py +0 -0
  21. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/layout_opt/__init__.py +0 -0
  22. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/layout_opt/doc/__init__.py +0 -0
  23. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/layout_opt/doc/direct_details.pdf +0 -0
  24. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/layout_opt/evaluation.py +0 -0
  25. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/layout_opt/opt_tools/__init__.py +0 -0
  26. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/layout_opt/opt_tools/crossover.py +0 -0
  27. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/layout_opt/opt_tools/fitness_c_urfd.py +0 -0
  28. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/layout_opt/opt_tools/fitness_util.py +0 -0
  29. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/layout_opt/opt_tools/init.py +0 -0
  30. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/layout_opt/opt_tools/mutation.py +0 -0
  31. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/layout_opt/optimize_c_urfd.py +0 -0
  32. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/layout_opt/packing.py +0 -0
  33. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/layout_opt/settings.py +0 -0
  34. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/layout_opt/template_creation.py +0 -0
  35. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/layout_opt/util.py +0 -0
  36. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/plots.py +0 -0
  37. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/resources.py +0 -0
  38. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/settings_config.py +0 -0
  39. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/simulation.py +0 -0
  40. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/smart_charging.py +0 -0
  41. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/standalone.py +0 -0
  42. {eflips_depot-4.15.1 → eflips_depot-4.15.9}/eflips/depot/validation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eflips-depot
3
- Version: 4.15.1
3
+ Version: 4.15.9
4
4
  Summary: Depot Simulation for eFLIPS
5
5
  License: AGPL-3.0-or-later
6
6
  License-File: LICENSE.md
@@ -131,5 +131,5 @@ This project is licensed under the AGPLv3 license - see the [LICENSE](LICENSE.md
131
131
 
132
132
  ## Funding Notice
133
133
 
134
- This code was developed as part of the project [eBus2030+]([https://www.eflip.de/](https://www.now-gmbh.de/projektfinder/e-bus-2030/)) funded by the Federal German Ministry for Digital and Transport (BMDV) under grant number 03EMF0402.
134
+ This code was developed as part of the project [eBus2030+](https://www.now-gmbh.de/projektfinder/e-bus-2030/) funded by the Federal German Ministry for Digital and Transport (BMDV) under grant number 03EMF0402.
135
135
 
@@ -104,4 +104,4 @@ This project is licensed under the AGPLv3 license - see the [LICENSE](LICENSE.md
104
104
 
105
105
  ## Funding Notice
106
106
 
107
- This code was developed as part of the project [eBus2030+]([https://www.eflip.de/](https://www.now-gmbh.de/projektfinder/e-bus-2030/)) funded by the Federal German Ministry for Digital and Transport (BMDV) under grant number 03EMF0402.
107
+ This code was developed as part of the project [eBus2030+](https://www.now-gmbh.de/projektfinder/e-bus-2030/) funded by the Federal German Ministry for Digital and Transport (BMDV) under grant number 03EMF0402.
@@ -685,7 +685,9 @@ def simulate_scenario(
685
685
  case SmartChargingStrategy.NONE:
686
686
  pass
687
687
  case SmartChargingStrategy.EVEN:
688
- apply_even_smart_charging(scenario, database_url)
688
+ apply_even_smart_charging(
689
+ scenario, database_url, delete_existing_charging_timeseries=True
690
+ )
689
691
  case SmartChargingStrategy.MIN_PRICE:
690
692
  raise NotImplementedError("MIN_PRICE strategy is not implemented yet.")
691
693
  case _:
@@ -3,7 +3,7 @@ import warnings
3
3
  from dataclasses import dataclass
4
4
  from datetime import timedelta, datetime
5
5
  from math import ceil
6
- from typing import Tuple, List
6
+ from typing import Tuple, List, Optional
7
7
  from zoneinfo import ZoneInfo
8
8
 
9
9
  import numpy as np
@@ -88,11 +88,13 @@ class ConsumptionInformation:
88
88
  """
89
89
 
90
90
  trip_id: int
91
- consumption_lut: ConsumptionLut | None # the LUT for the vehicle class
91
+ consumption_lut: Optional[ConsumptionLut] # the LUT for the vehicle class
92
92
  average_speed: float # the average speed of the trip in km/h
93
93
  distance: float # the distance of the trip in km
94
- temperature: float # The ambient temperature in °C
95
- level_of_loading: float
94
+ temperature: Optional[float] # The ambient temperature in °C
95
+ level_of_loading: Optional[
96
+ float
97
+ ] # The level of loading of the vehicle as a fraction of its maximum payload
96
98
  incline: float = 0.0 # The incline of the trip in 0.0-1.0
97
99
  consumption: float = None # The consumption of the trip in kWh
98
100
  consumption_per_km: float = None # The consumption per km in kWh
@@ -302,22 +304,22 @@ def extract_trip_information(
302
304
 
303
305
  temperature = temperature_for_trip(trip_id, session)
304
306
 
305
- payload_mass = passenger_mass * passenger_count
306
- assert (
307
- trip.rotation.vehicle_type.allowed_mass is not None
308
- ), f"allowed_mass of vehicle {trip.rotation.vehicle_type} must be set"
307
+ if len(all_consumption_luts) == 1:
308
+ payload_mass = passenger_mass * passenger_count
309
+ assert (
310
+ trip.rotation.vehicle_type.allowed_mass is not None
311
+ ), f"allowed_mass of vehicle {trip.rotation.vehicle_type} must be set"
309
312
 
310
- assert (
311
- trip.rotation.vehicle_type.empty_mass is not None
312
- ), f"empty_mass of vehicle {trip.rotation.vehicle_type} must be set"
313
+ assert (
314
+ trip.rotation.vehicle_type.empty_mass is not None
315
+ ), f"empty_mass of vehicle {trip.rotation.vehicle_type} must be set"
313
316
 
314
- full_payload = (
315
- trip.rotation.vehicle_type.allowed_mass
316
- - trip.rotation.vehicle_type.empty_mass
317
- )
318
- level_of_loading = payload_mass / full_payload
317
+ full_payload = (
318
+ trip.rotation.vehicle_type.allowed_mass
319
+ - trip.rotation.vehicle_type.empty_mass
320
+ )
321
+ level_of_loading = payload_mass / full_payload
319
322
 
320
- if len(all_consumption_luts) == 1:
321
323
  consumption_lut = all_consumption_luts[0]
322
324
  # Disconnect the consumption LUT from the session to avoid loading the whole table
323
325
 
@@ -339,9 +341,10 @@ def extract_trip_information(
339
341
  )
340
342
  # Here, we fill out the condumption information without the LUT and LUT data, but with `consumption_per_km`
341
343
  # set to the vehicle's `consumption` value.
342
- assert (
343
- VehicleType.consumption is not None
344
- ), f"Vehicle type {trip.rotation.vehicle_type} must have a consumption value set if no consumption LUT is available."
344
+ if trip.rotation.vehicle_type.consumption is None:
345
+ raise ValueError(
346
+ f"Vehicle type {trip.rotation.vehicle_type} must have a consumption value set if no consumption LUT is available."
347
+ )
345
348
  info = ConsumptionInformation(
346
349
  trip_id=trip.id,
347
350
  average_speed=average_speed,
@@ -350,7 +353,7 @@ def extract_trip_information(
350
353
  consumption=trip.rotation.vehicle_type.consumption * total_distance,
351
354
  consumption_lut=None,
352
355
  temperature=temperature,
353
- level_of_loading=level_of_loading,
356
+ level_of_loading=None,
354
357
  )
355
358
  else:
356
359
  raise ValueError(
@@ -126,20 +126,27 @@ class DepotConfigurationWish:
126
126
  self.areas = areas
127
127
 
128
128
  if self.auto_generate is True:
129
- if self.default_power is None or self.standard_block_length is None:
130
- raise ValueError(
131
- "If auto_generate is True, default_power, standard_block_length, cleaning_slots, cleaning_duration and shunting_slots must be provided."
132
- )
133
- if (
134
- self.cleaning_slots is not None
135
- or self.cleaning_duration is not None
136
- or self.shunting_slots is not None
137
- or self.shunting_duration is not None
138
- ):
139
- raise ValueError(
140
- "If auto_generate is True, default_power, standard_block_length, cleaning_slots, cleaning_duration and shunting_slots cannot be provided."
141
- )
142
- # do some simple validation here
129
+ assert (
130
+ self.default_power is not None
131
+ ), "default_power must be provided if auto_generate is True"
132
+ assert (
133
+ self.standard_block_length is not None
134
+ ), "standard_block_length must be provided if auto_generate is True"
135
+
136
+ assert (
137
+ self.cleaning_slots is None
138
+ ), "cleaning_slots cannot be provided if auto_generate is True"
139
+ assert (
140
+ self.cleaning_duration is None
141
+ ), "cleaning_duration cannot be provided if auto_generate is True"
142
+ assert (
143
+ self.shunting_slots is None
144
+ ), "shunting_slots cannot be provided if auto_generate is True"
145
+ assert (
146
+ self.shunting_duration is None
147
+ ), "shunting_duration cannot be provided if auto_generate is True"
148
+
149
+ assert areas is None, "areas cannot be provided if auto_generate is True"
143
150
 
144
151
 
145
152
  def delete_depots(scenario: Scenario, session: Session) -> None:
@@ -230,7 +237,7 @@ def depot_to_template(depot: Depot) -> Dict[str, str | Dict[str, str | int]]:
230
237
  if process_type(processes_in_area) == ProcessType.CHARGING:
231
238
  # Add the charging process for this vehicle type
232
239
  template["areas"][area_name]["available_processes"].append(
233
- str(processes_in_area.id) + str(area.vehicle_type_id)
240
+ str(processes_in_area.id) + "vt" + str(area.vehicle_type_id)
234
241
  )
235
242
  # Delete the original charging process
236
243
  template["areas"][area_name]["available_processes"].remove(
@@ -253,7 +260,7 @@ def depot_to_template(depot: Depot) -> Dict[str, str | Dict[str, str | int]]:
253
260
  # Add the charging process for this vehicle type
254
261
  for vt in scenario.vehicle_types:
255
262
  template["areas"][area_name]["available_processes"].append(
256
- str(processes_in_area.id) + str(vt.id)
263
+ str(processes_in_area.id) + "vt" + str(vt.id)
257
264
  )
258
265
  # Delete the original charging process
259
266
  template["areas"][area_name]["available_processes"].remove(
@@ -386,30 +393,31 @@ def depot_to_template(depot: Depot) -> Dict[str, str | Dict[str, str | int]]:
386
393
 
387
394
  for vt in all_vehicle_types:
388
395
  charging_curve = vt.charging_curve
389
- template["processes"][process_name + str(vt.id)] = template[
396
+
397
+ charging_process_name = process_name + "vt" + str(vt.id)
398
+ template["processes"][charging_process_name] = template[
390
399
  "processes"
391
400
  ][process_name].copy()
392
- template["processes"][process_name + str(vt.id)][
401
+ template["processes"][charging_process_name][
393
402
  "typename"
394
403
  ] = "ChargeEquationSteps"
395
- template["processes"][process_name + str(vt.id)][
396
- "vehicle_filter"
397
- ] = {
404
+ template["processes"][charging_process_name]["vehicle_filter"] = {
398
405
  "filter_names": ["vehicle_type"],
399
406
  "vehicle_types": [str(vt.id)],
400
407
  }
401
408
 
402
- template["processes"][process_name + str(vt.id)][
409
+ template["processes"][charging_process_name][
403
410
  "peq_name"
404
411
  ] = "charging_curve_power"
405
- template["processes"][process_name + str(vt.id)]["peq_params"] = {
412
+ template["processes"][charging_process_name]["peq_params"] = {
406
413
  "soc": [soc_power_pair[0] for soc_power_pair in charging_curve],
407
414
  "power": [
408
415
  soc_power_pair[1] for soc_power_pair in charging_curve
409
416
  ],
417
+ "precision": 0.01,
410
418
  }
411
419
 
412
- del template["processes"][process_name + str(vt.id)]["dur"]
420
+ del template["processes"][charging_process_name]["dur"]
413
421
 
414
422
  # delete the original process
415
423
  del template["processes"][process_name]
@@ -1195,7 +1203,9 @@ def depot_smallest_possible_size(
1195
1203
 
1196
1204
  # Simulate the depot
1197
1205
  simulate_scenario(
1198
- scenario, smart_charging_strategy=SmartChargingStrategy.NONE
1206
+ scenario,
1207
+ smart_charging_strategy=SmartChargingStrategy.NONE,
1208
+ ignore_unstable_simulation=True,
1199
1209
  )
1200
1210
 
1201
1211
  # Find the peak usage of the depot
@@ -1259,12 +1269,6 @@ def depot_smallest_possible_size(
1259
1269
 
1260
1270
  except MissingVehicleDimensionError as e:
1261
1271
  raise e
1262
- except UnstableSimulationException as e:
1263
- # This change is made after Unstable exception and delay exceptions are introduced
1264
- logger.debug(
1265
- f"Results are unstable, suggesting depot is too small."
1266
- )
1267
- continue
1268
1272
  except DelayedTripException as e:
1269
1273
  logger.debug(f"Trips are delayed, suggesting depot is too small.")
1270
1274
  continue
@@ -1274,6 +1278,10 @@ def depot_smallest_possible_size(
1274
1278
  # Identify the best configuration for each vehicle type
1275
1279
  ret_val: Dict[VehicleType, Dict[AreaType, int]] = dict()
1276
1280
  for vt in vts_and_rotations.keys():
1281
+ assert area_needed[vt] != {}, (
1282
+ f"No valid configurations found for {vt.name}, "
1283
+ f"please check if there are any delays after simulating scenario."
1284
+ )
1277
1285
  best_config = min(area_needed[vt].keys(), key=lambda x: area_needed[vt][x])
1278
1286
  ret_val[vt] = {
1279
1287
  AreaType.LINE: best_config * standard_block_length,
@@ -1,6 +1,7 @@
1
1
  import datetime
2
2
  import itertools
3
3
  import logging
4
+ import math
4
5
  import warnings
5
6
  from datetime import timedelta
6
7
  from typing import List, Dict
@@ -398,6 +399,10 @@ def add_soc_to_events(dict_of_events, battery_log) -> None:
398
399
  """
399
400
  battery_log_list = []
400
401
  for log in battery_log:
402
+ # TODO this is a bypass of update events having lower energy_real than the event before. It happens in processes L 1304
403
+ if log.event_name == "update":
404
+ continue
405
+
401
406
  battery_log_list.append((log.t, round(log.energy / log.energy_real, 4)))
402
407
 
403
408
  time_keys = sorted(dict_of_events.keys())
@@ -496,7 +501,7 @@ def add_events_into_database(
496
501
  '"Standby", "Precondition"'
497
502
  )
498
503
 
499
- if process_dict["end"] == start_time:
504
+ if math.ceil(process_dict["end"]) == math.ceil(start_time):
500
505
  logger.warning("Refusing to create an event with zero duration.")
501
506
  continue
502
507
 
@@ -522,7 +527,7 @@ def add_events_into_database(
522
527
  if "timeseries" in process_dict.keys():
523
528
  # Convert "time" in timeseries to timedelta
524
529
  timeseries["time"] = [
525
- (timedelta(seconds=t) + simulation_start_time).isoformat()
530
+ (timedelta(seconds=math.ceil(t)) + simulation_start_time).isoformat()
526
531
  for t in process_dict["timeseries"]["time"]
527
532
  ]
528
533
  timeseries["soc"] = process_dict["timeseries"]["soc"]
@@ -540,8 +545,9 @@ def add_events_into_database(
540
545
  area_id=area_id,
541
546
  subloc_no=process_dict["slot"] if "slot" in process_dict.keys() else 00,
542
547
  trip_id=None,
543
- time_start=timedelta(seconds=start_time) + simulation_start_time,
544
- time_end=timedelta(seconds=process_dict["end"]) + simulation_start_time,
548
+ time_start=timedelta(seconds=math.ceil(start_time)) + simulation_start_time,
549
+ time_end=timedelta(seconds=math.ceil(process_dict["end"]))
550
+ + simulation_start_time,
545
551
  soc_start=process_dict["soc_start"]
546
552
  if process_dict["soc_start"] is not None
547
553
  else process_dict["soc_end"],
@@ -102,6 +102,7 @@ def vehicle_type_to_global_constants_dict(vt: VehicleType) -> Dict[str, float]:
102
102
  "soc_max": 1.0,
103
103
  "soc_init": 1.0,
104
104
  "soh": 1.0,
105
+ "charging_efficiency": vt.charging_efficiency,
105
106
  }
106
107
  return the_dict
107
108
 
@@ -840,6 +840,7 @@ class Charge(ChargeAbstract):
840
840
 
841
841
  @property
842
842
  def power(self):
843
+ # TODO this doesn't consider vehicle charging power
843
844
  return self.charging_interface.max_power
844
845
 
845
846
  def _action(self, *args, **kwargs):
@@ -1240,6 +1241,8 @@ class ChargeEquationSteps(ChargeAbstract):
1240
1241
  self.precision = precision
1241
1242
  Charge.check_soc_target(soc_target, vehicle_filter)
1242
1243
  self.soc_target = soc_target
1244
+ if "precision" in self.peq_params:
1245
+ self.precision = self.peq_params["precision"]
1243
1246
 
1244
1247
  @property
1245
1248
  def power(self):
@@ -1271,8 +1274,12 @@ class ChargeEquationSteps(ChargeAbstract):
1271
1274
  )
1272
1275
  soc_target_step = self.vehicle.battery.soc + soc_interval
1273
1276
  amount = self.vehicle.battery.energy_real * soc_interval
1274
- effective_power = self.power * self.efficiency
1275
- self.dur = int(amount / effective_power * 3600)
1277
+ effective_power = (
1278
+ self.power
1279
+ * self.efficiency
1280
+ * self.vehicle.vehicle_type.charging_efficiency
1281
+ )
1282
+ self.dur = round(amount / effective_power * 3600, 12)
1276
1283
 
1277
1284
  if self.dur == 0:
1278
1285
  # amount is so small that dur is <1s. Reduce the precision
@@ -1295,6 +1302,7 @@ class ChargeEquationSteps(ChargeAbstract):
1295
1302
  yield self.env.timeout(self.dur)
1296
1303
 
1297
1304
  if soc_target_step < self.soc_target:
1305
+ # TODO why here we have energy higher than the step_soc_target?
1298
1306
  # recalculate amount because update_battery may have been
1299
1307
  # called in the meantime
1300
1308
  amount_step = (
@@ -1438,13 +1446,21 @@ def charging_curve_power(vehicle, charging_interface, peq_params):
1438
1446
  :return: charging power in float for given SimpleVehicle
1439
1447
  """
1440
1448
 
1449
+ precision = peq_params.get("precision", 0.01)
1441
1450
  current_soc = vehicle.battery.soc
1442
1451
  p_max = charging_interface.max_power
1452
+ target_step_soc = min(vehicle.battery.soc + precision, vehicle.battery.soc_max)
1443
1453
 
1444
- current_power = min(
1454
+ power_current_soc = min(
1445
1455
  p_max, np.interp(current_soc, peq_params["soc"], peq_params["power"])
1446
1456
  )
1447
1457
 
1458
+ power_target_soc = min(
1459
+ p_max, np.interp(target_step_soc, peq_params["soc"], peq_params["power"])
1460
+ )
1461
+
1462
+ current_power = min(power_current_soc, power_target_soc)
1463
+
1448
1464
  return float(current_power)
1449
1465
 
1450
1466
 
@@ -422,7 +422,7 @@ class RfdDiffDispatch:
422
422
  diffs = []
423
423
  for vehicle in area.vehicles:
424
424
  etc = vehicle.dwd.etc_processes
425
- if isinstance(etc, int):
425
+ if isinstance(etc, int) or isinstance(etc, float):
426
426
  diff = etc - slot[0].env.now
427
427
  diffs.append(diff)
428
428
  # Convert EstimateValue to numerical rfddiff
@@ -36,7 +36,17 @@ class VehicleType:
36
36
 
37
37
  """
38
38
 
39
- def __init__(self, ID, battery_capacity, soc_min, soc_max, soc_init, soh, CR=None):
39
+ def __init__(
40
+ self,
41
+ ID,
42
+ battery_capacity,
43
+ soc_min,
44
+ soc_max,
45
+ soc_init,
46
+ soh,
47
+ charging_efficiency=1.0,
48
+ CR=None,
49
+ ):
40
50
  self.ID = ID
41
51
  self.battery_capacity = battery_capacity
42
52
  self.soc_min = soc_min
@@ -45,6 +55,7 @@ class VehicleType:
45
55
  self.soh = soh
46
56
  self.CR = CR
47
57
  self.group = None
58
+ self.charging_efficiency = charging_efficiency
48
59
 
49
60
  self.count = {}
50
61
  self.share = {}
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "eflips-depot"
3
- version = "4.15.1"
3
+ version = "4.15.9"
4
4
  description = "Depot Simulation for eFLIPS"
5
5
  authors = ["Enrico Lauth <enrico.lauth@tu-berlin.de>",
6
6
  "Ludger Heide <ludger.heide@tu-berlin.de",
File without changes