Node Breaker Models
This section contains description of transmission node-breaker modeling concepts and usage of the CIMantic Graphs NodeBreakerModel class for accessing CIM feeder models in a centralized and distributed manner.
All diagrams within this page have been auto-generated using mermaid.js and the cimgraph.utils module of CIMantic Graphs, which can be imported using
[1]:
from cimgraph import utils
from mermaid import Mermaid
Transmission Network Models in CIM
CIM was originally designed to support full node-breaker modeling of transmission network models and substations
[2]:
# TODO: Provide sample Node Breaker Model diagram
Loading a FeederModel from an XML File
It is possible to use CIMantic Graphs without any database and instead directly build the graph from an XML file.
The first step is to import the correct CIM profile to use and set the associated environment variable used by CIM-Graph. For an explanation of CIM profiles, see Profiles Overview
[3]:
import os
os.environ['CIMG_CIM_PROFILE'] = 'cim17v40' # import and env var must match
import cimgraph.data_profile.cim17v40 as cim # import and env var must match
Next, use the XMLFile interface to open the XML file:
[4]:
from cimgraph.databases import XMLFile
file = XMLFile(filename='../../sample_models/maple10nodebreaker.xml')
If custom extensions are used, provide a namespaces dictionary mapping the prefix to the custom namespaces:
[5]:
namespaces={'cim': 'http://iec.ch/TC57/CIM100#',
'gmdm': 'http://epri.com/gmdm/2025#',
'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
'gad': 'http://gridappsd.org/CIM/extension#'}
file = XMLFile(filename='../../sample_models/maple10nodebreaker.xml',
namespaces=namespaces)
Finally, create a new NodeBreakerModel network class to load the transmission model into the graph:
[6]:
from cimgraph.models import NodeBreakerModel
network = NodeBreakerModel(container=None, connection=file)
[7]:
# Get first breaker in graph
breaker = network.first(cim.Breaker)
# Display the line
Mermaid(utils.get_mermaid(breaker))
[7]:
Modifying Files
Objects can be created, modified, or deleted using the .add_to_graph(object), .delete(object), and .create('incremental_file.xml') methods
[8]:
new_breaker = cim.Breaker(name='new_breaker', open=False)
network.add_to_graph(new_breaker)
[9]:
network.delete(new_breaker)
[10]:
network.modify(breaker, 'open', True, incremental_file='breaker_incremental.xml')
Saving to a File
Use the utils.write_xml() and utils.write_json_ld methods to save modified network to file
[11]:
from cimgraph import utils
utils.write_xml(network, '../../sample_models/maple10nodebreaker_modified.xml')
utils.write_json_ld(network, '../../sample_models/maple10nodebreaker_modified.jsonld')
[ ]:
[ ]:
Advanced Concepts - Distributed Modeling
These features are still in development and intended to provide a preview of planned capabilities. Under certain use cases, users may wish to instantiate a new typed property graph for each substation and voltage level as its own standalone network.
[12]:
network = NodeBreakerModel(container=None, connection=file, distributed = True)
[13]:
for sr_area in network.distributed_areas[cim.SubGeographicalRegion].values():
print("subregion", sr_area.container.name)
for sub_area in sr_area.distributed_areas[cim.Substation].values():
print("substation", sub_area.container.name)
for vl_area in sub_area.distributed_areas[cim.VoltageLevel].values():
print("voltage level", vl_area.container.name)
for feeder_area in sub_area.distributed_areas[cim.Feeder].values():
print("feeder", feeder_area.container.name, "contains PV aggregates")
feeder_area.get_all_edges(cim.PowerElectronicsConnection)
feeder_area.get_all_edges(cim.PhotoVoltaicUnit)
if cim.PowerElectronicsConnection in feeder_area.graph:
for pv in feeder_area.graph[cim.PowerElectronicsConnection].values():
print(pv.name, float(pv.p)/1000000, "MW")
else:
print("none")
[ ]: