mobev 0.2.0__tar.gz → 0.4.0__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.
Files changed (137) hide show
  1. mobev-0.4.0/PKG-INFO +231 -0
  2. mobev-0.4.0/README.md +206 -0
  3. {mobev-0.2.0 → mobev-0.4.0}/mobev/__init__.py +24 -12
  4. {mobev-0.2.0 → mobev-0.4.0}/mobev/_version.py +1 -1
  5. mobev-0.4.0/mobev/aggregation/__init__.py +5 -0
  6. mobev-0.4.0/mobev/aggregation/results_aggregator.py +591 -0
  7. mobev-0.4.0/mobev/charging/__init__.py +6 -0
  8. mobev-0.4.0/mobev/charging/charging_simulator.py +976 -0
  9. mobev-0.4.0/mobev/charging/decision_engine.py +741 -0
  10. mobev-0.4.0/mobev/charging/events.py +439 -0
  11. mobev-0.4.0/mobev/charging/profiles.py +141 -0
  12. mobev-0.4.0/mobev/charging/sessions.py +238 -0
  13. mobev-0.4.0/mobev/cli/__init__.py +1 -0
  14. mobev-0.4.0/mobev/cli/run_mobev.py +205 -0
  15. mobev-0.4.0/mobev/config/__init__.py +39 -0
  16. mobev-0.4.0/mobev/config/config.py +296 -0
  17. mobev-0.4.0/mobev/config/defaults.py +88 -0
  18. mobev-0.4.0/mobev/config/load.py +274 -0
  19. mobev-0.4.0/mobev/config/models.py +207 -0
  20. mobev-0.4.0/mobev/config/random.py +48 -0
  21. mobev-0.4.0/mobev/config/serialization.py +39 -0
  22. mobev-0.4.0/mobev/config/validation.py +306 -0
  23. mobev-0.4.0/mobev/pipeline.py +325 -0
  24. mobev-0.4.0/mobev/plot/__init__.py +15 -0
  25. mobev-0.4.0/mobev/plot/axes.py +29 -0
  26. mobev-0.4.0/mobev/plot/output.py +45 -0
  27. mobev-0.4.0/mobev/plot/plot.py +273 -0
  28. mobev-0.4.0/mobev/plot/profile_data.py +118 -0
  29. mobev-0.4.0/mobev/plot/profile_render.py +147 -0
  30. mobev-0.4.0/mobev/plot/tariff.py +47 -0
  31. mobev-0.4.0/mobev/plot/time.py +67 -0
  32. mobev-0.4.0/mobev/plot/trip_map_data.py +224 -0
  33. mobev-0.4.0/mobev/plot/trip_map_html.py +139 -0
  34. mobev-0.4.0/mobev/plot/weather.py +75 -0
  35. mobev-0.4.0/mobev/results/__init__.py +19 -0
  36. mobev-0.4.0/mobev/results/aggregated_results.py +797 -0
  37. mobev-0.4.0/mobev/results/charging_simulation.py +261 -0
  38. mobev-0.4.0/mobev/results/common.py +254 -0
  39. mobev-0.4.0/mobev/results/indicators.py +350 -0
  40. mobev-0.4.0/mobev/results/metadata.py +404 -0
  41. mobev-0.4.0/mobev/results/output.py +226 -0
  42. mobev-0.4.0/mobev/results/prepared_trips.py +288 -0
  43. mobev-0.4.0/mobev/results/scenario_inputs.py +426 -0
  44. mobev-0.4.0/mobev/results/schemas.py +194 -0
  45. mobev-0.4.0/mobev/results/simulation_results.py +98 -0
  46. {mobev-0.2.0 → mobev-0.4.0}/mobev/scenario/__init__.py +2 -1
  47. mobev-0.4.0/mobev/scenario/fleet.py +122 -0
  48. mobev-0.4.0/mobev/scenario/parking.py +358 -0
  49. mobev-0.4.0/mobev/scenario/scenario_builder.py +638 -0
  50. mobev-0.4.0/mobev/scenario/stations.py +85 -0
  51. mobev-0.4.0/mobev/scenario/tariffs.py +241 -0
  52. mobev-0.4.0/mobev/scenario/weather.py +130 -0
  53. mobev-0.4.0/mobev/trips/boundaries.py +343 -0
  54. mobev-0.4.0/mobev/trips/chains.py +279 -0
  55. mobev-0.4.0/mobev/trips/distances.py +162 -0
  56. mobev-0.4.0/mobev/trips/source.py +428 -0
  57. mobev-0.4.0/mobev/trips/trip_preparer.py +452 -0
  58. {mobev-0.2.0 → mobev-0.4.0}/mobev/utils/logger.py +33 -10
  59. mobev-0.4.0/mobev.egg-info/PKG-INFO +231 -0
  60. mobev-0.4.0/mobev.egg-info/SOURCES.txt +93 -0
  61. mobev-0.4.0/mobev.egg-info/entry_points.txt +2 -0
  62. {mobev-0.2.0 → mobev-0.4.0}/mobev.egg-info/requires.txt +1 -0
  63. {mobev-0.2.0 → mobev-0.4.0}/pyproject.toml +10 -4
  64. mobev-0.4.0/tests/test_aggregated_results_plotting.py +54 -0
  65. mobev-0.4.0/tests/test_charging_decision.py +458 -0
  66. mobev-0.4.0/tests/test_charging_simulator.py +574 -0
  67. mobev-0.4.0/tests/test_cli.py +153 -0
  68. mobev-0.4.0/tests/test_config.py +468 -0
  69. mobev-0.4.0/tests/test_logger.py +20 -0
  70. mobev-0.4.0/tests/test_metadata.py +112 -0
  71. mobev-0.4.0/tests/test_output.py +131 -0
  72. mobev-0.4.0/tests/test_pipeline.py +309 -0
  73. mobev-0.4.0/tests/test_pipeline_api.py +198 -0
  74. mobev-0.4.0/tests/test_plot_export.py +66 -0
  75. mobev-0.4.0/tests/test_random.py +38 -0
  76. mobev-0.4.0/tests/test_results.py +277 -0
  77. mobev-0.4.0/tests/test_results_aggregator.py +493 -0
  78. mobev-0.4.0/tests/test_results_indicators.py +234 -0
  79. mobev-0.4.0/tests/test_scenario_builder.py +258 -0
  80. mobev-0.4.0/tests/test_tariff_builder.py +358 -0
  81. mobev-0.4.0/tests/test_tariff_plotting.py +68 -0
  82. mobev-0.4.0/tests/test_trip_boundaries.py +471 -0
  83. mobev-0.4.0/tests/test_trip_chains.py +61 -0
  84. mobev-0.4.0/tests/test_trip_distances.py +115 -0
  85. {mobev-0.2.0 → mobev-0.4.0}/tests/test_trip_plotting.py +56 -67
  86. mobev-0.4.0/tests/test_trip_preparer.py +225 -0
  87. mobev-0.4.0/tests/test_trip_source.py +116 -0
  88. mobev-0.4.0/tests/test_weather.py +149 -0
  89. mobev-0.4.0/tests/test_weather_demand.py +138 -0
  90. mobev-0.4.0/tests/test_weather_plotting.py +83 -0
  91. mobev-0.2.0/PKG-INFO +0 -191
  92. mobev-0.2.0/README.md +0 -167
  93. mobev-0.2.0/mobev/charging/__init__.py +0 -5
  94. mobev-0.2.0/mobev/charging/charging_simulator.py +0 -605
  95. mobev-0.2.0/mobev/charging/tariffs.py +0 -451
  96. mobev-0.2.0/mobev/core/config.py +0 -900
  97. mobev-0.2.0/mobev/core/pipeline.py +0 -206
  98. mobev-0.2.0/mobev/plotting/__init__.py +0 -6
  99. mobev-0.2.0/mobev/plotting/api.py +0 -250
  100. mobev-0.2.0/mobev/plotting/data.py +0 -122
  101. mobev-0.2.0/mobev/plotting/render.py +0 -83
  102. mobev-0.2.0/mobev/plotting/tariff.py +0 -137
  103. mobev-0.2.0/mobev/plotting/trips.py +0 -376
  104. mobev-0.2.0/mobev/profiles/__init__.py +0 -5
  105. mobev-0.2.0/mobev/profiles/profile_aggregator.py +0 -382
  106. mobev-0.2.0/mobev/results/__init__.py +0 -54
  107. mobev-0.2.0/mobev/results/aggregated_profiles.py +0 -118
  108. mobev-0.2.0/mobev/results/charging_simulation.py +0 -133
  109. mobev-0.2.0/mobev/results/common.py +0 -281
  110. mobev-0.2.0/mobev/results/factories.py +0 -87
  111. mobev-0.2.0/mobev/results/prepared_trips.py +0 -91
  112. mobev-0.2.0/mobev/results/results_indicators.py +0 -132
  113. mobev-0.2.0/mobev/results/scenario_inputs.py +0 -219
  114. mobev-0.2.0/mobev/results/simulation_results.py +0 -48
  115. mobev-0.2.0/mobev/scenario/scenario_builder.py +0 -401
  116. mobev-0.2.0/mobev/trips/trip_preparer.py +0 -656
  117. mobev-0.2.0/mobev/utils/metadata.py +0 -132
  118. mobev-0.2.0/mobev.egg-info/PKG-INFO +0 -191
  119. mobev-0.2.0/mobev.egg-info/SOURCES.txt +0 -52
  120. mobev-0.2.0/tests/test_aggregated_profile_plotting.py +0 -136
  121. mobev-0.2.0/tests/test_charging_simulator.py +0 -149
  122. mobev-0.2.0/tests/test_config.py +0 -93
  123. mobev-0.2.0/tests/test_pipeline.py +0 -154
  124. mobev-0.2.0/tests/test_pipeline_api.py +0 -121
  125. mobev-0.2.0/tests/test_profile_aggregator.py +0 -235
  126. mobev-0.2.0/tests/test_results.py +0 -99
  127. mobev-0.2.0/tests/test_results_indicators.py +0 -116
  128. mobev-0.2.0/tests/test_scenario_builder.py +0 -78
  129. mobev-0.2.0/tests/test_tariff_pipeline.py +0 -36
  130. mobev-0.2.0/tests/test_trip_pipeline.py +0 -64
  131. mobev-0.2.0/tests/test_unit_boundaries.py +0 -73
  132. mobev-0.2.0/tests/test_utils.py +0 -310
  133. {mobev-0.2.0 → mobev-0.4.0}/LICENSE +0 -0
  134. {mobev-0.2.0 → mobev-0.4.0}/mobev/trips/__init__.py +0 -0
  135. {mobev-0.2.0 → mobev-0.4.0}/mobev.egg-info/dependency_links.txt +0 -0
  136. {mobev-0.2.0 → mobev-0.4.0}/mobev.egg-info/top_level.txt +0 -0
  137. {mobev-0.2.0 → mobev-0.4.0}/setup.cfg +0 -0
