Network importers (I/O)¶
External-network importers convert existing power-system models from
third-party tools into a groundinsight.Network. They do not build
grounding networks from scratch — instead they project an existing
distribution-network topology onto the bus / branch primitives that
groundinsight solves for, while the user supplies the grounding-side
impedance formulas via an ImportDefaults object. The first
inhabitant is the pandapower importer; PowerFactory .dgs and the
live PowerFactory Python API are on the roadmap.
Physical / modelling context¶
Distribution-network databases (pandapower, PowerFactory, NEPLAN,
PSS®E) carry the electrical topology: buses, lines, transformers,
their resistance and reactance per phase. They do not carry the
grounding-side model — neither the bus grounding impedance
\(Z_{\text{B}}(\rho_E, f)\) nor the cable-shield self / mutual
impedance \(Z_{\text{self}}, Z_{\text{mutual}}\) that
groundinsight needs. The importer therefore adopts the pandapower
topology (which buses exist, which lines connect them, how long the
lines are) and asks the user to supply the grounding-side
parameters via ImportDefaults. That separation keeps the importer
schema-stable across tools — every importer accepts the same
ImportDefaults shape — and lets the user attach the same set of
grounding formulas to networks coming from different sources.
The active flag (default True) is propagated from
pandapower.in_service so that out-of-service equipment is excluded
from the nodal solve straight away — see the
outage-study reference for the runtime equivalent.
Example¶
import pandapower.networks as pn
import groundinsight as gi
# Any pandapower MV / LV demo network — here a simple 4-bus MV ring.
net_pp = pn.example_simple()
defaults = gi.ImportDefaults(
rho=100.0,
frequencies=[50.0, 250.0],
default_bus_type=gi.BusType(
name="MVbus",
description="Default substation grounding grid",
system_type="Substation",
voltage_level=20.0,
impedance_formula="rho * 0.01 + j * f * 1/50 * 0.1",
),
default_branch_type=gi.BranchType(
name="MVcable",
description="Default 20 kV cable",
grounding_conductor=True,
self_impedance_formula="(0.25 + j * f * 0.012) * l",
mutual_impedance_formula="(0.0 + j * f * 0.012) * l",
),
)
# 1. Pre-flight summary: kept vs. skipped elements with a reason column.
preview = gi.preview_pandapower_import(net_pp, voltage_level_kV=20.0)
print(preview)
# 2. Build the Network. Only buses / lines on the chosen voltage
# level are imported; switches, ext_grids, sgens, loads are ignored.
net = gi.from_pandapower(
net_pp,
defaults=defaults,
voltage_level_kV=20.0,
network_name="MV ring (from pandapower)",
)
print(f"Imported {len(net.buses)} buses, {len(net.branches)} branches.")
The pandapower extra is optional; install with
pip install 'groundinsight[pandapower]' (or
poetry install --extras pandapower).
API reference¶
io ¶
External-network importers.
This sub-package converts existing power-system models from third-party
tools (pandapower today, PowerFactory .dgs next) into a
:class:groundinsight.models.core_models.Network. Importers do not
build grounding networks from scratch -- they project an existing
distribution-network topology onto the bus/branch primitives that
groundinsight solves for, and let the user supply the impedance
formulas via :class:ImportDefaults.
Public API:
- :class:
ImportDefaults - :func:
groundinsight.io.pandapower_import.from_pandapower - :func:
groundinsight.io.pandapower_import.preview_pandapower_import
The importers themselves live in tool-specific submodules so that the optional third-party dependency is loaded lazily.
ImportDefaults ¶
Bases: BaseModel
Per-import defaults shared by every external-network importer.
Attributes:
| Name | Type | Description |
|---|---|---|
rho |
float
|
Specific earth resistance applied to every imported
|
frequencies |
List[float]
|
Frequencies at which impedance values
are evaluated. Becomes |
default_bus_type |
BusType
|
Default |
default_branch_type |
BranchType
|
Default |
Examples:
>>> from groundinsight.models.core_models import BusType, BranchType
>>> from groundinsight.io import ImportDefaults
>>> defaults = ImportDefaults(
... rho=100.0,
... frequencies=[50.0],
... default_bus_type=BusType(
... name="ImportedBus",
... system_type="Grounded",
... voltage_level=20.0,
... impedance_formula="rho * 0 + 1.0 + I * f * 0",
... ),
... default_branch_type=BranchType(
... name="ImportedCable",
... grounding_conductor=True,
... self_impedance_formula="(0.25 + I * 0.6) * l",
... mutual_impedance_formula="(0.0 + I * 0.6) * l",
... ),
... )
from_pandapower ¶
from_pandapower(
net,
*,
defaults: ImportDefaults,
voltage_level_kV: float,
network_name: Optional[str] = None,
include_trafos: bool = False
) -> Network
Build a :class:~groundinsight.models.core_models.Network from a
pandapower net, restricted to a single voltage level.
The mapping is intentionally narrow:
pp.busrows whosevn_kvmatchesvoltage_level_kVbecome :class:~groundinsight.models.core_models.Businstances usingdefaults.default_bus_type.in_service=Falsepropagates toBus.active=Falseso the outage helpers can reason over them.pp.linerows whose endpoints both lie on the target voltage level become :class:~groundinsight.models.core_models.Branchinstances usingdefaults.default_branch_typewithlength=length_km.in_service=Falsepropagates toBranch.active=False.- Switches, ext_grids, sgens, loads etc. are ignored. Trafos are
skipped unless
include_trafos=True, which is reserved for a future release (raisesNotImplementedErrorfor now).
No fault, source or path is created -- those are project-specific additions left to the caller.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
net
|
A pandapower |
required | |
defaults
|
ImportDefaults
|
Project-level defaults; see :class: |
required |
voltage_level_kV
|
float
|
Voltage level ( |
required |
network_name
|
Optional[str]
|
Optional name for the resulting Network. Defaults
to |
None
|
include_trafos
|
bool
|
Reserved for a future release. Setting this to
|
False
|
Returns:
| Name | Type | Description |
|---|---|---|
Network |
Network
|
A new groundinsight Network containing the imported |
Network
|
buses and branches, with frequencies = |
Raises:
| Type | Description |
|---|---|
ImportError
|
If pandapower is not installed. |
ValueError
|
If |
NotImplementedError
|
If |
Examples:
>>> import pandapower as pp
>>> from groundinsight.io import ImportDefaults, from_pandapower
>>> net = pp.networks.create_kerber_landnetz_freileitung_1()
>>> network = from_pandapower(
... net,
... defaults=defaults,
... voltage_level_kV=0.4,
... network_name="kerber_lv",
... )
Source code in src/groundinsight/io/pandapower_import.py
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 | |
preview_pandapower_import ¶
Return a Polars DataFrame describing what :func:from_pandapower
would do on this net at this voltage level, without building a
Network.
The frame has the following columns:
kind--"bus"or"line".status--"keep"or"skip".pp_index-- The pandapower index of the row.name-- Resolved groundinsight name (with fallback).vn_kv-- Bus voltage level (Nonefor lines).from_bus-- Resolved from-bus name (lines only).to_bus-- Resolved to-bus name (lines only).length_km-- Line length in km (lines only).in_service-- Boolean flag from pandapower (best effort).reason-- Skip reason ifstatus == "skip",Noneotherwise.
Use this before committing to a full import to validate the mapping or diagnose unexpectedly skipped elements.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
net
|
The pandapower |
required | |
voltage_level_kV
|
float
|
Voltage level to keep ( |
required |
Returns:
| Type | Description |
|---|---|
DataFrame
|
pl.DataFrame: One row per bus and one per line. |
Source code in src/groundinsight/io/pandapower_import.py
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 | |