https://bessbaltdmv.streamlit.app/
Where in PJM's BGE load zone should a battery energy storage developer look first, and do the price signals already justify a project?
BGE sits at the intersection of three forces: data center demand growth pushing load higher, an aging coal and gas supply stack approaching retirement, and a state government actively funding storage development. The goal was to find out whether the market data already reflects that opportunity — and build a tool that lets a developer or investor interact with the answer.
A Streamlit dashboard that moves from market context down to site-level project economics:
- PJM vs ERCOT fuel mix — shows why PJM's limited generation diversity concentrates price pressure in zones like BGE
- DMV power plant map — filterable by state, technology, and retirement status; built from EIA 860-M generator data
- BGE grid node map — all 263 BGE pricing nodes (LOAD / GEN / EHV) pulled from PJM Data Miner
- LMP price signal maps — volatility, arbitrage spread, and congestion across BGE substations for Feb–Mar 2026
- Revenue estimator — interactive model: set MW, duration, round-trip efficiency, and operating days to project arbitrage revenue at any substation; outputs $/kW-yr for comparison against industry benchmarks
- Investment thesis — synthesizes the price signal, supply gap, and policy tailwind into a bottom-line case
- Zone-wide arbitrage spreads of $225–$360/MWh across February 2026 are among the strongest in PJM. The Baltimore corridor substations sit consistently at the top.
- Brandon Shores and Wagner retire by 2028–2029. Batteries represent less than 1% of BGE's current supply stack with no large-scale replacements planned.
- Congestion accounts for over 20% of total LMP costs zone-wide — a structural feature, not a weather event. Storage anywhere in BGE captures congestion relief value.
- Maryland's Lower Bills and Local Power Act mobilizes ~$200M for local storage and solar, reducing friction and adding grant revenue on top of merchant returns.
git clone <repo-url>
cd dmvbess
pip install -r requirements.txt
streamlit run app.pyThe data pipeline (load.py) requires an EIA API key set as eia_key in a .env file. Pre-processed CSVs are included in data/ so the dashboard runs without re-fetching.
app.py # Streamlit dashboard
bge.py # BGE LMP data loading and chart functions
compareproviders.py # PJM vs ERCOT fuel mix analysis
dmv.py # BGE generation mix chart
load.py # Data pipeline (EIA API + PJM Data Miner)
project.ipynb # Research notebook with analysis narrative
data/
bge/ # BGE substation LMPs and node info
daily_gen/ # PJM and ERCOT daily generation by fuel type
dmv/ # EIA 860-M plant-level generator data
I started by defining the question — not "what can I visualize" but "what would a BESS developer actually need to know." That framing drove every data source and chart choice.
Data pipeline: Pulled monthly generation data from the EIA 930 API across all of 2025 for PJM and ERCOT, then fetched real-time hourly LMPs from PJM Data Miner for BGE-zone substations. Merged pricing node IDs with substation coordinates and equipment metadata to make the LMP data mappable. Pulled generator-level capacity and retirement data from EIA 860-M to build the supply stack picture.
AI workflow: I used Claude throughout as a collaborative tool — not to generate analysis, but to pressure-test it. When I identified the arbitrage opportunity in the LMP data, I used Claude to check whether the revenue model formula was defensible and what industry benchmarks to compare against. When structuring the dashboard, I used Claude to identify what was missing from the narrative (the PJM/ERCOT context, the conclusion section, the revenue estimator) and to help implement those additions in Streamlit. The analytical decisions — which markets to compare, which substations to highlight, what the data actually means for developers — were mine.
| Source | Description |
|---|---|
| EIA API (Form 930) | Daily generation by fuel type, PJM and ERCOT, full year 2025 |
| PJM Data Miner — RT Hourly LMPs | Real-time hourly LMPs for BGE-zone substations, Feb 1 – Mar 3, 2026 |
| EIA 860-M | Generator-level capacity and technology data, January 2026 |