mobev-0.4.0/PKG-INFO ADDED
@@ -0,0 +1,231 @@
1
+ Metadata-Version: 2.4
2
+ Name: mobev
3
+ Version: 0.4.0
4
+ Summary: MobEV: mobility-based, geolocalized EV charging-demand model.
5
+ Author-email: Yoann Chiche <yoann.chiche@minesparis.psl.eu>
6
+ License: MIT
7
+ Project-URL: Repository, https://git.persee.minesparis.psl.eu/planeterr/mobev
8
+ Project-URL: Documentation, https://pages.persee.minesparis.psl.eu/planeterr/mobev/
9
+ Classifier: Programming Language :: Python :: 3.13
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.13
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: pandas
15
+ Requires-Dist: numpy
16
+ Requires-Dist: geopandas
17
+ Requires-Dist: pyproj
18
+ Requires-Dist: shapely>=2
19
+ Requires-Dist: polars
20
+ Requires-Dist: PyYAML
21
+ Requires-Dist: matplotlib
22
+ Requires-Dist: pyarrow
23
+ Requires-Dist: colorlog
24
+ Dynamic: license-file
25
+
26
+ # MobEV
27
+
28
+ <p align="left">
29
+ <a href="https://pages.persee.minesparis.psl.eu/planeterr/mobev/">
30
+ <img src="https://pages.persee.minesparis.psl.eu/planeterr/mobev/_static/logo.png" alt="MobEV logo" width="220">
31
+ </a>
32
+ </p>
33
+
34
+ [![Python](https://img.shields.io/badge/python-3.13%2B-3776AB)](https://www.python.org/)
35
+ [![PyPI](https://img.shields.io/pypi/v/mobev)](https://pypi.org/project/mobev/)
36
+ [![uv](https://img.shields.io/badge/uv-managed-blue)](https://docs.astral.sh/uv/)
37
+
38
+ MobEV is a mobility-based, geolocalized electric-vehicle (EV) charging-demand
39
+ model. It turns weekly geolocated car trips into charging sessions and demand
40
+ profiles for distribution-network studies. MobEV samples an EV fleet and
41
+ charging access, simulates battery state of charge and charging decisions, and
42
+ reports demand at the configured timestep.
43
+
44
+ MobEV requires Python 3.13 or newer. Install the published package with:
45
+
46
+ ```bash
47
+ python -m pip install mobev
48
+ # or
49
+ uv add mobev
50
+ ```
51
+
52
+ [Read the full documentation](https://pages.persee.minesparis.psl.eu/planeterr/mobev/).
53
+
54
+ ## How the pipeline works
55
+
56
+ The main pipeline runs three stages in order:
57
+
58
+ 1. **Prepare trips:** validate and expand weekday and weekend trip data across
59
+ the configured simulation dates.
60
+ 2. **Build the scenario:** sample EV ownership and vehicle attributes, assign
61
+ parking and charging opportunities, and prepare tariffs and optional weather.
62
+ 3. **Simulate charging:** process trips and parking chronologically to produce
63
+ battery state, charging sessions, and timestep charging profiles.
64
+
65
+ In Python, `pipeline.run()` returns the results from those stages. Aggregation
66
+ is a separate analysis step: it groups the detailed charging profiles by a
67
+ chosen population or location attribute and sums active charging power at each
68
+ timestep. The default `total` aggregate gives the combined load profile;
69
+ `location_type` and `charging_power` aggregates let you inspect subsets.
70
+
71
+ ## Inputs and formats
72
+
73
+ ### Configuration file
74
+
75
+ The simulation configuration is a YAML file. It defines the simulation dates
76
+ and timestep, fleet and battery behavior, charging rules, tariffs, and
77
+ locations. Relative tariff paths resolve from the YAML file. See the
78
+ [configuration reference](https://pages.persee.minesparis.psl.eu/planeterr/mobev/configuration.html).
79
+
80
+ A minimal configuration with a flat tariff looks like this:
81
+
82
+ ```yaml
83
+ simulation:
84
+ start_date: 2024-01-01
85
+ end_date: 2024-01-07
86
+ charging:
87
+ target_soc: 0.9
88
+ minimum_parking_time_minutes: 15
89
+ charging_setup_duration_minutes: 0
90
+ range_anxiety:
91
+ type: normal
92
+ mean: 0.5
93
+ std: 0.15
94
+ min: 0.1
95
+ max: 0.9
96
+ tariff:
97
+ unit: EUR/kWh
98
+ flat_tariff: 0.30
99
+ ```
100
+
101
+ Other settings use their documented defaults. For the complete template and
102
+ all parameters, see the [configuration reference](https://pages.persee.minesparis.psl.eu/planeterr/mobev/configuration.html).
103
+
104
+ ### Trip files
105
+
106
+ Pass a directory containing `weekday_trips.gpkg` and `weekend_trips.gpkg`.
107
+ Each GeoPackage needs a declared CRS, line geometry, and the fields
108
+ `person_id`, `trip_index`, `preceding_activity_index`,
109
+ `following_activity_index`, `departure_time`, `arrival_time`,
110
+ `preceding_purpose`, `following_purpose`, `is_first`, `is_last`, and `mode`.
111
+ Times are seconds since source-day midnight; only trimmed, case-insensitive
112
+ `car` rows are retained. See the [trip input schema](https://pages.persee.minesparis.psl.eu/planeterr/mobev/inputs.html#trip-inputs).
113
+
114
+ ### Tariff files (optional)
115
+
116
+ Configure one or more CSV files under `tariff.files`. Each file has a zero-based
117
+ contiguous integer positional index and exactly one numeric `price` or
118
+ `price_eur_kwh` column in EUR/kWh. Without tariff files, MobEV uses the
119
+ configured flat tariff. Relative paths resolve from the configuration file.
120
+ See [tariff inputs](https://pages.persee.minesparis.psl.eu/planeterr/mobev/inputs.html#tariff-inputs).
121
+
122
+ ### Weather file (optional)
123
+
124
+ For `battery.consumption_mode: temperature`, pass a separate CSV or Parquet
125
+ file containing `datetime` and numeric `air_temperature` values in °C.
126
+ Timestamps are normalized to UTC, and every hour in the simulation horizon
127
+ needs coverage. See [weather inputs](https://pages.persee.minesparis.psl.eu/planeterr/mobev/inputs.html#weather-inputs)
128
+ and [battery consumption](https://pages.persee.minesparis.psl.eu/planeterr/mobev/battery-consumption.html).
129
+
130
+ Pass the trip directory, YAML configuration, and weather file separately. The
131
+ [input guide](https://pages.persee.minesparis.psl.eu/planeterr/mobev/inputs.html)
132
+ describes field requirements, validation, and supported behavior.
133
+
134
+ ## Run from Python
135
+
136
+ ```python
137
+ from mobev import SimulationPipeline
138
+
139
+ pipeline = SimulationPipeline.from_yaml(
140
+ config_path="config/config.yaml",
141
+ trip_source_dir="data/input/trips/TRIP_FOLDER",
142
+ )
143
+ result = pipeline.run()
144
+
145
+ # Detailed timestep-level charging demand
146
+ print(result.charging_simulation.charging_profiles_df.head())
147
+
148
+ # Combined demand profile (aggregation is separate from run())
149
+ total = pipeline.aggregate(by="total")
150
+ print(total.aggregated_profiles_df.head())
151
+ ```
152
+
153
+ The default `battery.consumption_mode` is `none`; `season` applies configured
154
+ seasonal factors. For temperature-based consumption, set the mode to
155
+ `temperature` and pass weather separately:
156
+
157
+ ```python
158
+ pipeline = SimulationPipeline.from_yaml(
159
+ config_path="config/config.yaml",
160
+ trip_source_dir="data/input/trips/TRIP_FOLDER",
161
+ weather_file="data/input/weather.csv",
162
+ )
163
+ result = pipeline.run()
164
+ ```
165
+
166
+ ## Run from the command line
167
+
168
+ The installed `mobev` command writes stage tables as Parquet, indicator tables
169
+ as CSV, a log file, and (by default) metadata and analysis plots.
170
+
171
+ ```bash
172
+ mobev \
173
+ --trips-dir data/input/trips/TRIP_FOLDER \
174
+ --output-dir output \
175
+ --config config/config.yaml
176
+ ```
177
+
178
+ For temperature-based consumption, also pass the separate weather file:
179
+
180
+ ```bash
181
+ mobev \
182
+ --trips-dir data/input/trips/TRIP_FOLDER \
183
+ --output-dir output \
184
+ --config config/config.yaml \
185
+ --weather data/input/weather.csv
186
+ ```
187
+
188
+ `--trips-dir` and `--output-dir` are required. `--config` defaults to
189
+ `config/config.yaml`; `--save-metadata` and `--analyze-results` default to
190
+ `true`. Use `--max-profiles` to limit plotted vehicle and location groups and
191
+ `--weekday` to add plots for a chosen weekday. See all [CLI options and output
192
+ details](https://pages.persee.minesparis.psl.eu/planeterr/mobev/workflow.html#command-line-runner).
193
+
194
+ ## Aggregate and plot results
195
+
196
+ Aggregation operates on a completed run and returns a separate result. For
197
+ example, aggregate charging by location type or by nominal charger power:
198
+
199
+ ```python
200
+ by_location_type = pipeline.aggregate(by="location_type")
201
+ by_charging_power = pipeline.aggregate(
202
+ by="charging_power", charging_powers=[7.4]
203
+ )
204
+
205
+ by_location_type.plot(category="location_type", save_path="by_type.png")
206
+ by_charging_power.plot(category="charging_power_kw", save_path="by_power.png")
207
+ ```
208
+
209
+ These category plots show how the load profile is distributed across location
210
+ types and charger power levels:
211
+
212
+ ![Charging demand profile by location type](https://pages.persee.minesparis.psl.eu/planeterr/mobev/_static/test21_location_profile_by_type.png)
213
+
214
+ ![Charging demand profile by charging power](https://pages.persee.minesparis.psl.eu/planeterr/mobev/_static/test21_charging_power_category.png)
215
+
216
+ See the [visualization guide](https://pages.persee.minesparis.psl.eu/planeterr/mobev/visualization.html)
217
+ for aggregation modes, filters, sampling, indicators, and plotting options.
218
+
219
+ ## Documentation and project links
220
+
221
+ - [Full documentation](https://pages.persee.minesparis.psl.eu/planeterr/mobev/)
222
+ - [Input formats](https://pages.persee.minesparis.psl.eu/planeterr/mobev/inputs.html)
223
+ - [Configuration reference](https://pages.persee.minesparis.psl.eu/planeterr/mobev/configuration.html)
224
+ - [Charging decision algorithm](https://pages.persee.minesparis.psl.eu/planeterr/mobev/charging-algorithm.html)
225
+ - [Results reference](https://pages.persee.minesparis.psl.eu/planeterr/mobev/results.html)
226
+ - [Changelog](https://pages.persee.minesparis.psl.eu/planeterr/mobev/changelog.html)
227
+ - [Contributing](https://pages.persee.minesparis.psl.eu/planeterr/mobev/contribute.html)
228
+ - [API reference](https://pages.persee.minesparis.psl.eu/planeterr/mobev/api/)
229
+
230
+ Build the docs from a checkout with `uv sync --group docs` followed by
231
+ `make -C docs html`.
mobev-0.4.0/README.md ADDED
@@ -0,0 +1,206 @@
1
+ # MobEV
2
+
3
+ <p align="left">
4
+ <a href="https://pages.persee.minesparis.psl.eu/planeterr/mobev/">
5
+ <img src="https://pages.persee.minesparis.psl.eu/planeterr/mobev/_static/logo.png" alt="MobEV logo" width="220">
6
+ </a>
7
+ </p>
8
+
9
+ [![Python](https://img.shields.io/badge/python-3.13%2B-3776AB)](https://www.python.org/)
10
+ [![PyPI](https://img.shields.io/pypi/v/mobev)](https://pypi.org/project/mobev/)
11
+ [![uv](https://img.shields.io/badge/uv-managed-blue)](https://docs.astral.sh/uv/)
12
+
13
+ MobEV is a mobility-based, geolocalized electric-vehicle (EV) charging-demand
14
+ model. It turns weekly geolocated car trips into charging sessions and demand
15
+ profiles for distribution-network studies. MobEV samples an EV fleet and
16
+ charging access, simulates battery state of charge and charging decisions, and
17
+ reports demand at the configured timestep.
18
+
19
+ MobEV requires Python 3.13 or newer. Install the published package with:
20
+
21
+ ```bash
22
+ python -m pip install mobev
23
+ # or
24
+ uv add mobev
25
+ ```
26
+
27
+ [Read the full documentation](https://pages.persee.minesparis.psl.eu/planeterr/mobev/).
28
+
29
+ ## How the pipeline works
30
+
31
+ The main pipeline runs three stages in order:
32
+
33
+ 1. **Prepare trips:** validate and expand weekday and weekend trip data across
34
+ the configured simulation dates.
35
+ 2. **Build the scenario:** sample EV ownership and vehicle attributes, assign
36
+ parking and charging opportunities, and prepare tariffs and optional weather.
37
+ 3. **Simulate charging:** process trips and parking chronologically to produce
38
+ battery state, charging sessions, and timestep charging profiles.
39
+
40
+ In Python, `pipeline.run()` returns the results from those stages. Aggregation
41
+ is a separate analysis step: it groups the detailed charging profiles by a
42
+ chosen population or location attribute and sums active charging power at each
43
+ timestep. The default `total` aggregate gives the combined load profile;
44
+ `location_type` and `charging_power` aggregates let you inspect subsets.
45
+
46
+ ## Inputs and formats
47
+
48
+ ### Configuration file
49
+
50
+ The simulation configuration is a YAML file. It defines the simulation dates
51
+ and timestep, fleet and battery behavior, charging rules, tariffs, and
52
+ locations. Relative tariff paths resolve from the YAML file. See the
53
+ [configuration reference](https://pages.persee.minesparis.psl.eu/planeterr/mobev/configuration.html).
54
+
55
+ A minimal configuration with a flat tariff looks like this:
56
+
57
+ ```yaml
58
+ simulation:
59
+ start_date: 2024-01-01
60
+ end_date: 2024-01-07
61
+ charging:
62
+ target_soc: 0.9
63
+ minimum_parking_time_minutes: 15
64
+ charging_setup_duration_minutes: 0
65
+ range_anxiety:
66
+ type: normal
67
+ mean: 0.5
68
+ std: 0.15
69
+ min: 0.1
70
+ max: 0.9
71
+ tariff:
72
+ unit: EUR/kWh
73
+ flat_tariff: 0.30
74
+ ```
75
+
76
+ Other settings use their documented defaults. For the complete template and
77
+ all parameters, see the [configuration reference](https://pages.persee.minesparis.psl.eu/planeterr/mobev/configuration.html).
78
+
79
+ ### Trip files
80
+
81
+ Pass a directory containing `weekday_trips.gpkg` and `weekend_trips.gpkg`.
82
+ Each GeoPackage needs a declared CRS, line geometry, and the fields
83
+ `person_id`, `trip_index`, `preceding_activity_index`,
84
+ `following_activity_index`, `departure_time`, `arrival_time`,
85
+ `preceding_purpose`, `following_purpose`, `is_first`, `is_last`, and `mode`.
86
+ Times are seconds since source-day midnight; only trimmed, case-insensitive
87
+ `car` rows are retained. See the [trip input schema](https://pages.persee.minesparis.psl.eu/planeterr/mobev/inputs.html#trip-inputs).
88
+
89
+ ### Tariff files (optional)
90
+
91
+ Configure one or more CSV files under `tariff.files`. Each file has a zero-based
92
+ contiguous integer positional index and exactly one numeric `price` or
93
+ `price_eur_kwh` column in EUR/kWh. Without tariff files, MobEV uses the
94
+ configured flat tariff. Relative paths resolve from the configuration file.
95
+ See [tariff inputs](https://pages.persee.minesparis.psl.eu/planeterr/mobev/inputs.html#tariff-inputs).
96
+
97
+ ### Weather file (optional)
98
+
99
+ For `battery.consumption_mode: temperature`, pass a separate CSV or Parquet
100
+ file containing `datetime` and numeric `air_temperature` values in °C.
101
+ Timestamps are normalized to UTC, and every hour in the simulation horizon
102
+ needs coverage. See [weather inputs](https://pages.persee.minesparis.psl.eu/planeterr/mobev/inputs.html#weather-inputs)
103
+ and [battery consumption](https://pages.persee.minesparis.psl.eu/planeterr/mobev/battery-consumption.html).
104
+
105
+ Pass the trip directory, YAML configuration, and weather file separately. The
106
+ [input guide](https://pages.persee.minesparis.psl.eu/planeterr/mobev/inputs.html)
107
+ describes field requirements, validation, and supported behavior.
108
+
109
+ ## Run from Python
110
+
111
+ ```python
112
+ from mobev import SimulationPipeline
113
+
114
+ pipeline = SimulationPipeline.from_yaml(
115
+ config_path="config/config.yaml",
116
+ trip_source_dir="data/input/trips/TRIP_FOLDER",
117
+ )
118
+ result = pipeline.run()
119
+
120
+ # Detailed timestep-level charging demand
121
+ print(result.charging_simulation.charging_profiles_df.head())
122
+
123
+ # Combined demand profile (aggregation is separate from run())
124
+ total = pipeline.aggregate(by="total")
125
+ print(total.aggregated_profiles_df.head())
126
+ ```
127
+
128
+ The default `battery.consumption_mode` is `none`; `season` applies configured
129
+ seasonal factors. For temperature-based consumption, set the mode to
130
+ `temperature` and pass weather separately:
131
+
132
+ ```python
133
+ pipeline = SimulationPipeline.from_yaml(
134
+ config_path="config/config.yaml",
135
+ trip_source_dir="data/input/trips/TRIP_FOLDER",
136
+ weather_file="data/input/weather.csv",
137
+ )
138
+ result = pipeline.run()
139
+ ```
140
+
141
+ ## Run from the command line
142
+
143
+ The installed `mobev` command writes stage tables as Parquet, indicator tables
144
+ as CSV, a log file, and (by default) metadata and analysis plots.
145
+
146
+ ```bash
147
+ mobev \
148
+ --trips-dir data/input/trips/TRIP_FOLDER \
149
+ --output-dir output \
150
+ --config config/config.yaml
151
+ ```
152
+
153
+ For temperature-based consumption, also pass the separate weather file:
154
+
155
+ ```bash
156
+ mobev \
157
+ --trips-dir data/input/trips/TRIP_FOLDER \
158
+ --output-dir output \
159
+ --config config/config.yaml \
160
+ --weather data/input/weather.csv
161
+ ```
162
+
163
+ `--trips-dir` and `--output-dir` are required. `--config` defaults to
164
+ `config/config.yaml`; `--save-metadata` and `--analyze-results` default to
165
+ `true`. Use `--max-profiles` to limit plotted vehicle and location groups and
166
+ `--weekday` to add plots for a chosen weekday. See all [CLI options and output
167
+ details](https://pages.persee.minesparis.psl.eu/planeterr/mobev/workflow.html#command-line-runner).
168
+
169
+ ## Aggregate and plot results
170
+
171
+ Aggregation operates on a completed run and returns a separate result. For
172
+ example, aggregate charging by location type or by nominal charger power:
173
+
174
+ ```python
175
+ by_location_type = pipeline.aggregate(by="location_type")
176
+ by_charging_power = pipeline.aggregate(
177
+ by="charging_power", charging_powers=[7.4]
178
+ )
179
+
180
+ by_location_type.plot(category="location_type", save_path="by_type.png")
181
+ by_charging_power.plot(category="charging_power_kw", save_path="by_power.png")
182
+ ```
183
+
184
+ These category plots show how the load profile is distributed across location
185
+ types and charger power levels:
186
+
187
+ ![Charging demand profile by location type](https://pages.persee.minesparis.psl.eu/planeterr/mobev/_static/test21_location_profile_by_type.png)
188
+
189
+ ![Charging demand profile by charging power](https://pages.persee.minesparis.psl.eu/planeterr/mobev/_static/test21_charging_power_category.png)
190
+
191
+ See the [visualization guide](https://pages.persee.minesparis.psl.eu/planeterr/mobev/visualization.html)
192
+ for aggregation modes, filters, sampling, indicators, and plotting options.
193
+
194
+ ## Documentation and project links
195
+
196
+ - [Full documentation](https://pages.persee.minesparis.psl.eu/planeterr/mobev/)
197
+ - [Input formats](https://pages.persee.minesparis.psl.eu/planeterr/mobev/inputs.html)
198
+ - [Configuration reference](https://pages.persee.minesparis.psl.eu/planeterr/mobev/configuration.html)
199
+ - [Charging decision algorithm](https://pages.persee.minesparis.psl.eu/planeterr/mobev/charging-algorithm.html)
200
+ - [Results reference](https://pages.persee.minesparis.psl.eu/planeterr/mobev/results.html)
201
+ - [Changelog](https://pages.persee.minesparis.psl.eu/planeterr/mobev/changelog.html)
202
+ - [Contributing](https://pages.persee.minesparis.psl.eu/planeterr/mobev/contribute.html)
203
+ - [API reference](https://pages.persee.minesparis.psl.eu/planeterr/mobev/api/)
204
+
205
+ Build the docs from a checkout with `uv sync --group docs` followed by
206
+ `make -C docs html`.
@@ -1,51 +1,63 @@
1
- """MobEV public API."""
2
-
3
1
  from mobev._version import __version__
4
- from mobev.charging import ChargingSimulator
5
- from mobev.core.config import (
2
+ from mobev.charging import ChargingDecisionEngine, ChargingSimulator
3
+ from mobev.config import (
6
4
  BatteryConfig,
7
5
  ChargingConfig,
8
6
  Config,
7
+ EVSegmentConfig,
9
8
  FixedVehicleConfig,
10
9
  FleetConfig,
10
+ FlexibilityConfig,
11
11
  InitialSocConfig,
12
+ LocationChargingConfig,
13
+ PowerDistributionConfig,
14
+ RangeAnxietyConfig,
12
15
  SimulationConfig,
13
- SocLimitsConfig,
16
+ SocDistributionConfig,
14
17
  TariffConfig,
18
+ TariffFileConfig,
15
19
  )
16
- from mobev.core.pipeline import SimulationPipeline
17
- from mobev.profiles import ProfileAggregator
20
+ from mobev.pipeline import SimulationPipeline
21
+ from mobev.aggregation import ResultsAggregator
18
22
  from mobev.results import (
19
- AggregatedProfiles,
23
+ AggregatedResults,
20
24
  ChargingSimulation,
21
25
  Metadata,
22
26
  PreparedTrips,
23
27
  ScenarioInputs,
24
28
  SimulationResults,
25
29
  )
26
- from mobev.scenario import ScenarioBuilder
30
+ from mobev.scenario import ScenarioBuilder, TariffBuilder
27
31
  from mobev.trips import TripPreparer
28
32
 
29
33
  __all__ = [
30
- "AggregatedProfiles",
34
+ "AggregatedResults",
31
35
  "BatteryConfig",
32
36
  "ChargingConfig",
37
+ "ChargingDecisionEngine",
33
38
  "ChargingSimulation",
34
39
  "ChargingSimulator",
35
40
  "Config",
41
+ "EVSegmentConfig",
36
42
  "FixedVehicleConfig",
37
43
  "FleetConfig",
44
+ "FlexibilityConfig",
38
45
  "InitialSocConfig",
46
+ "LocationChargingConfig",
39
47
  "Metadata",
48
+ "PowerDistributionConfig",
40
49
  "PreparedTrips",
41
- "ProfileAggregator",
50
+ "ResultsAggregator",
51
+ "RangeAnxietyConfig",
42
52
  "ScenarioBuilder",
43
53
  "ScenarioInputs",
44
54
  "SimulationConfig",
45
55
  "SimulationPipeline",
46
56
  "SimulationResults",
47
- "SocLimitsConfig",
57
+ "SocDistributionConfig",
58
+ "TariffBuilder",
48
59
  "TariffConfig",
60
+ "TariffFileConfig",
49
61
  "TripPreparer",
50
62
  "__version__",
51
63
  ]
@@ -1,3 +1,3 @@
1
1
  """The single source of truth for the MobEV package version."""
2
2
 
3
- __version__ = "0.2.0"
3
+ __version__ = "0.4.0"
@@ -0,0 +1,5 @@
1
+ """Aggregate charging sessions into load profiles."""
2
+
3
+ from mobev.aggregation.results_aggregator import ResultsAggregator
4
+
5
+ __all__ = ["ResultsAggregator"]