The Virtual Power Plant Simulator is an open source project for simulating small C&I site-scale Virtual Power Plant (VPP) behavior in real time.
The simulator models a local distribution feeder with a mix of flexible and inflexible devices, including:
- ☀️ On-site solar PV
- 🔋 On-site battery storage systems
- ⚙️ Flexible electric loads (e.g., EV charging, pumps, refrigeration)
- 💡 Baseline and controllable site demand
- 🧠 A coordinating aggregator (the "VPP")
- 🚨 Demand response events for temporary load reduction
- 📏 Feeder import/export capacity constraints
- 📊 End-of-run KPI reporting
The simulation advances in fast-forwarded, discrete time steps (e.g. 5-minute intervals), allowing users to explore different configurations and control strategies through terminal output.
🚧 Work in Progress – This repository is under active development and working towards MVP status.
Stay tuned!
Running the default binary triggers a demonstrative 24-step (1-hr interval) simulation with:
- Baseline load + solar generation
- Flexible electric demand (EV/pump/refrigeration-like profiles)
- Battery tracking control
- Feeder import/export limits
- A demand response event window
- Post-run KPI summary
Run methods:
cargo run --release -- --preset democargo run --release -- --scenario /path/to/scenario.tomlcargo build --release
./target/release/vpp-sim --preset demoWrite per-timestep telemetry to CSV (schema v1):
cargo run --release -- --preset demo --telemetry-out telemetry.csvRun the HTTP API for state + telemetry snapshots:
cargo run --release -- --preset demo --api-bind 127.0.0.1:8080Example requests:
curl -s http://127.0.0.1:8080/statecurl -s http://127.0.0.1:8080/telemetrycurl -s "http://127.0.0.1:8080/telemetry?from=4&to=8"Example scenario file:
houses = 20
feeder_kw = 200.0
seed = 42
steps_per_day = 24
solar_kw_peak_per_house = 5.0
dr_start_step = 17
dr_end_step = 21
dr_reduction_kw_per_house = 1.5Time (Hr) 0: BaseLoad=1.35 kW, RawBase=1.35 kW, Forecast=0.79 kW, Target=0.79 kW,
SolarPV=0.00 kW, EvCharger=0.00 kW (Req=0.00, DR=0.00, Cap=0.00),
Battery=0.56 kW (SoC=44.1%), MainFeeder=0.79 kW, Error=0.00 kW,
DR(req=0.00, done=0.00), LimitOK=true
...
# demand response event active; EV/baseload may be curtailed
Time (Hr) 18: BaseLoad=0.40 kW, RawBase=1.20 kW, Forecast=0.96 kW, Target=0.79 kW,
SolarPV=0.00 kW, EvCharger=0.70 kW (Req=1.20, DR=0.70, Cap=0.70),
Battery=0.31 kW (SoC=40.2%), MainFeeder=0.79 kW, Error=0.00 kW,
DR(req=1.50, done=1.30), LimitOK=true
...
--- KPI Report ---
RMSE tracking error: 0.084 kW
Curtailment achieved: 92.5%
Feeder peak load: 3.91 kW
Notes:
- Example values are illustrative; exact numbers depend on random seeds and configuration.
- Same scenario + same seed yields deterministic telemetry output.
LimitOK=trueindicates the feeder stayed within configured import/export limits at that timestep.--telemetry-outwrites CSV columns:timestep,time_hr,target_kw,feeder_kw,tracking_error_kw,baseload_kw,solar_kw,ev_requested_kw,ev_dispatched_kw,battery_kw,battery_soc,dr_requested_kw,dr_achieved_kw,limit_ok
Canonical scenario format is TOML. Built-in presets live under ./scenarios/:
baseline.tomlhigh_solar.tomldr_event.toml
Run them via CLI:
cargo run --release -- --scenario scenarios/baseline.tomlcargo run --release -- --scenario scenarios/high_solar.tomlcargo run --release -- --scenario scenarios/dr_event.tomlBare filenames are also resolved from ./scenarios, for example:
cargo run --release -- --scenario high_solar.tomlScenario schema keys:
houses(u32, > 0)feeder_kw(f32, > 0)seed(u64)steps_per_day(usize, > 0)solar_kw_peak_per_house(f32, >= 0)dr_start_step(usize,< steps_per_day)dr_end_step(usize,<= steps_per_dayand> dr_start_step)dr_reduction_kw_per_house(f32, >= 0)
The API serves JSON objects using the same schema v1 field names as telemetry CSV.
GET /statereturns the latest snapshot object.GET /telemetryreturns all recorded telemetry rows.GET /telemetry?from=<timestep>&to=<timestep>returns rows in an inclusive timestep range.
Hosted docs:
The documentation for this project can also be opened locally using:
cargo doc --openIt contains detailed information about the architecture, modules, and usage of the simulator.
This project is licensed under the MIT License. See the LICENSE file for details.