eflips-depot 4.6.3__py3-none-any.whl → 4.6.5__py3-none-any.whl
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/api/__init__.py +15 -3
- eflips/depot/api/private/consumption.py +24 -30
- eflips/depot/api/private/depot.py +7 -1
- {eflips_depot-4.6.3.dist-info → eflips_depot-4.6.5.dist-info}/METADATA +2 -2
- {eflips_depot-4.6.3.dist-info → eflips_depot-4.6.5.dist-info}/RECORD +7 -7
- {eflips_depot-4.6.3.dist-info → eflips_depot-4.6.5.dist-info}/LICENSE.md +0 -0
- {eflips_depot-4.6.3.dist-info → eflips_depot-4.6.5.dist-info}/WHEEL +0 -0
eflips/depot/api/__init__.py
CHANGED
|
@@ -48,6 +48,7 @@ from eflips.model import (
|
|
|
48
48
|
VehicleType,
|
|
49
49
|
AreaType,
|
|
50
50
|
ChargeType,
|
|
51
|
+
Route,
|
|
51
52
|
)
|
|
52
53
|
from sqlalchemy.orm import Session
|
|
53
54
|
|
|
@@ -246,7 +247,11 @@ def simple_consumption_simulation(
|
|
|
246
247
|
session.query(Rotation)
|
|
247
248
|
.filter(Rotation.scenario_id == scenario.id)
|
|
248
249
|
.order_by(Rotation.id)
|
|
249
|
-
.options(
|
|
250
|
+
.options(
|
|
251
|
+
sqlalchemy.orm.joinedload(Rotation.trips)
|
|
252
|
+
.joinedload(Trip.route)
|
|
253
|
+
.joinedload(Route.arrival_station)
|
|
254
|
+
)
|
|
250
255
|
.options(sqlalchemy.orm.joinedload(Rotation.vehicle_type))
|
|
251
256
|
.options(sqlalchemy.orm.joinedload(Rotation.vehicle))
|
|
252
257
|
)
|
|
@@ -789,6 +794,10 @@ def init_simulation(
|
|
|
789
794
|
if "None" in vehicle_types_for_depot:
|
|
790
795
|
vehicle_types_for_depot.remove("None")
|
|
791
796
|
|
|
797
|
+
# In this case, all types are allowed
|
|
798
|
+
if len(vehicle_types_for_depot) == 0:
|
|
799
|
+
vehicle_types_for_depot = set([str(vt.id) for vt in scenario.vehicle_types])
|
|
800
|
+
|
|
792
801
|
# If we have a vehicle count dictionary, we validate and use ir
|
|
793
802
|
if vehicle_count_dict is not None and depot_id in vehicle_count_dict.keys():
|
|
794
803
|
if set(vehicle_count_dict[depot_id].keys()) < vehicle_types_for_depot:
|
|
@@ -804,8 +813,11 @@ def init_simulation(
|
|
|
804
813
|
for vehicle_type in vehicle_types_for_depot:
|
|
805
814
|
vehicle_count = 0
|
|
806
815
|
for area in depot.areas:
|
|
807
|
-
if
|
|
808
|
-
|
|
816
|
+
if (
|
|
817
|
+
area.vehicle_type_id == int(vehicle_type)
|
|
818
|
+
or area.vehicle_type_id is None
|
|
819
|
+
):
|
|
820
|
+
# The areas allow either one type, or all vehicle types
|
|
809
821
|
for p in area.processes:
|
|
810
822
|
if p.electric_power is not None and p.duration is None:
|
|
811
823
|
vehicle_count += area.capacity
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
import warnings
|
|
2
3
|
from datetime import timedelta, datetime
|
|
3
4
|
from math import ceil
|
|
4
5
|
from typing import Tuple
|
|
@@ -7,7 +8,6 @@ from zoneinfo import ZoneInfo
|
|
|
7
8
|
import numpy as np
|
|
8
9
|
import sqlalchemy.orm
|
|
9
10
|
from eflips.model import (
|
|
10
|
-
Area,
|
|
11
11
|
Event,
|
|
12
12
|
EventType,
|
|
13
13
|
Rotation,
|
|
@@ -15,6 +15,7 @@ from eflips.model import (
|
|
|
15
15
|
Trip,
|
|
16
16
|
Station,
|
|
17
17
|
ChargeType,
|
|
18
|
+
ConsistencyWarning,
|
|
18
19
|
)
|
|
19
20
|
|
|
20
21
|
|
|
@@ -51,7 +52,7 @@ def initialize_vehicle(rotation: Rotation, session: sqlalchemy.orm.session.Sessi
|
|
|
51
52
|
|
|
52
53
|
def add_initial_standby_event(
|
|
53
54
|
vehicle: Vehicle, session: sqlalchemy.orm.session.Session
|
|
54
|
-
):
|
|
55
|
+
) -> None:
|
|
55
56
|
"""
|
|
56
57
|
Create and add a standby event immediately before the earliest trip of the given vehicle.
|
|
57
58
|
|
|
@@ -76,25 +77,20 @@ def add_initial_standby_event(
|
|
|
76
77
|
``None``. A new event is added to the session for the earliest trip,
|
|
77
78
|
but changes are not yet committed.
|
|
78
79
|
"""
|
|
79
|
-
logger = logging.getLogger(__name__)
|
|
80
|
-
|
|
81
|
-
rotation_per_vehicle = sorted(
|
|
82
|
-
vehicle.rotations, key=lambda r: r.trips[0].departure_time
|
|
83
|
-
)
|
|
84
|
-
|
|
85
|
-
# Only keep the rotations that contain trips
|
|
86
|
-
rotation_per_vehicle = [r for r in rotation_per_vehicle if len(r.trips) > 0]
|
|
87
|
-
if len(rotation_per_vehicle) == 0:
|
|
88
|
-
logger.warning(f"No trips found for vehicle {vehicle.id}.")
|
|
89
|
-
return
|
|
90
80
|
|
|
91
|
-
earliest_trip =
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
.filter(
|
|
95
|
-
.
|
|
81
|
+
earliest_trip = (
|
|
82
|
+
session.query(Trip)
|
|
83
|
+
.join(Rotation)
|
|
84
|
+
.filter(Rotation.vehicle == vehicle)
|
|
85
|
+
.order_by(Trip.departure_time)
|
|
96
86
|
.first()
|
|
97
87
|
)
|
|
88
|
+
if earliest_trip is None:
|
|
89
|
+
warnings.warn(
|
|
90
|
+
f"No trips found for vehicle {vehicle.id}. Cannot add initial standby event.",
|
|
91
|
+
ConsistencyWarning,
|
|
92
|
+
)
|
|
93
|
+
return
|
|
98
94
|
|
|
99
95
|
standby_start = earliest_trip.departure_time - timedelta(seconds=1)
|
|
100
96
|
standby_event = Event(
|
|
@@ -148,15 +144,11 @@ def find_charger_occupancy(
|
|
|
148
144
|
(shape: ``(n,)``), indicating how many charging events are active.
|
|
149
145
|
"""
|
|
150
146
|
# Load all charging events that could be relevant
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
.
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
Event.time_start < time_end,
|
|
157
|
-
Event.time_end > time_start,
|
|
158
|
-
)
|
|
159
|
-
.all()
|
|
147
|
+
charging_events_q = session.query(Event).filter(
|
|
148
|
+
Event.event_type == EventType.CHARGING_OPPORTUNITY,
|
|
149
|
+
Event.station_id == station.id,
|
|
150
|
+
Event.time_start < time_end,
|
|
151
|
+
Event.time_end > time_start,
|
|
160
152
|
)
|
|
161
153
|
|
|
162
154
|
# We need to change the times to numpy datetime64 with implicit UTC timezone
|
|
@@ -166,7 +158,7 @@ def find_charger_occupancy(
|
|
|
166
158
|
|
|
167
159
|
times = np.arange(time_start, time_end, resolution)
|
|
168
160
|
occupancy = np.zeros_like(times, dtype=int)
|
|
169
|
-
for event in
|
|
161
|
+
for event in charging_events_q:
|
|
170
162
|
event_start = np.datetime64(
|
|
171
163
|
event.time_start.astimezone(tz).replace(tzinfo=None)
|
|
172
164
|
)
|
|
@@ -272,9 +264,11 @@ def attempt_opportunity_charging_event(
|
|
|
272
264
|
|
|
273
265
|
# Sanity checks
|
|
274
266
|
if previous_trip.route.arrival_station_id != next_trip.route.departure_station_id:
|
|
275
|
-
|
|
276
|
-
f"Trips {previous_trip.id} and {next_trip.id} are not consecutive."
|
|
267
|
+
warnings.warn(
|
|
268
|
+
f"Trips {previous_trip.id} and {next_trip.id} are not consecutive.",
|
|
269
|
+
ConsistencyWarning,
|
|
277
270
|
)
|
|
271
|
+
return charge_start_soc
|
|
278
272
|
if previous_trip.rotation_id != next_trip.rotation_id:
|
|
279
273
|
raise ValueError(
|
|
280
274
|
f"Trips {previous_trip.id} and {next_trip.id} are not in the same rotation."
|
|
@@ -111,7 +111,13 @@ def depot_to_template(depot: Depot) -> Dict[str, str | Dict[str, str | int]]:
|
|
|
111
111
|
}
|
|
112
112
|
else:
|
|
113
113
|
# If the vehicle type id is not set, the area is for all vehicle types
|
|
114
|
-
|
|
114
|
+
scenario = depot.scenario
|
|
115
|
+
all_vehicle_type_ids = [str(vt.id) for vt in scenario.vehicle_types]
|
|
116
|
+
|
|
117
|
+
template["areas"][area_name]["entry_filter"] = {
|
|
118
|
+
"filter_names": ["vehicle_type"],
|
|
119
|
+
"vehicle_types": all_vehicle_type_ids,
|
|
120
|
+
}
|
|
115
121
|
|
|
116
122
|
for process in area.processes:
|
|
117
123
|
# Add process into process list
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: eflips-depot
|
|
3
|
-
Version: 4.6.
|
|
3
|
+
Version: 4.6.5
|
|
4
4
|
Summary: Depot Simulation for eFLIPS
|
|
5
5
|
License: AGPL-3.0-or-later
|
|
6
6
|
Author: Enrico Lauth
|
|
@@ -13,7 +13,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.13
|
|
15
15
|
Requires-Dist: eflips (>=0.1.3,<0.2.0)
|
|
16
|
-
Requires-Dist: eflips-model (>=6.0.
|
|
16
|
+
Requires-Dist: eflips-model (>=6.0.6,<7.0.0)
|
|
17
17
|
Requires-Dist: pandas (>=2.2.0,<3.0.0)
|
|
18
18
|
Requires-Dist: scipy (>=1.14.0,<2.0.0)
|
|
19
19
|
Requires-Dist: simpy (>=4.0.1,<5.0.0)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
eflips/depot/__init__.py,sha256=RQ_UKNrGWA6q17TZFu86ai8pC7qCpcbmAgVKh7aImwo,1613
|
|
2
|
-
eflips/depot/api/__init__.py,sha256=
|
|
2
|
+
eflips/depot/api/__init__.py,sha256=0ifYtEwSs2LbpPINxdDsGNxdywKRicCQBETB7BpBh9Y,48631
|
|
3
3
|
eflips/depot/api/defaults/default_settings.json,sha256=0eUDTw_rtLQFvthP8oJL93iRXlmAOravAg-4qqGMQAY,5375
|
|
4
4
|
eflips/depot/api/private/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
-
eflips/depot/api/private/consumption.py,sha256=
|
|
6
|
-
eflips/depot/api/private/depot.py,sha256=
|
|
5
|
+
eflips/depot/api/private/consumption.py,sha256=vDPCogd3NPx2duCUhg_CcW9rMQWgrppfqsS4E7W9T1Y,16400
|
|
6
|
+
eflips/depot/api/private/depot.py,sha256=WcCcib3NSbvoL3G06I2ajT8U5L7AkDK5qe969PHq-fg,41014
|
|
7
7
|
eflips/depot/api/private/results_to_database.py,sha256=Sh2VJ3k60QJ5RGkc8sw-7XbljiMe65EHeoagKIpYlHM,24585
|
|
8
8
|
eflips/depot/api/private/smart_charging.py,sha256=MQ9fXdKByHAz6RSKXYcpJXDBccdJKZ2qGReCHagVCyo,13033
|
|
9
9
|
eflips/depot/api/private/util.py,sha256=gk5TJZrcvtkyrqnjR3Cq-hPRGRCovhzKz3LrBDIvN0E,16799
|
|
@@ -37,7 +37,7 @@ eflips/depot/simulation.py,sha256=ee0qTzOzG-8ybN36ie_NJallXfC7jUaS9JZvaYFziLs,10
|
|
|
37
37
|
eflips/depot/smart_charging.py,sha256=C3BYqzn2-OYY4ipXm0ETtavbAM9QXZMYULBpVoChf0E,54311
|
|
38
38
|
eflips/depot/standalone.py,sha256=VxcTzBaB67fNJUMmjPRwKXjhqTy6oQ41Coote2LvAmk,22338
|
|
39
39
|
eflips/depot/validation.py,sha256=TIuY7cQtEJI4H2VVMSuY5IIVkacEEZ67weeMuY3NSAM,7097
|
|
40
|
-
eflips_depot-4.6.
|
|
41
|
-
eflips_depot-4.6.
|
|
42
|
-
eflips_depot-4.6.
|
|
43
|
-
eflips_depot-4.6.
|
|
40
|
+
eflips_depot-4.6.5.dist-info/LICENSE.md,sha256=KB4XTk1fPHjtZCYDyPyreu6h1LVJVZXYg-5vePcWZAc,34143
|
|
41
|
+
eflips_depot-4.6.5.dist-info/METADATA,sha256=aPK2OCraATDQr-H1kBZGqyZkj1fC0ZUBecES6EFCyoU,5940
|
|
42
|
+
eflips_depot-4.6.5.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
|
43
|
+
eflips_depot-4.6.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|