eflips-depot 3.0.2__tar.gz → 3.0.4__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 (59) hide show
  1. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/PKG-INFO +7 -5
  2. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/api/__init__.py +89 -60
  3. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/api/private/depot.py +23 -19
  4. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/filters.py +14 -0
  5. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/pyproject.toml +6 -4
  6. eflips_depot-3.0.2/eflips/depot/.DS_Store +0 -0
  7. eflips_depot-3.0.2/eflips/depot/api/__pycache__/__init__.cpython-311.pyc +0 -0
  8. eflips_depot-3.0.2/eflips/depot/api/__pycache__/__init__.cpython-312.pyc +0 -0
  9. eflips_depot-3.0.2/eflips/depot/api/private/__pycache__/__init__.cpython-312.pyc +0 -0
  10. eflips_depot-3.0.2/eflips/depot/api/private/__pycache__/depot.cpython-312.pyc +0 -0
  11. eflips_depot-3.0.2/eflips/depot/api/private/__pycache__/depot_layout.cpython-312.pyc +0 -0
  12. eflips_depot-3.0.2/eflips/depot/api/private/__pycache__/util.cpython-312.pyc +0 -0
  13. eflips_depot-3.0.2/eflips/depot/layout_opt/__pycache__/__init__.cpython-311.pyc +0 -0
  14. eflips_depot-3.0.2/eflips/depot/layout_opt/__pycache__/__init__.cpython-312.pyc +0 -0
  15. eflips_depot-3.0.2/eflips/depot/layout_opt/__pycache__/evaluation.cpython-311.pyc +0 -0
  16. eflips_depot-3.0.2/eflips/depot/layout_opt/__pycache__/packing.cpython-311.pyc +0 -0
  17. eflips_depot-3.0.2/eflips/depot/layout_opt/__pycache__/settings.cpython-311.pyc +0 -0
  18. eflips_depot-3.0.2/eflips/depot/layout_opt/__pycache__/util.cpython-311.pyc +0 -0
  19. eflips_depot-3.0.2/eflips/depot/layout_opt/opt_tools/__pycache__/__init__.cpython-311.pyc +0 -0
  20. eflips_depot-3.0.2/eflips/depot/layout_opt/opt_tools/__pycache__/crossover.cpython-311.pyc +0 -0
  21. eflips_depot-3.0.2/eflips/depot/layout_opt/opt_tools/__pycache__/fitness_c_urfd.cpython-311.pyc +0 -0
  22. eflips_depot-3.0.2/eflips/depot/layout_opt/opt_tools/__pycache__/fitness_util.cpython-311.pyc +0 -0
  23. eflips_depot-3.0.2/eflips/depot/layout_opt/opt_tools/__pycache__/init.cpython-311.pyc +0 -0
  24. eflips_depot-3.0.2/eflips/depot/layout_opt/opt_tools/__pycache__/mutation.cpython-311.pyc +0 -0
  25. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/LICENSE.md +0 -0
  26. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/README.md +0 -0
  27. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/__init__.py +0 -0
  28. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/api/defaults/default_settings.json +0 -0
  29. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/api/private/__init__.py +0 -0
  30. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/api/private/util.py +0 -0
  31. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/configuration.py +0 -0
  32. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/depot.py +0 -0
  33. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/evaluation.py +0 -0
  34. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/input_epex_power_price.py +0 -0
  35. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/__init__.py +0 -0
  36. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/doc/__init__.py +0 -0
  37. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/doc/direct_details.pdf +0 -0
  38. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/evaluation.py +0 -0
  39. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/opt_tools/__init__.py +0 -0
  40. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/opt_tools/crossover.py +0 -0
  41. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/opt_tools/fitness_c_urfd.py +0 -0
  42. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/opt_tools/fitness_util.py +0 -0
  43. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/opt_tools/init.py +0 -0
  44. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/opt_tools/mutation.py +0 -0
  45. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/optimize_c_urfd.py +0 -0
  46. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/packing.py +0 -0
  47. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/settings.py +0 -0
  48. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/template_creation.py +0 -0
  49. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/util.py +0 -0
  50. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/plots.py +0 -0
  51. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/processes.py +0 -0
  52. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/rating.py +0 -0
  53. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/resources.py +0 -0
  54. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/settings_config.py +0 -0
  55. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/simple_vehicle.py +0 -0
  56. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/simulation.py +0 -0
  57. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/smart_charging.py +0 -0
  58. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/standalone.py +0 -0
  59. {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/validation.py +0 -0
@@ -1,22 +1,24 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: eflips-depot
3
- Version: 3.0.2
3
+ Version: 3.0.4
4
4
  Summary: Depot Simulation for eFLIPS
5
- License: AGPLv3
5
+ Home-page: https://github.com/mpm-tu-berlin/eflips-depot
6
+ License: AGPL-3.0-or-later
6
7
  Author: Enrico Lauth
7
8
  Author-email: enrico.lauth@tu-berlin.de
8
9
  Requires-Python: >=3.10,<4.0
9
- Classifier: License :: Other/Proprietary License
10
+ Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
10
11
  Classifier: Programming Language :: Python :: 3
11
12
  Classifier: Programming Language :: Python :: 3.10
12
13
  Classifier: Programming Language :: Python :: 3.11
13
14
  Classifier: Programming Language :: Python :: 3.12
14
- Requires-Dist: eflips (>=0.1.1,<0.2.0)
15
- Requires-Dist: eflips-model (>=3.1.0,<4.0.0)
15
+ Requires-Dist: eflips (>=0.1.3,<0.2.0)
16
+ Requires-Dist: eflips-model (>=3.2.0,<4.0.0)
16
17
  Requires-Dist: pandas (>=2.1.4,<3.0.0)
17
18
  Requires-Dist: simpy (>=4.0.1,<5.0.0)
18
19
  Requires-Dist: xlrd (<=1.2.0)
19
20
  Requires-Dist: xlsxwriter (>=3.1.9,<4.0.0)
21
+ Project-URL: Repository, https://github.com/mpm-tu-berlin/eflips-depot
20
22
  Description-Content-Type: text/markdown
21
23
 
22
24
  [![Tests](https://github.com/mpm-tu-berlin/eflips-depot/actions/workflows/postgres_eflips_depot.yml/badge.svg)](https://github.com/mpm-tu-berlin/eflips-depot/actions/workflows/postgres_eflips_depot.yml)
@@ -26,6 +26,7 @@ The following steps are recommended for using the API:
26
26
  """
27
27
  import copy
28
28
  import os
29
+ import warnings
29
30
  from datetime import timedelta
30
31
  from math import ceil
31
32
  from typing import Any, Dict, Optional, Union
@@ -41,6 +42,8 @@ from eflips.model import (
41
42
  Scenario,
42
43
  Trip,
43
44
  Vehicle,
45
+ Process,
46
+ AssocAreaProcess,
44
47
  )
45
48
  from sqlalchemy.orm import Session
46
49
  from sqlalchemy.sql import select
@@ -303,7 +306,7 @@ def generate_depot_layout(
303
306
  max_occupancies: Dict[eflips.model.VehicleType, int] = {}
304
307
  max_clean_occupancies: Dict[eflips.model.VehicleType, int] = {}
305
308
  for vehicle_type, rotations in vehicle_type_dict.items():
306
- # Slightly convoulted vehicle summation
309
+ # Slightly convoluted vehicle summation
307
310
  start_time = min(
308
311
  [rotation.trips[0].departure_time for rotation in rotations]
309
312
  ).timestamp()
@@ -529,13 +532,15 @@ def init_simulation(
529
532
  depot_id
530
533
  ] = vehicle_count_dict[depot_id]
531
534
  else:
532
- # Calculate it from the size of the areas, with a 2x margin
535
+ # Calculate it from the size of the areas (except the area for the first standby process, which is already
536
+ # really large), with a 2x margin
533
537
  for vehicle_type in vehicle_types_for_depot:
534
538
  vehicle_count = sum(
535
539
  [
536
540
  area.capacity
537
541
  for area in depot.areas
538
542
  if area.vehicle_type_id == int(vehicle_type)
543
+ and depot.default_plan.processes[0] not in area.processes
539
544
  ]
540
545
  )
541
546
  eflips.globalConstants["depot"]["vehicle_count"][depot_id][
@@ -660,14 +665,10 @@ def add_evaluation_to_database(
660
665
 
661
666
  list_of_vehicles = []
662
667
 
663
- list_of_events = []
664
-
665
668
  list_of_assigned_schedules = []
666
669
 
667
670
  # Read results from depot_evaluation categorized by vehicle
668
671
  for current_vehicle in depot_evaluation.vehicle_generator.items:
669
- list_of_events_per_vehicle = []
670
-
671
672
  vehicle_type_id = int(current_vehicle.vehicle_type.ID)
672
673
 
673
674
  # Create a Vehicle object for database
@@ -684,6 +685,7 @@ def add_evaluation_to_database(
684
685
 
685
686
  dict_of_events = {}
686
687
 
688
+ # Generate process log for each schedule
687
689
  for finished_trip in current_vehicle.finished_trips:
688
690
  dict_of_events[finished_trip.atd] = {
689
691
  "type": "trip",
@@ -710,6 +712,57 @@ def add_evaluation_to_database(
710
712
  waiting_log = current_vehicle.logger.loggedData["area_waiting_time"]
711
713
  battery_log = current_vehicle.battery_logs
712
714
 
715
+ # Create standby events according to waiting_log
716
+ waiting_log_timekeys = sorted(waiting_log.keys())
717
+
718
+ for idx in range(len(waiting_log_timekeys)):
719
+ end_time = waiting_log_timekeys[idx]
720
+ waiting_info = waiting_log[end_time]
721
+
722
+ if waiting_info["waiting_time"] == 0:
723
+ continue
724
+
725
+ # Vehicle is waiting in the last area in waiting_log and expecting to enter the current area
726
+ expected_area = waiting_info["area"]
727
+ # Find the area for standby arrival event
728
+
729
+ waiting_area_id = (
730
+ session.query(Area.id)
731
+ .join(AssocAreaProcess, AssocAreaProcess.area_id == Area.id)
732
+ .join(Process, Process.id == AssocAreaProcess.process_id)
733
+ .filter(
734
+ Process.dispatchable == False,
735
+ Process.duration.is_(None),
736
+ Process.electric_power.is_(None),
737
+ Area.vehicle_type_id == int(current_vehicle.vehicle_type.ID),
738
+ Area.scenario_id == scenario.id,
739
+ )
740
+ .one()[0]
741
+ )
742
+
743
+ # Make sure the vehicle is waiting at an area with enough capacity
744
+
745
+ current_slot = slot_log[waiting_log_timekeys[idx - 1]]
746
+
747
+ start_time = end_time - waiting_info["waiting_time"]
748
+
749
+ warnings.warn(
750
+ f"Vehicle {current_vehicle.ID} is waiting at {waiting_area_id} because area {expected_area} is full."
751
+ )
752
+
753
+ dict_of_events[start_time] = {
754
+ "type": "Standby",
755
+ "end": end_time,
756
+ "area": waiting_area_id,
757
+ "slot": current_slot,
758
+ "is_area_sink": False,
759
+ }
760
+
761
+ # Create a list of battery log in order of time asc. Convenient for looking up corresponding soc
762
+ battery_log_list = []
763
+ for log in battery_log:
764
+ battery_log_list.append((log.t, log.energy / log.energy_real))
765
+
713
766
  for start_time, process_log in current_vehicle.logger.loggedData[
714
767
  "dwd.active_processes_copy"
715
768
  ].items():
@@ -843,11 +896,11 @@ def add_evaluation_to_database(
843
896
  f"Invalid process status {process.status} for process {process.ID}."
844
897
  )
845
898
 
846
- time_keys = sorted(dict_of_events.keys(), reverse=True)
847
- if len(time_keys) != 0:
899
+ reversed_time_keys = sorted(dict_of_events.keys(), reverse=True)
900
+ if len(reversed_time_keys) != 0:
848
901
  # Generating valid event-list
849
902
  is_copy = True
850
- for start_time in time_keys:
903
+ for start_time in reversed_time_keys:
851
904
  process_dict = dict_of_events[start_time]
852
905
  if process_dict["type"] == "trip":
853
906
  is_copy = process_dict["is_copy"]
@@ -875,17 +928,31 @@ def add_evaluation_to_database(
875
928
  # End time of 0-duration processes are start time of the next process
876
929
 
877
930
  if "end" not in process_dict:
878
- end_time = time_keys[time_keys.index(start_time) - 1]
931
+ # End time will be the one time key "later"
932
+ end_time = reversed_time_keys[
933
+ reversed_time_keys.index(start_time) - 1
934
+ ]
879
935
  process_dict["end"] = end_time
880
936
 
881
937
  # Get soc
882
938
  soc_start = None
883
939
  soc_end = None
884
- for log in battery_log:
885
- if log.t == start_time:
886
- soc_start = log.energy / log.energy_real
887
- if log.t == process_dict["end"]:
888
- soc_end = log.energy / log.energy_real
940
+
941
+ for i in range(len(battery_log_list)):
942
+ log = battery_log_list[i]
943
+
944
+ if log[0] == start_time:
945
+ soc_start = log[1]
946
+ if log[0] == process_dict["end"]:
947
+ soc_end = log[1]
948
+ if log[0] < start_time < battery_log_list[i + 1][0]:
949
+ soc_start = log[1]
950
+ if (
951
+ log[0]
952
+ < process_dict["end"]
953
+ < battery_log_list[i + 1][0]
954
+ ):
955
+ soc_end = log[1]
889
956
 
890
957
  current_event = Event(
891
958
  scenario=scenario,
@@ -911,18 +978,15 @@ def add_evaluation_to_database(
911
978
  timeseries=None,
912
979
  )
913
980
  session.add(current_event)
914
- list_of_events_per_vehicle.append(current_event)
915
-
916
- list_of_events.extend(list_of_events_per_vehicle)
917
981
 
918
982
  # For non-copy schedules with no predecessor events, adding a dummy standby-departure
919
983
  if (
920
- dict_of_events[time_keys[-1]]["type"] == "trip"
921
- and dict_of_events[time_keys[-1]]["is_copy"] is False
984
+ dict_of_events[reversed_time_keys[-1]]["type"] == "trip"
985
+ and dict_of_events[reversed_time_keys[-1]]["is_copy"] is False
922
986
  ):
923
- standby_start = time_keys[-1] - 1
924
- standby_end = time_keys[-1]
925
- rotation_id = str(dict_of_events[time_keys[-1]]["id"])
987
+ standby_start = reversed_time_keys[-1] - 1
988
+ standby_end = reversed_time_keys[-1]
989
+ rotation_id = str(dict_of_events[reversed_time_keys[-1]]["id"])
926
990
  area = (
927
991
  session.query(Area)
928
992
  .filter(Area.vehicle_type_id == vehicle_type_id)
@@ -961,49 +1025,15 @@ def add_evaluation_to_database(
961
1025
  timeseries=None,
962
1026
  )
963
1027
 
964
- list_of_events.append(standby_event)
965
-
966
- new_old_vehicle = {}
967
- matched_vehicle_id = 0
968
- for schedule_id, vehicle_id in list_of_assigned_schedules:
969
- if vehicle_id != matched_vehicle_id:
970
- matched_vehicle_id = vehicle_id
971
- # Get rotation from db with id
972
- rotation_q = session.query(Rotation).filter(Rotation.id == schedule_id)
973
- # Match old and new vehicle id
974
- old_vehicle_id = rotation_q.one().vehicle_id
975
- new_old_vehicle[vehicle_id] = old_vehicle_id
1028
+ session.add(standby_event)
976
1029
 
977
1030
  # New rotation assignment
978
-
979
1031
  for schedule_id, vehicle_id in list_of_assigned_schedules:
980
1032
  # Get corresponding old vehicle id
981
- old_vehicle_id = new_old_vehicle[vehicle_id]
982
1033
  session.query(Rotation).filter(Rotation.id == schedule_id).update(
983
- {"vehicle_id": old_vehicle_id}, synchronize_session="auto"
1034
+ {"vehicle_id": vehicle_id}, synchronize_session="auto"
984
1035
  )
985
1036
 
986
- # Delete all non-depot events
987
- session.query(Event).filter(
988
- Event.scenario == scenario,
989
- Event.trip_id.isnot(None) | Event.station_id.isnot(None),
990
- ).delete()
991
-
992
- session.flush()
993
-
994
- # Update depot events with old vehicle id
995
- for new_vehicle_id, old_vehicle_id in new_old_vehicle.items():
996
- session.query(Event).filter(
997
- Event.scenario == scenario,
998
- Event.vehicle_id == new_vehicle_id,
999
- ).update({"vehicle_id": old_vehicle_id}, synchronize_session="auto")
1000
-
1001
- session.query(Vehicle).filter(
1002
- Vehicle.id == new_vehicle_id,
1003
- ).delete(synchronize_session="auto")
1004
-
1005
- session.flush()
1006
-
1007
1037
  # Delete all non-depot events
1008
1038
  session.query(Event).filter(
1009
1039
  Event.scenario == scenario,
@@ -1013,7 +1043,6 @@ def add_evaluation_to_database(
1013
1043
  session.flush()
1014
1044
 
1015
1045
  # Delete all vehicles without rotations
1016
-
1017
1046
  vehicle_assigned_sq = (
1018
1047
  session.query(Rotation.vehicle_id)
1019
1048
  .filter(Rotation.scenario == scenario)
@@ -302,10 +302,13 @@ def create_simple_depot(
302
302
  It has one area for each vehicle type and a charging process for each
303
303
  area. Also an arrival area for each vehicle type.
304
304
 
305
- :param scenario:
306
- :param station:
307
- :param vehicle_type_dict:
308
- :param session:
305
+ :param scenario: The scenario to be simulated
306
+ :param station: The station where the depot is located
307
+ :param charging_capacities: A dictionary of vehicle types and the number of vehicles that can be charged at the same time
308
+ :param cleaning_capacities: A dictionary of vehicle types and the number of vehicles that can be cleaned at the same time
309
+ :param charging_power: The power of the charging process
310
+ :param cleaning_duration: The duration of the cleaning process
311
+ :param session: An SQLAlchemy session object to the database
309
312
  :return: Nothing. Depots are created in the database.
310
313
  """
311
314
 
@@ -354,19 +357,8 @@ def create_simple_depot(
354
357
 
355
358
  for vehicle_type in charging_capacities.keys():
356
359
  charging_count = charging_capacities[vehicle_type]
357
- # Add a safety margin of 20% to the parking capacity
358
- charging_count = int(ceil(charging_count * 1.2))
359
-
360
- # Create stand by arrival area
361
- arrival_area = Area(
362
- scenario=scenario,
363
- name=f"Arrival for {vehicle_type.name_short}",
364
- depot=depot,
365
- area_type=AreaType.DIRECT_ONESIDE,
366
- capacity=charging_count,
367
- )
368
- session.add(arrival_area)
369
- arrival_area.vehicle_type = vehicle_type
360
+ # Add a safety margin of 100% to the parking capacity
361
+ charging_count = int(ceil(charging_count * 2))
370
362
 
371
363
  # Create charging area
372
364
  charging_area = Area(
@@ -381,8 +373,8 @@ def create_simple_depot(
381
373
 
382
374
  # Create cleaning area
383
375
  cleaning_count = cleaning_capacities[vehicle_type]
384
- # Add a safety margin of 20% to the parking capacity
385
- cleaning_count = int(ceil(cleaning_count * 1.2))
376
+ # Add a safety margin of 100% to the parking capacity
377
+ cleaning_count = int(ceil(cleaning_count * 2))
386
378
 
387
379
  cleaning_area = Area(
388
380
  scenario=scenario,
@@ -394,6 +386,18 @@ def create_simple_depot(
394
386
  session.add(cleaning_area)
395
387
  cleaning_area.vehicle_type = vehicle_type
396
388
 
389
+ # Create stand by arrival area
390
+ arrival_area = Area(
391
+ scenario=scenario,
392
+ name=f"Arrival for {vehicle_type.name_short}",
393
+ depot=depot,
394
+ area_type=AreaType.DIRECT_ONESIDE,
395
+ capacity=(charging_count + cleaning_count)
396
+ * 2, # SHould be huge, not all of it will be used
397
+ )
398
+ session.add(arrival_area)
399
+ arrival_area.vehicle_type = vehicle_type
400
+
397
401
  arrival_area.processes.append(standby_arrival)
398
402
  cleaning_area.processes.append(clean)
399
403
  charging_area.processes.append(charging)
@@ -1,4 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
+ import warnings
3
+
2
4
  import eflips
3
5
  from eflips.settings import globalConstants
4
6
  from eflips.helperFunctions import flexprint
@@ -248,6 +250,18 @@ class VehicleFilter:
248
250
  required_energy = (
249
251
  self.trip.start_soc - self.trip.end_soc
250
252
  ) * vehicle.battery.energy_real
253
+
254
+ # If the vehicle is fully charged and its fully charged energy is still lower than the required energy,
255
+ # dispatch anyway and warn the user
256
+ if (
257
+ abs(vehicle.battery.soc - 1) < 1e-6
258
+ and vehicle.battery.energy_real < required_energy
259
+ ):
260
+ warnings.warn(
261
+ f"Vehicle {vehicle.ID} is fully charged but the required energy for the trip is higher than the fully charged energy. Dispatching anyway."
262
+ )
263
+ return True
264
+
251
265
  result = required_energy <= vehicle.battery.energy_remaining
252
266
 
253
267
  else:
@@ -1,20 +1,22 @@
1
1
  [tool.poetry]
2
2
  name = "eflips-depot"
3
- version = "3.0.2"
3
+ version = "3.0.4"
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",
7
7
  "Shuyao Guo <shuyao.guo@tu-berlin.de"]
8
- license = "AGPLv3"
8
+ license = "AGPL-3.0-or-later"
9
9
  readme = "README.md"
10
+ homepage = "https://github.com/mpm-tu-berlin/eflips-depot"
11
+ repository = "https://github.com/mpm-tu-berlin/eflips-depot"
10
12
  packages = [{ include = "eflips/depot" }]
11
13
 
12
14
  [tool.poetry.dependencies]
13
15
  python = "^3.10"
14
16
  simpy = "^4.0.1"
15
- eflips-model = "^3.1.0"
17
+ eflips-model = "^3.2.0"
16
18
  # Legacy dependencies, which are still needed until we refactor the code
17
- eflips = "^0.1.1"
19
+ eflips = "^0.1.3"
18
20
  xlsxwriter = "^3.1.9"
19
21
  pandas = "^2.1.4"
20
22
  xlrd = "<=1.2.0"
Binary file
File without changes
File without changes