eflips-depot 3.0.4__tar.gz → 3.0.5__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.4 → eflips_depot-3.0.5}/PKG-INFO +2 -2
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/README.md +1 -1
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/api/__init__.py +277 -241
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/api/private/util.py +12 -12
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/pyproject.toml +1 -1
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/LICENSE.md +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/__init__.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/api/defaults/default_settings.json +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/api/private/__init__.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/api/private/depot.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/configuration.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/depot.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/evaluation.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/filters.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/input_epex_power_price.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/layout_opt/__init__.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/layout_opt/doc/__init__.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/layout_opt/doc/direct_details.pdf +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/layout_opt/evaluation.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/layout_opt/opt_tools/__init__.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/layout_opt/opt_tools/crossover.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/layout_opt/opt_tools/fitness_c_urfd.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/layout_opt/opt_tools/fitness_util.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/layout_opt/opt_tools/init.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/layout_opt/opt_tools/mutation.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/layout_opt/optimize_c_urfd.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/layout_opt/packing.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/layout_opt/settings.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/layout_opt/template_creation.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/layout_opt/util.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/plots.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/processes.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/rating.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/resources.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/settings_config.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/simple_vehicle.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/simulation.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/smart_charging.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/eflips/depot/standalone.py +0 -0
- {eflips_depot-3.0.4 → eflips_depot-3.0.5}/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.5
|
|
4
4
|
Summary: Depot Simulation for eFLIPS
|
|
5
5
|
Home-page: https://github.com/mpm-tu-berlin/eflips-depot
|
|
6
6
|
License: AGPL-3.0-or-later
|
|
@@ -21,7 +21,7 @@ Requires-Dist: xlsxwriter (>=3.1.9,<4.0.0)
|
|
|
21
21
|
Project-URL: Repository, https://github.com/mpm-tu-berlin/eflips-depot
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
|
|
24
|
-
[](https://github.com/mpm-tu-berlin/eflips-depot/actions/workflows/unittests.yml)
|
|
25
25
|
[](https://github.com/psf/black)
|
|
26
26
|
|
|
27
27
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[](https://github.com/mpm-tu-berlin/eflips-depot/actions/workflows/unittests.yml)
|
|
2
2
|
[](https://github.com/psf/black)
|
|
3
3
|
|
|
4
4
|
|
|
@@ -663,8 +663,6 @@ def add_evaluation_to_database(
|
|
|
663
663
|
|
|
664
664
|
# Initialization of empty lists
|
|
665
665
|
|
|
666
|
-
list_of_vehicles = []
|
|
667
|
-
|
|
668
666
|
list_of_assigned_schedules = []
|
|
669
667
|
|
|
670
668
|
# Read results from depot_evaluation categorized by vehicle
|
|
@@ -681,26 +679,56 @@ def add_evaluation_to_database(
|
|
|
681
679
|
# Flush the vehicle object to get the vehicle id
|
|
682
680
|
session.add(current_vehicle_db)
|
|
683
681
|
session.flush()
|
|
684
|
-
list_of_vehicles.append(current_vehicle_db)
|
|
685
682
|
|
|
686
683
|
dict_of_events = {}
|
|
687
684
|
|
|
688
|
-
# Generate process log for each
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
685
|
+
# Generate process log for each
|
|
686
|
+
list_of_finished_trips = current_vehicle.finished_trips
|
|
687
|
+
list_of_finished_trips.sort(key=lambda x: x.atd)
|
|
688
|
+
|
|
689
|
+
for i in range(len(list_of_finished_trips)):
|
|
690
|
+
if list_of_finished_trips[i].is_copy is False:
|
|
691
|
+
current_trip = list_of_finished_trips[i]
|
|
692
|
+
|
|
693
|
+
# Add all non-copy trips to the dictionary
|
|
694
|
+
dict_of_events[current_trip.atd] = {
|
|
695
|
+
"type": "Trip",
|
|
696
|
+
"end": current_trip.ata,
|
|
697
|
+
"is_copy": current_trip.is_copy,
|
|
698
|
+
"id": current_trip.ID,
|
|
699
|
+
}
|
|
695
700
|
|
|
696
|
-
|
|
697
|
-
assigned_schedule_id = int(
|
|
701
|
+
# Match current trip to its serving vehicle
|
|
702
|
+
assigned_schedule_id = int(current_trip.ID)
|
|
698
703
|
list_of_assigned_schedules.append(
|
|
699
704
|
(assigned_schedule_id, current_vehicle_db.id)
|
|
700
705
|
)
|
|
706
|
+
# Also add two copy trips before and after the non-copy trip as "time boarders" for the depot process
|
|
707
|
+
try:
|
|
708
|
+
if list_of_finished_trips[i + 1].is_copy is True:
|
|
709
|
+
dict_of_events[list_of_finished_trips[i + 1].atd] = {
|
|
710
|
+
"type": "Trip",
|
|
711
|
+
"end": list_of_finished_trips[i + 1].ata,
|
|
712
|
+
"is_copy": list_of_finished_trips[i + 1].is_copy,
|
|
713
|
+
"id": list_of_finished_trips[i + 1].ID,
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
if list_of_finished_trips[i - 1].is_copy is True:
|
|
717
|
+
dict_of_events[list_of_finished_trips[i - 1].atd] = {
|
|
718
|
+
"type": "Trip",
|
|
719
|
+
"end": list_of_finished_trips[i - 1].ata,
|
|
720
|
+
"is_copy": list_of_finished_trips[i - 1].is_copy,
|
|
721
|
+
"id": list_of_finished_trips[i - 1].ID,
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
except IndexError:
|
|
725
|
+
# In case there are no copy trips before or after the non-copy trip
|
|
726
|
+
continue
|
|
701
727
|
|
|
702
|
-
#
|
|
703
|
-
#
|
|
728
|
+
# The range of time of events to be generated. It is between the copy trip before the first non-copy trip and the
|
|
729
|
+
# copy trip after the last non-copy trip
|
|
730
|
+
earliest_time = sorted(dict_of_events.keys())[0]
|
|
731
|
+
latest_time = sorted(dict_of_events.keys())[-1]
|
|
704
732
|
|
|
705
733
|
last_standby_departure_start = 0
|
|
706
734
|
|
|
@@ -708,7 +736,6 @@ def add_evaluation_to_database(
|
|
|
708
736
|
area_log = current_vehicle.logger.loggedData["dwd.current_area"]
|
|
709
737
|
slot_log = current_vehicle.logger.loggedData["dwd.current_slot"]
|
|
710
738
|
|
|
711
|
-
# For future uses
|
|
712
739
|
waiting_log = current_vehicle.logger.loggedData["area_waiting_time"]
|
|
713
740
|
battery_log = current_vehicle.battery_logs
|
|
714
741
|
|
|
@@ -717,46 +744,52 @@ def add_evaluation_to_database(
|
|
|
717
744
|
|
|
718
745
|
for idx in range(len(waiting_log_timekeys)):
|
|
719
746
|
end_time = waiting_log_timekeys[idx]
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
Process.
|
|
737
|
-
|
|
738
|
-
|
|
747
|
+
|
|
748
|
+
# Only extract events if the time is within the upper mentioned range
|
|
749
|
+
|
|
750
|
+
if earliest_time < end_time < latest_time:
|
|
751
|
+
waiting_info = waiting_log[end_time]
|
|
752
|
+
|
|
753
|
+
if waiting_info["waiting_time"] == 0:
|
|
754
|
+
continue
|
|
755
|
+
|
|
756
|
+
# Vehicle is waiting in the last area in waiting_log and expecting to enter the current area
|
|
757
|
+
expected_area = waiting_info["area"]
|
|
758
|
+
# Find the area for standby arrival event
|
|
759
|
+
|
|
760
|
+
waiting_area_id = (
|
|
761
|
+
session.query(Area.id)
|
|
762
|
+
.join(AssocAreaProcess, AssocAreaProcess.area_id == Area.id)
|
|
763
|
+
.join(Process, Process.id == AssocAreaProcess.process_id)
|
|
764
|
+
.filter(
|
|
765
|
+
Process.dispatchable == False,
|
|
766
|
+
# Must use "==" instead of "is". Or it would be recongnize as a python statement rather than a SQL statement
|
|
767
|
+
Process.duration.is_(None),
|
|
768
|
+
Process.electric_power.is_(None),
|
|
769
|
+
Area.vehicle_type_id
|
|
770
|
+
== int(current_vehicle.vehicle_type.ID),
|
|
771
|
+
Area.scenario_id == scenario.id,
|
|
772
|
+
)
|
|
773
|
+
.one()[0]
|
|
739
774
|
)
|
|
740
|
-
.one()[0]
|
|
741
|
-
)
|
|
742
775
|
|
|
743
|
-
|
|
776
|
+
# Make sure the vehicle is waiting at an area with enough capacity
|
|
744
777
|
|
|
745
|
-
|
|
778
|
+
current_slot = slot_log[waiting_log_timekeys[idx - 1]]
|
|
746
779
|
|
|
747
|
-
|
|
780
|
+
start_time = end_time - waiting_info["waiting_time"]
|
|
748
781
|
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
782
|
+
warnings.warn(
|
|
783
|
+
f"Vehicle {current_vehicle.ID} is waiting at {waiting_area_id} because area {expected_area} is full."
|
|
784
|
+
)
|
|
752
785
|
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
786
|
+
dict_of_events[start_time] = {
|
|
787
|
+
"type": "Standby",
|
|
788
|
+
"end": end_time,
|
|
789
|
+
"area": waiting_area_id,
|
|
790
|
+
"slot": current_slot,
|
|
791
|
+
"is_area_sink": False,
|
|
792
|
+
}
|
|
760
793
|
|
|
761
794
|
# Create a list of battery log in order of time asc. Convenient for looking up corresponding soc
|
|
762
795
|
battery_log_list = []
|
|
@@ -766,227 +799,230 @@ def add_evaluation_to_database(
|
|
|
766
799
|
for start_time, process_log in current_vehicle.logger.loggedData[
|
|
767
800
|
"dwd.active_processes_copy"
|
|
768
801
|
].items():
|
|
769
|
-
if
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
802
|
+
if earliest_time < start_time < latest_time:
|
|
803
|
+
if len(process_log) == 0:
|
|
804
|
+
# A departure happens
|
|
805
|
+
if last_standby_departure_start != 0:
|
|
806
|
+
# Update the last standby-departure end time
|
|
807
|
+
dict_of_events[last_standby_departure_start][
|
|
808
|
+
"end"
|
|
809
|
+
] = start_time
|
|
810
|
+
else:
|
|
811
|
+
continue
|
|
776
812
|
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
current_area = area_log[start_time]
|
|
788
|
-
current_slot = slot_log[start_time]
|
|
789
|
-
|
|
790
|
-
if current_area is None or current_slot is None:
|
|
791
|
-
raise ValueError(
|
|
792
|
-
f"For process {process.ID} Area and slot should not be None."
|
|
813
|
+
else:
|
|
814
|
+
for process in process_log:
|
|
815
|
+
match process.status:
|
|
816
|
+
case ProcessStatus.COMPLETED | ProcessStatus.CANCELLED:
|
|
817
|
+
assert (
|
|
818
|
+
len(process.starts) == 1
|
|
819
|
+
and len(process.ends) == 1
|
|
820
|
+
), (
|
|
821
|
+
f"Current process {process.ID} is completed and should only contain one start and "
|
|
822
|
+
f"one end time."
|
|
793
823
|
)
|
|
824
|
+
current_area = area_log[start_time]
|
|
825
|
+
current_slot = slot_log[start_time]
|
|
794
826
|
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
}
|
|
804
|
-
else:
|
|
805
|
-
# Duration is 0
|
|
806
|
-
if current_area.issink is True:
|
|
807
|
-
# Standby departure
|
|
808
|
-
if start_time in dict_of_events:
|
|
809
|
-
# Actual start time should be the end time of the other positive duration
|
|
810
|
-
# process starting at the same time
|
|
811
|
-
actual_start_time = dict_of_events[
|
|
812
|
-
start_time
|
|
813
|
-
]["end"]
|
|
814
|
-
else:
|
|
815
|
-
for other_process in process_log:
|
|
816
|
-
if (
|
|
817
|
-
other_process.dur > 0
|
|
818
|
-
and len(other_process.ends) != 0
|
|
819
|
-
):
|
|
820
|
-
actual_start_time = (
|
|
821
|
-
other_process.ends[0]
|
|
822
|
-
)
|
|
823
|
-
else:
|
|
824
|
-
# Invalid standby before a process in progress will be ignored
|
|
825
|
-
continue
|
|
826
|
-
|
|
827
|
-
last_standby_departure_start = actual_start_time
|
|
828
|
-
|
|
829
|
-
# If this standby event lasts actually 0 seconds, it is not a real event
|
|
830
|
-
if (
|
|
831
|
-
actual_start_time in dict_of_events.keys()
|
|
832
|
-
and dict_of_events[actual_start_time][
|
|
833
|
-
"type"
|
|
834
|
-
]
|
|
835
|
-
== "trip"
|
|
836
|
-
):
|
|
837
|
-
continue
|
|
838
|
-
dict_of_events[actual_start_time] = {
|
|
827
|
+
if current_area is None or current_slot is None:
|
|
828
|
+
raise ValueError(
|
|
829
|
+
f"For process {process.ID} Area and slot should not be None."
|
|
830
|
+
)
|
|
831
|
+
|
|
832
|
+
if process.dur > 0:
|
|
833
|
+
# Valid duration
|
|
834
|
+
dict_of_events[start_time] = {
|
|
839
835
|
"type": type(process).__name__,
|
|
836
|
+
"end": process.ends[0],
|
|
840
837
|
"area": current_area.ID,
|
|
841
|
-
"is_area_sink": current_area.issink,
|
|
842
838
|
"slot": current_slot,
|
|
843
839
|
"id": process.ID,
|
|
844
840
|
}
|
|
845
|
-
|
|
846
841
|
else:
|
|
847
|
-
#
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
842
|
+
# Duration is 0
|
|
843
|
+
if current_area.issink is True:
|
|
844
|
+
# Standby departure
|
|
845
|
+
if start_time in dict_of_events:
|
|
846
|
+
# Actual start time should be the end time of the other positive
|
|
847
|
+
# duration process starting at the same time
|
|
848
|
+
actual_start_time = dict_of_events[
|
|
849
|
+
start_time
|
|
850
|
+
]["end"]
|
|
851
|
+
else:
|
|
852
|
+
for other_process in process_log:
|
|
853
|
+
if (
|
|
854
|
+
other_process.dur > 0
|
|
855
|
+
and len(other_process.ends) != 0
|
|
856
|
+
):
|
|
857
|
+
actual_start_time = (
|
|
858
|
+
other_process.ends[0]
|
|
859
|
+
)
|
|
860
|
+
else:
|
|
861
|
+
# Invalid standby before a process in progress will be ignored
|
|
862
|
+
continue
|
|
863
|
+
|
|
864
|
+
last_standby_departure_start = (
|
|
865
|
+
actual_start_time
|
|
866
|
+
)
|
|
867
|
+
|
|
868
|
+
# If this standby event lasts actually 0 seconds, it is not a real event
|
|
869
|
+
if (
|
|
870
|
+
actual_start_time
|
|
871
|
+
in dict_of_events.keys()
|
|
872
|
+
and dict_of_events[actual_start_time][
|
|
873
|
+
"type"
|
|
874
|
+
]
|
|
875
|
+
== "Trip"
|
|
876
|
+
):
|
|
877
|
+
continue
|
|
878
|
+
dict_of_events[actual_start_time] = {
|
|
879
|
+
"type": type(process).__name__,
|
|
880
|
+
"area": current_area.ID,
|
|
881
|
+
"is_area_sink": current_area.issink,
|
|
882
|
+
"slot": current_slot,
|
|
883
|
+
"id": process.ID,
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
else:
|
|
887
|
+
# Standby arrival
|
|
888
|
+
assert current_area.issink is False, (
|
|
889
|
+
f"A bus cannot go from Area {current_area.ID} to other areas. A Parking Area"
|
|
890
|
+
f" for standby arrival should be added."
|
|
891
|
+
)
|
|
892
|
+
dict_of_events[start_time] = {
|
|
893
|
+
"type": type(process).__name__,
|
|
894
|
+
"area": current_area.ID,
|
|
895
|
+
"is_area_sink": current_area.issink,
|
|
896
|
+
"slot": current_slot,
|
|
897
|
+
"id": process.ID,
|
|
898
|
+
}
|
|
899
|
+
case ProcessStatus.IN_PROGRESS:
|
|
900
|
+
assert (
|
|
901
|
+
len(process.starts) == 1
|
|
902
|
+
and len(process.ends) == 0
|
|
903
|
+
), f"Current process {process.ID} is marked IN_PROGRESS, but has an end."
|
|
904
|
+
current_area = area_log[start_time]
|
|
905
|
+
current_slot = slot_log[start_time]
|
|
906
|
+
|
|
907
|
+
if current_area is None or current_slot is None:
|
|
908
|
+
raise ValueError(
|
|
909
|
+
f"For process {process.ID} Area and slot should not be None."
|
|
851
910
|
)
|
|
911
|
+
|
|
912
|
+
if process.dur > 0:
|
|
913
|
+
# Valid duration
|
|
852
914
|
dict_of_events[start_time] = {
|
|
853
915
|
"type": type(process).__name__,
|
|
916
|
+
"end": process.etc,
|
|
854
917
|
"area": current_area.ID,
|
|
855
|
-
"is_area_sink": current_area.issink,
|
|
856
918
|
"slot": current_slot,
|
|
857
919
|
"id": process.ID,
|
|
858
920
|
}
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
if current_area is None or current_slot is None:
|
|
867
|
-
raise ValueError(
|
|
868
|
-
f"For process {process.ID} Area and slot should not be None."
|
|
921
|
+
else:
|
|
922
|
+
raise NotImplementedError(
|
|
923
|
+
"We believe this should never happen. If it happens, handle it here."
|
|
924
|
+
)
|
|
925
|
+
case ProcessStatus.WAITING:
|
|
926
|
+
raise NotImplementedError(
|
|
927
|
+
f"Current process {process.ID} is waiting. Not implemented yet."
|
|
869
928
|
)
|
|
870
929
|
|
|
871
|
-
|
|
872
|
-
# Valid duration
|
|
873
|
-
dict_of_events[start_time] = {
|
|
874
|
-
"type": type(process).__name__,
|
|
875
|
-
"end": process.etc,
|
|
876
|
-
"area": current_area.ID,
|
|
877
|
-
"slot": current_slot,
|
|
878
|
-
"id": process.ID,
|
|
879
|
-
}
|
|
880
|
-
else:
|
|
930
|
+
case ProcessStatus.NOT_STARTED:
|
|
881
931
|
raise NotImplementedError(
|
|
882
|
-
"
|
|
932
|
+
f"Current process {process.ID} is not started. Not implemented yet."
|
|
883
933
|
)
|
|
884
|
-
|
|
885
|
-
raise NotImplementedError(
|
|
886
|
-
f"Current process {process.ID} is waiting. Not implemented yet."
|
|
887
|
-
)
|
|
888
|
-
|
|
889
|
-
case ProcessStatus.NOT_STARTED:
|
|
890
|
-
raise NotImplementedError(
|
|
891
|
-
f"Current process {process.ID} is not started. Not implemented yet."
|
|
892
|
-
)
|
|
893
|
-
|
|
894
|
-
case _:
|
|
895
|
-
raise ValueError(
|
|
896
|
-
f"Invalid process status {process.status} for process {process.ID}."
|
|
897
|
-
)
|
|
898
|
-
|
|
899
|
-
reversed_time_keys = sorted(dict_of_events.keys(), reverse=True)
|
|
900
|
-
if len(reversed_time_keys) != 0:
|
|
901
|
-
# Generating valid event-list
|
|
902
|
-
is_copy = True
|
|
903
|
-
for start_time in reversed_time_keys:
|
|
904
|
-
process_dict = dict_of_events[start_time]
|
|
905
|
-
if process_dict["type"] == "trip":
|
|
906
|
-
is_copy = process_dict["is_copy"]
|
|
907
|
-
else:
|
|
908
|
-
if is_copy is False:
|
|
909
|
-
# Generate EventType
|
|
910
|
-
match process_dict["type"]:
|
|
911
|
-
case "Serve":
|
|
912
|
-
event_type = EventType.SERVICE
|
|
913
|
-
case "Charge":
|
|
914
|
-
event_type = EventType.CHARGING_DEPOT
|
|
915
|
-
case "Standby":
|
|
916
|
-
if process_dict["is_area_sink"] is True:
|
|
917
|
-
event_type = EventType.STANDBY_DEPARTURE
|
|
918
|
-
else:
|
|
919
|
-
event_type = EventType.STANDBY
|
|
920
|
-
case "Precondition":
|
|
921
|
-
event_type = EventType.PRECONDITIONING
|
|
934
|
+
|
|
922
935
|
case _:
|
|
923
936
|
raise ValueError(
|
|
924
|
-
|
|
925
|
-
'"Standby", "Precondition"'
|
|
937
|
+
f"Invalid process status {process.status} for process {process.ID}."
|
|
926
938
|
)
|
|
927
939
|
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
soc_end = log[1]
|
|
956
|
-
|
|
957
|
-
current_event = Event(
|
|
958
|
-
scenario=scenario,
|
|
959
|
-
vehicle_type_id=vehicle_type_id,
|
|
960
|
-
vehicle=current_vehicle_db,
|
|
961
|
-
station_id=None,
|
|
962
|
-
area_id=int(process_dict["area"]),
|
|
963
|
-
subloc_no=int(process_dict["slot"]),
|
|
964
|
-
trip_id=None,
|
|
965
|
-
time_start=timedelta(seconds=start_time)
|
|
966
|
-
+ simulation_start_time,
|
|
967
|
-
time_end=timedelta(seconds=process_dict["end"])
|
|
968
|
-
+ simulation_start_time,
|
|
969
|
-
soc_start=soc_start
|
|
970
|
-
if soc_start is not None
|
|
971
|
-
else soc_end,
|
|
972
|
-
soc_end=soc_end
|
|
973
|
-
if soc_end is not None
|
|
974
|
-
else soc_start, # if only one battery log is found,
|
|
975
|
-
# then this is not an event with soc change
|
|
976
|
-
event_type=event_type,
|
|
977
|
-
description=None,
|
|
978
|
-
timeseries=None,
|
|
940
|
+
# Reverse the time keys to make generation of events before the trip easier
|
|
941
|
+
time_keys = sorted(dict_of_events.keys())
|
|
942
|
+
if len(time_keys) != 0:
|
|
943
|
+
# Generating valid event-list
|
|
944
|
+
|
|
945
|
+
for start_time in time_keys:
|
|
946
|
+
process_dict = dict_of_events[start_time]
|
|
947
|
+
|
|
948
|
+
# Generate EventType
|
|
949
|
+
match process_dict["type"]:
|
|
950
|
+
case "Serve":
|
|
951
|
+
event_type = EventType.SERVICE
|
|
952
|
+
case "Charge":
|
|
953
|
+
event_type = EventType.CHARGING_DEPOT
|
|
954
|
+
case "Standby":
|
|
955
|
+
if process_dict["is_area_sink"] is True:
|
|
956
|
+
event_type = EventType.STANDBY_DEPARTURE
|
|
957
|
+
else:
|
|
958
|
+
event_type = EventType.STANDBY
|
|
959
|
+
case "Precondition":
|
|
960
|
+
event_type = EventType.PRECONDITIONING
|
|
961
|
+
case "Trip":
|
|
962
|
+
continue
|
|
963
|
+
case _:
|
|
964
|
+
raise ValueError(
|
|
965
|
+
'Invalid process type %s. Valid process types are "Serve", "Charge", '
|
|
966
|
+
'"Standby", "Precondition"'
|
|
979
967
|
)
|
|
980
|
-
|
|
968
|
+
|
|
969
|
+
# End time of 0-duration processes are start time of the next process
|
|
970
|
+
|
|
971
|
+
if "end" not in process_dict:
|
|
972
|
+
# End time will be the one time key "later"
|
|
973
|
+
end_time = time_keys[time_keys.index(start_time) + 1]
|
|
974
|
+
|
|
975
|
+
process_dict["end"] = end_time
|
|
976
|
+
|
|
977
|
+
# Get soc
|
|
978
|
+
soc_start = None
|
|
979
|
+
soc_end = None
|
|
980
|
+
|
|
981
|
+
for i in range(len(battery_log_list)):
|
|
982
|
+
# Access the correct battery log according to time since there is only one battery log for each time
|
|
983
|
+
log = battery_log_list[i]
|
|
984
|
+
|
|
985
|
+
if log[0] == start_time:
|
|
986
|
+
soc_start = log[1]
|
|
987
|
+
if log[0] == process_dict["end"]:
|
|
988
|
+
soc_end = log[1]
|
|
989
|
+
if log[0] < start_time < battery_log_list[i + 1][0]:
|
|
990
|
+
soc_start = log[1]
|
|
991
|
+
if log[0] < process_dict["end"] < battery_log_list[i + 1][0]:
|
|
992
|
+
soc_end = log[1]
|
|
993
|
+
|
|
994
|
+
current_event = Event(
|
|
995
|
+
scenario=scenario,
|
|
996
|
+
vehicle_type_id=vehicle_type_id,
|
|
997
|
+
vehicle=current_vehicle_db,
|
|
998
|
+
station_id=None,
|
|
999
|
+
area_id=int(process_dict["area"]),
|
|
1000
|
+
subloc_no=int(process_dict["slot"]),
|
|
1001
|
+
trip_id=None,
|
|
1002
|
+
time_start=timedelta(seconds=start_time)
|
|
1003
|
+
+ simulation_start_time,
|
|
1004
|
+
time_end=timedelta(seconds=process_dict["end"])
|
|
1005
|
+
+ simulation_start_time,
|
|
1006
|
+
soc_start=soc_start if soc_start is not None else soc_end,
|
|
1007
|
+
soc_end=soc_end
|
|
1008
|
+
if soc_end is not None
|
|
1009
|
+
else soc_start, # if only one battery log is found,
|
|
1010
|
+
# then this is not an event with soc change
|
|
1011
|
+
event_type=event_type,
|
|
1012
|
+
description=None,
|
|
1013
|
+
timeseries=None,
|
|
1014
|
+
)
|
|
1015
|
+
|
|
1016
|
+
session.add(current_event)
|
|
981
1017
|
|
|
982
1018
|
# For non-copy schedules with no predecessor events, adding a dummy standby-departure
|
|
983
1019
|
if (
|
|
984
|
-
dict_of_events[
|
|
985
|
-
and dict_of_events[
|
|
1020
|
+
dict_of_events[time_keys[0]]["type"] == "Trip"
|
|
1021
|
+
and dict_of_events[time_keys[0]]["is_copy"] is False
|
|
986
1022
|
):
|
|
987
|
-
standby_start =
|
|
988
|
-
standby_end =
|
|
989
|
-
rotation_id =
|
|
1023
|
+
standby_start = time_keys[0] - 1
|
|
1024
|
+
standby_end = time_keys[0]
|
|
1025
|
+
rotation_id = int(dict_of_events[time_keys[0]]["id"])
|
|
990
1026
|
area = (
|
|
991
1027
|
session.query(Area)
|
|
992
1028
|
.filter(Area.vehicle_type_id == vehicle_type_id)
|
|
@@ -340,18 +340,18 @@ class VehicleSchedule:
|
|
|
340
340
|
departure = int((self.departure - simulation_start_time).total_seconds())
|
|
341
341
|
arrival = int((self.arrival - simulation_start_time).total_seconds())
|
|
342
342
|
simple_trip = SimpleTrip(
|
|
343
|
-
env,
|
|
344
|
-
self.id,
|
|
345
|
-
None,
|
|
346
|
-
self.start_depot_id,
|
|
347
|
-
self.end_depot_id,
|
|
348
|
-
vehicle_types,
|
|
349
|
-
departure,
|
|
350
|
-
arrival,
|
|
351
|
-
None,
|
|
352
|
-
self.departure_soc,
|
|
353
|
-
self.arrival_soc,
|
|
354
|
-
self.opportunity_charging,
|
|
343
|
+
env=env,
|
|
344
|
+
ID=self.id,
|
|
345
|
+
line_name=None,
|
|
346
|
+
origin=self.start_depot_id,
|
|
347
|
+
destination=self.end_depot_id,
|
|
348
|
+
vehicle_types=vehicle_types,
|
|
349
|
+
std=departure,
|
|
350
|
+
sta=arrival,
|
|
351
|
+
distance=None,
|
|
352
|
+
start_soc=self.departure_soc,
|
|
353
|
+
end_soc=self.arrival_soc,
|
|
354
|
+
charge_on_track=self.opportunity_charging,
|
|
355
355
|
is_copy=self._is_copy,
|
|
356
356
|
)
|
|
357
357
|
return simple_trip
|
|
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.4 → eflips_depot-3.0.5}/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
|