Metadata-Version: 2.4
Name: mobev
Version: 0.4.0
Summary: MobEV: mobility-based, geolocalized EV charging-demand model.
Author-email: Yoann Chiche <yoann.chiche@minesparis.psl.eu>
License: MIT
Project-URL: Repository, https://git.persee.minesparis.psl.eu/planeterr/mobev
Project-URL: Documentation, https://pages.persee.minesparis.psl.eu/planeterr/mobev/
Classifier: Programming Language :: Python :: 3.13
Classifier: Operating System :: OS Independent
Requires-Python: >=3.13
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pandas
Requires-Dist: numpy
Requires-Dist: geopandas
Requires-Dist: pyproj
Requires-Dist: shapely>=2
Requires-Dist: polars
Requires-Dist: PyYAML
Requires-Dist: matplotlib
Requires-Dist: pyarrow
Requires-Dist: colorlog
Dynamic: license-file

# MobEV

<p align="left">
  <a href="https://pages.persee.minesparis.psl.eu/planeterr/mobev/">
    <img src="https://pages.persee.minesparis.psl.eu/planeterr/mobev/_static/logo.png" alt="MobEV logo" width="220">
  </a>
</p>

[![Python](https://img.shields.io/badge/python-3.13%2B-3776AB)](https://www.python.org/)
[![PyPI](https://img.shields.io/pypi/v/mobev)](https://pypi.org/project/mobev/)
[![uv](https://img.shields.io/badge/uv-managed-blue)](https://docs.astral.sh/uv/)

MobEV is a mobility-based, geolocalized electric-vehicle (EV) charging-demand
model. It turns weekly geolocated car trips into charging sessions and demand
profiles for distribution-network studies. MobEV samples an EV fleet and
charging access, simulates battery state of charge and charging decisions, and
reports demand at the configured timestep.

MobEV requires Python 3.13 or newer. Install the published package with:

```bash
python -m pip install mobev
# or
uv add mobev
```

[Read the full documentation](https://pages.persee.minesparis.psl.eu/planeterr/mobev/).

## How the pipeline works

The main pipeline runs three stages in order:

1. **Prepare trips:** validate and expand weekday and weekend trip data across
   the configured simulation dates.
2. **Build the scenario:** sample EV ownership and vehicle attributes, assign
   parking and charging opportunities, and prepare tariffs and optional weather.
3. **Simulate charging:** process trips and parking chronologically to produce
   battery state, charging sessions, and timestep charging profiles.

In Python, `pipeline.run()` returns the results from those stages. Aggregation
is a separate analysis step: it groups the detailed charging profiles by a
chosen population or location attribute and sums active charging power at each
timestep. The default `total` aggregate gives the combined load profile;
`location_type` and `charging_power` aggregates let you inspect subsets.

## Inputs and formats

### Configuration file

The simulation configuration is a YAML file. It defines the simulation dates
and timestep, fleet and battery behavior, charging rules, tariffs, and
locations. Relative tariff paths resolve from the YAML file. See the
[configuration reference](https://pages.persee.minesparis.psl.eu/planeterr/mobev/configuration.html).

A minimal configuration with a flat tariff looks like this:

```yaml
simulation:
  start_date: 2024-01-01
  end_date: 2024-01-07
charging:
  target_soc: 0.9
  minimum_parking_time_minutes: 15
  charging_setup_duration_minutes: 0
  range_anxiety:
    type: normal
    mean: 0.5
    std: 0.15
    min: 0.1
    max: 0.9
tariff:
  unit: EUR/kWh
  flat_tariff: 0.30
```

Other settings use their documented defaults. For the complete template and
all parameters, see the [configuration reference](https://pages.persee.minesparis.psl.eu/planeterr/mobev/configuration.html).

### Trip files

Pass a directory containing `weekday_trips.gpkg` and `weekend_trips.gpkg`.
Each GeoPackage needs a declared CRS, line geometry, and the fields
`person_id`, `trip_index`, `preceding_activity_index`,
`following_activity_index`, `departure_time`, `arrival_time`,
`preceding_purpose`, `following_purpose`, `is_first`, `is_last`, and `mode`.
Times are seconds since source-day midnight; only trimmed, case-insensitive
`car` rows are retained. See the [trip input schema](https://pages.persee.minesparis.psl.eu/planeterr/mobev/inputs.html#trip-inputs).

### Tariff files (optional)

Configure one or more CSV files under `tariff.files`. Each file has a zero-based
contiguous integer positional index and exactly one numeric `price` or
`price_eur_kwh` column in EUR/kWh. Without tariff files, MobEV uses the
configured flat tariff. Relative paths resolve from the configuration file.
See [tariff inputs](https://pages.persee.minesparis.psl.eu/planeterr/mobev/inputs.html#tariff-inputs).

### Weather file (optional)

For `battery.consumption_mode: temperature`, pass a separate CSV or Parquet
file containing `datetime` and numeric `air_temperature` values in °C.
Timestamps are normalized to UTC, and every hour in the simulation horizon
needs coverage. See [weather inputs](https://pages.persee.minesparis.psl.eu/planeterr/mobev/inputs.html#weather-inputs)
and [battery consumption](https://pages.persee.minesparis.psl.eu/planeterr/mobev/battery-consumption.html).

Pass the trip directory, YAML configuration, and weather file separately. The
[input guide](https://pages.persee.minesparis.psl.eu/planeterr/mobev/inputs.html)
describes field requirements, validation, and supported behavior.

## Run from Python

```python
from mobev import SimulationPipeline

pipeline = SimulationPipeline.from_yaml(
    config_path="config/config.yaml",
    trip_source_dir="data/input/trips/TRIP_FOLDER",
)
result = pipeline.run()

# Detailed timestep-level charging demand
print(result.charging_simulation.charging_profiles_df.head())

# Combined demand profile (aggregation is separate from run())
total = pipeline.aggregate(by="total")
print(total.aggregated_profiles_df.head())
```

The default `battery.consumption_mode` is `none`; `season` applies configured
seasonal factors. For temperature-based consumption, set the mode to
`temperature` and pass weather separately:

```python
pipeline = SimulationPipeline.from_yaml(
    config_path="config/config.yaml",
    trip_source_dir="data/input/trips/TRIP_FOLDER",
    weather_file="data/input/weather.csv",
)
result = pipeline.run()
```

## Run from the command line

The installed `mobev` command writes stage tables as Parquet, indicator tables
as CSV, a log file, and (by default) metadata and analysis plots.

```bash
mobev \
  --trips-dir data/input/trips/TRIP_FOLDER \
  --output-dir output \
  --config config/config.yaml
```

For temperature-based consumption, also pass the separate weather file:

```bash
mobev \
  --trips-dir data/input/trips/TRIP_FOLDER \
  --output-dir output \
  --config config/config.yaml \
  --weather data/input/weather.csv
```

`--trips-dir` and `--output-dir` are required. `--config` defaults to
`config/config.yaml`; `--save-metadata` and `--analyze-results` default to
`true`. Use `--max-profiles` to limit plotted vehicle and location groups and
`--weekday` to add plots for a chosen weekday. See all [CLI options and output
details](https://pages.persee.minesparis.psl.eu/planeterr/mobev/workflow.html#command-line-runner).

## Aggregate and plot results

Aggregation operates on a completed run and returns a separate result. For
example, aggregate charging by location type or by nominal charger power:

```python
by_location_type = pipeline.aggregate(by="location_type")
by_charging_power = pipeline.aggregate(
    by="charging_power", charging_powers=[7.4]
)

by_location_type.plot(category="location_type", save_path="by_type.png")
by_charging_power.plot(category="charging_power_kw", save_path="by_power.png")
```

These category plots show how the load profile is distributed across location
types and charger power levels:

![Charging demand profile by location type](https://pages.persee.minesparis.psl.eu/planeterr/mobev/_static/test21_location_profile_by_type.png)

![Charging demand profile by charging power](https://pages.persee.minesparis.psl.eu/planeterr/mobev/_static/test21_charging_power_category.png)

See the [visualization guide](https://pages.persee.minesparis.psl.eu/planeterr/mobev/visualization.html)
for aggregation modes, filters, sampling, indicators, and plotting options.

## Documentation and project links

- [Full documentation](https://pages.persee.minesparis.psl.eu/planeterr/mobev/)
- [Input formats](https://pages.persee.minesparis.psl.eu/planeterr/mobev/inputs.html)
- [Configuration reference](https://pages.persee.minesparis.psl.eu/planeterr/mobev/configuration.html)
- [Charging decision algorithm](https://pages.persee.minesparis.psl.eu/planeterr/mobev/charging-algorithm.html)
- [Results reference](https://pages.persee.minesparis.psl.eu/planeterr/mobev/results.html)
- [Changelog](https://pages.persee.minesparis.psl.eu/planeterr/mobev/changelog.html)
- [Contributing](https://pages.persee.minesparis.psl.eu/planeterr/mobev/contribute.html)
- [API reference](https://pages.persee.minesparis.psl.eu/planeterr/mobev/api/)

Build the docs from a checkout with `uv sync --group docs` followed by
`make -C docs html`.
