Modifying Network Elements
This guide covers common patterns for modifying existing networks: finding elements, changing properties, bulk updates, adding notes, and deleting elements.
Full Example
View the complete code: 03_modify_network.py
Loading and Finding Elements
Load an Existing Network
from pyptp import NetworkMV, configure_logging
configure_logging(level="INFO")
network = NetworkMV.from_file("network.vnf")Find Elements by Name
from uuid import UUID
from pyptp.elements.element_utils import Guid
# Get GUID string by name
node_guid_str = network.get_node_guid_by_name("Substation_01")
# Convert to Guid object for dictionary lookup
node_guid = Guid(UUID(node_guid_str))
# Access the element
node = network.nodes[node_guid]Why Two GUID Types?
| Type | Usage |
|---|---|
str | Human-readable, returned by lookup methods |
Guid | Dictionary key type, wraps UUID for proper hashing |
The conversion Guid(UUID(guid_str)) is required because Python's dict uses the object's hash for lookups, and Guid provides the correct hash implementation.
Find by Iteration
# Find first node matching a condition
target_node = next(
(n for n in network.nodes.values() if n.general.unom > 20.0),
None
)
# Find all loads above threshold
large_loads = [
load for load in network.loads.values()
if load.general.P > 500.0
]Modifying Properties
Single Element Update
from pyptp.ptp_log import logger
node.general.unom = 11.0 # Change voltage from 10kV to 11kV
logger.info("Updated {} voltage to {}kV", node.general.name, node.general.unom)Properties are accessed through the element's nested dataclass structure:
element
├── general # Core properties (name, GUID, etc.)
│ ├── name
│ ├── guid
│ └── unom
├── presentations # Visual data
└── [other groups] # Element-specific (protection, etc.)Bulk Updates
# Increase all loads by 10%
for load in network.loads.values():
load.general.P *= 1.1
load.general.Q *= 1.1
logger.info("Scaled {} loads by 10%", len(network.loads))Conditional Updates
# Update only loads on specific node
target_node_guid = network.get_node_guid_by_name("Substation_A")
for load in network.loads.values():
if str(load.general.node) == target_node_guid:
load.general.P *= 1.2Adding Notes
Elements support notes for documentation and audit trails:
from pyptp.elements.mixins import Note
line = next(iter(network.lines.values()))
line.notes.append(Note(text="Verified 2025-01"))Note Properties
| Property | Description |
|---|---|
text | The note content |
author | Optional author name |
timestamp | Optional creation time |
Notes are preserved through save/load cycles and appear in Gaia/Vision.
Deleting Elements
Delete by GUID
# Get the GUID of the element to delete
source_guid = next(iter(network.sources.keys()))
# Remove from the collection
del network.sources[source_guid]Delete with Validation
def safe_delete_source(network, guid):
"""Delete source if it exists, return success status."""
if guid in network.sources:
del network.sources[guid]
return True
return FalseCascading Deletions
Deleting a node does not automatically delete connected branches or elements. You must manually remove dependent elements to maintain network integrity.
Delete Connected Elements
def delete_node_cascade(network, node_guid):
"""Delete a node and all elements referencing it."""
# Remove loads connected to this node
loads_to_delete = [
guid for guid, load in network.loads.items()
if load.general.node == node_guid
]
for guid in loads_to_delete:
del network.loads[guid]
# Remove lines connected to this node
lines_to_delete = [
guid for guid, line in network.lines.items()
if line.general.node1 == node_guid or line.general.node2 == node_guid
]
for guid in lines_to_delete:
del network.lines[guid]
# Finally remove the node
del network.nodes[node_guid]Saving Changes
network.save("network_modified.vnf")
logger.info("Network modifications saved")Save to Different File
Saving to a new filename preserves the original:
# Load original
network = NetworkMV.from_file("original.vnf")
# Make modifications
# ...
# Save as new file (original unchanged)
network.save("modified.vnf")Complete Example
"""Modify existing network elements."""
from uuid import UUID
from pyptp import NetworkMV, configure_logging
from pyptp.elements.element_utils import Guid
from pyptp.elements.mixins import Note
from pyptp.ptp_log import logger
configure_logging(level="INFO")
# Load network
network = NetworkMV.from_file("network.vnf")
# Find and modify a node by name
node_guid_str = network.get_node_guid_by_name("Substation_01")
node_guid = Guid(UUID(node_guid_str))
node = network.nodes[node_guid]
node.general.unom = 11.0
logger.info("Updated {} voltage to {}kV", node.general.name, node.general.unom)
# Modify all loads
for load in network.loads.values():
load.general.P *= 1.1
load.general.Q *= 1.1
logger.info("Scaled {} loads by 10%", len(network.loads))
# Add note to specific element
line = next(iter(network.lines.values()))
line.notes.append(Note(text="Verified 2025-01"))
# Delete element
del network.sources[next(iter(network.sources.keys()))]
# Save modified network
network.save("network_modified.vnf")
logger.info("Network modifications saved")