eflips-depot 4.6.3__py3-none-any.whl → 4.6.4__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.
@@ -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(sqlalchemy.orm.joinedload(Rotation.trips).joinedload(Trip.route))
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
  )
@@ -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 = rotation_per_vehicle[0].trips[0]
92
- area = (
93
- session.query(Area)
94
- .filter(Area.scenario_id == vehicle.scenario_id)
95
- .filter(Area.vehicle_type_id == vehicle.vehicle_type_id)
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
- charging_events = (
152
- session.query(Event)
153
- .filter(
154
- Event.event_type == EventType.CHARGING_OPPORTUNITY,
155
- Event.station_id == station.id,
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 charging_events:
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
- raise ValueError(
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."
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: eflips-depot
3
- Version: 4.6.3
3
+ Version: 4.6.4
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.4,<7.0.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,8 +1,8 @@
1
1
  eflips/depot/__init__.py,sha256=RQ_UKNrGWA6q17TZFu86ai8pC7qCpcbmAgVKh7aImwo,1613
2
- eflips/depot/api/__init__.py,sha256=Sxsqj5qIcSK-dqtE2UqaHVWEWnycU65N-pDnLuTJfeU,48244
2
+ eflips/depot/api/__init__.py,sha256=4WPZoYSsOgDMI-hsZrQPx_5PRjSztogZNpu3xwwAlUk,48353
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=k-YYeBTvlKBAE-YSoPSiJofsz6VmazRn__Qe238mE2w,16616
5
+ eflips/depot/api/private/consumption.py,sha256=vDPCogd3NPx2duCUhg_CcW9rMQWgrppfqsS4E7W9T1Y,16400
6
6
  eflips/depot/api/private/depot.py,sha256=v5Edb0sQP2QNIyBLvccVzAK9_kxCszar0cOu5ciFyrw,40780
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
@@ -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.3.dist-info/LICENSE.md,sha256=KB4XTk1fPHjtZCYDyPyreu6h1LVJVZXYg-5vePcWZAc,34143
41
- eflips_depot-4.6.3.dist-info/METADATA,sha256=8mi6aRYWW1DOT4QkR5UytrBAoOK6OKHj6G3N1Ykiw00,5940
42
- eflips_depot-4.6.3.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
43
- eflips_depot-4.6.3.dist-info/RECORD,,
40
+ eflips_depot-4.6.4.dist-info/LICENSE.md,sha256=KB4XTk1fPHjtZCYDyPyreu6h1LVJVZXYg-5vePcWZAc,34143
41
+ eflips_depot-4.6.4.dist-info/METADATA,sha256=VApUGP1NNUQLv_GLCpPCLHAyY0r629HwAv8bMtv91w4,5940
42
+ eflips_depot-4.6.4.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
43
+ eflips_depot-4.6.4.dist-info/RECORD,,