eflips-depot 4.14.3__py3-none-any.whl → 4.15.1__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.
@@ -532,6 +532,7 @@ def apply_even_smart_charging(
532
532
  scenario: Union[Scenario, int, Any],
533
533
  database_url: Optional[str] = None,
534
534
  standby_departure_duration: timedelta = timedelta(minutes=5),
535
+ delete_existing_charging_timeseries: bool = False,
535
536
  ) -> None:
536
537
  """
537
538
  Takes a scenario where depot simulation has been run and applies smart charging to the depot.
@@ -548,6 +549,8 @@ def apply_even_smart_charging(
548
549
  :param standby_departure_duration: The duration of the STANDBY_DEPARTURE event. This is the time the vehicle is
549
550
  allowed to wait at the depot before it has to leave. The default is 5 minutes.
550
551
 
552
+ :param delete_existing_timeseries: If True, the existing timeseries in the charging events will be deleted.
553
+
551
554
  :return: None. The results are added to the database.
552
555
  """
553
556
  logger = logging.getLogger(__name__)
@@ -564,6 +567,19 @@ def apply_even_smart_charging(
564
567
  raise
565
568
 
566
569
  with create_session(scenario, database_url) as (session, scenario):
570
+ if delete_existing_charging_timeseries is False:
571
+ raise ValueError(
572
+ "The existing timeseries of charging events needed to be deleted. Set "
573
+ "delete_existing_charging_timeseries=True to delete them."
574
+ )
575
+
576
+ # Delete existing timeseries in charging events
577
+ session.query(Event).filter(
578
+ Event.event_type == EventType.CHARGING_DEPOT,
579
+ Event.scenario_id == scenario.id,
580
+ ).update({"timeseries": None}, synchronize_session=False)
581
+ session.expire_all()
582
+
567
583
  depots = session.query(Depot).filter(Depot.scenario_id == scenario.id).all()
568
584
  for depot in depots:
569
585
  add_slack_time_to_events_of_depot(
@@ -286,20 +286,6 @@ def extract_trip_information(
286
286
  )
287
287
  .one()
288
288
  )
289
- # Check exactly one of the vehicle classes has a consumption LUT
290
- all_consumption_luts = [
291
- vehicle_class.consumption_lut
292
- for vehicle_class in trip.rotation.vehicle_type.vehicle_classes
293
- ]
294
- all_consumption_luts = [x for x in all_consumption_luts if x is not None]
295
- if len(all_consumption_luts) != 1:
296
- raise ValueError(
297
- f"Expected exactly one consumption LUT, got {len(all_consumption_luts)}"
298
- )
299
- consumption_lut = all_consumption_luts[0]
300
- # Disconnect the consumption LUT from the session to avoid loading the whole table
301
-
302
- del all_consumption_luts
303
289
 
304
290
  total_distance = trip.route.distance / 1000 # km
305
291
  total_duration = (
@@ -307,6 +293,13 @@ def extract_trip_information(
307
293
  ).total_seconds() / 3600
308
294
  average_speed = total_distance / total_duration # km/h
309
295
 
296
+ # Check exactly one of the vehicle classes has a consumption LUT
297
+ all_consumption_luts = [
298
+ vehicle_class.consumption_lut
299
+ for vehicle_class in trip.rotation.vehicle_type.vehicle_classes
300
+ ]
301
+ all_consumption_luts = [x for x in all_consumption_luts if x is not None]
302
+
310
303
  temperature = temperature_for_trip(trip_id, session)
311
304
 
312
305
  payload_mass = passenger_mass * passenger_count
@@ -324,16 +317,46 @@ def extract_trip_information(
324
317
  )
325
318
  level_of_loading = payload_mass / full_payload
326
319
 
327
- info = ConsumptionInformation(
328
- trip_id=trip.id,
329
- consumption_lut=consumption_lut,
330
- average_speed=average_speed,
331
- distance=total_distance,
332
- temperature=temperature,
333
- level_of_loading=level_of_loading,
334
- )
320
+ if len(all_consumption_luts) == 1:
321
+ consumption_lut = all_consumption_luts[0]
322
+ # Disconnect the consumption LUT from the session to avoid loading the whole table
323
+
324
+ del all_consumption_luts
325
+
326
+ info = ConsumptionInformation(
327
+ trip_id=trip.id,
328
+ consumption_lut=consumption_lut,
329
+ average_speed=average_speed,
330
+ distance=total_distance,
331
+ temperature=temperature,
332
+ level_of_loading=level_of_loading,
333
+ )
334
+ info.calculate()
335
+ elif len(all_consumption_luts) == 0:
336
+ warnings.warn(
337
+ f"No consumption LUT found for vehicle type {trip.rotation.vehicle_type}.",
338
+ ConsistencyWarning,
339
+ )
340
+ # Here, we fill out the condumption information without the LUT and LUT data, but with `consumption_per_km`
341
+ # 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."
345
+ info = ConsumptionInformation(
346
+ trip_id=trip.id,
347
+ average_speed=average_speed,
348
+ distance=total_distance,
349
+ consumption_per_km=trip.rotation.vehicle_type.consumption,
350
+ consumption=trip.rotation.vehicle_type.consumption * total_distance,
351
+ consumption_lut=None,
352
+ temperature=temperature,
353
+ level_of_loading=level_of_loading,
354
+ )
355
+ else:
356
+ raise ValueError(
357
+ f"Expected exactly one consumption LUT, got {len(all_consumption_luts)}"
358
+ )
335
359
 
336
- info.calculate()
337
360
  return info
338
361
 
339
362
 
@@ -204,7 +204,7 @@ def depot_to_template(depot: Depot) -> Dict[str, str | Dict[str, str | int]]:
204
204
  list_of_processes = []
205
205
 
206
206
  # Get dictionary of each area
207
- # For line areas, generate an dictionary item for total areas, later it will be split into individual lines
207
+ # For line areas, generate a dictionary item for total areas, later it will be split into individual lines
208
208
  for area in depot.areas:
209
209
  area_name = str(area.id)
210
210
  template["areas"][area_name] = {
@@ -226,6 +226,17 @@ def depot_to_template(depot: Depot) -> Dict[str, str | Dict[str, str | int]]:
226
226
  "filter_names": ["vehicle_type"],
227
227
  "vehicle_types": [str(area.vehicle_type_id)],
228
228
  }
229
+ for processes_in_area in area.processes:
230
+ if process_type(processes_in_area) == ProcessType.CHARGING:
231
+ # Add the charging process for this vehicle type
232
+ template["areas"][area_name]["available_processes"].append(
233
+ str(processes_in_area.id) + str(area.vehicle_type_id)
234
+ )
235
+ # Delete the original charging process
236
+ template["areas"][area_name]["available_processes"].remove(
237
+ str(processes_in_area.id)
238
+ )
239
+
229
240
  else:
230
241
  # If the vehicle type id is not set, the area is for all vehicle types
231
242
  scenario = depot.scenario
@@ -236,6 +247,19 @@ def depot_to_template(depot: Depot) -> Dict[str, str | Dict[str, str | int]]:
236
247
  "vehicle_types": all_vehicle_type_ids,
237
248
  }
238
249
 
250
+ # if there are any charging areas, all a unique charging process for each vehicle type
251
+ for processes_in_area in area.processes:
252
+ if process_type(processes_in_area) == ProcessType.CHARGING:
253
+ # Add the charging process for this vehicle type
254
+ for vt in scenario.vehicle_types:
255
+ template["areas"][area_name]["available_processes"].append(
256
+ str(processes_in_area.id) + str(vt.id)
257
+ )
258
+ # Delete the original charging process
259
+ template["areas"][area_name]["available_processes"].remove(
260
+ str(processes_in_area.id)
261
+ )
262
+
239
263
  for process in area.processes:
240
264
  # Add process into process list
241
265
  list_of_processes.append(
@@ -285,7 +309,7 @@ def depot_to_template(depot: Depot) -> Dict[str, str | Dict[str, str | int]]:
285
309
  for name in line_areas_to_delete:
286
310
  del area_template[name]
287
311
 
288
- # Fill in the dictionary of processess
312
+ # Fill in the dictionary of processes
289
313
  for process in list_of_processes:
290
314
  process_name = str(process.id)
291
315
  # Shared template for all processes
@@ -358,8 +382,42 @@ def depot_to_template(depot: Depot) -> Dict[str, str | Dict[str, str | int]]:
358
382
  ] = list_of_breaks_in_seconds
359
383
 
360
384
  case ProcessType.CHARGING:
361
- template["processes"][process_name]["typename"] = "Charge"
362
- del template["processes"][process_name]["dur"]
385
+ all_vehicle_types = depot.scenario.vehicle_types
386
+
387
+ for vt in all_vehicle_types:
388
+ charging_curve = vt.charging_curve
389
+ template["processes"][process_name + str(vt.id)] = template[
390
+ "processes"
391
+ ][process_name].copy()
392
+ template["processes"][process_name + str(vt.id)][
393
+ "typename"
394
+ ] = "ChargeEquationSteps"
395
+ template["processes"][process_name + str(vt.id)][
396
+ "vehicle_filter"
397
+ ] = {
398
+ "filter_names": ["vehicle_type"],
399
+ "vehicle_types": [str(vt.id)],
400
+ }
401
+
402
+ template["processes"][process_name + str(vt.id)][
403
+ "peq_name"
404
+ ] = "charging_curve_power"
405
+ template["processes"][process_name + str(vt.id)]["peq_params"] = {
406
+ "soc": [soc_power_pair[0] for soc_power_pair in charging_curve],
407
+ "power": [
408
+ soc_power_pair[1] for soc_power_pair in charging_curve
409
+ ],
410
+ }
411
+
412
+ del template["processes"][process_name + str(vt.id)]["dur"]
413
+
414
+ # delete the original process
415
+ del template["processes"][process_name]
416
+
417
+ # The original one
418
+ # template["processes"][process_name]["typename"] = "Charge"
419
+
420
+ # del template["processes"][process_name]["dur"]
363
421
 
364
422
  case ProcessType.STANDBY | ProcessType.STANDBY_DEPARTURE:
365
423
  template["processes"][process_name]["typename"] = "Standby"
@@ -225,8 +225,6 @@ def generate_vehicle_events(
225
225
  "is_waiting": True,
226
226
  }
227
227
 
228
- # Create a list of battery log in order of time asc. Convenient for looking up corresponding soc
229
-
230
228
  for time_stamp, process_log in current_vehicle.logger.loggedData[
231
229
  "dwd.active_processes_copy"
232
230
  ].items():
@@ -276,13 +274,18 @@ def generate_vehicle_events(
276
274
  )
277
275
  start_this_event = dict_of_events[time_stamp]["end"]
278
276
  else:
279
- for other_process in process_log:
280
- if (
281
- other_process.ID != process.ID
282
- and other_process.dur > 0
283
- ):
284
- start_this_event = other_process.ends[0]
285
- break
277
+ if len(process_log) > 1:
278
+ # This is for the case where the charging and standby_departure happen in the same area, and the standby_departure is the last process.
279
+ for other_process in process_log:
280
+ if (
281
+ other_process.ID != process.ID
282
+ and other_process.dur > 0
283
+ ):
284
+ start_this_event = other_process.ends[0]
285
+ break
286
+ else:
287
+ # This is for the case where only standby_departure happens in the last area.
288
+ start_this_event = time_stamp
286
289
 
287
290
  assert (
288
291
  start_this_event is not None
@@ -395,7 +398,7 @@ def add_soc_to_events(dict_of_events, battery_log) -> None:
395
398
  """
396
399
  battery_log_list = []
397
400
  for log in battery_log:
398
- battery_log_list.append((log.t, log.energy / log.energy_real))
401
+ battery_log_list.append((log.t, round(log.energy / log.energy_real, 4)))
399
402
 
400
403
  time_keys = sorted(dict_of_events.keys())
401
404
 
@@ -408,15 +411,42 @@ def add_soc_to_events(dict_of_events, battery_log) -> None:
408
411
  start_time = time_keys[i]
409
412
  process_dict = dict_of_events[time_keys[i]]
410
413
 
411
- if process_dict["type"] != "Trip":
412
- soc_start = np.interp(start_time, battery_log_times, battery_log_socs)
413
- process_dict["soc_start"] = min(float(soc_start), 1.0)
414
- soc_end = np.interp(
415
- process_dict["end"], battery_log_times, battery_log_socs
416
- )
417
- process_dict["soc_end"] = min(float(soc_end), 1.0)
418
- else:
419
- continue
414
+ match process_dict["type"]:
415
+ case "Charge" | "ChargeSteps" | "ChargeEquationSteps":
416
+ event_start = start_time
417
+ event_end = process_dict["end"]
418
+ start_time_index = battery_log_times.index(event_start)
419
+ end_time_index = battery_log_times.index(event_end)
420
+ time_series = {
421
+ "time": battery_log_times[start_time_index:end_time_index],
422
+ "soc": battery_log_socs[start_time_index:end_time_index],
423
+ }
424
+
425
+ # if there are repeated timestamps, we need to remove them
426
+ unique_indices = np.unique(
427
+ time_series["time"], return_index=True, return_inverse=False
428
+ )[1]
429
+ time_series["time"] = [
430
+ time_series["time"][index] for index in unique_indices
431
+ ]
432
+ time_series["soc"] = [
433
+ time_series["soc"][index] for index in unique_indices
434
+ ]
435
+ process_dict["timeseries"] = time_series
436
+ process_dict["soc_start"] = battery_log_socs[start_time_index]
437
+ process_dict["soc_end"] = battery_log_socs[end_time_index]
438
+
439
+ case "Serve" | "Standby":
440
+ soc_start = np.interp(start_time, battery_log_times, battery_log_socs)
441
+ process_dict["soc_start"] = min(float(soc_start), 1.0)
442
+ soc_end = np.interp(
443
+ process_dict["end"], battery_log_times, battery_log_socs
444
+ )
445
+ process_dict["soc_end"] = min(float(soc_end), 1.0)
446
+ case "Trip":
447
+ continue
448
+ case _:
449
+ raise NotImplementedError
420
450
 
421
451
 
422
452
  def add_events_into_database(
@@ -446,7 +476,7 @@ def add_events_into_database(
446
476
  match process_dict["type"]:
447
477
  case "Serve":
448
478
  event_type = EventType.SERVICE
449
- case "Charge":
479
+ case "Charge" | "ChargeSteps" | "ChargeEquationSteps": # TODO that might be problematic
450
480
  event_type = EventType.CHARGING_DEPOT
451
481
  case "Standby":
452
482
  if (
@@ -488,6 +518,20 @@ def add_events_into_database(
488
518
  capacity_per_line = int(current_area.capacity / current_area.row_count)
489
519
  process_dict["slot"] = capacity_per_line * row + process_dict["slot"] - 1
490
520
 
521
+ timeseries = {}
522
+ if "timeseries" in process_dict.keys():
523
+ # Convert "time" in timeseries to timedelta
524
+ timeseries["time"] = [
525
+ (timedelta(seconds=t) + simulation_start_time).isoformat()
526
+ for t in process_dict["timeseries"]["time"]
527
+ ]
528
+ timeseries["soc"] = process_dict["timeseries"]["soc"]
529
+
530
+ assert all(
531
+ timeseries["soc"][i] <= timeseries["soc"][i + 1]
532
+ for i in range(len(timeseries["soc"]) - 1)
533
+ ), "SOC values in the timeseries should be non-decreasing."
534
+
491
535
  current_event = Event(
492
536
  scenario=scenario,
493
537
  vehicle_type_id=db_vehicle.vehicle_type_id,
@@ -507,7 +551,7 @@ def add_events_into_database(
507
551
  # then this is not an event with soc change
508
552
  event_type=event_type,
509
553
  description=process_dict["id"] if "id" in process_dict.keys() else None,
510
- timeseries=None,
554
+ timeseries=timeseries if "timeseries" in process_dict.keys() else None,
511
555
  )
512
556
 
513
557
  session.add(current_event)
@@ -1,6 +1,7 @@
1
1
  """This module contains miscellaneous utility functions for the eflips-depot API."""
2
2
  import logging
3
3
  import os
4
+ import warnings
4
5
  from contextlib import contextmanager
5
6
  from dataclasses import dataclass
6
7
  from datetime import timedelta, datetime
@@ -17,9 +18,11 @@ from eflips.model import (
17
18
  Trip,
18
19
  Depot,
19
20
  Temperatures,
21
+ ConsistencyWarning,
20
22
  )
21
23
  from eflips.model import create_engine
22
24
  from sqlalchemy import inspect
25
+ from sqlalchemy.exc import NoResultFound
23
26
  from sqlalchemy.orm import Session
24
27
 
25
28
  from eflips.depot import SimpleTrip, Timetable as EflipsTimeTable
@@ -204,7 +207,9 @@ def check_depot_validity(depot: Depot) -> None:
204
207
 
205
208
  def temperature_for_trip(trip_id: int, session: Session) -> float:
206
209
  """
207
- Returns the temperature for a trip. Finds the temperature for the mid-point of the trip.
210
+ Returns the temperature for a trip.
211
+
212
+ Finds the temperature for the mid-point of the trip.
208
213
 
209
214
  :param trip_id: The ID of the trip
210
215
  :param session: The SQLAlchemy session
@@ -212,11 +217,18 @@ def temperature_for_trip(trip_id: int, session: Session) -> float:
212
217
  """
213
218
 
214
219
  trip = session.query(Trip).filter(Trip.id == trip_id).one()
215
- temperatures = (
216
- session.query(Temperatures)
217
- .filter(Temperatures.scenario_id == trip.scenario_id)
218
- .one()
219
- )
220
+ try:
221
+ temperatures = (
222
+ session.query(Temperatures)
223
+ .filter(Temperatures.scenario_id == trip.scenario_id)
224
+ .one()
225
+ )
226
+ except NoResultFound:
227
+ warnings.warn(
228
+ f"No temperatures found for scenario {trip.scenario_id}.",
229
+ ConsistencyWarning,
230
+ )
231
+ return None
220
232
 
221
233
  # Find the mid-point of the trip
222
234
  mid_time = trip.departure_time + (trip.arrival_time - trip.departure_time) / 2
eflips/depot/depot.py CHANGED
@@ -1360,7 +1360,9 @@ class DepotControl:
1360
1360
  for procID in area.available_processes
1361
1361
  if self.depot.processes[procID]["type"].request_immediately
1362
1362
  and (
1363
+ # TODO: Simplify this condition
1363
1364
  self.depot.processes[procID]["kwargs"]["ismandatory"]
1365
+ and self.depot.processes[procID]["kwargs"]["vehicle_filter"](vehicle)
1364
1366
  or not self.depot.processes[procID]["kwargs"]["ismandatory"]
1365
1367
  and self.depot.processes[procID]["kwargs"]["vehicle_filter"](vehicle)
1366
1368
  )
eflips/depot/processes.py CHANGED
@@ -6,6 +6,7 @@ from abc import ABC, abstractmethod
6
6
  from enum import auto, Enum
7
7
  from warnings import warn
8
8
 
9
+ import numpy as np
9
10
  import simpy
10
11
  from eflips.helperFunctions import flexprint
11
12
  from eflips.settings import globalConstants
@@ -672,7 +673,7 @@ class ChargeAbstract(VehicleProcess, ABC):
672
673
  cancellable_for_dispatch=False,
673
674
  efficiency=1,
674
675
  *args,
675
- **kwargs
676
+ **kwargs,
676
677
  ):
677
678
  if required_resources is not None:
678
679
  raise ValueError(
@@ -1428,6 +1429,25 @@ def exponential_power(vehicle, charging_interface, peq_params, *args, **kwargs):
1428
1429
  )
1429
1430
 
1430
1431
 
1432
+ def charging_curve_power(vehicle, charging_interface, peq_params):
1433
+ """
1434
+ Return power in kW for given peq_params in the format of dict[flaot, float]
1435
+ :param vehicle: SimpleVehicle
1436
+ :param charging_interface: DepotChargingInterface storing maximum power from charger
1437
+ :param peq_params: A dictionary with "soc" storing soc turning points and "power" for corresponding charging power
1438
+ :return: charging power in float for given SimpleVehicle
1439
+ """
1440
+
1441
+ current_soc = vehicle.battery.soc
1442
+ p_max = charging_interface.max_power
1443
+
1444
+ current_power = min(
1445
+ p_max, np.interp(current_soc, peq_params["soc"], peq_params["power"])
1446
+ )
1447
+
1448
+ return float(current_power)
1449
+
1450
+
1431
1451
  class Standby(VehicleProcess):
1432
1452
  """Process of mandatory waiting such as standby times."""
1433
1453
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eflips-depot
3
- Version: 4.14.3
3
+ Version: 4.15.1
4
4
  Summary: Depot Simulation for eFLIPS
5
5
  License: AGPL-3.0-or-later
6
6
  License-File: LICENSE.md
@@ -14,7 +14,7 @@ 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
16
  Requires-Dist: eflips-model (>=10.0.0,<11.0.0)
17
- Requires-Dist: eflips-opt (>=0.3.0,<0.4.0)
17
+ Requires-Dist: eflips-opt (>=0.3.6,<0.4.0)
18
18
  Requires-Dist: pandas (>=2.2.0,<3.0.0)
19
19
  Requires-Dist: scipy (>=1.14.0,<2.0.0)
20
20
  Requires-Dist: simpy (>=4.0.1,<5.0.0)
@@ -1,13 +1,13 @@
1
1
  eflips/depot/__init__.py,sha256=FCVnYU7aSfR4BNCo722I1V3uU5336qr1tTt-zT6X4UI,1555
2
- eflips/depot/api/__init__.py,sha256=B1Ph7nQd0W0-Io2tInnaw07bzxCXK7d1M7oWbr1jN8I,66813
2
+ eflips/depot/api/__init__.py,sha256=nq5aHGTOIpDmvDfcGMlCH_jd97E0VZ28KVcT3XTwpbE,67539
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=0wfI3ryfZS9qUqPbJP0okvwY2s6ogylw1PZFyAnCRf4,28915
6
- eflips/depot/api/private/depot.py,sha256=c4XsRN06PScy4Z4yocqrdvMntmgOZdbIxNT9uuN2lxA,56857
7
- eflips/depot/api/private/results_to_database.py,sha256=nvWb4jEM5JwPAhvAdiQ-qzxUSawfRNsYfv3twNUFcGs,27348
8
- eflips/depot/api/private/util.py,sha256=DasTkuGUhlBpY_BtTFWoxSNZU_CRyM3RqEDgO07Eks8,17990
5
+ eflips/depot/api/private/consumption.py,sha256=494u6FelymWfI-Yt3ybJpLHUL-6zEqBOT2qSrPhRmMo,30038
6
+ eflips/depot/api/private/depot.py,sha256=Vx6mC5YynyQ5hEw9QeXAi84VSaYc3qVJAqE2dSfHGJI,59655
7
+ eflips/depot/api/private/results_to_database.py,sha256=-8qXk8lRsMElm9pke6MWzCNUQKtrd59n4Ye2X8Ojw-M,29814
8
+ eflips/depot/api/private/util.py,sha256=rZzyfEYYhF55f6QkiXjwMvJkg98KeHx8XN4Z1OwtSU8,18287
9
9
  eflips/depot/configuration.py,sha256=Op3hlir-dEN7yHr0kTqbYANoCBKFWK6uKOv3NJl8w_w,35678
10
- eflips/depot/depot.py,sha256=yNsH7xPYKpplHP3OeznKRxmmkEYLRP9aoAc6hBS_6Ms,107421
10
+ eflips/depot/depot.py,sha256=5NBw5bvOP2cplkRGZbKbG3SOA23F2Kw-UsabHubocPU,107555
11
11
  eflips/depot/evaluation.py,sha256=qqXyP4jA1zFcKuWhliQ6n25ZlGl9mJV-vtXf0yu8WN8,140842
12
12
  eflips/depot/filters.py,sha256=1aUK7czuhiATC3P3NN5oRtH1I-kN_-mp_-vkzyyBXn4,16089
13
13
  eflips/depot/input_epex_power_price.py,sha256=VPDC1zy-klQpveGIZ8941hL1P_jeNq3IHoLgFTsANig,5569
@@ -27,7 +27,7 @@ eflips/depot/layout_opt/settings.py,sha256=EUGCp4dAX22j2uF8sKqbi9a5iP8hb6QpP7t2N
27
27
  eflips/depot/layout_opt/template_creation.py,sha256=H4LoFjQfbPjTt9rGvapH2tEUWcQ56kPwDucq7t6YahU,9736
28
28
  eflips/depot/layout_opt/util.py,sha256=EYh7IN58ZjysmCFdSieQqIQ9goe1a_ZwARRHxOgjEQo,3780
29
29
  eflips/depot/plots.py,sha256=85xInZWfJIOVm03onvppgP5yLTgQeMn-1t5aoNdavyY,2509
30
- eflips/depot/processes.py,sha256=wVacSuHQnHwe2kN18h4014eN4xs2XEegy9vJdHZ7wzQ,58610
30
+ eflips/depot/processes.py,sha256=n4p_TDvtCDdkagLyX8eJbFFxext3fpVTTfbrGsCO52o,59321
31
31
  eflips/depot/rating.py,sha256=audUASHExeWg5ugytPLlcy5QGiTiFucnZ6-v3REoO2g,16427
32
32
  eflips/depot/resources.py,sha256=0SuzN8qgMmCqa7oUEXVC_XE6pCUtxTsqOfCsaM9Oh3o,13568
33
33
  eflips/depot/settings_config.py,sha256=z7CqPdjd8QRlgZj0Zis-H13cL7LOiheRT4ctYCYGguc,2527
@@ -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.14.3.dist-info/METADATA,sha256=7kG6MB_RgTTOyfwBxNFRle9rfIvnk3bLm5CIGHsygwk,5961
40
- eflips_depot-4.14.3.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
41
- eflips_depot-4.14.3.dist-info/licenses/LICENSE.md,sha256=KB4XTk1fPHjtZCYDyPyreu6h1LVJVZXYg-5vePcWZAc,34143
42
- eflips_depot-4.14.3.dist-info/RECORD,,
39
+ eflips_depot-4.15.1.dist-info/METADATA,sha256=K-X0YzOgpwV6fXCxQxDZP9h_uKiOVMZMKdPz2uu2c_k,5961
40
+ eflips_depot-4.15.1.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
41
+ eflips_depot-4.15.1.dist-info/licenses/LICENSE.md,sha256=KB4XTk1fPHjtZCYDyPyreu6h1LVJVZXYg-5vePcWZAc,34143
42
+ eflips_depot-4.15.1.dist-info/RECORD,,