DERMS Case Study

I Built a DERMS Controller That Eliminates Voltage Violations

An OpenDSS quasi-static time-series simulation of a high-PV IEEE 13-bus feeder. I implemented four control strategies—baseline, heuristic Volt-VAR, coordinated optimization, and battery storage—and measured their impact on voltage compliance and curtailment waste.

OpenDSS QSTS 288 timesteps / 24 h CVXPY optimization Real simulation data
Violation reduction
−42%
Heuristic vs. uncontrolled baseline
Best outcome
0 min
Optimization: zero violations in 24 h
Worst baseline
1.075
p.u. max voltage · ANSI limit 1.05
Curtailment gap
808×
Heuristic 970 kWh vs. optimization 1.2 kWh
What I Built

A Python simulation pipeline for grid-edge voltage control

Simulation Engine

Python wrapper around OpenDSS driving a quasi-static time-series power flow. Each 5-minute timestep scales load and PV profiles, solves the power flow, applies control setpoints, and re-solves—288 steps per 24-hour day on the IEEE 13-bus test feeder.

🗂️

Feeder Model

IEEE 13-bus test feeder with synthetic high-PV penetration that causes reverse power flow and midday overvoltage. DER placements are CSV-driven; the same code runs the larger 123-bus production feeder by changing a single config flag.

🎛️

Control Strategies

Baseline: unity power factor, no DERMS.
Heuristic: rule-based Volt-VAR — absorb Q when V > 1.03 p.u., curtail P when V > 1.05.
Optimization: CVXPY convex dispatch minimising curtailment subject to voltage bounds.
Battery: energy shifting to reduce peak-hour curtailment.

How I Evaluated It

Problem framing, control design, and measured outcomes

Problem and Objective

High PV penetration on the IEEE 13-bus feeder caused sustained midday overvoltage beyond ANSI limits. The objective was to bring voltages back into bounds while minimizing renewable energy curtailment.

Method

  • Ran the same load and PV profiles across four control strategies.
  • Compared baseline, heuristic Volt-VAR, optimization dispatch, and battery support.
  • Evaluated each run using the same feeder model and time horizon.

This keeps the comparison fair and isolates the effect of each control strategy.

Result Highlights

Violation Minutes
355 -> 0
Baseline vs optimization
Max Voltage
1.0747 -> 1.0499
Back inside ANSI upper limit
Curtailment Tradeoff
970 -> 1.2 kWh
Heuristic vs optimization

Technical Setup (Short Version)

  • Feeder: IEEE 13-bus OpenDSS model (IEEE13Nodeckt.dss) from the IEEE PES Test Feeder Repository or the OpenDSS package.
  • Inputs: 24-hour load and clear-sky PV profiles from CSV (load_24h.csv, pv_clear_sky_24h.csv) plus DER placement CSV (ders_ieee13.csv).
  • Compute stack: Python orchestration + OpenDSS power flow (OpenDSSDirect.py), with optimization dispatch solved in cvxpy using ECOS.
  • Run loop: every 5 minutes, update load/PV, solve power flow, compute DER commands, apply setpoints, re-solve, then log voltages and KPIs.
python -m src.sim.run_qsts --config config/study_optimization.yaml --pv-scale 4.0
python -m src.analysis.run_phase5_analysis --baseline-config config/study_mvp.yaml --heuristic-config config/study_heuristic.yaml --optimization-config config/study_optimization.yaml --battery-config config/study_battery.yaml --output results/phase5
Key Results

24-hour simulation across four control strategies

Strategy Violation Minutes Max Voltage (p.u.) Curtailment (kWh) Avg Q Dispatch (kvar)
Baseline 355 1.0747 0 0
Heuristic 205 1.0570 970 168
Optimization 0 1.0499 1.2 4.4
Battery
Interactive Playground

Switch strategy, watch the feeder react

Control strategy:
Violation Minutes
min above 1.05 p.u.
Max Voltage
feeder peak (p.u.)
Curtailment
kWh lost
Avg Q Dispatch
kvar average
Voltage Envelope — 24 hours
Feeder-wide min / max / mean. ANSI limits: 0.95–1.05 p.u.
Reactive Power Dispatch
Q absorbed by smart inverters (kvar)
Active Power Curtailment
PV generation withheld to limit voltage rise (kW)