eflips-depot 4.15.4__py3-none-any.whl → 4.15.12__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.
@@ -328,13 +328,23 @@ def simple_consumption_simulation(
328
328
 
329
329
  # The departure SoC for this rotation is the SoC of the last event preceding the first trip
330
330
  with session.no_autoflush:
331
- current_soc = (
331
+ current_soc_q = (
332
332
  session.query(Event.soc_end)
333
333
  .filter(Event.vehicle_id == rotation.vehicle_id)
334
334
  .filter(Event.time_end <= rotation.trips[0].departure_time)
335
335
  .order_by(Event.time_end.desc())
336
- .first()[0]
336
+ .first()
337
337
  )
338
+ if current_soc_q is None:
339
+ # We – for some reason – do not have an initial event for this vehicle. This is due to unstable
340
+ # simulation in the depot. We set the SoC to 1.0 and add a warning.
341
+ current_soc = 1.0
342
+ warnings.warn(
343
+ f"No initial event found for vehicle {vehicle.id} before rotation {rotation.id}. Assuming 100% SoC.",
344
+ ConsistencyWarning,
345
+ )
346
+ else:
347
+ current_soc = current_soc_q[0]
338
348
 
339
349
  for trip in rotation.trips:
340
350
  # Set up a timeseries
@@ -3,7 +3,7 @@ import warnings
3
3
  from dataclasses import dataclass
4
4
  from datetime import timedelta, datetime
5
5
  from math import ceil
6
- from typing import Tuple, List
6
+ from typing import Tuple, List, Optional
7
7
  from zoneinfo import ZoneInfo
8
8
 
9
9
  import numpy as np
@@ -88,11 +88,13 @@ class ConsumptionInformation:
88
88
  """
89
89
 
90
90
  trip_id: int
91
- consumption_lut: ConsumptionLut | None # the LUT for the vehicle class
91
+ consumption_lut: Optional[ConsumptionLut] # the LUT for the vehicle class
92
92
  average_speed: float # the average speed of the trip in km/h
93
93
  distance: float # the distance of the trip in km
94
- temperature: float # The ambient temperature in °C
95
- level_of_loading: float
94
+ temperature: Optional[float] # The ambient temperature in °C
95
+ level_of_loading: Optional[
96
+ float
97
+ ] # The level of loading of the vehicle as a fraction of its maximum payload
96
98
  incline: float = 0.0 # The incline of the trip in 0.0-1.0
97
99
  consumption: float = None # The consumption of the trip in kWh
98
100
  consumption_per_km: float = None # The consumption per km in kWh
@@ -302,22 +304,22 @@ def extract_trip_information(
302
304
 
303
305
  temperature = temperature_for_trip(trip_id, session)
304
306
 
305
- payload_mass = passenger_mass * passenger_count
306
- assert (
307
- trip.rotation.vehicle_type.allowed_mass is not None
308
- ), f"allowed_mass of vehicle {trip.rotation.vehicle_type} must be set"
307
+ if len(all_consumption_luts) == 1:
308
+ payload_mass = passenger_mass * passenger_count
309
+ assert (
310
+ trip.rotation.vehicle_type.allowed_mass is not None
311
+ ), f"allowed_mass of vehicle {trip.rotation.vehicle_type} must be set"
309
312
 
310
- assert (
311
- trip.rotation.vehicle_type.empty_mass is not None
312
- ), f"empty_mass of vehicle {trip.rotation.vehicle_type} must be set"
313
+ assert (
314
+ trip.rotation.vehicle_type.empty_mass is not None
315
+ ), f"empty_mass of vehicle {trip.rotation.vehicle_type} must be set"
313
316
 
314
- full_payload = (
315
- trip.rotation.vehicle_type.allowed_mass
316
- - trip.rotation.vehicle_type.empty_mass
317
- )
318
- level_of_loading = payload_mass / full_payload
317
+ full_payload = (
318
+ trip.rotation.vehicle_type.allowed_mass
319
+ - trip.rotation.vehicle_type.empty_mass
320
+ )
321
+ level_of_loading = payload_mass / full_payload
319
322
 
320
- if len(all_consumption_luts) == 1:
321
323
  consumption_lut = all_consumption_luts[0]
322
324
  # Disconnect the consumption LUT from the session to avoid loading the whole table
323
325
 
@@ -339,9 +341,10 @@ def extract_trip_information(
339
341
  )
340
342
  # Here, we fill out the condumption information without the LUT and LUT data, but with `consumption_per_km`
341
343
  # set to the vehicle's `consumption` value.
342
- assert (
343
- VehicleType.consumption is not None
344
- ), f"Vehicle type {trip.rotation.vehicle_type} must have a consumption value set if no consumption LUT is available."
344
+ if trip.rotation.vehicle_type.consumption is None:
345
+ raise ValueError(
346
+ f"Vehicle type {trip.rotation.vehicle_type} must have a consumption value set if no consumption LUT is available."
347
+ )
345
348
  info = ConsumptionInformation(
346
349
  trip_id=trip.id,
347
350
  average_speed=average_speed,
@@ -350,7 +353,7 @@ def extract_trip_information(
350
353
  consumption=trip.rotation.vehicle_type.consumption * total_distance,
351
354
  consumption_lut=None,
352
355
  temperature=temperature,
353
- level_of_loading=level_of_loading,
356
+ level_of_loading=None,
354
357
  )
355
358
  else:
356
359
  raise ValueError(
@@ -49,7 +49,7 @@ class AreaInformation:
49
49
  capacity: int
50
50
  """Capacity of the area."""
51
51
  block_length: int | None
52
- """Block length of the area in meters. Only needed for AreaType.LINE."""
52
+ """Block length of the area in number of buses. Only needed for AreaType.LINE."""
53
53
  power: float
54
54
  """Charging power of the area in kW."""
55
55
  vehicle_type_id: int
@@ -96,12 +96,33 @@ class DepotConfigurationWish:
96
96
  True if the depot should be auto-generated, False if the depot should be created from user input.
97
97
  """
98
98
  default_power: float | None
99
+ """
100
+ Default charging power in kW for auto-generated depots.
101
+ """
99
102
  standard_block_length: int | None
103
+ """
104
+ Default number of vehicles in a line for auto-generated depots.
105
+ """
100
106
  cleaning_slots: int | None
107
+ """
108
+ Number of cleaning slots for auto-generated depots.
109
+ """
101
110
  cleaning_duration: timedelta | None
111
+ """
112
+ Duration of the cleaning process for auto-generated depots.
113
+ """
102
114
  shunting_slots: int | None
115
+ """
116
+ Duration of the shunting process for auto-generated depots.
117
+ """
103
118
  shunting_duration: timedelta | None
119
+ """
120
+ Duration of the shunting process for auto-generated depots.
121
+ """
104
122
  areas: list[AreaInformation] | None #
123
+ """
124
+ List of AreaInformation objects representing charging area configurations for user-defined depots.
125
+ """
105
126
 
106
127
  def __init__(
107
128
  self,
@@ -126,20 +147,27 @@ class DepotConfigurationWish:
126
147
  self.areas = areas
127
148
 
128
149
  if self.auto_generate is True:
129
- if self.default_power is None or self.standard_block_length is None:
130
- raise ValueError(
131
- "If auto_generate is True, default_power, standard_block_length must be provided."
132
- )
133
- if (
134
- self.cleaning_slots is not None
135
- or self.cleaning_duration is not None
136
- or self.shunting_slots is not None
137
- or self.shunting_duration is not None
138
- ):
139
- raise ValueError(
140
- "If auto_generate is True, default_power, standard_block_length, cleaning_slots, cleaning_duration and shunting_slots cannot be provided."
141
- )
142
- # do some simple validation here
150
+ assert (
151
+ self.default_power is not None
152
+ ), "default_power must be provided if auto_generate is True"
153
+ assert (
154
+ self.standard_block_length is not None
155
+ ), "standard_block_length must be provided if auto_generate is True"
156
+
157
+ assert (
158
+ self.cleaning_slots is None
159
+ ), "cleaning_slots cannot be provided if auto_generate is True"
160
+ assert (
161
+ self.cleaning_duration is None
162
+ ), "cleaning_duration cannot be provided if auto_generate is True"
163
+ assert (
164
+ self.shunting_slots is None
165
+ ), "shunting_slots cannot be provided if auto_generate is True"
166
+ assert (
167
+ self.shunting_duration is None
168
+ ), "shunting_duration cannot be provided if auto_generate is True"
169
+
170
+ assert not areas, "areas cannot be provided if auto_generate is True"
143
171
 
144
172
 
145
173
  def delete_depots(scenario: Scenario, session: Session) -> None:
@@ -501,7 +501,7 @@ def add_events_into_database(
501
501
  '"Standby", "Precondition"'
502
502
  )
503
503
 
504
- if process_dict["end"] == start_time:
504
+ if math.ceil(process_dict["end"]) == math.ceil(start_time):
505
505
  logger.warning("Refusing to create an event with zero duration.")
506
506
  continue
507
507
 
@@ -545,8 +545,9 @@ def add_events_into_database(
545
545
  area_id=area_id,
546
546
  subloc_no=process_dict["slot"] if "slot" in process_dict.keys() else 00,
547
547
  trip_id=None,
548
- time_start=timedelta(seconds=start_time) + simulation_start_time,
549
- time_end=timedelta(seconds=process_dict["end"]) + simulation_start_time,
548
+ time_start=timedelta(seconds=math.ceil(start_time)) + simulation_start_time,
549
+ time_end=timedelta(seconds=math.ceil(process_dict["end"]))
550
+ + simulation_start_time,
550
551
  soc_start=process_dict["soc_start"]
551
552
  if process_dict["soc_start"] is not None
552
553
  else process_dict["soc_end"],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eflips-depot
3
- Version: 4.15.4
3
+ Version: 4.15.12
4
4
  Summary: Depot Simulation for eFLIPS
5
5
  License: AGPL-3.0-or-later
6
6
  License-File: LICENSE.md
@@ -131,5 +131,5 @@ This project is licensed under the AGPLv3 license - see the [LICENSE](LICENSE.md
131
131
 
132
132
  ## Funding Notice
133
133
 
134
- This code was developed as part of the project [eBus2030+]([https://www.eflip.de/](https://www.now-gmbh.de/projektfinder/e-bus-2030/)) funded by the Federal German Ministry for Digital and Transport (BMDV) under grant number 03EMF0402.
134
+ This code was developed as part of the project [eBus2030+](https://www.now-gmbh.de/projektfinder/e-bus-2030/) funded by the Federal German Ministry for Digital and Transport (BMDV) under grant number 03EMF0402.
135
135
 
@@ -1,10 +1,10 @@
1
1
  eflips/depot/__init__.py,sha256=FCVnYU7aSfR4BNCo722I1V3uU5336qr1tTt-zT6X4UI,1555
2
- eflips/depot/api/__init__.py,sha256=HvPtHi55hXwGgxD_DcYZxUnws1KRkKnezxI3Bao9TTg,67619
2
+ eflips/depot/api/__init__.py,sha256=m3B8HQbUc9PRNZbF_OyPF4BiqUz4c54GGZkHK4KpoO0,68206
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=494u6FelymWfI-Yt3ybJpLHUL-6zEqBOT2qSrPhRmMo,30038
6
- eflips/depot/api/private/depot.py,sha256=wFzKYbUTtU-mOGZD6gB_fQBaKGRTXZn4f5hRuuV6gkg,59629
7
- eflips/depot/api/private/results_to_database.py,sha256=OewbDwbk54GPORMVavLbJ7DSZpRKBLHM7q9aWKTngs8,30026
5
+ eflips/depot/api/private/consumption.py,sha256=fgivEmP9A-kLpVpxCzxYdXW_OnvopUOKbmX8siBERd0,30244
6
+ eflips/depot/api/private/depot.py,sha256=pwPIdU1kwZhxh2cK0ut7az3V5KKxRXuu1lxdgXWPLUo,60460
7
+ eflips/depot/api/private/results_to_database.py,sha256=daNGNsqsVPqs-0xVBhIdHmtcJUcNjcYMsBJxSB66zWo,30082
8
8
  eflips/depot/api/private/util.py,sha256=e7T_-1AUXoCV9c11zaED2-za7p0TDhYG4Dg0lBZnrZI,18342
9
9
  eflips/depot/configuration.py,sha256=Op3hlir-dEN7yHr0kTqbYANoCBKFWK6uKOv3NJl8w_w,35678
10
10
  eflips/depot/depot.py,sha256=5NBw5bvOP2cplkRGZbKbG3SOA23F2Kw-UsabHubocPU,107555
@@ -36,7 +36,7 @@ eflips/depot/simulation.py,sha256=ee0qTzOzG-8ybN36ie_NJallXfC7jUaS9JZvaYFziLs,10
36
36
  eflips/depot/smart_charging.py,sha256=C3BYqzn2-OYY4ipXm0ETtavbAM9QXZMYULBpVoChf0E,54311
37
37
  eflips/depot/standalone.py,sha256=8O01zEXghFG9zZBu0fUD0sXvbHQ-AXw6RB5M750a_sM,22419
38
38
  eflips/depot/validation.py,sha256=TIuY7cQtEJI4H2VVMSuY5IIVkacEEZ67weeMuY3NSAM,7097
39
- eflips_depot-4.15.4.dist-info/METADATA,sha256=96QASZxpS3Z6obl3xDrwcEsxD-84hCR2y88o_6Yg0kE,5961
40
- eflips_depot-4.15.4.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
41
- eflips_depot-4.15.4.dist-info/licenses/LICENSE.md,sha256=KB4XTk1fPHjtZCYDyPyreu6h1LVJVZXYg-5vePcWZAc,34143
42
- eflips_depot-4.15.4.dist-info/RECORD,,
39
+ eflips_depot-4.15.12.dist-info/METADATA,sha256=GBPVrOAwSZqkNdwCndYbJDygTriTqBUVP3v6eJUQMY0,5937
40
+ eflips_depot-4.15.12.dist-info/WHEEL,sha256=kJCRJT_g0adfAJzTx2GUMmS80rTJIVHRCfG0DQgLq3o,88
41
+ eflips_depot-4.15.12.dist-info/licenses/LICENSE.md,sha256=KB4XTk1fPHjtZCYDyPyreu6h1LVJVZXYg-5vePcWZAc,34143
42
+ eflips_depot-4.15.12.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.2.1
2
+ Generator: poetry-core 2.3.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any