eflips-depot 3.0.2__tar.gz → 3.0.3__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.3}/PKG-INFO +3 -3
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/api/__init__.py +88 -51
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/api/private/depot.py +23 -19
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/filters.py +14 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/pyproject.toml +3 -3
- 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.3}/LICENSE.md +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/README.md +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/__init__.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/api/defaults/default_settings.json +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/api/private/__init__.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/api/private/util.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/configuration.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/depot.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/evaluation.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/input_epex_power_price.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/layout_opt/__init__.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/layout_opt/doc/__init__.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/layout_opt/doc/direct_details.pdf +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/layout_opt/evaluation.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/layout_opt/opt_tools/__init__.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/layout_opt/opt_tools/crossover.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/layout_opt/opt_tools/fitness_c_urfd.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/layout_opt/opt_tools/fitness_util.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/layout_opt/opt_tools/init.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/layout_opt/opt_tools/mutation.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/layout_opt/optimize_c_urfd.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/layout_opt/packing.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/layout_opt/settings.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/layout_opt/template_creation.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/layout_opt/util.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/plots.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/processes.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/rating.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/resources.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/settings_config.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/simple_vehicle.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/simulation.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/smart_charging.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/standalone.py +0 -0
- {eflips_depot-3.0.2 → eflips_depot-3.0.3}/eflips/depot/validation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: eflips-depot
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.3
|
|
4
4
|
Summary: Depot Simulation for eFLIPS
|
|
5
5
|
License: AGPLv3
|
|
6
6
|
Author: Enrico Lauth
|
|
@@ -11,8 +11,8 @@ Classifier: Programming Language :: Python :: 3
|
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
-
Requires-Dist: eflips (>=0.1.
|
|
15
|
-
Requires-Dist: eflips-model (>=3.
|
|
14
|
+
Requires-Dist: eflips (>=0.1.3,<0.2.0)
|
|
15
|
+
Requires-Dist: eflips-model (>=3.2.0,<4.0.0)
|
|
16
16
|
Requires-Dist: pandas (>=2.1.4,<3.0.0)
|
|
17
17
|
Requires-Dist: simpy (>=4.0.1,<5.0.0)
|
|
18
18
|
Requires-Dist: xlrd (<=1.2.0)
|
|
@@ -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
|
|
@@ -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][
|
|
@@ -684,6 +689,7 @@ def add_evaluation_to_database(
|
|
|
684
689
|
|
|
685
690
|
dict_of_events = {}
|
|
686
691
|
|
|
692
|
+
# Generate process log for each schedule
|
|
687
693
|
for finished_trip in current_vehicle.finished_trips:
|
|
688
694
|
dict_of_events[finished_trip.atd] = {
|
|
689
695
|
"type": "trip",
|
|
@@ -710,6 +716,57 @@ def add_evaluation_to_database(
|
|
|
710
716
|
waiting_log = current_vehicle.logger.loggedData["area_waiting_time"]
|
|
711
717
|
battery_log = current_vehicle.battery_logs
|
|
712
718
|
|
|
719
|
+
# Create standby events according to waiting_log
|
|
720
|
+
waiting_log_timekeys = sorted(waiting_log.keys())
|
|
721
|
+
|
|
722
|
+
for idx in range(len(waiting_log_timekeys)):
|
|
723
|
+
end_time = waiting_log_timekeys[idx]
|
|
724
|
+
waiting_info = waiting_log[end_time]
|
|
725
|
+
|
|
726
|
+
if waiting_info["waiting_time"] == 0:
|
|
727
|
+
continue
|
|
728
|
+
|
|
729
|
+
# Vehicle is waiting in the last area in waiting_log and expecting to enter the current area
|
|
730
|
+
expected_area = waiting_info["area"]
|
|
731
|
+
# Find the area for standby arrival event
|
|
732
|
+
|
|
733
|
+
waiting_area_id = (
|
|
734
|
+
session.query(Area.id)
|
|
735
|
+
.join(AssocAreaProcess, AssocAreaProcess.area_id == Area.id)
|
|
736
|
+
.join(Process, Process.id == AssocAreaProcess.process_id)
|
|
737
|
+
.filter(
|
|
738
|
+
Process.dispatchable == False,
|
|
739
|
+
Process.duration.is_(None),
|
|
740
|
+
Process.electric_power.is_(None),
|
|
741
|
+
Area.vehicle_type_id == int(current_vehicle.vehicle_type.ID),
|
|
742
|
+
Area.scenario_id == scenario.id,
|
|
743
|
+
)
|
|
744
|
+
.one()[0]
|
|
745
|
+
)
|
|
746
|
+
|
|
747
|
+
# Make sure the vehicle is waiting at an area with enough capacity
|
|
748
|
+
|
|
749
|
+
current_slot = slot_log[waiting_log_timekeys[idx - 1]]
|
|
750
|
+
|
|
751
|
+
start_time = end_time - waiting_info["waiting_time"]
|
|
752
|
+
|
|
753
|
+
warnings.warn(
|
|
754
|
+
f"Vehicle {current_vehicle.ID} is waiting at {waiting_area_id} because area {expected_area} is full."
|
|
755
|
+
)
|
|
756
|
+
|
|
757
|
+
dict_of_events[start_time] = {
|
|
758
|
+
"type": "Standby",
|
|
759
|
+
"end": end_time,
|
|
760
|
+
"area": waiting_area_id,
|
|
761
|
+
"slot": current_slot,
|
|
762
|
+
"is_area_sink": waiting_area_id,
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
# Create a list of battery log in order of time asc. Convenient for looking up corresponding soc
|
|
766
|
+
battery_log_list = []
|
|
767
|
+
for log in battery_log:
|
|
768
|
+
battery_log_list.append((log.t, log.energy / log.energy_real))
|
|
769
|
+
|
|
713
770
|
for start_time, process_log in current_vehicle.logger.loggedData[
|
|
714
771
|
"dwd.active_processes_copy"
|
|
715
772
|
].items():
|
|
@@ -843,11 +900,11 @@ def add_evaluation_to_database(
|
|
|
843
900
|
f"Invalid process status {process.status} for process {process.ID}."
|
|
844
901
|
)
|
|
845
902
|
|
|
846
|
-
|
|
847
|
-
if len(
|
|
903
|
+
reversed_time_keys = sorted(dict_of_events.keys(), reverse=True)
|
|
904
|
+
if len(reversed_time_keys) != 0:
|
|
848
905
|
# Generating valid event-list
|
|
849
906
|
is_copy = True
|
|
850
|
-
for start_time in
|
|
907
|
+
for start_time in reversed_time_keys:
|
|
851
908
|
process_dict = dict_of_events[start_time]
|
|
852
909
|
if process_dict["type"] == "trip":
|
|
853
910
|
is_copy = process_dict["is_copy"]
|
|
@@ -875,17 +932,31 @@ def add_evaluation_to_database(
|
|
|
875
932
|
# End time of 0-duration processes are start time of the next process
|
|
876
933
|
|
|
877
934
|
if "end" not in process_dict:
|
|
878
|
-
|
|
935
|
+
# End time will be the one time key "later"
|
|
936
|
+
end_time = reversed_time_keys[
|
|
937
|
+
reversed_time_keys.index(start_time) - 1
|
|
938
|
+
]
|
|
879
939
|
process_dict["end"] = end_time
|
|
880
940
|
|
|
881
941
|
# Get soc
|
|
882
942
|
soc_start = None
|
|
883
943
|
soc_end = None
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
944
|
+
|
|
945
|
+
for i in range(len(battery_log_list)):
|
|
946
|
+
log = battery_log_list[i]
|
|
947
|
+
|
|
948
|
+
if log[0] == start_time:
|
|
949
|
+
soc_start = log[1]
|
|
950
|
+
if log[0] == process_dict["end"]:
|
|
951
|
+
soc_end = log[1]
|
|
952
|
+
if log[0] < start_time < battery_log_list[i + 1][0]:
|
|
953
|
+
soc_start = log[1]
|
|
954
|
+
if (
|
|
955
|
+
log[0]
|
|
956
|
+
< process_dict["end"]
|
|
957
|
+
< battery_log_list[i + 1][0]
|
|
958
|
+
):
|
|
959
|
+
soc_end = log[1]
|
|
889
960
|
|
|
890
961
|
current_event = Event(
|
|
891
962
|
scenario=scenario,
|
|
@@ -917,12 +988,12 @@ def add_evaluation_to_database(
|
|
|
917
988
|
|
|
918
989
|
# For non-copy schedules with no predecessor events, adding a dummy standby-departure
|
|
919
990
|
if (
|
|
920
|
-
dict_of_events[
|
|
921
|
-
and dict_of_events[
|
|
991
|
+
dict_of_events[reversed_time_keys[-1]]["type"] == "trip"
|
|
992
|
+
and dict_of_events[reversed_time_keys[-1]]["is_copy"] is False
|
|
922
993
|
):
|
|
923
|
-
standby_start =
|
|
924
|
-
standby_end =
|
|
925
|
-
rotation_id = str(dict_of_events[
|
|
994
|
+
standby_start = reversed_time_keys[-1] - 1
|
|
995
|
+
standby_end = reversed_time_keys[-1]
|
|
996
|
+
rotation_id = str(dict_of_events[reversed_time_keys[-1]]["id"])
|
|
926
997
|
area = (
|
|
927
998
|
session.query(Area)
|
|
928
999
|
.filter(Area.vehicle_type_id == vehicle_type_id)
|
|
@@ -961,49 +1032,16 @@ def add_evaluation_to_database(
|
|
|
961
1032
|
timeseries=None,
|
|
962
1033
|
)
|
|
963
1034
|
|
|
1035
|
+
session.add(standby_event)
|
|
964
1036
|
list_of_events.append(standby_event)
|
|
965
1037
|
|
|
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
|
|
976
|
-
|
|
977
1038
|
# New rotation assignment
|
|
978
|
-
|
|
979
1039
|
for schedule_id, vehicle_id in list_of_assigned_schedules:
|
|
980
1040
|
# Get corresponding old vehicle id
|
|
981
|
-
old_vehicle_id = new_old_vehicle[vehicle_id]
|
|
982
1041
|
session.query(Rotation).filter(Rotation.id == schedule_id).update(
|
|
983
|
-
{"vehicle_id":
|
|
1042
|
+
{"vehicle_id": vehicle_id}, synchronize_session="auto"
|
|
984
1043
|
)
|
|
985
1044
|
|
|
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
1045
|
# Delete all non-depot events
|
|
1008
1046
|
session.query(Event).filter(
|
|
1009
1047
|
Event.scenario == scenario,
|
|
@@ -1013,7 +1051,6 @@ def add_evaluation_to_database(
|
|
|
1013
1051
|
session.flush()
|
|
1014
1052
|
|
|
1015
1053
|
# Delete all vehicles without rotations
|
|
1016
|
-
|
|
1017
1054
|
vehicle_assigned_sq = (
|
|
1018
1055
|
session.query(Rotation.vehicle_id)
|
|
1019
1056
|
.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,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "eflips-depot"
|
|
3
|
-
version = "3.0.
|
|
3
|
+
version = "3.0.3"
|
|
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",
|
|
@@ -12,9 +12,9 @@ packages = [{ include = "eflips/depot" }]
|
|
|
12
12
|
[tool.poetry.dependencies]
|
|
13
13
|
python = "^3.10"
|
|
14
14
|
simpy = "^4.0.1"
|
|
15
|
-
eflips-model = "^3.
|
|
15
|
+
eflips-model = "^3.2.0"
|
|
16
16
|
# Legacy dependencies, which are still needed until we refactor the code
|
|
17
|
-
eflips = "^0.1.
|
|
17
|
+
eflips = "^0.1.3"
|
|
18
18
|
xlsxwriter = "^3.1.9"
|
|
19
19
|
pandas = "^2.1.4"
|
|
20
20
|
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.3}/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
|