Skip to content

Building Networks from Scratch

This guide walks through creating an electrical network programmatically. You'll learn how to create sheets, nodes, branches, and elements with proper presentations for visualization in Gaia/Vision.

Full Example

View the complete code: 02_build_network.py

Overview

Building a network from scratch involves four key concepts:

  1. Sheets: Canvas pages where network elements are displayed
  2. Nodes: Electrical connection points (busbars, substations)
  3. Branches: Elements connecting two nodes (lines, cables, links)
  4. Elements: Components attached to a single node (sources, loads)

Every element requires a presentation: visual metadata defining how it appears on a sheet.

0

Create the Network and Sheet

python
from pyptp import NetworkMV, configure_logging
from pyptp.elements.color_utils import CL_GRAY
from pyptp.elements.element_utils import Guid
from pyptp.elements.mv.sheet import SheetMV

configure_logging(level="INFO")

# Create an empty network
network = NetworkMV()

# Create a sheet (required for any visual elements)
sheet = SheetMV(SheetMV.General(name="Main", color=CL_GRAY))
sheet.register(network)
sheet_guid: Guid = sheet.general.guid

What's being imported?

  • NetworkMV: Empty balanced network container
  • configure_logging: Enables PyPtP's logging output
  • CL_GRAY: Predefined sheet color constant
  • Guid: Type alias for GUID strings
  • SheetMV: Sheet element class

Key Concepts

  • register(network) adds the element to the network's internal collections and assigns a GUID if not already set
  • sheet.general.guid retrieves the auto-generated GUID for referencing this sheet later

Color Constants

PyPtP provides predefined colors: CL_GRAY, CL_BLUE, CL_GREEN, CL_RED from pyptp.elements.color_utils.

0

Create Nodes

python
from pyptp.elements.mv.node import NodeMV
from pyptp.elements.mv.presentations import NodePresentation

# Create source node
source_node = NodeMV(
    NodeMV.General(name="Source", unom=10.0),
    presentations=[NodePresentation(sheet=sheet_guid, x=150, y=250)],
)
source_node.register(network)

# Create load node
load_node = NodeMV(
    NodeMV.General(name="Load", unom=10.0),
    presentations=[NodePresentation(sheet=sheet_guid, x=450, y=250)],
)
load_node.register(network)

Node Structure

Nodes are constructed with:

ParameterDescription
GeneralCore properties: name, nominal voltage (unom), GUID
presentationsList of visual positions on sheets

NodePresentation

Nodes require a NodePresentation specifying the sheet, x, and y position. Optional parameters include symbol and size.

Full Reference

See Presentations Guide for all parameters.

0

Create a Source

python
from pyptp.elements.mv.source import SourceMV
from pyptp.elements.mv.presentations import ElementPresentation

source = SourceMV(
    SourceMV.General(node=source_node.general.guid, sk2nom=100.0),
    presentations=[ElementPresentation(sheet=sheet_guid, x=150, y=100)],
)
source.general.sk2nom = 900.0  # Modify after creation
source.register(network)

Source Properties

  • node: GUID of the node this source is connected to
  • sk2nom: Two-phase short-circuit power in MVA (grid strength indicator)

Sources use ElementPresentation which positions the symbol near its connected node.

Modifying Properties

Element properties can be modified after construction but before or after register(). The example shows setting sk2nom after initial construction.

0

Connect Nodes with a Branch

python
from pyptp.elements.mv.link import LinkMV
from pyptp.elements.mv.presentations import BranchPresentation

link = LinkMV(
    LinkMV.General(node1=source_node.general.guid, node2=load_node.general.guid),
    presentations=[
        BranchPresentation(
            sheet=sheet_guid,
            first_corners=[(150, 250), (300, 250)],
            second_corners=[(450, 250)],
        )
    ],
)
link.general.switch_state1 = 1  # Switch closed at node1
link.general.switch_state2 = 1  # Switch closed at node2
link.register(network)

Branch Presentation Coordinates

Branch presentations define the visual path:

  • first_corners: Polyline starting from node1, traveling outward
  • second_corners: Polyline starting from node2, traveling outward

The rendering engine draws a connection between the last point of each list.

100150200250300350400100Node1Node2AB
Afirst_corners: [(150,250), (300,250)]
BConnection to second_corners: [(450,250)]

Common Mistake

second_corners must start at node2, not end at it.

Deep Dive

See Branch Corners for complex routing patterns.

Switch States

ValueMeaning
0Switch open (disconnected)
1Switch closed (connected)
0

Add a Load

python
from pyptp.elements.mv.load import LoadMV

load = LoadMV(
    LoadMV.General(node=load_node.general.guid, P=100.0, Q=50.0),
    presentations=[ElementPresentation(sheet=sheet_guid, x=450, y=350)],
)
load.register(network)

Load Properties

PropertyUnitDescription
PkWActive power consumption
QkVArReactive power consumption
0

Save the Network

python
from pyptp.ptp_log import logger

network.save("simple_network.vnf")
logger.info("Network created with {} nodes and {} links", len(network.nodes), len(network.links))

The save() method serializes all elements to the VNF format.

Complete Example

python
"""Build a simple network from scratch."""

from pyptp import NetworkMV, configure_logging
from pyptp.elements.color_utils import CL_GRAY
from pyptp.elements.element_utils import Guid
from pyptp.elements.mv.link import LinkMV
from pyptp.elements.mv.load import LoadMV
from pyptp.elements.mv.node import NodeMV
from pyptp.elements.mv.presentations import BranchPresentation, ElementPresentation, NodePresentation
from pyptp.elements.mv.sheet import SheetMV
from pyptp.elements.mv.source import SourceMV
from pyptp.ptp_log import logger

configure_logging(level="INFO")

# Create balanced network (works for any voltage level)
network = NetworkMV()

# Create sheet
sheet = SheetMV(SheetMV.General(name="Main", color=CL_GRAY))
sheet.register(network)
sheet_guid: Guid = sheet.general.guid

# Create source node
source_node = NodeMV(
    NodeMV.General(name="Source", unom=10.0),
    presentations=[NodePresentation(sheet=sheet_guid, x=150, y=250)],
)
source_node.register(network)

# Create source
source = SourceMV(
    SourceMV.General(node=source_node.general.guid, sk2nom=100.0),
    presentations=[ElementPresentation(sheet=sheet_guid, x=150, y=100)],
)
source.general.sk2nom = 900.0
source.register(network)

# Create load node
load_node = NodeMV(
    NodeMV.General(name="Load", unom=10.0),
    presentations=[NodePresentation(sheet=sheet_guid, x=450, y=250)],
)
load_node.register(network)

# Connect with link
link = LinkMV(
    LinkMV.General(node1=source_node.general.guid, node2=load_node.general.guid),
    presentations=[
        BranchPresentation(
            sheet=sheet_guid,
            first_corners=[(150, 250), (300, 250)],
            second_corners=[(450, 250)],
        )
    ],
)
link.general.switch_state1 = 1
link.general.switch_state2 = 1
link.register(network)

# Add load
load = LoadMV(
    LoadMV.General(node=load_node.general.guid, P=100.0, Q=50.0),
    presentations=[ElementPresentation(sheet=sheet_guid, x=450, y=350)],
)
load.register(network)

# Save
network.save("simple_network.vnf")
logger.info("Network created with {} nodes and {} links", len(network.nodes), len(network.links))

Next Steps