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.
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/PKG-INFO +7 -5
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/api/__init__.py +89 -60
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/api/private/depot.py +23 -19
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/filters.py +14 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/pyproject.toml +6 -4
- eflips_depot-3.0.2/eflips/depot/.DS_Store +0 -0
- eflips_depot-3.0.2/eflips/depot/api/__pycache__/__init__.cpython-311.pyc +0 -0
- eflips_depot-3.0.2/eflips/depot/api/__pycache__/__init__.cpython-312.pyc +0 -0
- eflips_depot-3.0.2/eflips/depot/api/private/__pycache__/__init__.cpython-312.pyc +0 -0
- eflips_depot-3.0.2/eflips/depot/api/private/__pycache__/depot.cpython-312.pyc +0 -0
- eflips_depot-3.0.2/eflips/depot/api/private/__pycache__/depot_layout.cpython-312.pyc +0 -0
- eflips_depot-3.0.2/eflips/depot/api/private/__pycache__/util.cpython-312.pyc +0 -0
- eflips_depot-3.0.2/eflips/depot/layout_opt/__pycache__/__init__.cpython-311.pyc +0 -0
- eflips_depot-3.0.2/eflips/depot/layout_opt/__pycache__/__init__.cpython-312.pyc +0 -0
- eflips_depot-3.0.2/eflips/depot/layout_opt/__pycache__/evaluation.cpython-311.pyc +0 -0
- eflips_depot-3.0.2/eflips/depot/layout_opt/__pycache__/packing.cpython-311.pyc +0 -0
- eflips_depot-3.0.2/eflips/depot/layout_opt/__pycache__/settings.cpython-311.pyc +0 -0
- eflips_depot-3.0.2/eflips/depot/layout_opt/__pycache__/util.cpython-311.pyc +0 -0
- eflips_depot-3.0.2/eflips/depot/layout_opt/opt_tools/__pycache__/__init__.cpython-311.pyc +0 -0
- eflips_depot-3.0.2/eflips/depot/layout_opt/opt_tools/__pycache__/crossover.cpython-311.pyc +0 -0
- eflips_depot-3.0.2/eflips/depot/layout_opt/opt_tools/__pycache__/fitness_c_urfd.cpython-311.pyc +0 -0
- eflips_depot-3.0.2/eflips/depot/layout_opt/opt_tools/__pycache__/fitness_util.cpython-311.pyc +0 -0
- eflips_depot-3.0.2/eflips/depot/layout_opt/opt_tools/__pycache__/init.cpython-311.pyc +0 -0
- eflips_depot-3.0.2/eflips/depot/layout_opt/opt_tools/__pycache__/mutation.cpython-311.pyc +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/LICENSE.md +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/README.md +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/__init__.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/api/defaults/default_settings.json +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/api/private/__init__.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/api/private/util.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/configuration.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/depot.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/evaluation.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/input_epex_power_price.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/__init__.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/doc/__init__.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/doc/direct_details.pdf +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/evaluation.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/opt_tools/__init__.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/opt_tools/crossover.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/opt_tools/fitness_c_urfd.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/opt_tools/fitness_util.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/opt_tools/init.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/opt_tools/mutation.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/optimize_c_urfd.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/packing.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/settings.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/template_creation.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/util.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/plots.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/processes.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/rating.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/resources.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/settings_config.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/simple_vehicle.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/simulation.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/smart_charging.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/standalone.py +0 -0
- {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.
|
|
3
|
+
Version: 3.0.4
|
|
4
4
|
Summary: Depot Simulation for eFLIPS
|
|
5
|
-
|
|
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 ::
|
|
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.
|
|
15
|
-
Requires-Dist: eflips-model (>=3.
|
|
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
|
[](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
|
|
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,
|
|
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
|
-
|
|
847
|
-
if len(
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
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[
|
|
921
|
-
and dict_of_events[
|
|
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 =
|
|
924
|
-
standby_end =
|
|
925
|
-
rotation_id = str(dict_of_events[
|
|
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
|
-
|
|
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":
|
|
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
|
|
308
|
-
:param
|
|
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
|
|
358
|
-
charging_count = int(ceil(charging_count *
|
|
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
|
|
385
|
-
cleaning_count = int(ceil(cleaning_count *
|
|
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.
|
|
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 = "
|
|
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.
|
|
17
|
+
eflips-model = "^3.2.0"
|
|
16
18
|
# Legacy dependencies, which are still needed until we refactor the code
|
|
17
|
-
eflips = "^0.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
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
eflips_depot-3.0.2/eflips/depot/layout_opt/opt_tools/__pycache__/fitness_c_urfd.cpython-311.pyc
DELETED
|
Binary file
|
eflips_depot-3.0.2/eflips/depot/layout_opt/opt_tools/__pycache__/fitness_util.cpython-311.pyc
DELETED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{eflips_depot-3.0.2 → eflips_depot-3.0.4}/eflips/depot/layout_opt/opt_tools/fitness_c_urfd.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|