Skip to content

dustinscurlock/grid-topology-engine

Repository files navigation

Grid Topology Engine — Prototype

A Python + Flask prototype for modeling distribution feeder topology, tracing fault isolation paths, and generating switching plans using BFS. Built by a power system operator exploring how far deterministic graph algorithms can go for fault isolation and restoration planning without a full Distribution Management System (DMS).

This is a deliberate, working prototype — not a finished product. It's published because the domain is underrepresented on GitHub and the code reflects real operational thinking about how faults are isolated and load is restored.


System Architecture

Architecture

Screenshots

Normal Feeder State

The feeder with all sources energized and no faults present.

Normal Feeder

Fault Insertion

A fault is inserted on a feeder segment. The system traces isolation paths and determines candidate switching operations.

Fault

Restoration Analysis

BFS analysis determines energized regions, frontier edges, and possible switching plans to restore service.

Restoration

Original Vision

The project started with a specific goal: use an LLM as the interface between a grid operator and the feeder model.

The idea was that an operator could describe a situation in plain language — "there's a fault on the E lateral, I need to isolate it and pick up as much load as possible from the Tie2 side" — and the LLM would translate that into structured calls against the deterministic BFS engine, then format the results as a step-by-step switching procedure in the style of an actual utility switching order:

1. OPEN HB11.E|HB11.E1 (recloser) — isolate fault
2. VERIFY HB11.E1 dead
3. CLOSE HB11.E5|HB11.Tie2 (disconnect) — restore via Tie2
4. VERIFY load picked up on E1–E5 section

The BFS layer exists specifically to keep the LLM grounded. Topology, energization state, and isolation logic are computed deterministically — the LLM handles language and procedure formatting, not graph reasoning. This prevents the model from hallucinating switching steps that would be physically wrong or operationally dangerous.

That architecture — deterministic engine as the source of truth, LLM as the natural language intermediary — is where the project was heading before development paused.


What It Does

  • Feeder graph model — nodes and edges representing a distribution feeder (Hunterwood B11), with component types (breaker, disconnect, recloser, regulator, fuse, tie)
  • Source BFS — traces energization from all source nodes simultaneously, respecting open/faulted edge states
  • Regions BFS — identifies contiguous energized segments and assigns each to a source region
  • Fault isolation — given a faulted edge, walks the path back to source and finds the nearest isolation device(s)
  • Alternate feed planning — traces paths from alternate/tie sources to both endpoints of the faulted edge
  • Switching plan generation — ranks and proposes a switching sequence to isolate the fault and restore as many nodes as possible via backfeed
  • Interactive SVG UI — browser-based single-line diagram; left-click toggles switches open/closed, right-click inserts or clears faults, "Run BFS" re-analyzes and repaints the diagram

Algorithm Overview

The restoration engine models the feeder as a graph where:

  • Nodes represent buses, taps, and connection points
  • Edges represent electrical devices or line segments
  • Edge state determines whether current can flow (closed, open, faulted)

The analysis pipeline works in several stages:

  1. Source BFS

    A multi-source breadth-first search begins at all energized source nodes and traverses closed edges to determine which portions of the feeder are energized.

  2. Region Identification

    Energized nodes are grouped into contiguous regions associated with the source feeding them. This allows the UI to display energized "islands".

  3. Fault Isolation

    When a faulted edge is inserted, the engine traces the path from the fault back toward the primary source to identify the nearest upstream isolation device capable of clearing the faulted section.

  4. Alternate Feed Planning

    Paths from alternate or tie sources are evaluated to determine whether de-energized sections of the feeder can be restored via backfeed.

  5. Restoration Ranking

    Candidate switching plans are simulated and ranked based on how many nodes can be re-energized while respecting the current device states.

Because the topology analysis is deterministic, the switching recommendations are derived entirely from graph structure and device metadata rather than heuristics or machine learning.


Stack

  • Python 3 / Flask
  • NetworkX (graph construction)
  • Vanilla JS + SVG (frontend — no framework)
  • Matplotlib (used for layout math, not rendered in the UI)

Running It

pip install -r requirements.txt
python app.py

Then open http://127.0.0.1:8000 in a browser.


Project Structure

app.py                  Flask app, /analyze endpoint, orchestration
feeder_graph.py         Feeder definition (nodes, edges, components, initial state)
component_dictionary.py Component type metadata (isolation capability, protective, etc.)
source_bfs.py           Energization trace from all sources
regions_bfs.py          Contiguous energized region identification
find_path_bfs.py        Path from faulted edge back to primary source
plan_path_bfs.py        Paths from alternate/tie sources to faulted edge endpoints
rank_restore.py         Switching plan generation and node pickup ranking
svg.py                  SVG single-line diagram builder
static/index.html       Browser UI

Honest Limitations

This is a prototype with a hardcoded feeder. Before it could be used for anything real, it would need:

  • General feeder loader — read from CIM, GeoJSON, or a database instead of hardcoded Python dicts
  • Load modeling — no ampacity or thermal ratings; the switching planner picks up nodes but doesn't check whether the path can carry the load
  • Persistent stateCURRENT_STATE lives in memory and resets on server restart
  • Multi-feeder support — currently single-feeder only
  • Substation modeling — no bus work, transformer, or high-side switching
  • Radial enforcement — no check to prevent inadvertent paralleling during restoration
  • Telemetry integration — all state is manually toggled; no SCADA feed

What's Interesting About It (If You Work in This Space)

The switching plan logic in rank_restore.py reflects how a dispatcher actually thinks: isolate the fault with the nearest upstream device, then evaluate whether either tie source can pick up the de-energized sections and how many customers that restores. The BFS structure makes constraint propagation straightforward — open an edge, re-run, compare node counts.

The component dictionary approach (component_dictionary.py) is intentionally simple but maps cleanly to real device classifications — isolation capability and protective function are tracked separately, which matters when you're deciding what you can open remotely vs. what requires a truck.


Status

Active development paused. The foundation is solid and the core algorithms work. The natural next steps would be ampacity checking on backfeed paths and loading a real feeder from an external source. Substation development and integration is also planned.

Pull requests and issues welcome, especially from anyone with domain experience.


License

MIT

About

Prototype system for modeling electric distribution grid topology and generating fault isolation and restoration switching plans using graph algorithms.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors