Source code for VeraGridEngine.IO.dgs.dgs_objects

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
from __future__ import annotations

import csv
from typing import Any, Dict, List


def _split_dgs_line(line: str) -> List[str]:
    """
    Split a DGS record honoring quoted semicolons.

    :param line: Raw DGS record line.
    :return: Parsed record fields.
    """
    return next(csv.reader([line.rstrip('\n')], delimiter=';', quotechar='"'))


def _parse_elm_dsl_param_value(raw: str | None) -> float | str | None:
    """
    Parse one ElmDsl parameter value from the DGS row.

    :param raw: Raw DGS text.
    :return: Parsed numeric value, raw text fallback, or ``None`` for empty placeholders.
    """
    if raw is None:
        return None
    else:
        pass

    text: str = raw.strip()
    if text in {'', '*'}:
        return None
    else:
        pass

    try:
        return float(text.replace(',', '.'))
    except ValueError:
        return text


[docs] class DgsProperty: """ Dgs Property """ def __init__(self, name: str, dgs_type: str, description: str, py_name: str): self.name = name self.dgs_type = dgs_type self.description = description self.py_name = py_name if dgs_type.startswith("b"): # boolean self.py_type = bool self.default_value = False elif dgs_type.startswith("i"): # integer self.py_type = int self.default_value = 0 elif dgs_type.startswith("r"): # real/float self.py_type = float self.default_value = 0.0 elif dgs_type.startswith("a"): # string self.py_type = str self.default_value = "" elif dgs_type.startswith("p"): # object reference self.py_type = str self.default_value = None else: # Unknown/rare types: keep as string by default self.py_type = str self.default_value = None
[docs] def parse(self, raw: str) -> str | int | bool | float | None: """ :param raw: incoming value :return: """ if raw is None: return self.default_value raw = raw.strip() # PowerFactory placeholders / missing values if raw == "" or raw == "*": return self.default_value # Boolean parsing if self.py_type is bool: v = raw.strip().lower() if v in {"1", "true", "t", "yes", "y"}: return True elif v in {"0", "false", "f", "no", "n"}: return False else: # Unexpected encoding β†’ fallback return self.default_value # Numeric parsing (int/float) with decimal comma if self.py_type in (int, float): raw_norm = raw.replace(",", ".") try: if self.py_type is int: # Some PF fields may show "1.0" for ints; tolerate that return int(float(raw_norm)) else: return float(raw_norm) except ValueError: return self.default_value # String/reference return raw
[docs] def format(self, value: Any) -> str: """ :param value: :return: """ if value is None: return '' if self.dgs_type == 'b': return '1' if bool(value) else '0' return str(value)
[docs] class DGSElement: """ Base class """ element_type: str properties_list: List[DgsProperty] properties: Dict[str, DgsProperty] def __init_subclass__(cls): cls.properties = {p.name: p for p in cls.properties_list}
[docs] @classmethod def parse_line(cls, line: str, header_map: dict[str, int]): """ Parse a DGS data line using a header-derived column map. Parameters ---------- line : str Raw data line from DGS header_map : dict[str, int] Mapping {property_name -> column_index} derived from the $$ header line """ parts = _split_dgs_line(line) obj = cls() for prop in cls.properties_list: idx = header_map.get(prop.name, None) # Fix ID vs FID thing, internally it is always ID, and we handle the FID issue if idx is None and prop.name == "ID": idx = header_map.get("FID", None) if idx is not None: if -1 < idx < len(parts): raw = parts[idx] value = prop.parse(raw) setattr(obj, prop.py_name, value) else: # Column declared but missing in this line pass else: # Property not present in this DGS version pass return obj
[docs] def to_dgs_line(self) -> str: """ Create DGS line :return: """ return ';'.join(p.format(getattr(self, p.py_name)) for p in self.properties_list)
def __repr__(self): """ :return: """ if hasattr(self, "loc_name"): return getattr(self, "loc_name") else: return getattr(self, "ID")
[docs] class ChaRef(DGSElement): element_type = 'ChaRef' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a:40', 'DGS field loc_name (a:40)', py_name='loc_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = ""
[docs] class ChaVec(DGSElement): element_type = 'ChaVec' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a:40', 'DGS field loc_name (a:40)', py_name='loc_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('scale', 'p', 'DGS field scale (p)', py_name='scale'), DgsProperty('usage', 'i', 'DGS field usage (i)', py_name='usage'), DgsProperty('approx', 'i', 'DGS field approx (i)', py_name='approx'), DgsProperty('vector:SIZEROW', 'i', 'DGS field vector:SIZEROW (i)', py_name='vector_SIZEROW'), DgsProperty('vector:0', 'r', 'DGS field vector:0 (r)', py_name='vector_0'), DgsProperty('vector:1', 'r', 'DGS field vector:1 (r)', py_name='vector_1'), DgsProperty('vector:2', 'r', 'DGS field vector:2 (r)', py_name='vector_2'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.scale: str = "" self.usage: int = 0 self.approx: int = 0 self.vector_SIZEROW: int = 0 self.vector_0: float = 0.0 self.vector_1: float = 0.0 self.vector_2: float = 0.0
[docs] class ElmComp(DGSElement): element_type = 'ElmComp' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a', 'DGS field loc_name (a)', py_name='loc_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('outserv', 'i', 'DGS field outserv (i)', py_name='outserv'), DgsProperty('typ_id', 'p', 'DGS field typ_id (p)', py_name='typ_id'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.typ_id: str = "" self.outserv: int = 0 self.pblk: List[str | None] = list() self.pelm: List[str | None] = list() self.contents: List[str] = list()
[docs] @classmethod def parse_line(cls, line: str, header_map: dict[str, int]): parts = _split_dgs_line(line) obj = super().parse_line(";".join(parts), header_map) raw_pblk = _dgs_get(parts, header_map, 'pblk:SIZEROW') n_pblk = int(float(raw_pblk.replace(',', '.'))) if raw_pblk is not None and raw_pblk.strip() != '' else 0 for i in range(n_pblk): raw_ptr = _dgs_get(parts, header_map, f'pblk:{i}') raw_ptr = raw_ptr.strip() if raw_ptr is not None else '' obj.pblk.append(raw_ptr if raw_ptr != '' and raw_ptr != '*' else None) raw_pelm = _dgs_get(parts, header_map, 'pelm:SIZEROW') n_pelm = int(float(raw_pelm.replace(',', '.'))) if raw_pelm is not None and raw_pelm.strip() != '' else 0 for i in range(n_pelm): raw_ptr = _dgs_get(parts, header_map, f'pelm:{i}') raw_ptr = raw_ptr.strip() if raw_ptr is not None else '' obj.pelm.append(raw_ptr if raw_ptr != '' and raw_ptr != '*' else None) raw_contents = _dgs_get(parts, header_map, 'contents:SIZEROW') n_contents = int(float(raw_contents.replace(',', '.'))) if raw_contents is not None and raw_contents.strip() != '' else 0 for i in range(n_contents): raw_text = _dgs_get(parts, header_map, f'contents:{i}') raw_text = raw_text.strip() if raw_text is not None else '' if raw_text != '' and raw_text != '*': obj.contents.append(raw_text) return obj
[docs] class ElmDsl(DGSElement): element_type = 'ElmDsl' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a', 'DGS field loc_name (a)', py_name='loc_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('outserv', 'i', 'DGS field outserv (i)', py_name='outserv'), DgsProperty('typ_id', 'p', 'DGS field typ_id (p)', py_name='typ_id'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.typ_id: str = "" self.outserv: int = 0 self.params: List[float | str | None] = list() self.pelm: List[str | None] = list() self.signal: List[str] = list() self.parameter_names: List[str] = list()
[docs] def get_parameter_map(self) -> Dict[str, float | str | None]: """ Return the instance parameter mapping using the DGS order. :return: Dictionary keyed by PowerFactory parameter name. """ return { name: value for name, value in zip(self.parameter_names, self.params) }
[docs] @classmethod def parse_line(cls, line: str, header_map: dict[str, int]): parts = _split_dgs_line(line) obj = super().parse_line(";".join(parts), header_map) raw_params_size = _dgs_get(parts, header_map, 'params:SIZEROW') n_params = int(float(raw_params_size.replace(',', '.'))) if raw_params_size is not None and raw_params_size.strip() != '' else 0 for i in range(n_params): # The ElmDsl row stores the concrete instance values that must later feed the generated event_dict. obj.params.append(_parse_elm_dsl_param_value(_dgs_get(parts, header_map, f'params:{i}'))) raw_pelm = _dgs_get(parts, header_map, 'pelm:SIZEROW') n_pelm = int(float(raw_pelm.replace(',', '.'))) if raw_pelm is not None and raw_pelm.strip() != '' else 0 for i in range(n_pelm): raw_ptr = _dgs_get(parts, header_map, f'pelm:{i}') raw_ptr = raw_ptr.strip() if raw_ptr is not None else '' obj.pelm.append(raw_ptr if raw_ptr != '' and raw_ptr != '*' else None) raw_signal = _dgs_get(parts, header_map, 'signal:SIZEROW') n_signal = int(float(raw_signal.replace(',', '.'))) if raw_signal is not None and raw_signal.strip() != '' else 0 for i in range(n_signal): raw_sig = _dgs_get(parts, header_map, f'signal:{i}') raw_sig = raw_sig.strip() if raw_sig is not None else '' if raw_sig != '' and raw_sig != '*': obj.signal.append(raw_sig) raw_params = _dgs_get(parts, header_map, 'parameterNames') if raw_params is not None and raw_params.strip() not in {'', '*'}: obj.parameter_names = [item.strip() for item in raw_params.split(',') if item.strip()] return obj
[docs] class BlkFrom(DGSElement): element_type = 'BlkFrom' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('OP', 'a:1', 'DGS field OP (a:1)', py_name='OP'), DgsProperty('sSig:SIZEROW', 'i', 'DGS field sSig:SIZEROW (i)', py_name='sSig_SIZEROW'), DgsProperty('sSig:0', 'a', 'DGS field sSig:0 (a)', py_name='sSig_0'), DgsProperty('loc_name', 'a:80', 'DGS field loc_name (a:80)', py_name='loc_name'), ] def __init__(self) -> None: self.ID: str = '' self.OP: str = '' self.sSig_SIZEROW: int = 0 self.sSig_0: str = '' self.loc_name: str = '' self.signals: List[str] = list()
[docs] @classmethod def parse_line(cls, line: str, header_map: dict[str, int]): parts = _split_dgs_line(line) obj = super().parse_line(";".join(parts), header_map) if obj.sSig_0.strip() not in {'', '*'}: obj.signals = [item.strip() for item in obj.sSig_0.split(',') if item.strip()] return obj
[docs] class BlkGoto(DGSElement): element_type = 'BlkGoto' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('OP', 'a:1', 'DGS field OP (a:1)', py_name='OP'), DgsProperty('loc_name', 'a:80', 'DGS field loc_name (a:80)', py_name='loc_name'), DgsProperty('sSig:SIZEROW', 'i', 'DGS field sSig:SIZEROW (i)', py_name='sSig_SIZEROW'), ] def __init__(self) -> None: self.ID: str = '' self.OP: str = '' self.loc_name: str = '' self.sSig_SIZEROW: int = 0
[docs] class BlkRef(DGSElement): element_type = 'BlkRef' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('OP', 'a:1', 'DGS field OP (a:1)', py_name='OP'), DgsProperty('typ_id', 'p', 'DGS field typ_id (p)', py_name='typ_id'), DgsProperty('cdisName', 'a', 'DGS field cdisName (a)', py_name='cdisName'), ] def __init__(self) -> None: self.ID: str = '' self.OP: str = '' self.typ_id: str = '' self.cdisName: str = '' self.params: List[str] = list() self.states: List[str] = list() self.internals: List[str] = list()
[docs] @classmethod def parse_line(cls, line: str, header_map: dict[str, int]): parts = _split_dgs_line(line) obj = super().parse_line(";".join(parts), header_map) raw_params = _dgs_get(parts, header_map, 'sParams:0') if raw_params is not None and raw_params.strip() not in {'', '*'}: obj.params = [item.strip() for item in raw_params.split(',') if item.strip()] raw_states = _dgs_get(parts, header_map, 'sStates:0') if raw_states is not None and raw_states.strip() not in {'', '*'}: obj.states = [item.strip() for item in raw_states.split(',') if item.strip()] raw_internals = _dgs_get(parts, header_map, 'sIntern:0') if raw_internals is not None and raw_internals.strip() not in {'', '*'}: obj.internals = [item.strip() for item in raw_internals.split(',') if item.strip()] return obj
[docs] class BlkSig(DGSElement): element_type = 'BlkSig' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('OP', 'a:1', 'DGS field OP (a:1)', py_name='OP'), DgsProperty('inodfrom', 'i', 'DGS field inodfrom (i)', py_name='inodfrom'), DgsProperty('loc_name', 'a:80', 'DGS field loc_name (a:80)', py_name='loc_name'), DgsProperty('iconfrom', 'i', 'DGS field iconfrom (i)', py_name='iconfrom'), DgsProperty('inodto', 'i', 'DGS field inodto (i)', py_name='inodto'), DgsProperty('iconto', 'i', 'DGS field iconto (i)', py_name='iconto'), DgsProperty('pnodfrom', 'p', 'DGS field pnodfrom (p)', py_name='pnodfrom'), DgsProperty('pnodto', 'p', 'DGS field pnodto (p)', py_name='pnodto'), ] def __init__(self) -> None: self.ID: str = '' self.OP: str = '' self.inodfrom: int = 0 self.loc_name: str = '' self.iconfrom: int = 0 self.inodto: int = 0 self.iconto: int = 0 self.pnodfrom: str = '' self.pnodto: str = ''
[docs] class BlkSlot(DGSElement): element_type = 'BlkSlot' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('OP', 'a:1', 'DGS field OP (a:1)', py_name='OP'), DgsProperty('loc_name', 'a:80', 'DGS field loc_name (a:80)', py_name='loc_name'), DgsProperty('element', 'p', 'DGS field element (p)', py_name='element'), DgsProperty('filtmod', 'a:80', 'DGS field filtmod (a:80)', py_name='filtmod'), ] def __init__(self) -> None: self.ID: str = '' self.OP: str = '' self.loc_name: str = '' self.element: str = '' self.filtmod: str = '' self.outputs: List[str] = list() self.inputs: List[str] = list()
[docs] @classmethod def parse_line(cls, line: str, header_map: dict[str, int]): parts = _split_dgs_line(line) obj = super().parse_line(";".join(parts), header_map) raw_outputs = _dgs_get(parts, header_map, 'sOutput:0') if raw_outputs is not None and raw_outputs.strip() not in {'', '*'}: obj.outputs = [item.strip() for item in raw_outputs.split(',') if item.strip()] raw_inputs = _dgs_get(parts, header_map, 'sInput:0') if raw_inputs is not None and raw_inputs.strip() not in {'', '*'}: obj.inputs = [item.strip() for item in raw_inputs.split(',') if item.strip()] return obj
[docs] class BlkSum(DGSElement): element_type = 'BlkSum' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('OP', 'a:1', 'DGS field OP (a:1)', py_name='OP'), DgsProperty('loc_name', 'a:80', 'DGS field loc_name (a:80)', py_name='loc_name'), DgsProperty('iInput0', 'i', 'DGS field iInput0 (i)', py_name='iInput0'), DgsProperty('iInput0:act', 'i', 'DGS field iInput0:act (i)', py_name='iInput0_act'), DgsProperty('iInput1', 'i', 'DGS field iInput1 (i)', py_name='iInput1'), DgsProperty('iInput1:act', 'i', 'DGS field iInput1:act (i)', py_name='iInput1_act'), DgsProperty('iInput3', 'i', 'DGS field iInput3 (i)', py_name='iInput3'), DgsProperty('iInput3:act', 'i', 'DGS field iInput3:act (i)', py_name='iInput3_act'), DgsProperty('iInput2', 'i', 'DGS field iInput2 (i)', py_name='iInput2'), DgsProperty('iInput2:act', 'i', 'DGS field iInput2:act (i)', py_name='iInput2_act'), ] def __init__(self) -> None: self.ID: str = '' self.OP: str = '' self.loc_name: str = '' self.iInput0: int = 0 self.iInput0_act: int = 0 self.iInput1: int = 0 self.iInput1_act: int = 0 self.iInput3: int = 0 self.iInput3_act: int = 0 self.iInput2: int = 0 self.iInput2_act: int = 0
[docs] class ElmAsm(DGSElement): element_type = 'ElmAsm' properties_list = [ DgsProperty('FID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('OP', 'a:1', 'Operation', py_name='OP'), DgsProperty('loc_name', 'a', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('typ_id', 'p', 'Type in TypAsmo', py_name='typ_id'), DgsProperty('ngnum', 'i', 'Number of Parallel Machines', py_name='ngnum'), DgsProperty('i_mot', 'i', 'Operating Mode: Generator:Motor', py_name='i_mot'), DgsProperty('outserv', 'i', 'Out of Service', py_name='outserv'), DgsProperty('pgini', 'r', 'Active Power Setpoint in MW', py_name='pgini'), DgsProperty('qgini', 'r', 'Reactive Power Setpoint in MVAr', py_name='qgini'), DgsProperty('chr_name', 'a', 'Characteristic Name', py_name='chr_name'), DgsProperty('idfig', 'i', 'Machine type', py_name='idfig'), DgsProperty('bustp', 'a:4', 'Bus type: AS:PQ', py_name='bustp'), DgsProperty('cCategory', 'a', 'Plant Category', py_name='cCategory'), DgsProperty('pmode', 'i', 'Electrical power:Mechanical power:Mechanical torque', py_name='pmode'), ] def __init__(self) -> None: self.ID: str = '' self.OP: str = '' self.loc_name: str = '' self.fold_id: str = '' self.typ_id: str = '' self.ngnum: int = 0 self.i_mot: int = 0 self.outserv: int = 0 self.pgini: float = 0.0 self.qgini: float = 0.0 self.chr_name: str = '' self.idfig: int = 0 self.bustp: str = '' self.cCategory: str = '' self.pmode: int = 0
[docs] class ElmCoup(DGSElement): element_type = 'ElmCoup' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('loc_name', 'a', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('typ_id', 'p', 'Type in TypSwitch', py_name='typ_id'), DgsProperty('chr_name', 'a', 'Characteristic Name', py_name='chr_name'), DgsProperty('aUsage', 'a', 'Switch Usage Code', py_name='aUsage'), DgsProperty('nneutral', 'i', 'Number of Neutral Conductors', py_name='nneutral'), DgsProperty('nphase', 'i', 'Number of Phases', py_name='nphase'), DgsProperty('on_off', 'i', 'Switch Position: Open:Closed', py_name='on_off'), DgsProperty('for_name', 'a:50', 'Foreign Key', py_name='for_name'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.typ_id: str = "" self.chr_name: str = "" self.aUsage: str = "" self.nneutral: int = 0 self.nphase: int = 3 self.on_off: int = 0 self.for_name: str = ""
[docs] class ElmBranch(DGSElement): """ Branch element container (PowerFactory/DGS). Notes ----- ElmBranch is a hierarchical container used to organize the project/model and the single-line diagram. It does NOT define electrical connectivity. """ element_type = 'ElmBranch' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a:80', 'DGS field loc_name (a:80)', py_name='loc_name'), DgsProperty('for_name', 'a:100', 'DGS field for_name (a:100)', py_name='for_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('iDatCon0', 'i', 'DGS field iDatCon0 (i)', py_name='iDatCon0'), DgsProperty('iDatCon1', 'i', 'DGS field iDatCon1 (i)', py_name='iDatCon1'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.for_name: str = "" self.fold_id: str = "" self.iDatCon0: int = 0 self.iDatCon1: int = 0
[docs] class ElmFeeder(DGSElement): element_type = 'ElmFeeder' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a:40', 'DGS field loc_name (a:40)', py_name='loc_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('obj_id', 'p', 'DGS field obj_id (p)', py_name='obj_id'), DgsProperty('iorient', 'i', 'DGS field iorient (i)', py_name='iorient'), DgsProperty('i_scale', 'i', 'DGS field i_scale (i)', py_name='i_scale'), DgsProperty('Iset', 'r', 'DGS field Iset (r)', py_name='Iset'), DgsProperty('icolor', 'i', 'DGS field icolor (i)', py_name='icolor'), DgsProperty('outserv', 'i', 'DGS field outserv (i)', py_name='outserv'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.obj_id: str = "" self.iorient: int = 0 self.i_scale: int = 0 self.Iset: float = 0.0 self.icolor: int = 0 self.outserv: int = 0
[docs] class ElmGenstat(DGSElement): element_type = 'ElmGenstat' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('loc_name', 'a:40', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('bus1', 'p', 'Connected Terminal Cubicle', py_name='bus1'), DgsProperty('outserv', 'i', 'Out of Service', py_name='outserv'), DgsProperty('sgn', 'r', 'Rated Apparent Power in MVA', py_name='sgn'), DgsProperty('cosn', 'r', 'Rated Power Factor', py_name='cosn'), DgsProperty('ngnum', 'i', 'Number of Parallel Units', py_name='ngnum'), DgsProperty('pgini', 'r', 'Active Power Setpoint in MW', py_name='pgini'), DgsProperty('qgini', 'r', 'Reactive Power Setpoint in MVAr', py_name='qgini'), DgsProperty('av_mode', 'a', 'Active Power Control Mode', py_name='av_mode'), DgsProperty('mode_inp', 'a:6', 'Dispatch: Input mode', py_name='mode_inp'), DgsProperty('ip_ctrl', 'i', 'Reference Machine Flag', py_name='ip_ctrl'), DgsProperty('cCategory', 'a:40', 'plant types', py_name='cCategory'), DgsProperty('c_pmod', 'a:40', 'plant model', py_name='c_pmod'), DgsProperty('ddroop', 'r', 'Voltage droop value [%]', py_name='ddroop'), DgsProperty('usp_max', 'r', 'Maximum voltage setpoint [pu]', py_name='usp_max'), DgsProperty('usp_min', 'r', 'Minimum voltage setpoint [pu]', py_name='usp_min'), DgsProperty('usetp', 'r', 'Specified voltage setpoint [pu]', py_name='usetp'), DgsProperty('cQ_min', 'r', 'Minimum reactive power to inject/absorb [MVAr]', py_name='cQ_min'), DgsProperty('cQ_max', 'r', 'Maximum reactive power to inject/absorb [MVAr]', py_name='cQ_max'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.bus1: str = "" self.outserv: int = 0 self.sgn: float = 0.0 self.cosn: float = 0.0 self.ngnum: int = 0 self.pgini: float = 0.0 self.qgini: float = 0.0 self.av_mode: str = "" self.mode_inp: str = "" self.ip_ctrl: int = 0 self.cCategory: str = "" self.c_pmod: str = "" self.ddroop: float = 0.0 self.usp_max: float = 0.0 self.usp_min: float = 0.0 self.usetp: float = 0.0 self.cQ_min: float = 0.0 self.cQ_max: float = 0.0
[docs] class ElmLne(DGSElement): element_type = 'ElmLne' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('loc_name', 'a:40', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('typ_id', 'p', 'Type in TypLne', py_name='typ_id'), DgsProperty('dline', 'r', 'Line Length in km', py_name='dline'), DgsProperty('chr_name', 'a:20', 'Characteristic Name', py_name='chr_name'), DgsProperty('fline', 'r', 'Derating factor', py_name='fline'), DgsProperty('outserv', 'i', 'Out of Service', py_name='outserv'), DgsProperty('pStoch', 'p', 'Reference to Stochastic Model', py_name='pStoch'), DgsProperty('for_name', 'a:50', 'Foreign Key', py_name='for_name'), DgsProperty('GPScoords:SIZEROW', 'i', 'Number of Stored GPS Coordinate Rows', py_name='GPScoords_SIZEROW'), DgsProperty('GPScoords:SIZECOL', 'i', 'Number of Stored GPS Coordinate Columns', py_name='GPScoords_SIZECOL'), DgsProperty('nlnum', 'i', 'Number of Parallel Line Systems', py_name='nlnum'), DgsProperty('inAir', 'i', 'Installation Flag: In Air: Underground/Other', py_name='inAir'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.typ_id: str = "" self.dline: float = 0.0 self.chr_name: str = "" self.fline: float = 1.0 self.outserv: int = 0 self.pStoch: str = "" self.for_name: str = "" self.GPScoords_SIZEROW: int = 0 self.GPScoords_SIZECOL: int = 0 self.nlnum: int = 1 self.inAir: int = 0
[docs] class ElmZpu(DGSElement): element_type = 'ElmZpu' properties_list = [ DgsProperty('FID', 'a:40', 'DGS field FID (a:40)', py_name='ID'), DgsProperty('OP', 'a:1', 'DGS field OP (a:1)', py_name='OP'), DgsProperty('loc_name', 'a:80', 'Name', py_name='loc_name'), DgsProperty('for_name', 'a:100', 'Foreign Key', py_name='for_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('Sn', 'r', 'Rated Power in MVA', py_name='Sn'), DgsProperty('ratfac', 'r', 'Rating Factor', py_name='ratfac'), DgsProperty('r_pu', 'r', 'Positive-Sequence Impedance i-j: Real Part in p.u.', py_name='r_pu'), DgsProperty('x_pu', 'r', 'Positive-Sequence Impedance i-j: Imaginary Part in p.u.', py_name='x_pu'), DgsProperty('outserv', 'i', 'Out of Service', py_name='outserv'), ] def __init__(self): self.ID: str = "" self.OP: str = "" self.loc_name: str = "" self.for_name: str = "" self.fold_id: str = "" self.Sn: float = 0.0 self.ratfac: float = 0.0 self.r_pu: float = 0.0 self.x_pu: float = 0.0 self.outserv: int = 0
[docs] class ElmScap(DGSElement): element_type = 'ElmScap' properties_list = [ DgsProperty('FID', 'a:40', 'DGS field FID (a:40)', py_name='ID'), DgsProperty('OP', 'a:1', 'DGS field OP (a:1)', py_name='OP'), DgsProperty('loc_name', 'a:80', 'Name', py_name='loc_name'), DgsProperty('for_name', 'a:100', 'Foreign Key', py_name='for_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('ucn', 'r', 'Rated Voltage in kV', py_name='ucn'), DgsProperty('Curn', 'r', 'Rated Current in kA', py_name='Curn'), DgsProperty('xcap', 'r', 'Reactance 1/B in Ohm', py_name='xcap'), DgsProperty('outserv', 'i', 'Out of Service', py_name='outserv'), ] def __init__(self): self.ID: str = "" self.OP: str = "" self.loc_name: str = "" self.for_name: str = "" self.fold_id: str = "" self.ucn: float = 0.0 self.Curn: float = 0.0 self.xcap: float = 0.0 self.outserv: int = 0
[docs] class ElmSind(DGSElement): element_type = 'ElmSind' properties_list = [ # test_export_v5.dgs uses FID(...) not ID(...) DgsProperty('FID', 'a:40', 'DGS field FID (a:40)', py_name='ID'), # Optional alias (harmless if missing) DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('OP', 'a:1', 'DGS field OP (a:1)', py_name='OP'), DgsProperty('loc_name', 'a:80', 'Name', py_name='loc_name'), DgsProperty('for_name', 'a:100', 'Foreign Key', py_name='for_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('ucn', 'r', 'Rated Voltage in kV', py_name='ucn'), DgsProperty('Sn', 'r', 'Rated Power in MVA', py_name='Sn'), DgsProperty('uk', 'r', 'Short-Circuit Voltage uk in %', py_name='uk'), DgsProperty('Pcu', 'r', 'Copper Losses in kW', py_name='Pcu'), DgsProperty('outserv', 'i', 'Out of Service', py_name='outserv'), ] def __init__(self): self.ID: str = "" self.OP: str = "" self.loc_name: str = "" self.for_name: str = "" self.fold_id: str = "" self.typ_id: str = "" self.ucn: float = 0.0 self.Sn: float = 0.0 self.uk: float = 0.0 self.Pcu: float = 0.0 self.outserv: int = 0
[docs] class TypSind(DGSElement): """PowerFactory Series Reactor type (TypSind).""" element_type = 'TypSind' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a:40', 'DGS field loc_name (a:40)', py_name='loc_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), # Type impedance parameters (same naming as ElmSind in many exports) DgsProperty('Re', 'r', 'Type series resistance (Re)', py_name='Re'), DgsProperty('Xe', 'r', 'Type series reactance (Xe)', py_name='Xe'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.Re: float = 0.0 self.Xe: float = 0.0
[docs] class ElmLnesec(DGSElement): element_type = 'ElmLnesec' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('loc_name', 'a', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'Parent Line Folder', py_name='fold_id'), DgsProperty('typ_id', 'p', 'Type in TypLne', py_name='typ_id'), DgsProperty('chr_name', 'a', 'Characteristic Name', py_name='chr_name'), DgsProperty('dline', 'r', 'Section Length in km', py_name='dline'), DgsProperty('fline', 'r', 'Section Derating Factor', py_name='fline'), DgsProperty('index', 'r', 'Section Order Index', py_name='index'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.typ_id: str = "" self.chr_name: str = "" self.dline: float = 0.0 self.fline: float = 0.0 self.index: float = 0.0
[docs] class ElmVac(DGSElement): element_type = 'ElmVac' properties_list = [ DgsProperty('FID', 'a:40', 'DGS field FID (a:40)', py_name='ID'), DgsProperty('OP', 'a:1', 'DGS field OP (a:1)', py_name='OP'), DgsProperty('loc_name', 'a:80', 'Name', py_name='loc_name'), DgsProperty('for_name', 'a:100', 'Foreign Key', py_name='for_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('outserv', 'i', 'Out of Service', py_name='outserv'), DgsProperty('itype', 'i', '0=Voltage Source, 1=Ideal RC-Source, 2=Ward Equivalent, 3=Extended Ward Equivalent', py_name='itype'), DgsProperty('Pload', 'r', 'Constant P Load - Active Power in MW', py_name='Pload'), DgsProperty('Qload', 'r', 'Constant Q Load - Reactive Power in Mvar', py_name='Qload'), DgsProperty('Pgen', 'r', 'Generated Active Power in MW', py_name='Pgen'), DgsProperty('Qgen', 'r', 'Generated Reactive Power in Mvar', py_name='Qgen'), DgsProperty('Pzload', 'r', 'Constant Z Load - Active Power in MW', py_name='Pzload'), DgsProperty('Qzload', 'r', 'Constant Z Load - Reactive Power in Mvar', py_name='Qzload'), ] def __init__(self): self.ID: str = "" self.OP: str = "" self.loc_name: str = "" self.for_name: str = "" self.fold_id: str = "" self.outserv: int = 0 self.itype: int = 0 self.Pload: float = 0.0 self.Qload: float = 0.0 self.Pgen: float = 0.0 self.Qgen: float = 0.0 self.Pzload: float = 0.0 self.Qzload: float = 0.0
[docs] class ElmLod(DGSElement): element_type = 'ElmLod' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a:40', 'DGS field loc_name (a:40)', py_name='loc_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('typ_id', 'p', 'DGS field typ_id (p)', py_name='typ_id'), DgsProperty('chr_name', 'a:20', 'DGS field chr_name (a:20)', py_name='chr_name'), DgsProperty('plini', 'r', 'DGS field plini (r)', py_name='plini'), DgsProperty('qlini', 'r', 'DGS field qlini (r)', py_name='qlini'), DgsProperty('scale0', 'r', 'DGS field scale0 (r)', py_name='scale0'), DgsProperty('outserv', 'i', 'DGS field outserv (i)', py_name='outserv'), DgsProperty('for_name', 'a:50', 'DGS field for_name (a:50)', py_name='for_name'), DgsProperty('mode_inp', 'a:3', 'DGS field mode_inp (a:3)', py_name='mode_inp'), DgsProperty('slini', 'r', 'DGS field slini (r)', py_name='slini'), DgsProperty('coslini', 'r', 'DGS field coslini (r)', py_name='coslini'), DgsProperty('pf_recap', 'i', 'DGS field pf_recap (i)', py_name='pf_recap'), DgsProperty('i_scale', 'i', 'DGS field i_scale (i)', py_name='i_scale'), DgsProperty('classif', 'a:20', 'DGS field classif (a:20)', py_name='classif'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.typ_id: str = "" self.chr_name: str = "" self.plini: float = 0.0 self.qlini: float = 0.0 self.scale0: float = 0.0 self.outserv: int = 0 self.for_name: str = "" self.mode_inp: str = "" self.slini: float = 0.0 self.coslini: float = 0.0 self.pf_recap: int = 0 self.i_scale: int = 0 self.classif: str = ""
[docs] class ElmLodlv(DGSElement): element_type = 'ElmLodlv' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a', 'DGS field loc_name (a)', py_name='loc_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('typ_id', 'p', 'DGS field typ_id (p)', py_name='typ_id'), DgsProperty('chr_name', 'a', 'DGS field chr_name (a)', py_name='chr_name'), DgsProperty('for_name', 'a', 'DGS field for_name (a)', py_name='for_name'), DgsProperty('ulini', 'r', 'DGS field ulini (r)', py_name='ulini'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.typ_id: str = "" self.chr_name: str = "" self.for_name: str = "" self.ulini: float = 0.0
[docs] class ElmLodlvp(DGSElement): element_type = 'ElmLodlvp' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a', 'DGS field loc_name (a)', py_name='loc_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('typ_id', 'p', 'DGS field typ_id (p)', py_name='typ_id'), DgsProperty('chr_name', 'a', 'DGS field chr_name (a)', py_name='chr_name'), DgsProperty('for_name', 'a', 'DGS field for_name (a)', py_name='for_name'), DgsProperty('lneposkm', 'r', 'DGS field lneposkm (r)', py_name='lneposkm'), DgsProperty('outserv', 'i', 'DGS field outserv (i)', py_name='outserv'), DgsProperty('ulini', 'r', 'DGS field ulini (r)', py_name='ulini'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.typ_id: str = "" self.chr_name: str = "" self.for_name: str = "" self.lneposkm: float = 0.0 self.outserv: int = 0 self.ulini: float = 0.0
[docs] class ElmNet(DGSElement): element_type = 'ElmNet' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a:40', 'DGS field loc_name (a:40)', py_name='loc_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('frnom', 'r', 'Nominal Frequency in Hz', py_name='frnom'), DgsProperty('for_name', 'a:50', 'DGS field for_name (a:50)', py_name='for_name'), DgsProperty('pDiagram', 'p', 'Diagram in IntGrfnet', py_name='pDiagram'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.frnom: float = 0.0 self.for_name: str = "" self.pDiagram: str = ""
[docs] class ElmShnt(DGSElement): element_type = 'ElmShnt' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('loc_name', 'a:40', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('chr_name', 'a:20', 'Characteristic Name', py_name='chr_name'), DgsProperty('shtype', 'i', 'Shunt Type Code', py_name='shtype'), DgsProperty('ushnm', 'r', 'Rated Voltage in kV', py_name='ushnm'), DgsProperty('qcapn', 'r', 'Rated Capacitive Reactive Power per Step in MVAr', py_name='qcapn'), DgsProperty('ncapx', 'i', 'Maximum Number of Capacitor Steps', py_name='ncapx'), DgsProperty('ncapa', 'i', 'Actual Number of Switched Capacitor Steps', py_name='ncapa'), DgsProperty('outserv', 'i', 'Out of Service', py_name='outserv'), DgsProperty('qrean', 'r', 'Rated Inductive Reactive Power per Step in MVAr', py_name='qrean'), DgsProperty('ctech', 'i', 'Connection Technology Code', py_name='ctech'), DgsProperty('fres', 'r', 'Resonance Frequency in Hz', py_name='fres'), DgsProperty('greaf0', 'r', 'Zero-Sequence Conductance in S', py_name='greaf0'), DgsProperty('grea', 'r', 'Positive-Sequence Conductance in S', py_name='grea'), DgsProperty('iswitch', 'i', 'Automatic Step Switching Enabled', py_name='iswitch'), DgsProperty('qtotn', 'r', 'Total Rated Reactive Power in MVAr', py_name='qtotn'), DgsProperty('tandc', 'r', 'Loss Factor tan(delta)', py_name='tandc'), # Voltage setpoint for controlled operation (p.u.). Not always present in the DGS header. # If absent in the file, it will remain at its default value (1.0). DgsProperty('usetp', 'r', 'Voltage Setpoint in p.u.', py_name='usetp'), DgsProperty('rpara', 'r', 'Parallel Damping Resistance in Ohm', py_name='rpara'), DgsProperty('i_cont', 'i', 'Tap Changer (Discrete=0, Continuous=1)', py_name='i_cont'), DgsProperty('usetp_mx', 'r', 'Upper Voltage Limit in p.u.', py_name='usetp_mx'), DgsProperty('usetp_mn', 'r', 'Lower Voltage Limit in p.u.', py_name='usetp_mn'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.chr_name: str = "" self.shtype: int = 0 self.ushnm: float = 0.0 self.qcapn: float = 0.0 self.ncapx: int = 0 self.ncapa: int = 0 self.outserv: int = 0 self.qrean: float = 0.0 self.ctech: int = 0 self.fres: float = 0.0 self.greaf0: float = 0.0 self.grea: float = 0.0 self.iswitch: int = 0 self.qtotn: float = 0.0 self.tandc: float = 0.0 self.usetp: float = 1.0 self.rpara: float = 0.0 self.i_cont: int = 0 self.usetp_mx: float = 1.0 self.usetp_mn: float = 1.0
[docs] class ElmSvs(DGSElement): element_type = 'ElmSvs' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('loc_name', 'a:40', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('chr_name', 'a:20', 'Characteristic Name', py_name='chr_name'), # Reactive limits (MVAr @ v=1 p.u.) DgsProperty('qmin', 'r', 'Minimum Reactive Power at 1.0 p.u. in MVAr', py_name='qmin'), DgsProperty('qmax', 'r', 'Maximum Reactive Power at 1.0 p.u. in MVAr', py_name='qmax'), # PF SVS/SVC model-specific fields (kept for completeness) DgsProperty('tcrmax', 'r', 'Maximum TCR Reactive Absorption in MVAr', py_name='tcrmax'), DgsProperty('nxcap', 'i', 'Maximum Number of Switched Capacitor Steps', py_name='nxcap'), DgsProperty('nfixcap', 'i', 'Number of Fixed Capacitor Steps', py_name='nfixcap'), DgsProperty('Qfixcap', 'r', 'Reactive Power of Fixed Capacitor Part in MVAr', py_name='Qfixcap'), # Out of service flag (0/1) DgsProperty('outserv', 'i', 'Out of Service', py_name='outserv'), # Voltage setpoint for controlled operation (p.u.). Not always present in the DGS header. # If absent in the file, it will remain at its default value (1.0). DgsProperty('usetp', 'r', 'Voltage Setpoint in p.u.', py_name='usetp'), DgsProperty('i_ctrl', 'i', 'Control mode', py_name='i_ctrl'), DgsProperty('i_droop', 'i', 'Droop control enabled?', py_name='i_droop'), DgsProperty('ddroop', 'r', 'Droop [%]', py_name='ddroop'), DgsProperty('Srated', 'r', 'Rated reactive power [Mvar]', py_name='Srated'), DgsProperty('nncap', 'i', 'Actual number of capacitors', py_name='nncap'), DgsProperty('tcrqact', 'r', 'Actual value of TCR [Mvar]', py_name='tcrqact'), DgsProperty('qsetp', 'r', 'Reactive Power Setpoint [Mvar]', py_name='qsetp'), ] def __init__(self) -> None: # Identifiers self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.chr_name: str = "" # Operating limits (MVAr @ v=1 p.u.) self.qmin: float = 0.0 self.qmax: float = 0.0 # Thyristor controlled reactor max (PF SVC/SVS model-specific, may be unused in VeraGrid) self.tcrmax: float = 0.0 # Step / block data (PF model-specific, may be used to infer an equivalent stepped model) self.nxcap: int = 0 self.nfixcap: int = 0 self.Qfixcap: float = 0.0 # Status self.outserv: int = 0 # Voltage setpoint (p.u.) for controlled shunts self.usetp: float = 1.0 self.ddroop: float = 0.0 # Droop [%] self.Srated: float = 0.0 # Rated reactive power [Mvar] self.i_ctrl: int = 0 # Control mode self.i_droop: int = 0 # Droop control self.nncap: int = 0 # Actual number of capacitors self.tcrqact: float = 0.0 # Actual value of TCR [Mvar] self.qsetp: float = 0.0 # Reactive Power Setpoint [Mvar]
[docs] class ElmSite(DGSElement): element_type = 'ElmSite' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a:40', 'DGS field loc_name (a:40)', py_name='loc_name'), DgsProperty('for_name', 'a:50', 'DGS field for_name (a:50)', py_name='for_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('sType', 'a:80', 'DGS field sType (a:80)', py_name='sType'), DgsProperty('GPSlat', 'r', 'DGS field GPSlat (r)', py_name='GPSlat'), DgsProperty('GPSlon', 'r', 'DGS field GPSlon (r)', py_name='GPSlon'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.for_name: str = "" self.fold_id: str = "" self.sType: str = "" self.GPSlat: float = 0.0 self.GPSlon: float = 0.0
[docs] class ElmSubstat(DGSElement): element_type = 'ElmSubstat' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('OP', 'a:1', 'Operation flag', py_name='OP'), DgsProperty('loc_name', 'a:80', 'DGS field loc_name (a)', py_name='loc_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('Unom', 'r', 'DGS field Unom (r)', py_name='Unom'), DgsProperty('pRA', 'p', 'DGS field pRA (p)', py_name='pRA'), DgsProperty('for_name', 'a:50', 'DGS field for_name (a:50)', py_name='for_name'), DgsProperty('sShort', 'a:24', 'DGS field sShort (a:6)', py_name='sShort'), DgsProperty('sType', 'a:160', 'DGS field sType (a:80)', py_name='sType'), DgsProperty('GPSlat', 'r', 'Latitude / Northing in deg', py_name='GPSlat'), DgsProperty('GPSlon', 'r', 'Longitude / Easting in deg', py_name='GPSlon'), DgsProperty('cpArea', 'p', 'Default Area in ElmArea', py_name='cpArea'), DgsProperty('cpZone', 'p', 'Default Zone in ElmZone', py_name='cpZone'), ] def __init__(self) -> None: self.ID: str = "" self.OP: str = "" self.loc_name: str = "" self.fold_id: str = "" self.Unom: float = 0.0 self.pRA: str = "" self.for_name: str = "" self.sShort: str = "" self.sType: str = "" self.GPSlat: float = 0.0 self.GPSlon: float = 0.0 self.cpArea: str = "" self.cpZone: str = ""
[docs] class ElmSym(DGSElement): element_type = 'ElmSym' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('loc_name', 'a:40', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('typ_id', 'p', 'Type in TypSym', py_name='typ_id'), DgsProperty('ngnum', 'i', 'Number of Parallel Machines', py_name='ngnum'), DgsProperty('i_mot', 'i', 'Operating Mode: Generator:Motor', py_name='i_mot'), DgsProperty('chr_name', 'a:20', 'Characteristic Name', py_name='chr_name'), DgsProperty('outserv', 'i', 'Out of Service', py_name='outserv'), DgsProperty('pgini', 'r', 'Active Power Setpoint in MW', py_name='pgini'), DgsProperty('qgini', 'r', 'Reactive Power Setpoint in MVAr', py_name='qgini'), DgsProperty('usetp', 'r', 'Voltage Setpoint in p.u.', py_name='usetp'), DgsProperty('iv_mode', 'i', 'Voltage Control Mode Code', py_name='iv_mode'), DgsProperty('q_min', 'r', 'Minimum Reactive Power Limit in MVAr', py_name='q_min'), DgsProperty('q_max', 'r', 'Maximum Reactive Power Limit in MVAr', py_name='q_max'), DgsProperty('Pmin_uc', 'r', 'Minimum Active Power Limit in MW', py_name='Pmin_uc'), DgsProperty('Pmax_uc', 'r', 'Maximum Active Power Limit in MW', py_name='Pmax_uc'), DgsProperty('iqtype', 'i', 'Reactive Power Capability Mode Code', py_name='iqtype'), DgsProperty('for_name', 'a:50', 'Foreign Key', py_name='for_name'), DgsProperty('cCategory', 'a', 'Generator Category', py_name='cCategory'), DgsProperty('cosgini', 'r', 'Initial Power Factor', py_name='cosgini'), DgsProperty('pf_recap', 'i', 'Power Factor Sign: Overexcited:Underexcited', py_name='pf_recap'), DgsProperty('av_mode', 'a', 'Active Power Control Mode', py_name='av_mode'), DgsProperty('phtech', 'i', 'Phase Technology Code', py_name='phtech'), DgsProperty('ip_ctrl', 'i', 'Reference machine', py_name='ip_ctrl'), DgsProperty('c_pmod', 'a:40', 'plant model', py_name='c_pmod'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.typ_id: str = "" self.ngnum: int = 1 self.i_mot: int = 0 self.chr_name: str = "" self.outserv: int = 0 self.pgini: float = 0.0 self.qgini: float = 0.0 self.usetp: float = 0.0 self.iv_mode: int = 0 self.q_min: float = 0.0 self.q_max: float = 0.0 self.Pmin_uc: float = 0.0 self.Pmax_uc: float = 0.0 self.iqtype: int = 0 self.for_name: str = "" self.cCategory: str = "" self.cosgini: float = 0.0 self.pf_recap: int = 0 self.av_mode: str = "" self.phtech: int = 0 self.ip_ctrl: int = 0 self.c_pmod: str = ""
[docs] class ElmTerm(DGSElement): """ * FID: Unique identifier for DGS file * OP: Operation (C=create, U=update, D=delete, M=merge, I=ignore) * loc_name: Name * fold_id: In Folder * typ_id: Type in TypBar * systype: System Type:AC:DC:AC/BI * iUsage: Usage:Busbar:Junction Node:Internal Node * uknom: Nominal Voltage: Line-Line in kV * unknom: Nominal Voltage: Line-Ground in kV * iminus: Nominal Voltage: DC-Polarity:positive (+):negative (-):neutral * outserv: Out of Service * GPSlat: Geographical Position: Latitude / Northing in deg * GPSlon: Geographical Position: Longitude / Easting in deg * vtarget: Voltage Control: Target Voltage in p.u. """ element_type = 'ElmTerm' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('loc_name', 'a:40', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('typ_id', 'p', 'Type in TypBar', py_name='typ_id'), DgsProperty('iUsage', 'i', 'Usage: Busbar:Junction Node:Internal Node', py_name='iUsage'), DgsProperty('uknom', 'r', 'Nominal Voltage Line-Line in kV', py_name='uknom'), DgsProperty('chr_name', 'a:20', 'Characteristic Name', py_name='chr_name'), DgsProperty('outserv', 'i', 'Out of Service', py_name='outserv'), DgsProperty('cpZone', 'p', 'Zone in ElmZone', py_name='cpZone'), DgsProperty('phtech', 'i', 'Phase Technology Code', py_name='phtech'), DgsProperty('for_name', 'a:50', 'Foreign Key', py_name='for_name'), DgsProperty('systype', 'i', 'System Type: AC:DC:AC/BI', py_name='systype'), DgsProperty('unknom', 'r', 'Nominal Voltage Line-Ground in kV', py_name='unknom'), DgsProperty('iminus', 'i', 'DC Polarity: Positive:Negative:Neutral', py_name='iminus'), DgsProperty('GPSlat', 'r', 'Latitude / Northing in deg', py_name='GPSlat'), DgsProperty('GPSlon', 'r', 'Longitude / Easting in deg', py_name='GPSlon'), DgsProperty('vtarget', 'r', 'Voltage Control Target in p.u.', py_name='vtarget'), DgsProperty('m:u', 'r', 'Measured Voltage Magnitude in p.u.', py_name='m_u'), DgsProperty('m:phiu', 'r', 'Measured Voltage Angle in deg', py_name='m_phiu'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.typ_id: str = "" self.iUsage: int = 0 self.uknom: float = 0.0 self.chr_name: str = "" self.outserv: int = 0 self.phtech: int = 0 self.for_name: str = "" self.systype: int = 0 self.unknom: float = 0.0 self.iminus: int = 0 self.GPSlat: float = 0.0 self.GPSlon: float = 0.0 self.vtarget: float = 0.0 self.m_u: float = 0.0 self.m_phiu: float = 0.0 self.cpZone: str = ""
[docs] class ElmTr2(DGSElement): element_type = 'ElmTr2' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('loc_name', 'a:40', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('typ_id', 'p', 'Type in TypTr2', py_name='typ_id'), DgsProperty('outserv', 'i', 'Out of Service', py_name='outserv'), DgsProperty('nntap', 'i', 'Tap Changer 1: Tap Position', py_name='nntap'), DgsProperty('sernum', 'a:20', 'Serial Number (a:20)', py_name='sernum'), DgsProperty('constr', 'i', 'Year of Construction', py_name='constr'), DgsProperty('chr_name', 'a:20', 'Characteristic Name', py_name='chr_name'), DgsProperty('cgnd_h', 'i', 'Internal Grounding Impedance, HV Side: Star Point:Connected:Not connected', py_name='cgnd_h'), DgsProperty('cgnd_l', 'i', 'Internal Grounding Impedance, LV Side: Star Point:Connected:Not connected', py_name='cgnd_l'), DgsProperty('i_auto', 'i', 'Auto Transformer', py_name='i_auto'), DgsProperty('ntrcn', 'i', 'Controller, Tap Changer 1: Automatic Tap Changing', py_name='ntrcn'), DgsProperty('ratfac', 'r', 'Rating Factor', py_name='ratfac'), DgsProperty('for_name', 'a:50', 'Foreign Key', py_name='for_name'), DgsProperty('ntnum', 'i', 'Number of Parallel Transformers', py_name='ntnum'), DgsProperty('usetp', 'r', 'Voltage Setpoint in p.u.', py_name='usetp'), DgsProperty('usp_low', 'r', 'Lower Voltage Band in p.u.', py_name='usp_low'), DgsProperty('usp_up', 'r', 'Upper Voltage Band in p.u.', py_name='usp_up'), DgsProperty('t2ldc', 'i', 'Line Drop Compensation Enabled', py_name='t2ldc'), DgsProperty('mTaps_SIZEROW', 'i', 'Number of Stored Tap Table Rows', py_name='mTaps_SIZEROW'), DgsProperty('mTaps_SIZECOL', 'i', 'Number of Stored Tap Table Columns', py_name='mTaps_SIZECOL'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.typ_id: str = "" self.outserv: int = 0 self.nntap: int = 0 self.sernum: str = "" self.constr: int = 0 self.chr_name: str = "" self.cgnd_h: int = 0 self.cgnd_l: int = 0 self.i_auto: int = 0 self.ntrcn: int = 0 self.ratfac: float = 1.0 self.for_name: str = "" self.ntnum: int = 1 self.usetp: float = 0.0 self.usp_low: float = 0.0 self.usp_up: float = 0.0 self.t2ldc: int = 0 self.mTaps_SIZEROW: int = 0 self.mTaps_SIZECOL: int = 0
[docs] class ElmTr3(DGSElement): element_type = 'ElmTr3' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('loc_name', 'a:40', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('typ_id', 'p', 'Type in TypTr3', py_name='typ_id'), DgsProperty('outserv', 'i', 'Out of Service', py_name='outserv'), DgsProperty('nt3nm', 'i', 'Number of Parallel Transformers', py_name='nt3nm'), DgsProperty('n3tap_h', 'i', 'Tap Position at HV Side', py_name='n3tap_h'), DgsProperty('n3tap_m', 'i', 'Tap Position at MV Side', py_name='n3tap_m'), DgsProperty('n3tap_l', 'i', 'Tap Position at LV Side', py_name='n3tap_l'), DgsProperty('chr_name', 'a:20', 'Characteristic Name', py_name='chr_name'), DgsProperty('for_name', 'a:50', 'Foreign Key', py_name='for_name'), DgsProperty('i_auto_hl', 'i', 'Autotransformer Flag for HV-LV Coupling', py_name='i_auto_hl'), DgsProperty('ictrlside', 'i', 'Controlled Side for Automatic Tap Changing', py_name='ictrlside'), DgsProperty('ntrcn', 'i', 'Automatic Tap Changing Enabled', py_name='ntrcn'), DgsProperty('t3ldc', 'i', 'Line Drop Compensation Enabled', py_name='t3ldc'), DgsProperty('usetp', 'r', 'Voltage Setpoint in p.u.', py_name='usetp'), DgsProperty('usp_low', 'r', 'Lower Voltage Band in p.u.', py_name='usp_low'), DgsProperty('usp_up', 'r', 'Upper Voltage Band in p.u.', py_name='usp_up'), DgsProperty('mTaps:SIZEROW', 'i', 'Number of Stored Tap Table Rows', py_name='mTaps_SIZEROW'), DgsProperty('mTaps:SIZECOL', 'i', 'Number of Stored Tap Table Columns', py_name='mTaps_SIZECOL'), DgsProperty('mTaps:0:0', 'r', 'Tap Table Entry Row 0 Column 0', py_name='mTaps_0_0'), DgsProperty('mTaps:0:1', 'r', 'Tap Table Entry Row 0 Column 1', py_name='mTaps_0_1'), DgsProperty('mTaps:0:2', 'r', 'Tap Table Entry Row 0 Column 2', py_name='mTaps_0_2'), DgsProperty('mTaps:0:3', 'r', 'Tap Table Entry Row 0 Column 3', py_name='mTaps_0_3'), DgsProperty('mTaps:0:4', 'r', 'Tap Table Entry Row 0 Column 4', py_name='mTaps_0_4'), DgsProperty('mTaps:0:5', 'r', 'Tap Table Entry Row 0 Column 5', py_name='mTaps_0_5'), DgsProperty('mTaps:0:6', 'r', 'Tap Table Entry Row 0 Column 6', py_name='mTaps_0_6'), DgsProperty('mTaps:0:7', 'r', 'Tap Table Entry Row 0 Column 7', py_name='mTaps_0_7'), DgsProperty('mTaps:1:0', 'r', 'Tap Table Entry Row 1 Column 0', py_name='mTaps_1_0'), DgsProperty('mTaps:1:1', 'r', 'Tap Table Entry Row 1 Column 1', py_name='mTaps_1_1'), DgsProperty('mTaps:1:2', 'r', 'Tap Table Entry Row 1 Column 2', py_name='mTaps_1_2'), DgsProperty('mTaps:1:3', 'r', 'Tap Table Entry Row 1 Column 3', py_name='mTaps_1_3'), DgsProperty('mTaps:1:4', 'r', 'Tap Table Entry Row 1 Column 4', py_name='mTaps_1_4'), DgsProperty('mTaps:1:5', 'r', 'Tap Table Entry Row 1 Column 5', py_name='mTaps_1_5'), DgsProperty('mTaps:1:6', 'r', 'Tap Table Entry Row 1 Column 6', py_name='mTaps_1_6'), DgsProperty('mTaps:1:7', 'r', 'Tap Table Entry Row 1 Column 7', py_name='mTaps_1_7'), DgsProperty('mTaps:2:0', 'r', 'Tap Table Entry Row 2 Column 0', py_name='mTaps_2_0'), DgsProperty('mTaps:2:1', 'r', 'Tap Table Entry Row 2 Column 1', py_name='mTaps_2_1'), DgsProperty('mTaps:2:2', 'r', 'Tap Table Entry Row 2 Column 2', py_name='mTaps_2_2'), DgsProperty('mTaps:2:3', 'r', 'Tap Table Entry Row 2 Column 3', py_name='mTaps_2_3'), DgsProperty('mTaps:2:4', 'r', 'Tap Table Entry Row 2 Column 4', py_name='mTaps_2_4'), DgsProperty('mTaps:2:5', 'r', 'Tap Table Entry Row 2 Column 5', py_name='mTaps_2_5'), DgsProperty('mTaps:2:6', 'r', 'Tap Table Entry Row 2 Column 6', py_name='mTaps_2_6'), DgsProperty('mTaps:2:7', 'r', 'Tap Table Entry Row 2 Column 7', py_name='mTaps_2_7'), DgsProperty('iMeasTap', 'i', 'Tap Position Used for Measurement', py_name='iMeasTap'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.typ_id: str = "" self.outserv: int = 0 self.nt3nm: int = 0 self.n3tap_h: int = 0 self.n3tap_m: int = 0 self.n3tap_l: int = 0 self.chr_name: str = "" self.for_name: str = "" self.i_auto_hl: int = 0 self.ictrlside: int = 0 self.ntrcn: int = 0 self.t3ldc: int = 0 self.usetp: float = 0.0 self.usp_low: float = 0.0 self.usp_up: float = 0.0 self.mTaps_SIZEROW: int = 0 self.mTaps_SIZECOL: int = 0 self.mTaps_0_0: float = 0.0 self.mTaps_0_1: float = 0.0 self.mTaps_0_2: float = 0.0 self.mTaps_0_3: float = 0.0 self.mTaps_0_4: float = 0.0 self.mTaps_0_5: float = 0.0 self.mTaps_0_6: float = 0.0 self.mTaps_0_7: float = 0.0 self.mTaps_1_0: float = 0.0 self.mTaps_1_1: float = 0.0 self.mTaps_1_2: float = 0.0 self.mTaps_1_3: float = 0.0 self.mTaps_1_4: float = 0.0 self.mTaps_1_5: float = 0.0 self.mTaps_1_6: float = 0.0 self.mTaps_1_7: float = 0.0 self.mTaps_2_0: float = 0.0 self.mTaps_2_1: float = 0.0 self.mTaps_2_2: float = 0.0 self.mTaps_2_3: float = 0.0 self.mTaps_2_4: float = 0.0 self.mTaps_2_5: float = 0.0 self.mTaps_2_6: float = 0.0 self.mTaps_2_7: float = 0.0 self.iMeasTap: int = 0
[docs] class ElmTr4(DGSElement): element_type = 'ElmTr4' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('OP', 'a:1', 'Operation flag', py_name='OP'), DgsProperty('loc_name', 'a:80', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('typ_id', 'p', 'Type in TypTr4', py_name='typ_id'), DgsProperty('outserv', 'i', 'Out of Service', py_name='outserv'), DgsProperty('ictrlside', 'i', 'Controlled Side', py_name='ictrlside'), DgsProperty('ntrcn', 'i', 'Control Node Number', py_name='ntrcn'), DgsProperty('usetp', 'r', 'Voltage Setpoint in p.u.', py_name='usetp'), DgsProperty('usp_low', 'r', 'Lower Voltage Setpoint Limit in p.u.', py_name='usp_low'), DgsProperty('usp_up', 'r', 'Upper Voltage Setpoint Limit in p.u.', py_name='usp_up'), DgsProperty('chr_name', 'a:40', 'Characteristic Name', py_name='chr_name'), DgsProperty('for_name', 'a:100', 'Foreign Key', py_name='for_name'), DgsProperty('Inom_l3', 'r', 'Nominal Current LV3 in kA', py_name='Inom_l3'), DgsProperty('Inom_l2', 'r', 'Nominal Current LV2 in kA', py_name='Inom_l2'), DgsProperty('Inom_l1', 'r', 'Nominal Current LV1 in kA', py_name='Inom_l1'), DgsProperty('Inom_h0', 'r', 'Nominal Current HV in kA', py_name='Inom_h0'), DgsProperty('Snom_l3', 'r', 'Nominal Power LV3 in MVA', py_name='Snom_l3'), DgsProperty('Snom_l2', 'r', 'Nominal Power LV2 in MVA', py_name='Snom_l2'), DgsProperty('Snom_l1', 'r', 'Nominal Power LV1 in MVA', py_name='Snom_l1'), DgsProperty('Snom_h0', 'r', 'Nominal Power HV in MVA', py_name='Snom_h0'), DgsProperty('Snom_l3_a', 'r', 'Actual Nominal Power LV3 in MVA', py_name='Snom_l3_a'), DgsProperty('Snom_l2_a', 'r', 'Actual Nominal Power LV2 in MVA', py_name='Snom_l2_a'), DgsProperty('Snom_l1_a', 'r', 'Actual Nominal Power LV1 in MVA', py_name='Snom_l1_a'), DgsProperty('Snom_h0_a', 'r', 'Actual Nominal Power HV in MVA', py_name='Snom_h0_a'), DgsProperty('xSbasepu_lv3', 'r', 'Positive Sequence Reactance LV3 in p.u.', py_name='xSbasepu_lv3'), DgsProperty('xSbasepu_lv2', 'r', 'Positive Sequence Reactance LV2 in p.u.', py_name='xSbasepu_lv2'), DgsProperty('xSbasepu_lv1', 'r', 'Positive Sequence Reactance LV1 in p.u.', py_name='xSbasepu_lv1'), DgsProperty('xSbasepu_hv0', 'r', 'Positive Sequence Reactance HV in p.u.', py_name='xSbasepu_hv0'), DgsProperty('rSbasepu_lv3', 'r', 'Positive Sequence Resistance LV3 in p.u.', py_name='rSbasepu_lv3'), DgsProperty('rSbasepu_lv2', 'r', 'Positive Sequence Resistance LV2 in p.u.', py_name='rSbasepu_lv2'), DgsProperty('rSbasepu_lv1', 'r', 'Positive Sequence Resistance LV1 in p.u.', py_name='rSbasepu_lv1'), DgsProperty('rSbasepu_hv0', 'r', 'Positive Sequence Resistance HV in p.u.', py_name='rSbasepu_hv0'), DgsProperty('xSbasepu_l2l3', 'r', 'Positive Sequence Reactance LV2-LV3 in p.u.', py_name='xSbasepu_l2l3'), DgsProperty('xSbasepu_l1l3', 'r', 'Positive Sequence Reactance LV1-LV3 in p.u.', py_name='xSbasepu_l1l3'), DgsProperty('xSbasepu_l1l2', 'r', 'Positive Sequence Reactance LV1-LV2 in p.u.', py_name='xSbasepu_l1l2'), DgsProperty('xSbasepu_h0l3', 'r', 'Positive Sequence Reactance HV-LV3 in p.u.', py_name='xSbasepu_h0l3'), DgsProperty('xSbasepu_h0l2', 'r', 'Positive Sequence Reactance HV-LV2 in p.u.', py_name='xSbasepu_h0l2'), DgsProperty('xSbasepu_h0l1', 'r', 'Positive Sequence Reactance HV-LV1 in p.u.', py_name='xSbasepu_h0l1'), DgsProperty('rSbasepu_l2l3', 'r', 'Positive Sequence Resistance LV2-LV3 in p.u.', py_name='rSbasepu_l2l3'), DgsProperty('rSbasepu_l1l3', 'r', 'Positive Sequence Resistance LV1-LV3 in p.u.', py_name='rSbasepu_l1l3'), DgsProperty('rSbasepu_l1l2', 'r', 'Positive Sequence Resistance LV1-LV2 in p.u.', py_name='rSbasepu_l1l2'), DgsProperty('rSbasepu_h0l3', 'r', 'Positive Sequence Resistance HV-LV3 in p.u.', py_name='rSbasepu_h0l3'), DgsProperty('rSbasepu_h0l2', 'r', 'Positive Sequence Resistance HV-LV2 in p.u.', py_name='rSbasepu_h0l2'), DgsProperty('rSbasepu_h0l1', 'r', 'Positive Sequence Resistance HV-LV1 in p.u.', py_name='rSbasepu_h0l1'), DgsProperty('x0Sbasepu_lv3', 'r', 'Zero Sequence Reactance LV3 in p.u.', py_name='x0Sbasepu_lv3'), DgsProperty('x0Sbasepu_lv2', 'r', 'Zero Sequence Reactance LV2 in p.u.', py_name='x0Sbasepu_lv2'), DgsProperty('x0Sbasepu_lv1', 'r', 'Zero Sequence Reactance LV1 in p.u.', py_name='x0Sbasepu_lv1'), DgsProperty('x0Sbasepu_hv0', 'r', 'Zero Sequence Reactance HV in p.u.', py_name='x0Sbasepu_hv0'), DgsProperty('r0Sbasepu_lv3', 'r', 'Zero Sequence Resistance LV3 in p.u.', py_name='r0Sbasepu_lv3'), DgsProperty('r0Sbasepu_lv2', 'r', 'Zero Sequence Resistance LV2 in p.u.', py_name='r0Sbasepu_lv2'), DgsProperty('r0Sbasepu_lv1', 'r', 'Zero Sequence Resistance LV1 in p.u.', py_name='r0Sbasepu_lv1'), DgsProperty('r0Sbasepu_hv0', 'r', 'Zero Sequence Resistance HV in p.u.', py_name='r0Sbasepu_hv0'), DgsProperty('bSbasepu', 'r', 'Magnetizing Susceptance in p.u.', py_name='bSbasepu'), DgsProperty('pT_lv3', 'a', 'Tap Position LV3', py_name='pT_lv3'), DgsProperty('pT_lv2', 'a', 'Tap Position LV2', py_name='pT_lv2'), DgsProperty('pT_lv1', 'a', 'Tap Position LV1', py_name='pT_lv1'), DgsProperty('pT_hv0', 'a', 'Tap Position HV', py_name='pT_hv0'), DgsProperty('i_tapini_lv3', 'i', 'Initial Tap Position LV3', py_name='i_tapini_lv3'), DgsProperty('i_tapini_lv2', 'i', 'Initial Tap Position LV2', py_name='i_tapini_lv2'), DgsProperty('i_tapini_lv1', 'i', 'Initial Tap Position LV1', py_name='i_tapini_lv1'), DgsProperty('i_tapini_hv0', 'i', 'Initial Tap Position HV', py_name='i_tapini_hv0'), DgsProperty('busl3', 'p', 'LV3 Terminal in ElmTerm', py_name='busl3'), DgsProperty('busl2', 'p', 'LV2 Terminal in ElmTerm', py_name='busl2'), DgsProperty('busl1', 'p', 'LV1 Terminal in ElmTerm', py_name='busl1'), DgsProperty('bush0', 'p', 'HV Terminal in ElmTerm', py_name='bush0'), DgsProperty('cpSubstat', 'p', 'Substation in ElmSubstat', py_name='cpSubstat'), DgsProperty('cpArea', 'p', 'Area in ElmArea', py_name='cpArea'), DgsProperty('cpZone', 'p', 'Zone in ElmZone', py_name='cpZone'), DgsProperty('cpGrid', 'p', 'Grid Reference', py_name='cpGrid'), DgsProperty('GPSlon', 'r', 'Longitude / Easting in deg', py_name='GPSlon'), DgsProperty('GPSlat', 'r', 'Latitude / Northing in deg', py_name='GPSlat'), DgsProperty('maxload', 'r', 'Maximum Loading in percent', py_name='maxload'), DgsProperty('ratfac_l3', 'r', 'Rating Factor LV3', py_name='ratfac_l3'), DgsProperty('ratfac_l2', 'r', 'Rating Factor LV2', py_name='ratfac_l2'), DgsProperty('ratfac_l1', 'r', 'Rating Factor LV1', py_name='ratfac_l1'), DgsProperty('ratfac_h0', 'r', 'Rating Factor HV', py_name='ratfac_h0'), DgsProperty('desc:0', 'a', 'Description Line 0', py_name='desc_0'), DgsProperty('desc:1', 'a', 'Description Line 1', py_name='desc_1'), DgsProperty('desc:2', 'a', 'Description Line 2', py_name='desc_2'), DgsProperty('desc:3', 'a', 'Description Line 3', py_name='desc_3'), DgsProperty('commissionDate', 'a:21', 'Commissioning Date', py_name='commissionDate'), DgsProperty('sernum', 'a:40', 'Serial Number', py_name='sernum'), DgsProperty('dat_src', 'a:6', 'Data Source', py_name='dat_src'), ] def __init__(self) -> None: self.ID: str = "" self.OP: str = "" self.loc_name: str = "" self.fold_id: str = "" self.typ_id: str = "" self.outserv: int = 0 self.ictrlside: int = 0 self.ntrcn: int = 0 self.usetp: float = 0.0 self.usp_low: float = 0.0 self.usp_up: float = 0.0 self.chr_name: str = "" self.for_name: str = "" self.Inom_l3: float = 0.0 self.Inom_l2: float = 0.0 self.Inom_l1: float = 0.0 self.Inom_h0: float = 0.0 self.Snom_l3: float = 0.0 self.Snom_l2: float = 0.0 self.Snom_l1: float = 0.0 self.Snom_h0: float = 0.0 self.Snom_l3_a: float = 0.0 self.Snom_l2_a: float = 0.0 self.Snom_l1_a: float = 0.0 self.Snom_h0_a: float = 0.0 self.xSbasepu_lv3: float = 0.0 self.xSbasepu_lv2: float = 0.0 self.xSbasepu_lv1: float = 0.0 self.xSbasepu_hv0: float = 0.0 self.rSbasepu_lv3: float = 0.0 self.rSbasepu_lv2: float = 0.0 self.rSbasepu_lv1: float = 0.0 self.rSbasepu_hv0: float = 0.0 self.xSbasepu_l2l3: float = 0.0 self.xSbasepu_l1l3: float = 0.0 self.xSbasepu_l1l2: float = 0.0 self.xSbasepu_h0l3: float = 0.0 self.xSbasepu_h0l2: float = 0.0 self.xSbasepu_h0l1: float = 0.0 self.rSbasepu_l2l3: float = 0.0 self.rSbasepu_l1l3: float = 0.0 self.rSbasepu_l1l2: float = 0.0 self.rSbasepu_h0l3: float = 0.0 self.rSbasepu_h0l2: float = 0.0 self.rSbasepu_h0l1: float = 0.0 self.x0Sbasepu_lv3: float = 0.0 self.x0Sbasepu_lv2: float = 0.0 self.x0Sbasepu_lv1: float = 0.0 self.x0Sbasepu_hv0: float = 0.0 self.r0Sbasepu_lv3: float = 0.0 self.r0Sbasepu_lv2: float = 0.0 self.r0Sbasepu_lv1: float = 0.0 self.r0Sbasepu_hv0: float = 0.0 self.bSbasepu: float = 0.0 self.pT_lv3: str = "" self.pT_lv2: str = "" self.pT_lv1: str = "" self.pT_hv0: str = "" self.i_tapini_lv3: int = 0 self.i_tapini_lv2: int = 0 self.i_tapini_lv1: int = 0 self.i_tapini_hv0: int = 0 self.busl3: str = "" self.busl2: str = "" self.busl1: str = "" self.bush0: str = "" self.cpSubstat: str = "" self.cpArea: str = "" self.cpZone: str = "" self.cpGrid: str = "" self.GPSlon: float = 0.0 self.GPSlat: float = 0.0 self.maxload: float = 0.0 self.ratfac_l3: float = 0.0 self.ratfac_l2: float = 0.0 self.ratfac_l1: float = 0.0 self.ratfac_h0: float = 0.0 self.desc_0: str = "" self.desc_1: str = "" self.desc_2: str = "" self.desc_3: str = "" self.commissionDate: str = "" self.sernum: str = "" self.dat_src: str = ""
[docs] class ElmXnet(DGSElement): element_type = 'ElmXnet' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('loc_name', 'a:40', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('outserv', 'i', 'Out of Service', py_name='outserv'), DgsProperty('snss', 'r', 'Maximum Short-Circuit Power in MVA', py_name='snss'), DgsProperty('rntxn', 'r', 'R/X Ratio for Maximum Short-Circuit Power', py_name='rntxn'), DgsProperty('z2tz1', 'r', 'Ratio Z2 / Z1', py_name='z2tz1'), DgsProperty('snssmin', 'r', 'Minimum Short-Circuit Power in MVA', py_name='snssmin'), DgsProperty('rntxnmin', 'r', 'R/X Ratio for Minimum Short-Circuit Power', py_name='rntxnmin'), DgsProperty('z2tz1min', 'r', 'Minimum Ratio Z2 / Z1', py_name='z2tz1min'), DgsProperty('chr_name', 'a:20', 'Characteristic Name', py_name='chr_name'), DgsProperty('bustp', 'a:2', 'Bus Type: SL:PV:PQ', py_name='bustp'), DgsProperty('pgini', 'r', 'Active Power Setpoint in MW', py_name='pgini'), DgsProperty('qgini', 'r', 'Reactive Power Setpoint in MVAr', py_name='qgini'), DgsProperty('phiini', 'r', 'Voltage Angle Setpoint in deg', py_name='phiini'), DgsProperty('usetp', 'r', 'Voltage Magnitude Setpoint in p.u.', py_name='usetp'), DgsProperty('cgnd', 'i', 'Neutral Grounded: Connected:Not connected', py_name='cgnd'), DgsProperty('iintgnd', 'i', 'Internal Grounding Impedance Enabled', py_name='iintgnd'), DgsProperty('ikssmin', 'r', 'Minimum Initial Symmetrical Short-Circuit Current in kA', py_name='ikssmin'), DgsProperty('r0tx0', 'r', 'Ratio R0 / X0', py_name='r0tx0'), DgsProperty('r0tx0min', 'r', 'Minimum Ratio R0 / X0', py_name='r0tx0min'), DgsProperty('cmax', 'r', 'Maximum voltage factor', py_name='cmax'), DgsProperty('xd', 'r', 'd synchronous reactance', py_name='xd'), DgsProperty('xq', 'r', 'q synchronous reactance', py_name='xq'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.outserv: int = 0 self.snss: float = 0.0 self.rntxn: float = 0.0 self.z2tz1: float = 0.0 self.snssmin: float = 0.0 self.rntxnmin: float = 0.0 self.z2tz1min: float = 0.0 self.chr_name: str = "" self.bustp: str = "" self.pgini: float = 0.0 self.qgini: float = 0.0 self.phiini: float = 0.0 self.usetp: float = 0.0 self.cgnd: int = 0 self.iintgnd: int = 0 self.ikssmin: float = 0.0 self.r0tx0: float = 0.0 self.r0tx0min: float = 0.0 self.cmax: float = 1.0 self.xd: float = 0.2 self.xq: float = 0.2
[docs] class ElmZone(DGSElement): element_type = 'ElmZone' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a:40', 'DGS field loc_name (a:40)', py_name='loc_name'), DgsProperty('for_name', 'a:50', 'DGS field for_name (a:50)', py_name='for_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('icolor', 'i', 'DGS field icolor (i)', py_name='icolor'), DgsProperty('curscale', 'r', 'DGS field curscale (r)', py_name='curscale'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.for_name: str = "" self.fold_id: str = "" self.icolor: int = 0 self.curscale: float = 0.0
[docs] class ElmArea(DGSElement): element_type = 'ElmArea' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field FID (a:40)', py_name='ID'), DgsProperty('OP', 'a:1', 'DGS field OP (a:1)', py_name='OP'), DgsProperty('loc_name', 'a:80', 'DGS field loc_name (a:80)', py_name='loc_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('icolor', 'i', 'DGS field icolor (i)', py_name='icolor'), DgsProperty('for_name', 'a:100', 'DGS field for_name (a:100)', py_name='for_name'), ] def __init__(self) -> None: self.ID: str = "" self.OP: str = "" self.loc_name: str = "" self.fold_id: str = "" self.icolor: int = 0 self.for_name: str = ""
[docs] class General(DGSElement): element_type = 'General' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('Descr', 'a:40', 'DGS field Descr (a:40)', py_name='Descr'), DgsProperty('Val', 'a:40', 'DGS field Val (a:40)', py_name='Val'), ] def __init__(self) -> None: self.ID: str = "" self.Descr: str = "" self.Val: str = ""
[docs] class BlkDef(DGSElement): element_type = 'BlkDef' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier of the block definition', py_name='ID'), DgsProperty('OP', 'a:1', 'DGS operation marker for the block definition', py_name='OP'), DgsProperty('loc_name', 'a:80', 'Name of the DSL frame or block definition', py_name='loc_name'), DgsProperty('fold_id', 'p', 'Folder containing the block definition', py_name='fold_id'), ] def __init__(self) -> None: self.ID: str = "" self.OP: str = "" self.loc_name: str = "" self.fold_id: str = "" self.isMacro: int = 0 self.level: int = 0 self.outputs: List[str] = list() self.inputs: List[str] = list() self.states: List[str] = list() self.params: List[str] = list() self.upper_limit_params: List[str] = list() self.lower_limit_params: List[str] = list() self.internals: List[str] = list() self.equations_raw: List[str] = list() @staticmethod def _split_symbol_field(raw: str | None) -> List[str]: if raw is None: return list() text = raw.strip().strip('"') if text == "" or text == "*": return list() values: List[str] = list() token: List[str] = list() for ch in text: if ch in {',', ';'}: item = ''.join(token).strip() if item: values.append(item) token = list() else: token.append(ch) item = ''.join(token).strip() if item: values.append(item) return values @classmethod def _append_unique_symbols(cls, target: List[str], raw: str | None) -> None: """ Append parsed symbols to a target list preserving order and uniqueness. :param target: Destination symbol list. :param raw: Raw DGS symbol field. :return: None. """ parsed_values: List[str] = cls._split_symbol_field(raw) for value in parsed_values: if value not in target: target.append(value) else: pass
[docs] @classmethod def parse_line(cls, line: str, header_map: dict[str, int]): parts = _split_dgs_line(line) obj = super().parse_line(";".join(parts), header_map) is_macro = _dgs_get(parts, header_map, 'isMacro') level = _dgs_get(parts, header_map, 'level') obj.isMacro = int(float(is_macro.replace(',', '.'))) if is_macro is not None and is_macro.strip() != '' else 0 obj.level = int(float(level.replace(',', '.'))) if level is not None and level.strip() != '' else 0 obj.outputs = cls._split_symbol_field(_dgs_get(parts, header_map, 'cOutput')) obj.inputs = cls._split_symbol_field(_dgs_get(parts, header_map, 'cInput')) obj.states = cls._split_symbol_field(_dgs_get(parts, header_map, 'cStates')) obj.params = cls._split_symbol_field(_dgs_get(parts, header_map, 'cParams')) obj.internals = cls._split_symbol_field(_dgs_get(parts, header_map, 'cIntern')) # PowerFactory exports limiter parameters separately from cParams through upper/lower limit fields. cls._append_unique_symbols(obj.upper_limit_params, _dgs_get(parts, header_map, 'sUpLimPar:0')) cls._append_unique_symbols(obj.lower_limit_params, _dgs_get(parts, header_map, 'sLowLimPar:0')) for param_name in obj.upper_limit_params: if param_name not in obj.params: obj.params.append(param_name) else: pass for param_name in obj.lower_limit_params: if param_name not in obj.params: obj.params.append(param_name) else: pass raw_n_eq = _dgs_get(parts, header_map, 'sAddEquat:SIZEROW') n_eq = int(float(raw_n_eq.replace(',', '.'))) if raw_n_eq is not None and raw_n_eq.strip() != '' else 0 for i in range(n_eq): raw_eq = _dgs_get(parts, header_map, f'sAddEquat:{i}') raw_eq = raw_eq.strip() if raw_eq is not None else '' if raw_eq != '' and raw_eq != '*': obj.equations_raw.append(raw_eq) return obj
[docs] class IntFolder(DGSElement): element_type = 'IntFolder' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a', 'DGS field loc_name (a)', py_name='loc_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('iopt_typ', 'i', 'DGS field iopt_typ (i)', py_name='iopt_typ'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.iopt_typ: int = 0
[docs] class IntRef(DGSElement): element_type = 'IntRef' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier of the internal reference object', py_name='ID'), DgsProperty('OP', 'a:1', 'DGS operation marker for the internal reference object', py_name='OP'), DgsProperty('loc_name', 'a:80', 'Name of the internal reference object', py_name='loc_name'), DgsProperty('fold_id', 'p', 'Folder containing the internal reference object', py_name='fold_id'), DgsProperty('obj_id', 'p', 'Referenced PowerFactory object', py_name='obj_id'), ] def __init__(self) -> None: self.ID: str = "" self.OP: str = "" self.loc_name: str = "" self.fold_id: str = "" self.obj_id: str = ""
[docs] class IntTemplate(DGSElement): element_type = 'IntTemplate' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier of the internal template', py_name='ID'), DgsProperty('OP', 'a:1', 'DGS operation marker for the internal template', py_name='OP'), DgsProperty('loc_name', 'a:80', 'Name of the internal template object', py_name='loc_name'), DgsProperty('fold_id', 'p', 'Folder containing the internal template object', py_name='fold_id'), ] def __init__(self) -> None: self.ID: str = "" self.OP: str = "" self.loc_name: str = "" self.fold_id: str = ""
[docs] class Matrix(DGSElement): element_type = 'Matrix' properties_list = [ DgsProperty('ID', 'a:40', 'Identifier of the matrix object', py_name='ID'), DgsProperty('MatRow', 'i', 'Row index of the matrix entry', py_name='MatRow'), DgsProperty('MatColumn', 'i', 'Column index of the matrix entry', py_name='MatColumn'), DgsProperty('Val', 'r', 'Numeric value stored at the given matrix row and column', py_name='Val'), ] def __init__(self) -> None: self.ID: str = "" self.MatRow: int = 0 self.MatColumn: int = 0 self.Val: float = 0.0
[docs] class IntGrf(DGSElement): element_type = 'IntGrf' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a:40', 'DGS field loc_name (a:40)', py_name='loc_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('iCol', 'i', 'DGS field iCol (i)', py_name='iCol'), DgsProperty('iVis', 'i', 'DGS field iVis (i)', py_name='iVis'), DgsProperty('iLevel', 'i', 'DGS field iLevel (i)', py_name='iLevel'), DgsProperty('rCenterX', 'r', 'DGS field rCenterX (r)', py_name='rCenterX'), DgsProperty('rCenterY', 'r', 'DGS field rCenterY (r)', py_name='rCenterY'), DgsProperty('sSymNam', 'a:40', 'DGS field sSymNam (a:40)', py_name='sSymNam'), DgsProperty('pDataObj', 'p', 'DGS field pDataObj (p)', py_name='pDataObj'), DgsProperty('iRot', 'i', 'DGS field iRot (i)', py_name='iRot'), DgsProperty('rSizeX', 'r', 'DGS field rSizeX (r)', py_name='rSizeX'), DgsProperty('rSizeY', 'r', 'DGS field rSizeY (r)', py_name='rSizeY'), DgsProperty('sAttr:SIZEROW', 'i', 'DGS field sAttr:SIZEROW (i)', py_name='sAttr_SIZEROW'), DgsProperty('sAttr:0', 'a', 'DGS field sAttr:0 (a)', py_name='sAttr_0'), DgsProperty('sAttr:1', 'a', 'DGS field sAttr:1 (a)', py_name='sAttr_1'), DgsProperty('sAttr:2', 'a', 'DGS field sAttr:2 (a)', py_name='sAttr_2'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.iCol: int = 0 self.iVis: int = 0 self.iLevel: int = 0 self.rCenterX: float = 0.0 self.rCenterY: float = 0.0 self.sSymNam: str = "" self.pDataObj: str = "" self.iRot: int = 0 self.rSizeX: float = 0.0 self.rSizeY: float = 0.0 self.sAttr_SIZEROW: int = 0 self.sAttr_0: str = "" self.sAttr_1: str = "" self.sAttr_2: str = ""
[docs] class IntGrfcon(DGSElement): element_type = 'IntGrfcon' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a:40', 'DGS field loc_name (a:40)', py_name='loc_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('rX:SIZEROW', 'i', 'DGS field rX:SIZEROW (i)', py_name='rX_SIZEROW'), DgsProperty('rX:0', 'r', 'DGS field rX:0 (r)', py_name='rX_0'), DgsProperty('rX:1', 'r', 'DGS field rX:1 (r)', py_name='rX_1'), DgsProperty('rX:2', 'r', 'DGS field rX:2 (r)', py_name='rX_2'), DgsProperty('rX:3', 'r', 'DGS field rX:3 (r)', py_name='rX_3'), DgsProperty('rY:SIZEROW', 'i', 'DGS field rY:SIZEROW (i)', py_name='rY_SIZEROW'), DgsProperty('rY:0', 'r', 'DGS field rY:0 (r)', py_name='rY_0'), DgsProperty('rY:1', 'r', 'DGS field rY:1 (r)', py_name='rY_1'), DgsProperty('rY:2', 'r', 'DGS field rY:2 (r)', py_name='rY_2'), DgsProperty('rY:3', 'r', 'DGS field rY:3 (r)', py_name='rY_3'), DgsProperty('rX:4', 'r', 'DGS field rX:4 (r)', py_name='rX_4'), DgsProperty('rX:5', 'r', 'DGS field rX:5 (r)', py_name='rX_5'), DgsProperty('rX:6', 'r', 'DGS field rX:6 (r)', py_name='rX_6'), DgsProperty('rX:7', 'r', 'DGS field rX:7 (r)', py_name='rX_7'), DgsProperty('rX:8', 'r', 'DGS field rX:8 (r)', py_name='rX_8'), DgsProperty('rX:9', 'r', 'DGS field rX:9 (r)', py_name='rX_9'), DgsProperty('rY:4', 'r', 'DGS field rY:4 (r)', py_name='rY_4'), DgsProperty('rY:5', 'r', 'DGS field rY:5 (r)', py_name='rY_5'), DgsProperty('rY:6', 'r', 'DGS field rY:6 (r)', py_name='rY_6'), DgsProperty('rY:7', 'r', 'DGS field rY:7 (r)', py_name='rY_7'), DgsProperty('rY:8', 'r', 'DGS field rY:8 (r)', py_name='rY_8'), DgsProperty('rY:9', 'r', 'DGS field rY:9 (r)', py_name='rY_9'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.rX_SIZEROW: int = 0 self.rX_0: float = 0.0 self.rX_1: float = 0.0 self.rX_2: float = 0.0 self.rX_3: float = 0.0 self.rY_SIZEROW: int = 0 self.rY_0: float = 0.0 self.rY_1: float = 0.0 self.rY_2: float = 0.0 self.rY_3: float = 0.0 self.rX_4: float = 0.0 self.rX_5: float = 0.0 self.rX_6: float = 0.0 self.rX_7: float = 0.0 self.rX_8: float = 0.0 self.rX_9: float = 0.0 self.rY_4: float = 0.0 self.rY_5: float = 0.0 self.rY_6: float = 0.0 self.rY_7: float = 0.0 self.rY_8: float = 0.0 self.rY_9: float = 0.0
[docs] class IntGrfnet(DGSElement): element_type = 'IntGrfnet' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a:40', 'DGS field loc_name (a:40)', py_name='loc_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('snap_on', 'i', 'DGS field snap_on (i)', py_name='snap_on'), DgsProperty('grid_on', 'i', 'DGS field grid_on (i)', py_name='grid_on'), DgsProperty('ortho_on', 'i', 'DGS field ortho_on (i)', py_name='ortho_on'), DgsProperty('pDataFolder', 'p', 'DGS field pDataFolder (p)', py_name='pDataFolder'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.snap_on: int = 0 self.grid_on: int = 0 self.ortho_on: int = 0 self.pDataFolder: str = ""
[docs] class RelFuse(DGSElement): element_type = 'RelFuse' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a', 'DGS field loc_name (a)', py_name='loc_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('typ_id', 'p', 'DGS field typ_id (p)', py_name='typ_id'), DgsProperty('chr_name', 'a', 'DGS field chr_name (a)', py_name='chr_name'), DgsProperty('aUsage', 'a', 'DGS field aUsage (a)', py_name='aUsage'), DgsProperty('nphase', 'i', 'DGS field nphase (i)', py_name='nphase'), DgsProperty('on_off', 'i', 'DGS field on_off (i)', py_name='on_off'), DgsProperty('outserv', 'i', 'DGS field outserv (i)', py_name='outserv'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.typ_id: str = "" self.chr_name: str = "" self.aUsage: str = "" self.nphase: int = 3 self.on_off: int = 0 self.outserv: int = 0
[docs] class StaCubic(DGSElement): element_type = 'StaCubic' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('loc_name', 'a:40', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('chr_name', 'a:20', 'Characteristic Name', py_name='chr_name'), DgsProperty('obj_bus', 'i', 'Bus Terminal Index within the Connected Device', py_name='obj_bus'), DgsProperty('obj_id', 'p', 'Connected PowerFactory Object', py_name='obj_id'), DgsProperty('for_name', 'a:50', 'Foreign Key', py_name='for_name'), DgsProperty('it2p1', 'i', 'Phase-to-Phase Connection Flag 1', py_name='it2p1'), DgsProperty('it2p2', 'i', 'Phase-to-Phase Connection Flag 2', py_name='it2p2'), DgsProperty('it2p3', 'i', 'Phase-to-Phase Connection Flag 3', py_name='it2p3'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.chr_name: str = "" self.obj_bus: int = 0 self.obj_id: str = "" self.for_name: str = "" self.it2p1: int = 0 self.it2p2: int = 0 self.it2p3: int = 0
[docs] class StaSwitch(DGSElement): element_type = 'StaSwitch' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('loc_name', 'a:40', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('on_off', 'i', 'Switch Position: Open:Closed', py_name='on_off'), DgsProperty('typ_id', 'p', 'Type in TypSwitch', py_name='typ_id'), DgsProperty('iUse', 'i', 'Switch Use Code', py_name='iUse'), DgsProperty('for_name', 'a:50', 'Foreign Key', py_name='for_name'), DgsProperty('aUsage', 'a', 'Switch Usage String', py_name='aUsage'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.on_off: int = 0 self.typ_id: str = "" self.iUse: int = 0 self.for_name: str = "" self.aUsage: str = ""
[docs] class StaCt(DGSElement): element_type = 'StaCt' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier of the current transformer', py_name='ID'), DgsProperty('OP', 'a:1', 'DGS operation marker for the current transformer', py_name='OP'), DgsProperty('loc_name', 'a:80', 'Name of the current transformer', py_name='loc_name'), DgsProperty('fold_id', 'p', 'Cubicle or parent object containing the current transformer', py_name='fold_id'), DgsProperty('chr_name', 'a:40', 'Short display name of the current transformer', py_name='chr_name'), DgsProperty('ptapset', 'r', 'Selected primary tap ratio multiplier', py_name='ptapset'), DgsProperty('stapset', 'r', 'Selected secondary tap ratio multiplier', py_name='stapset'), DgsProperty('outserv', 'i', 'Out-of-service flag of the current transformer', py_name='outserv'), DgsProperty('typ_id', 'p', 'Referenced current transformer type', py_name='typ_id'), ] def __init__(self) -> None: self.ID: str = "" self.OP: str = "" self.loc_name: str = "" self.fold_id: str = "" self.chr_name: str = "" self.ptapset: float = 0.0 self.stapset: float = 0.0 self.outserv: int = 0 self.typ_id: str = ""
[docs] class StaVt(DGSElement): element_type = 'StaVt' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier of the voltage transformer', py_name='ID'), DgsProperty('OP', 'a:1', 'DGS operation marker for the voltage transformer', py_name='OP'), DgsProperty('loc_name', 'a:80', 'Name of the voltage transformer', py_name='loc_name'), DgsProperty('fold_id', 'p', 'Cubicle or parent object containing the voltage transformer', py_name='fold_id'), DgsProperty('chr_name', 'a:40', 'Short display name of the voltage transformer', py_name='chr_name'), DgsProperty('ptapset', 'r', 'Selected primary tap ratio multiplier', py_name='ptapset'), DgsProperty('stapset', 'r', 'Selected secondary tap ratio multiplier', py_name='stapset'), DgsProperty('typ_id', 'p', 'Referenced voltage transformer type', py_name='typ_id'), DgsProperty('outserv', 'i', 'Out-of-service flag of the voltage transformer', py_name='outserv'), ] def __init__(self) -> None: self.ID: str = "" self.OP: str = "" self.loc_name: str = "" self.fold_id: str = "" self.chr_name: str = "" self.ptapset: float = 0.0 self.stapset: float = 0.0 self.typ_id: str = "" self.outserv: int = 0
[docs] class TypSwitch(DGSElement): element_type = 'TypSwitch' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier of the breaker or switch type', py_name='ID'), DgsProperty('loc_name', 'a:40', 'Name of the breaker or switch type', py_name='loc_name'), DgsProperty('fold_id', 'p', 'Folder containing the breaker or switch type', py_name='fold_id'), DgsProperty('Ron', 'r', 'Closed-state resistance of the switch', py_name='Ron'), DgsProperty('Xon', 'r', 'Closed-state reactance of the switch', py_name='Xon'), DgsProperty('InomA', 'r', 'Nominal current at terminal A', py_name='InomA'), DgsProperty('InomB', 'r', 'Nominal current at terminal B', py_name='InomB'), DgsProperty('for_name', 'a:50', 'Foreign name or external identifier of the switch type', py_name='for_name'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.Ron: float = 0.0 self.Xon: float = 0.0 self.InomA: float = 0.0 self.InomB: float = 0.0 self.for_name: str = ""
[docs] @classmethod def parse_line(cls, line: str, header_map: dict[str, int]): """Parse TypSwitch and tolerate several header aliases used by DGS variants.""" parts = line.rstrip('\n').split(';') obj = cls() alias_map: Dict[str, List[str]] = dict() alias_map['ID'] = ['ID', 'FID'] alias_map['loc_name'] = ['loc_name'] alias_map['fold_id'] = ['fold_id'] alias_map['Ron'] = ['Ron', 'ron', 'r_on'] alias_map['Xon'] = ['Xon', 'xon', 'x_on'] alias_map['InomA'] = ['InomA', 'inom_a', 'Inom1', 'inom1', 'InomBus1', 'inom_bus1'] alias_map['InomB'] = ['InomB', 'inom_b', 'Inom2', 'inom2', 'InomBus2', 'inom_bus2'] alias_map['for_name'] = ['for_name'] prop_by_name: Dict[str, DgsProperty] = dict() for prop in cls.properties_list: prop_by_name[prop.py_name] = prop for py_name, aliases in alias_map.items(): prop = prop_by_name.get(py_name, None) if prop is None: pass else: idx: int | None = None for alias in aliases: idx = header_map.get(alias, None) if idx is not None: break else: pass if idx is not None and -1 < idx < len(parts): raw = parts[idx] value = prop.parse(raw) setattr(obj, py_name, value) else: pass return obj
[docs] class TypAsmo(DGSElement): element_type = 'TypAsmo' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('loc_name', 'a', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('i_mode', 'i', 'Machine Model Type Code', py_name='i_mode'), DgsProperty('aiazn', 'r', 'Starting Current Ratio Ia / In', py_name='aiazn'), DgsProperty('amazn', 'r', 'Breakdown Torque Ratio Mk / Mn', py_name='amazn'), DgsProperty('amkzn', 'r', 'Locked-Rotor Torque Ratio Ma / Mn', py_name='amkzn'), DgsProperty('anend', 'r', 'Nominal Speed in rpm', py_name='anend'), DgsProperty('cosn', 'r', 'Rated Power Factor', py_name='cosn'), DgsProperty('effic', 'r', 'Efficiency in p.u.', py_name='effic'), DgsProperty('frequ', 'r', 'Rated Frequency in Hz', py_name='frequ'), DgsProperty('i_cage', 'i', 'Rotor Type: Squirrel Cage:Slip Ring', py_name='i_cage'), DgsProperty('nppol', 'i', 'Number of Pole Pairs', py_name='nppol'), DgsProperty('pgn', 'r', 'Rated Mechanical Power in MW', py_name='pgn'), DgsProperty('sgn', 'r', 'Rated Apparent Power in MVA', py_name='sgn'), DgsProperty('nslty', 'i', 'Neutral Grounding Type Code', py_name='nslty'), DgsProperty('rstr', 'r', 'Stator Resistance in p.u.', py_name='rstr'), DgsProperty('xm', 'r', 'Magnetizing Reactance in p.u.', py_name='xm'), DgsProperty('ugn', 'r', 'Rated Voltage in kV', py_name='ugn'), DgsProperty('xmrtr', 'r', 'Rotor Mutual Reactance in p.u.', py_name='xmrtr'), DgsProperty('xstr', 'r', 'Stator Reactance in p.u.', py_name='xstr'), DgsProperty('rrtrA', 'r', 'Rotor resistance in p.u.', py_name='rrtrA'), DgsProperty('xrtrA', 'r', 'Rotor reactance in p.u.', py_name='xrtrA'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.i_mode: int = 0 self.aiazn: float = 0.0 self.amazn: float = 0.0 self.amkzn: float = 0.0 self.anend: float = 0.0 self.cosn: float = 0.0 self.effic: float = 0.0 self.frequ: float = 0.0 self.i_cage: int = 0 self.nppol: int = 0 self.pgn: float = 0.0 self.ugn: float = 0.0 self.xmrtr: float = 0.0 self.xstr: float = 0.0 self.sgn: float = 0.0 self.nslty: int = 0 self.rstr: float = 0.0 self.xm: float = 0.0 self.rrtrA: float = 0.0 self.xrtrA: float = 0.0
[docs] class TypFuse(DGSElement): element_type = 'TypFuse' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a', 'DGS field loc_name (a)', py_name='loc_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('frq', 'r', 'DGS field frq (r)', py_name='frq'), DgsProperty('irat', 'r', 'DGS field irat (r)', py_name='irat'), DgsProperty('urat', 'r', 'DGS field urat (r)', py_name='urat'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.frq: float = 0.0 self.irat: float = 0.0 self.urat: float = 0.0
[docs] class TypLne(DGSElement): element_type = 'TypLne' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('loc_name', 'a:40', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('uline', 'r', 'Rated Voltage in kV', py_name='uline'), DgsProperty('sline', 'r', 'Rated Apparent Power in MVA', py_name='sline'), DgsProperty('aohl_', 'a:3', 'Installation Type: OHL:CAB', py_name='aohl_'), DgsProperty('rline', 'r', 'Positive-Sequence Resistance in Ohm/km', py_name='rline'), DgsProperty('xline', 'r', 'Positive-Sequence Reactance in Ohm/km', py_name='xline'), DgsProperty('cline', 'r', 'Positive-Sequence Capacitance in uF/km', py_name='cline'), DgsProperty('rline0', 'r', 'Zero-Sequence Resistance in Ohm/km', py_name='rline0'), DgsProperty('xline0', 'r', 'Zero-Sequence Reactance in Ohm/km', py_name='xline0'), DgsProperty('cline0', 'r', 'Zero-Sequence Capacitance in uF/km', py_name='cline0'), DgsProperty('rtemp', 'r', 'Reference Temperature in degC', py_name='rtemp'), DgsProperty('Ithr', 'r', 'Thermal Current Rating in kA', py_name='Ithr'), DgsProperty('chr_name', 'a:20', 'Characteristic Name', py_name='chr_name'), DgsProperty('nlnph', 'i', 'Phases:1:2:3', py_name='nlnph'), DgsProperty('nneutral', 'i', 'Number of Neutral Conductors', py_name='nneutral'), DgsProperty('for_name', 'a:50', 'Foreign Key', py_name='for_name'), DgsProperty('InomAir', 'r', 'Continuous Current Rating in Air in kA', py_name='InomAir'), DgsProperty('cohl_', 'i', 'Conductor Arrangement Code', py_name='cohl_'), DgsProperty('tmax', 'r', 'Maximum Conductor Temperature in degC', py_name='tmax'), DgsProperty('systp', 'i', 'System Type Code', py_name='systp'), DgsProperty('frnom', 'r', 'Nominal Frequency in Hz', py_name='frnom'), DgsProperty('mlei', 'a:2', 'Line Model Type Code', py_name='mlei'), DgsProperty('bline', 'r', 'Positive-Sequence Susceptance in uS/km', py_name='bline'), DgsProperty('bline0', 'r', 'Zero-Sequence Susceptance in uS/km', py_name='bline0'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.uline: float = 0.0 self.sline: float = 0.0 self.aohl_: str = "cab" # allowed values are "cab" and "ohl" self.rline: float = 0.0 self.xline: float = 0.0 self.cline: float = 0.0 self.rline0: float = 0.0 self.xline0: float = 0.0 self.cline0: float = 0.0 self.rtemp: float = 20.0 self.Ithr: float = 0.0 self.chr_name: str = "" self.nlnph: int = 3 self.nneutral: int = 0 self.for_name: str = "" self.InomAir: float = 0.0 self.cohl_: int = 0 self.tmax: float = 80.0 self.systp: int = 0 self.frnom: float = 0.0 self.mlei: str = "" self.bline: float = 0.0 self.bline0: float = 0.0
[docs] class TypLod(DGSElement): element_type = 'TypLod' properties_list = [ DgsProperty('ID', 'a:40', 'DGS field ID (a:40)', py_name='ID'), DgsProperty('loc_name', 'a:40', 'DGS field loc_name (a:40)', py_name='loc_name'), DgsProperty('fold_id', 'p', 'DGS field fold_id (p)', py_name='fold_id'), DgsProperty('kpu', 'r', 'DGS field kpu (r)', py_name='kpu'), DgsProperty('kqu', 'r', 'DGS field kqu (r)', py_name='kqu'), DgsProperty('systp', 'i', 'DGS field systp (i)', py_name='systp'), DgsProperty('phtech', 'i', 'DGS field phtech (i)', py_name='phtech'), DgsProperty('for_name', 'a:50', 'DGS field for_name (a:50)', py_name='for_name'), DgsProperty('aP', 'r', 'DGS field aP (r)', py_name='aP'), DgsProperty('bP', 'r', 'DGS field bP (r)', py_name='bP'), DgsProperty('kpu0', 'r', 'DGS field kpu0 (r)', py_name='kpu0'), DgsProperty('kpu1', 'r', 'DGS field kpu1 (r)', py_name='kpu1'), DgsProperty('aQ', 'r', 'DGS field aQ (r)', py_name='aQ'), DgsProperty('bQ', 'r', 'DGS field bQ (r)', py_name='bQ'), DgsProperty('kqu0', 'r', 'DGS field kqu0 (r)', py_name='kqu0'), DgsProperty('kqu1', 'r', 'DGS field kqu1 (r)', py_name='kqu1'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.kpu: float = 0.0 self.kqu: float = 0.0 self.systp: int = 0 self.phtech: int = 0 self.for_name: str = "" self.aP: float = 0.0 self.bP: float = 0.0 self.kpu0: float = 0.0 self.kpu1: float = 0.0 self.aQ: float = 0.0 self.bQ: float = 0.0 self.kqu0: float = 0.0 self.kqu1: float = 0.0
[docs] class TypSym(DGSElement): element_type = 'TypSym' # We comment out the dynamic stuff because it will trigger errors at import properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('loc_name', 'a:40', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('sgn', 'r', 'Rated Apparent Power in MVA', py_name='sgn'), DgsProperty('ugn', 'r', 'Rated voltage in kV', py_name='ugn'), DgsProperty('cosn', 'r', 'Rated Power Factor', py_name='cosn'), DgsProperty('xd', 'r', 'Synchronous d-Axis Reactance in p.u.', py_name='xd'), DgsProperty('xq', 'r', 'Synchronous q-Axis Reactance in p.u.', py_name='xq'), DgsProperty('xdsss', 'r', 'Subtransient d-Axis Reactance in p.u.', py_name='xdsss'), DgsProperty('rstr', 'r', 'Stator Resistance in p.u.', py_name='rstr'), DgsProperty('xdsat', 'r', 'Saturated d-Axis Reactance in p.u.', py_name='xdsat'), DgsProperty('satur', 'i', 'Magnetic Saturation Enabled', py_name='satur'), DgsProperty('Q_min', 'r', 'Minimum Reactive Power Capability in MVAr', py_name='Q_min'), DgsProperty('Q_max', 'r', 'Maximum Reactive Power Capability in MVAr', py_name='Q_max'), DgsProperty('q_min', 'r', 'Minimum Reactive Power Limit in MVAr', py_name='q_min'), DgsProperty('q_max', 'r', 'Maximum Reactive Power Limit in MVAr', py_name='q_max'), DgsProperty('for_name', 'a:50', 'Foreign Key', py_name='for_name'), DgsProperty('nphase', 'i', 'Number of Phases', py_name='nphase'), DgsProperty('nslty', 'i', 'Neutral Grounding Type Code', py_name='nslty'), DgsProperty('x0sy', 'r', 'Zero-Sequence Reactance in p.u.', py_name='x0sy'), DgsProperty('r0sy', 'r', 'Zero-Sequence Resistance in p.u.', py_name='r0sy'), DgsProperty('x2sy', 'r', 'Negative-Sequence Reactance in p.u.', py_name='x2sy'), DgsProperty('r2sy', 'r', 'Negative-Sequence Resistance in p.u.', py_name='r2sy'), DgsProperty('iopt_data', 'i', 'Machine Data Option Code', py_name='iopt_data'), DgsProperty('xds', 'r', 'Transient d-Axis Reactance in p.u.', py_name='xds'), DgsProperty('xqs', 'r', 'Transient q-Axis Reactance in p.u.', py_name='xqs'), DgsProperty('xl', 'r', 'Leakage Reactance in p.u.', py_name='xl'), DgsProperty('xdss', 'r', 'Subtransient d-Axis Reactance in p.u.', py_name='xdss'), DgsProperty('xqss', 'r', 'Subtransient q-Axis Reactance in p.u.', py_name='xqss'), DgsProperty('xrlq', 'r', 'q-Axis Damper Leakage Reactance in p.u.', py_name='xrlq'), DgsProperty('tds', 'r', 'Transient Open-Circuit Time Constant Tdo\' in s', py_name='tds'), DgsProperty('tqs', 'r', 'Transient Open-Circuit Time Constant Tqo\' in s', py_name='tqs'), DgsProperty('tdss', 'r', 'Subtransient Open-Circuit Time Constant Tdo\'\' in s', py_name='tdss'), DgsProperty('tqss', 'r', 'Subtransient Open-Circuit Time Constant Tqo\'\' in s', py_name='tqss'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.sgn: float = 0.1 self.ugn: float = 0.0 self.cosn: float = 0.0 self.xd: float = 0.0 self.xq: float = 0.0 self.xdsss: float = 0.0 self.rstr: float = 0.0 self.xdsat: float = 0.0 self.satur: int = 0 self.Q_min: float = 0.0 self.Q_max: float = 0.0 self.q_min: float = 0.0 self.q_max: float = 0.0 self.for_name: str = "" self.nphase: int = 3 self.nslty: int = 0 self.x0sy: float = 0.0 self.r0sy: float = 0.0 self.x2sy: float = 0.0 self.r2sy: float = 0.0 self.iopt_data: int = 0 self.xds: float = 0.0 self.xqs: float = 0.0 self.xl: float = 0.0 self.xdss: float = 0.0 self.xqss: float = 0.0 self.xrlq: float = 0.0 self.tds: float = 0.0 self.tqs: float = 0.0 self.tdss: float = 0.0 self.tqss: float = 0.0
[docs] class TypTr2(DGSElement): element_type = 'TypTr2' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('loc_name', 'a:40', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('strn', 'r', 'Rated Power in MVA', py_name='strn'), DgsProperty('frnom', 'r', 'Nominal Frequency in Hz', py_name='frnom'), DgsProperty('utrn_h', 'r', 'Rated Voltage: HV-Side in kV', py_name='utrn_h'), DgsProperty('utrn_l', 'r', 'Rated Voltage: LV-Side in kV', py_name='utrn_l'), DgsProperty('uktr', 'r', 'Positive Sequence Impedance: Short-Circuit Voltage uk in %', py_name='uktr'), DgsProperty('pcutr', 'r', 'Positive Sequence Impedance: Copper Losses in kW', py_name='pcutr'), DgsProperty('uk0tr', 'r', 'Zero Sequence Impedance: Short-Circuit Voltage uk0 in %', py_name='uk0tr'), DgsProperty('ur0tr', 'r', 'Zero Sequence Impedance: SHC-Voltage (Re(uk0)) uk0r in %', py_name='ur0tr'), DgsProperty('tr2cn_h', 'a:2', 'Vector Group: HV-Side:Y :YN:Z :ZN:D', py_name='tr2cn_h'), DgsProperty('tr2cn_l', 'a:2', 'Vector Group: LV-Side:Y :YN:Z :ZN:D', py_name='tr2cn_l'), DgsProperty('nt2ag', 'r', 'Vector Group: Phase Shift in *30deg', py_name='nt2ag'), DgsProperty('curmg', 'r', 'Magnetizing Impedance: No Load Current in %', py_name='curmg'), DgsProperty('pfe', 'r', 'Magnetizing Impedance: No Load Losses in kW', py_name='pfe'), DgsProperty('zx0hl_n', 'r', 'Zero Sequence Magnetizing Impedance: Mag. Impedance/uk0', py_name='zx0hl_n'), DgsProperty('tap_side', 'i', 'Tap Changer 1: at Side:HV:LV', py_name='tap_side'), DgsProperty('dutap', 'r', 'Additional Voltage per Tap in %', py_name='dutap'), DgsProperty('phitr', 'r', 'Phase of du in deg', py_name='phitr'), DgsProperty('nntap0', 'i', 'Neutral Position', py_name='nntap0'), DgsProperty('ntpmn', 'i', 'Minimum Position', py_name='ntpmn'), DgsProperty('ntpmx', 'i', 'Maximum Position', py_name='ntpmx'), DgsProperty('manuf', 'a:20', 'Manufacturer', py_name='manuf'), DgsProperty('chr_name', 'a:20', 'Characteristic Name', py_name='chr_name'), DgsProperty('for_name', 'a:50', 'Foreign Key', py_name='for_name'), DgsProperty('nt2ph', 'i', 'Number of Phases', py_name='nt2ph'), DgsProperty('itapch', 'i', 'Tap Changer Type Code', py_name='itapch'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" self.strn: float = 0.0 self.frnom: float = 0.0 self.utrn_h: float = 0.0 self.utrn_l: float = 0.0 self.uktr: float = 0.0 self.pcutr: float = 0.0 self.uk0tr: float = 0.0 self.ur0tr: float = 0.0 self.tr2cn_h: str = "D" # Y,YN,Z,ZN,D. self.tr2cn_l: str = "Y" self.nt2ag: float = 0.0 self.curmg: float = 0.0 self.pfe: float = 0.0 self.zx0hl_n: float = 0.0 self.tap_side: int = 0 self.dutap: float = 0.0 self.phitr: float = 0.0 self.nntap0: int = 0 self.ntpmn: int = 0 self.ntpmx: int = 0 self.manuf: str = "" self.chr_name: str = "" self.for_name: str = "" self.nt2ph: int = 3 # 3-phase self.itapch: int = 0
[docs] class TypTr3(DGSElement): element_type = 'TypTr3' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('loc_name', 'a', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('curm3', 'r', 'No-Load Current in %', py_name='curm3'), DgsProperty('du3tp_h', 'r', 'Additional Voltage per Tap at HV Side in %', py_name='du3tp_h'), DgsProperty('du3tp_l', 'r', 'Additional Voltage per Tap at LV Side in %', py_name='du3tp_l'), DgsProperty('du3tp_m', 'r', 'Additional Voltage per Tap at MV Side in %', py_name='du3tp_m'), DgsProperty('n3tmn_h', 'i', 'Minimum Tap Position at HV Side', py_name='n3tmn_h'), DgsProperty('n3tmn_l', 'i', 'Minimum Tap Position at LV Side', py_name='n3tmn_l'), DgsProperty('n3tmn_m', 'i', 'Minimum Tap Position at MV Side', py_name='n3tmn_m'), DgsProperty('n3tmx_h', 'i', 'Maximum Tap Position at HV Side', py_name='n3tmx_h'), DgsProperty('n3tmx_l', 'i', 'Maximum Tap Position at LV Side', py_name='n3tmx_l'), DgsProperty('n3tmx_m', 'i', 'Maximum Tap Position at MV Side', py_name='n3tmx_m'), DgsProperty('n3tp0_h', 'i', 'Neutral Tap Position at HV Side', py_name='n3tp0_h'), DgsProperty('n3tp0_l', 'i', 'Neutral Tap Position at LV Side', py_name='n3tp0_l'), DgsProperty('n3tp0_m', 'i', 'Neutral Tap Position at MV Side', py_name='n3tp0_m'), DgsProperty('nt3ag_h', 'r', 'Vector Group Phase Shift at HV Side in multiples of 30 deg', py_name='nt3ag_h'), DgsProperty('nt3ag_l', 'r', 'Vector Group Phase Shift at LV Side in multiples of 30 deg', py_name='nt3ag_l'), DgsProperty('nt3ag_m', 'r', 'Vector Group Phase Shift at MV Side in multiples of 30 deg', py_name='nt3ag_m'), DgsProperty('pcut3_h', 'r', 'Copper Losses of HV-MV Branch in kW', py_name='pcut3_h'), DgsProperty('pcut3_l', 'r', 'Copper Losses of LV-HV Branch in kW', py_name='pcut3_l'), DgsProperty('pcut3_m', 'r', 'Copper Losses of MV-LV Branch in kW', py_name='pcut3_m'), DgsProperty('pfe', 'r', 'No-Load Losses in kW', py_name='pfe'), DgsProperty('ph3tr_h', 'r', 'Phase of du at HV Side in deg', py_name='ph3tr_h'), DgsProperty('ph3tr_l', 'r', 'Phase of du at LV Side in deg', py_name='ph3tr_l'), DgsProperty('ph3tr_m', 'r', 'Phase of du at MV Side in deg', py_name='ph3tr_m'), DgsProperty('strn3_h', 'r', 'Rated Power of HV Winding in MVA', py_name='strn3_h'), DgsProperty('strn3_l', 'r', 'Rated Power of LV Winding in MVA', py_name='strn3_l'), DgsProperty('strn3_m', 'r', 'Rated Power of MV Winding in MVA', py_name='strn3_m'), DgsProperty('tr3cn_h', 'a', 'Vector Group at HV Side: Y:YN:Z:ZN:D', py_name='tr3cn_h'), DgsProperty('tr3cn_l', 'a', 'Vector Group at LV Side: Y:YN:Z:ZN:D', py_name='tr3cn_l'), DgsProperty('tr3cn_m', 'a', 'Vector Group at MV Side: Y:YN:Z:ZN:D', py_name='tr3cn_m'), DgsProperty('uk0hl', 'r', 'Zero-Sequence Short-Circuit Voltage between HV and LV in %', py_name='uk0hl'), DgsProperty('uk0hm', 'r', 'Zero-Sequence Short-Circuit Voltage between HV and MV in %', py_name='uk0hm'), DgsProperty('uk0ml', 'r', 'Zero-Sequence Short-Circuit Voltage between MV and LV in %', py_name='uk0ml'), DgsProperty('uktr3_h', 'r', 'Positive-Sequence Short-Circuit Voltage of HV-MV Branch in %', py_name='uktr3_h'), DgsProperty('uktr3_l', 'r', 'Positive-Sequence Short-Circuit Voltage of LV-HV Branch in %', py_name='uktr3_l'), DgsProperty('uktr3_m', 'r', 'Positive-Sequence Short-Circuit Voltage of MV-LV Branch in %', py_name='uktr3_m'), DgsProperty('ur0hl', 'r', 'Real Part of uk0 between HV and LV in %', py_name='ur0hl'), DgsProperty('ur0hm', 'r', 'Real Part of uk0 between HV and MV in %', py_name='ur0hm'), DgsProperty('ur0ml', 'r', 'Real Part of uk0 between MV and LV in %', py_name='ur0ml'), DgsProperty('utrn3_h', 'r', 'Rated Voltage at HV Side in kV', py_name='utrn3_h'), DgsProperty('utrn3_l', 'r', 'Rated Voltage at LV Side in kV', py_name='utrn3_l'), DgsProperty('utrn3_m', 'r', 'Rated Voltage at MV Side in kV', py_name='utrn3_m'), DgsProperty('for_name', 'a:50', 'Foreign Key', py_name='for_name'), DgsProperty('itapos', 'i', 'Tapped Winding Position Code', py_name='itapos'), DgsProperty('i3loc', 'i', 'Transformer Model Layout Code', py_name='i3loc'), ] def __init__(self) -> None: self.ID: str = "" self.loc_name: str = "" self.fold_id: str = "" # reals (r) self.curm3: float = 0.0 self.du3tp_h: float = 0.0 self.du3tp_l: float = 0.0 self.du3tp_m: float = 0.0 # ints (i) self.n3tmn_h: int = 0 self.n3tmn_l: int = 0 self.n3tmn_m: int = 0 self.n3tmx_h: int = 0 self.n3tmx_l: int = 0 self.n3tmx_m: int = 0 self.n3tp0_h: int = 0 self.n3tp0_l: int = 0 self.n3tp0_m: int = 0 # reals (r) self.nt3ag_h: float = 0.0 self.nt3ag_l: float = 0.0 self.nt3ag_m: float = 0.0 self.pcut3_h: float = 0.0 self.pcut3_l: float = 0.0 self.pcut3_m: float = 0.0 self.pfe: float = 0.0 self.ph3tr_h: float = 0.0 self.ph3tr_l: float = 0.0 self.ph3tr_m: float = 0.0 self.strn3_h: float = 0.0 self.strn3_l: float = 0.0 self.strn3_m: float = 0.0 # strings (a) self.tr3cn_h: str = "" self.tr3cn_l: str = "" self.tr3cn_m: str = "" # reals (r) self.uk0hl: float = 0.0 self.uk0hm: float = 0.0 self.uk0ml: float = 0.0 self.uktr3_h: float = 0.0 self.uktr3_l: float = 0.0 self.uktr3_m: float = 0.0 self.ur0hl: float = 0.0 self.ur0hm: float = 0.0 self.ur0ml: float = 0.0 self.utrn3_h: float = 0.0 self.utrn3_l: float = 0.0 self.utrn3_m: float = 0.0 # strings (a:50) self.for_name: str = "" # ints (i) self.itapos: int = 0 self.i3loc: int = 0
[docs] class TypTr4(DGSElement): element_type = 'TypTr4' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier for DGS file', py_name='ID'), DgsProperty('OP', 'a:1', 'Operation flag', py_name='OP'), DgsProperty('loc_name', 'a:80', 'Name', py_name='loc_name'), DgsProperty('fold_id', 'p', 'In Folder', py_name='fold_id'), DgsProperty('pfe', 'r', 'Iron Losses in kW', py_name='pfe'), DgsProperty('chr_name', 'a:40', 'Characteristic Name', py_name='chr_name'), DgsProperty('for_name', 'a:100', 'Foreign Key', py_name='for_name'), DgsProperty('dat_src', 'a:6', 'Data Source', py_name='dat_src'), DgsProperty('trcon_h0', 'a:4', 'Vector Group HV Winding', py_name='trcon_h0'), DgsProperty('trcon_l1', 'a:4', 'Vector Group LV1 Winding', py_name='trcon_l1'), DgsProperty('trcon_l2', 'a:4', 'Vector Group LV2 Winding', py_name='trcon_l2'), DgsProperty('trcon_l3', 'a:4', 'Vector Group LV3 Winding', py_name='trcon_l3'), DgsProperty('vecgrp', 'a', 'Vector Group', py_name='vecgrp'), DgsProperty('ansiclass', 'a:10', 'ANSI Class', py_name='ansiclass'), DgsProperty('manuf', 'a:40', 'Manufacturer', py_name='manuf'), DgsProperty('appr_modby', 'a:80', 'Approved / Modified By', py_name='appr_modby'), DgsProperty('appr_modif', 'l', 'Approval Modification Timestamp', py_name='appr_modif'), DgsProperty('sn_h0', 'r', 'Rated Power HV in MVA', py_name='sn_h0'), DgsProperty('sn_l1', 'r', 'Rated Power LV1 in MVA', py_name='sn_l1'), DgsProperty('sn_l2', 'r', 'Rated Power LV2 in MVA', py_name='sn_l2'), DgsProperty('sn_l3', 'r', 'Rated Power LV3 in MVA', py_name='sn_l3'), DgsProperty('un_h0', 'r', 'Rated Voltage HV in kV', py_name='un_h0'), DgsProperty('un_l1', 'r', 'Rated Voltage LV1 in kV', py_name='un_l1'), DgsProperty('un_l2', 'r', 'Rated Voltage LV2 in kV', py_name='un_l2'), DgsProperty('un_l3', 'r', 'Rated Voltage LV3 in kV', py_name='un_l3'), DgsProperty('uk_h0l1', 'r', 'Short-Circuit Voltage HV-LV1 in percent', py_name='uk_h0l1'), DgsProperty('uk_h0l2', 'r', 'Short-Circuit Voltage HV-LV2 in percent', py_name='uk_h0l2'), DgsProperty('uk_h0l3', 'r', 'Short-Circuit Voltage HV-LV3 in percent', py_name='uk_h0l3'), DgsProperty('uk_l1l2', 'r', 'Short-Circuit Voltage LV1-LV2 in percent', py_name='uk_l1l2'), DgsProperty('uk_l1l3', 'r', 'Short-Circuit Voltage LV1-LV3 in percent', py_name='uk_l1l3'), DgsProperty('uk_l2l3', 'r', 'Short-Circuit Voltage LV2-LV3 in percent', py_name='uk_l2l3'), DgsProperty('pcu_h0l1', 'r', 'Copper Losses HV-LV1 in kW', py_name='pcu_h0l1'), DgsProperty('pcu_h0l2', 'r', 'Copper Losses HV-LV2 in kW', py_name='pcu_h0l2'), DgsProperty('pcu_h0l3', 'r', 'Copper Losses HV-LV3 in kW', py_name='pcu_h0l3'), DgsProperty('pcu_l1l2', 'r', 'Copper Losses LV1-LV2 in kW', py_name='pcu_l1l2'), DgsProperty('pcu_l1l3', 'r', 'Copper Losses LV1-LV3 in kW', py_name='pcu_l1l3'), DgsProperty('pcu_l2l3', 'r', 'Copper Losses LV2-LV3 in kW', py_name='pcu_l2l3'), DgsProperty('uk_h0', 'r', 'Short-Circuit Voltage HV in percent', py_name='uk_h0'), DgsProperty('uk_l1', 'r', 'Short-Circuit Voltage LV1 in percent', py_name='uk_l1'), DgsProperty('uk_l2', 'r', 'Short-Circuit Voltage LV2 in percent', py_name='uk_l2'), DgsProperty('uk_l3', 'r', 'Short-Circuit Voltage LV3 in percent', py_name='uk_l3'), DgsProperty('pcu_h0', 'r', 'Copper Losses HV in kW', py_name='pcu_h0'), DgsProperty('pcu_l1', 'r', 'Copper Losses LV1 in kW', py_name='pcu_l1'), DgsProperty('pcu_l2', 'r', 'Copper Losses LV2 in kW', py_name='pcu_l2'), DgsProperty('pcu_l3', 'r', 'Copper Losses LV3 in kW', py_name='pcu_l3'), DgsProperty('curmag', 'r', 'No-Load Current in percent', py_name='curmag'), DgsProperty('cur0mag', 'r', 'Zero Sequence No-Load Current in percent', py_name='cur0mag'), DgsProperty('ntapmin_h0', 'i', 'Minimum Tap Position HV', py_name='ntapmin_h0'), DgsProperty('ntapmin_l1', 'i', 'Minimum Tap Position LV1', py_name='ntapmin_l1'), DgsProperty('ntapmin_l2', 'i', 'Minimum Tap Position LV2', py_name='ntapmin_l2'), DgsProperty('ntapmin_l3', 'i', 'Minimum Tap Position LV3', py_name='ntapmin_l3'), DgsProperty('ntapmax_h0', 'i', 'Maximum Tap Position HV', py_name='ntapmax_h0'), DgsProperty('ntapmax_l1', 'i', 'Maximum Tap Position LV1', py_name='ntapmax_l1'), DgsProperty('ntapmax_l2', 'i', 'Maximum Tap Position LV2', py_name='ntapmax_l2'), DgsProperty('ntapmax_l3', 'i', 'Maximum Tap Position LV3', py_name='ntapmax_l3'), DgsProperty('ntapneu_h0', 'i', 'Neutral Tap Position HV', py_name='ntapneu_h0'), DgsProperty('ntapneu_l1', 'i', 'Neutral Tap Position LV1', py_name='ntapneu_l1'), DgsProperty('ntapneu_l2', 'i', 'Neutral Tap Position LV2', py_name='ntapneu_l2'), DgsProperty('ntapneu_l3', 'i', 'Neutral Tap Position LV3', py_name='ntapneu_l3'), DgsProperty('dutap_h0', 'r', 'Tap Step HV in percent', py_name='dutap_h0'), DgsProperty('dutap_l1', 'r', 'Tap Step LV1 in percent', py_name='dutap_l1'), DgsProperty('dutap_l2', 'r', 'Tap Step LV2 in percent', py_name='dutap_l2'), DgsProperty('dutap_l3', 'r', 'Tap Step LV3 in percent', py_name='dutap_l3'), DgsProperty('phitr_h0', 'r', 'Phase Shift HV in deg', py_name='phitr_h0'), DgsProperty('phitr_l1', 'r', 'Phase Shift LV1 in deg', py_name='phitr_l1'), DgsProperty('phitr_l2', 'r', 'Phase Shift LV2 in deg', py_name='phitr_l2'), DgsProperty('phitr_l3', 'r', 'Phase Shift LV3 in deg', py_name='phitr_l3'), DgsProperty('oltc_h0', 'i', 'OLTC Available HV', py_name='oltc_h0'), DgsProperty('oltc_l1', 'i', 'OLTC Available LV1', py_name='oltc_l1'), DgsProperty('oltc_l2', 'i', 'OLTC Available LV2', py_name='oltc_l2'), DgsProperty('oltc_l3', 'i', 'OLTC Available LV3', py_name='oltc_l3'), DgsProperty('uk0_h0l1', 'r', 'Zero Sequence Short-Circuit Voltage HV-LV1 in percent', py_name='uk0_h0l1'), DgsProperty('uk0_h0l2', 'r', 'Zero Sequence Short-Circuit Voltage HV-LV2 in percent', py_name='uk0_h0l2'), DgsProperty('uk0_h0l3', 'r', 'Zero Sequence Short-Circuit Voltage HV-LV3 in percent', py_name='uk0_h0l3'), DgsProperty('uk0_l1l2', 'r', 'Zero Sequence Short-Circuit Voltage LV1-LV2 in percent', py_name='uk0_l1l2'), DgsProperty('uk0_l1l3', 'r', 'Zero Sequence Short-Circuit Voltage LV1-LV3 in percent', py_name='uk0_l1l3'), DgsProperty('uk0_l2l3', 'r', 'Zero Sequence Short-Circuit Voltage LV2-LV3 in percent', py_name='uk0_l2l3'), DgsProperty('ukr0_h0l1', 'r', 'Zero Sequence Resistive Short-Circuit Voltage HV-LV1 in percent', py_name='ukr0_h0l1'), DgsProperty('ukr0_h0l2', 'r', 'Zero Sequence Resistive Short-Circuit Voltage HV-LV2 in percent', py_name='ukr0_h0l2'), DgsProperty('ukr0_h0l3', 'r', 'Zero Sequence Resistive Short-Circuit Voltage HV-LV3 in percent', py_name='ukr0_h0l3'), DgsProperty('ukr0_l1l2', 'r', 'Zero Sequence Resistive Short-Circuit Voltage LV1-LV2 in percent', py_name='ukr0_l1l2'), DgsProperty('ukr0_l1l3', 'r', 'Zero Sequence Resistive Short-Circuit Voltage LV1-LV3 in percent', py_name='ukr0_l1l3'), DgsProperty('ukr0_l2l3', 'r', 'Zero Sequence Resistive Short-Circuit Voltage LV2-LV3 in percent', py_name='ukr0_l2l3'), DgsProperty('ukr_h0l1', 'r', 'Resistive Short-Circuit Voltage HV-LV1 in percent', py_name='ukr_h0l1'), DgsProperty('ukr_h0l2', 'r', 'Resistive Short-Circuit Voltage HV-LV2 in percent', py_name='ukr_h0l2'), DgsProperty('ukr_h0l3', 'r', 'Resistive Short-Circuit Voltage HV-LV3 in percent', py_name='ukr_h0l3'), DgsProperty('ukr_l1l2', 'r', 'Resistive Short-Circuit Voltage LV1-LV2 in percent', py_name='ukr_l1l2'), DgsProperty('ukr_l1l3', 'r', 'Resistive Short-Circuit Voltage LV1-LV3 in percent', py_name='ukr_l1l3'), DgsProperty('ukr_l2l3', 'r', 'Resistive Short-Circuit Voltage LV2-LV3 in percent', py_name='ukr_l2l3'), DgsProperty('xtor_h0l1', 'r', 'X/R Ratio HV-LV1', py_name='xtor_h0l1'), DgsProperty('xtor_h0l2', 'r', 'X/R Ratio HV-LV2', py_name='xtor_h0l2'), DgsProperty('xtor_h0l3', 'r', 'X/R Ratio HV-LV3', py_name='xtor_h0l3'), DgsProperty('xtor_l1l2', 'r', 'X/R Ratio LV1-LV2', py_name='xtor_l1l2'), DgsProperty('xtor_l1l3', 'r', 'X/R Ratio LV1-LV3', py_name='xtor_l1l3'), DgsProperty('xtor_l2l3', 'r', 'X/R Ratio LV2-LV3', py_name='xtor_l2l3'), DgsProperty('r1pu_h0l1', 'r', 'Positive Sequence Resistance HV-LV1 in p.u.', py_name='r1pu_h0l1'), DgsProperty('r1pu_h0l2', 'r', 'Positive Sequence Resistance HV-LV2 in p.u.', py_name='r1pu_h0l2'), DgsProperty('r1pu_h0l3', 'r', 'Positive Sequence Resistance HV-LV3 in p.u.', py_name='r1pu_h0l3'), DgsProperty('r1pu_l1l2', 'r', 'Positive Sequence Resistance LV1-LV2 in p.u.', py_name='r1pu_l1l2'), DgsProperty('r1pu_l1l3', 'r', 'Positive Sequence Resistance LV1-LV3 in p.u.', py_name='r1pu_l1l3'), DgsProperty('r1pu_l2l3', 'r', 'Positive Sequence Resistance LV2-LV3 in p.u.', py_name='r1pu_l2l3'), DgsProperty('x1pu_h0l1', 'r', 'Positive Sequence Reactance HV-LV1 in p.u.', py_name='x1pu_h0l1'), DgsProperty('x1pu_h0l2', 'r', 'Positive Sequence Reactance HV-LV2 in p.u.', py_name='x1pu_h0l2'), DgsProperty('x1pu_h0l3', 'r', 'Positive Sequence Reactance HV-LV3 in p.u.', py_name='x1pu_h0l3'), DgsProperty('x1pu_l1l2', 'r', 'Positive Sequence Reactance LV1-LV2 in p.u.', py_name='x1pu_l1l2'), DgsProperty('x1pu_l1l3', 'r', 'Positive Sequence Reactance LV1-LV3 in p.u.', py_name='x1pu_l1l3'), DgsProperty('x1pu_l2l3', 'r', 'Positive Sequence Reactance LV2-LV3 in p.u.', py_name='x1pu_l2l3'), DgsProperty('r0pu_h0', 'r', 'Zero Sequence Resistance HV in p.u.', py_name='r0pu_h0'), DgsProperty('r0pu_l1', 'r', 'Zero Sequence Resistance LV1 in p.u.', py_name='r0pu_l1'), DgsProperty('r0pu_l2', 'r', 'Zero Sequence Resistance LV2 in p.u.', py_name='r0pu_l2'), DgsProperty('r0pu_l3', 'r', 'Zero Sequence Resistance LV3 in p.u.', py_name='r0pu_l3'), DgsProperty('x0pu_h0', 'r', 'Zero Sequence Reactance HV in p.u.', py_name='x0pu_h0'), DgsProperty('x0pu_l1', 'r', 'Zero Sequence Reactance LV1 in p.u.', py_name='x0pu_l1'), DgsProperty('x0pu_l2', 'r', 'Zero Sequence Reactance LV2 in p.u.', py_name='x0pu_l2'), DgsProperty('x0pu_l3', 'r', 'Zero Sequence Reactance LV3 in p.u.', py_name='x0pu_l3'), DgsProperty('bm1', 'r', 'Positive Sequence Magnetizing Susceptance in p.u.', py_name='bm1'), DgsProperty('gm1', 'r', 'Positive Sequence Magnetizing Conductance in p.u.', py_name='gm1'), DgsProperty('desc:0', 'a', 'Description Line 0', py_name='desc_0'), DgsProperty('doc_id', 'p', 'Document Reference', py_name='doc_id'), ] def __init__(self) -> None: self.ID: str = "" self.OP: str = "" self.loc_name: str = "" self.fold_id: str = "" self.pfe: float = 0.0 self.chr_name: str = "" self.for_name: str = "" self.dat_src: str = "" self.trcon_h0: str = "" self.trcon_l1: str = "" self.trcon_l2: str = "" self.trcon_l3: str = "" self.vecgrp: str = "" self.ansiclass: str = "" self.manuf: str = "" self.appr_modby: str = "" self.appr_modif: int = 0 self.sn_h0: float = 0.0 self.sn_l1: float = 0.0 self.sn_l2: float = 0.0 self.sn_l3: float = 0.0 self.un_h0: float = 0.0 self.un_l1: float = 0.0 self.un_l2: float = 0.0 self.un_l3: float = 0.0 self.uk_h0l1: float = 0.0 self.uk_h0l2: float = 0.0 self.uk_h0l3: float = 0.0 self.uk_l1l2: float = 0.0 self.uk_l1l3: float = 0.0 self.uk_l2l3: float = 0.0 self.pcu_h0l1: float = 0.0 self.pcu_h0l2: float = 0.0 self.pcu_h0l3: float = 0.0 self.pcu_l1l2: float = 0.0 self.pcu_l1l3: float = 0.0 self.pcu_l2l3: float = 0.0 self.uk_h0: float = 0.0 self.uk_l1: float = 0.0 self.uk_l2: float = 0.0 self.uk_l3: float = 0.0 self.pcu_h0: float = 0.0 self.pcu_l1: float = 0.0 self.pcu_l2: float = 0.0 self.pcu_l3: float = 0.0 self.curmag: float = 0.0 self.cur0mag: float = 0.0 self.ntapmin_h0: int = 0 self.ntapmin_l1: int = 0 self.ntapmin_l2: int = 0 self.ntapmin_l3: int = 0 self.ntapmax_h0: int = 0 self.ntapmax_l1: int = 0 self.ntapmax_l2: int = 0 self.ntapmax_l3: int = 0 self.ntapneu_h0: int = 0 self.ntapneu_l1: int = 0 self.ntapneu_l2: int = 0 self.ntapneu_l3: int = 0 self.dutap_h0: float = 0.0 self.dutap_l1: float = 0.0 self.dutap_l2: float = 0.0 self.dutap_l3: float = 0.0 self.phitr_h0: float = 0.0 self.phitr_l1: float = 0.0 self.phitr_l2: float = 0.0 self.phitr_l3: float = 0.0 self.oltc_h0: int = 0 self.oltc_l1: int = 0 self.oltc_l2: int = 0 self.oltc_l3: int = 0 self.uk0_h0l1: float = 0.0 self.uk0_h0l2: float = 0.0 self.uk0_h0l3: float = 0.0 self.uk0_l1l2: float = 0.0 self.uk0_l1l3: float = 0.0 self.uk0_l2l3: float = 0.0 self.ukr0_h0l1: float = 0.0 self.ukr0_h0l2: float = 0.0 self.ukr0_h0l3: float = 0.0 self.ukr0_l1l2: float = 0.0 self.ukr0_l1l3: float = 0.0 self.ukr0_l2l3: float = 0.0 self.ukr_h0l1: float = 0.0 self.ukr_h0l2: float = 0.0 self.ukr_h0l3: float = 0.0 self.ukr_l1l2: float = 0.0 self.ukr_l1l3: float = 0.0 self.ukr_l2l3: float = 0.0 self.xtor_h0l1: float = 0.0 self.xtor_h0l2: float = 0.0 self.xtor_h0l3: float = 0.0 self.xtor_l1l2: float = 0.0 self.xtor_l1l3: float = 0.0 self.xtor_l2l3: float = 0.0 self.r1pu_h0l1: float = 0.0 self.r1pu_h0l2: float = 0.0 self.r1pu_h0l3: float = 0.0 self.r1pu_l1l2: float = 0.0 self.r1pu_l1l3: float = 0.0 self.r1pu_l2l3: float = 0.0 self.x1pu_h0l1: float = 0.0 self.x1pu_h0l2: float = 0.0 self.x1pu_h0l3: float = 0.0 self.x1pu_l1l2: float = 0.0 self.x1pu_l1l3: float = 0.0 self.x1pu_l2l3: float = 0.0 self.r0pu_h0: float = 0.0 self.r0pu_l1: float = 0.0 self.r0pu_l2: float = 0.0 self.r0pu_l3: float = 0.0 self.x0pu_h0: float = 0.0 self.x0pu_l1: float = 0.0 self.x0pu_l2: float = 0.0 self.x0pu_l3: float = 0.0 self.bm1: float = 0.0 self.gm1: float = 0.0 self.desc_0: str = "" self.doc_id: str = ""
# ---------------------------------------------------------------------------------------------------------------------- # Overhead line modelling (PowerFactory: conductor / tower / line coupling) # ---------------------------------------------------------------------------------------------------------------------- def _dgs_get(parts: List[str], header_map: Dict[str, int], key: str) -> str | None: """Get the raw column value for a given DGS key.""" idx = header_map.get(key) if idx is None: return None if 0 <= idx < len(parts): return parts[idx] return None
[docs] class TypCon(DGSElement): """PowerFactory conductor type (TypCon) mapped to VeraGrid Wire.""" element_type = 'TypCon' properties_list = [ DgsProperty(name='ID', dgs_type='a:40', description='Unique identifier for DGS file', py_name='ID'), DgsProperty(name='OP', dgs_type='a:1', description='Operation', py_name='OP'), DgsProperty(name='loc_name', dgs_type='a:80', description='Name', py_name='loc_name'), DgsProperty(name='fold_id', dgs_type='p', description='In Folder', py_name='fold_id'), DgsProperty(name='uline', dgs_type='r', description='Rated Voltage in kV', py_name='uline'), DgsProperty(name='sline', dgs_type='r', description='Rated Current in kA', py_name='sline'), DgsProperty(name='ncsub', dgs_type='i', description='Number of Subconductors', py_name='ncsub'), DgsProperty(name='dsubc', dgs_type='r', description='Bundle Spacing in m', py_name='dsubc'), DgsProperty(name='rpha', dgs_type='r', description='DC-Resistance (20C) in Ohm/km', py_name='rpha'), DgsProperty(name='diaco', dgs_type='r', description='Outer Diameter in mm', py_name='diaco'), DgsProperty(name='diatub', dgs_type='r', description='Inner Diameter in mm', py_name='diatub'), DgsProperty(name='mlei', dgs_type='a:20', description='Conductor Material', py_name='mlei'), DgsProperty(name='iModel', dgs_type='i', description='Solid or Tubular conductor', py_name='iModel'), ] def __init__(self): self.ID: str = '' self.OP: str = '' self.loc_name: str = '' self.fold_id: str | None = None self.uline: float = 0.0 self.sline: float = 0.0 self.ncsub: int = 1 self.dsubc: float = 0.0 self.rpha: float = 0.0 self.diaco: float = 0.0 self.diatub: float = 0.0 self.mlei: str = '' self.iModel: int = 1
[docs] class TypCt(DGSElement): element_type = 'TypCt' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier of the current transformer type', py_name='ID'), DgsProperty('OP', 'a:1', 'DGS operation marker for the current transformer type', py_name='OP'), DgsProperty('loc_name', 'a:80', 'Name of the current transformer type', py_name='loc_name'), DgsProperty('fold_id', 'p', 'Folder containing the current transformer type', py_name='fold_id'), DgsProperty('primtaps:SIZEROW', 'i', 'Number of available primary tap values', py_name='primtaps_SIZEROW'), DgsProperty('primtaps:0', 'r', 'First primary tap value', py_name='primtaps_0'), DgsProperty('sectaps:SIZEROW', 'i', 'Number of available secondary tap values', py_name='sectaps_SIZEROW'), DgsProperty('sectaps:0', 'r', 'First secondary tap value', py_name='sectaps_0'), ] def __init__(self) -> None: self.ID: str = "" self.OP: str = "" self.loc_name: str = "" self.fold_id: str = "" self.primtaps_SIZEROW: int = 0 self.primtaps_0: float = 0.0 self.sectaps_SIZEROW: int = 0 self.sectaps_0: float = 0.0 self.primtaps: List[float] = list() self.sectaps: List[float] = list()
[docs] @classmethod def parse_line(cls, line: str, header_map: dict[str, int]): parts = line.rstrip('\n').split(';') obj = cls() obj.ID = str(cls.properties['ID'].parse(_dgs_get(parts, header_map, 'ID') or "")) obj.OP = str(cls.properties['OP'].parse(_dgs_get(parts, header_map, 'OP') or "")) obj.loc_name = str(cls.properties['loc_name'].parse(_dgs_get(parts, header_map, 'loc_name') or "")) fold_raw = _dgs_get(parts, header_map, 'fold_id') obj.fold_id = str(cls.properties['fold_id'].parse(fold_raw or "")) if fold_raw is not None else "" obj.primtaps_SIZEROW = int(cls.properties['primtaps:SIZEROW'].parse(_dgs_get(parts, header_map, 'primtaps:SIZEROW') or "0") or 0) obj.primtaps_0 = float(cls.properties['primtaps:0'].parse(_dgs_get(parts, header_map, 'primtaps:0') or "0") or 0.0) obj.sectaps_SIZEROW = int(cls.properties['sectaps:SIZEROW'].parse(_dgs_get(parts, header_map, 'sectaps:SIZEROW') or "0") or 0) obj.sectaps_0 = float(cls.properties['sectaps:0'].parse(_dgs_get(parts, header_map, 'sectaps:0') or "0") or 0.0) obj.primtaps.append(obj.primtaps_0) obj.sectaps.append(obj.sectaps_0) return obj
[docs] class TypGeo(DGSElement): element_type = 'TypGeo' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier of the tower geometry type', py_name='ID'), DgsProperty('OP', 'a:1', 'DGS operation marker for the tower geometry type', py_name='OP'), DgsProperty('loc_name', 'a:80', 'Name of the tower geometry type', py_name='loc_name'), DgsProperty('fold_id', 'p', 'Folder containing the tower geometry type', py_name='fold_id'), DgsProperty('nlear', 'i', 'Number of earth wires in the tower geometry', py_name='nlear'), DgsProperty('nlcir', 'i', 'Number of line circuits represented by the tower geometry', py_name='nlcir'), DgsProperty('xy_e:SIZEROW', 'i', 'Number of earth-wire coordinate rows', py_name='xy_e_SIZEROW'), DgsProperty('xy_e:SIZECOL', 'i', 'Number of earth-wire coordinate columns', py_name='xy_e_SIZECOL'), DgsProperty('xy_c:SIZEROW', 'i', 'Number of conductor coordinate rows', py_name='xy_c_SIZEROW'), DgsProperty('xy_c:SIZECOL', 'i', 'Number of conductor coordinate columns', py_name='xy_c_SIZECOL'), DgsProperty('xy_c:0:0', 'r', 'Conductor geometry matrix entry row 0 column 0', py_name='xy_c_0_0'), DgsProperty('xy_c:0:1', 'r', 'Conductor geometry matrix entry row 0 column 1', py_name='xy_c_0_1'), DgsProperty('xy_c:0:2', 'r', 'Conductor geometry matrix entry row 0 column 2', py_name='xy_c_0_2'), DgsProperty('xy_c:0:3', 'r', 'Conductor geometry matrix entry row 0 column 3', py_name='xy_c_0_3'), DgsProperty('xy_c:0:4', 'r', 'Conductor geometry matrix entry row 0 column 4', py_name='xy_c_0_4'), DgsProperty('xy_c:0:5', 'r', 'Conductor geometry matrix entry row 0 column 5', py_name='xy_c_0_5'), DgsProperty('xy_c:0:6', 'r', 'Conductor geometry matrix entry row 0 column 6', py_name='xy_c_0_6'), ] def __init__(self) -> None: self.ID: str = "" self.OP: str = "" self.loc_name: str = "" self.fold_id: str = "" self.nlear: int = 0 self.nlcir: int = 0 self.xy_e_SIZEROW: int = 0 self.xy_e_SIZECOL: int = 0 self.xy_c_SIZEROW: int = 0 self.xy_c_SIZECOL: int = 0 self.xy_c_0_0: float = 0.0 self.xy_c_0_1: float = 0.0 self.xy_c_0_2: float = 0.0 self.xy_c_0_3: float = 0.0 self.xy_c_0_4: float = 0.0 self.xy_c_0_5: float = 0.0 self.xy_c_0_6: float = 0.0 self.xy_c_row_0: List[float] = list()
[docs] @classmethod def parse_line(cls, line: str, header_map: dict[str, int]): parts = line.rstrip('\n').split(';') obj = cls() obj.ID = str(cls.properties['ID'].parse(_dgs_get(parts, header_map, 'ID') or "")) obj.OP = str(cls.properties['OP'].parse(_dgs_get(parts, header_map, 'OP') or "")) obj.loc_name = str(cls.properties['loc_name'].parse(_dgs_get(parts, header_map, 'loc_name') or "")) fold_raw = _dgs_get(parts, header_map, 'fold_id') obj.fold_id = str(cls.properties['fold_id'].parse(fold_raw or "")) if fold_raw is not None else "" obj.nlear = int(cls.properties['nlear'].parse(_dgs_get(parts, header_map, 'nlear') or "0") or 0) obj.nlcir = int(cls.properties['nlcir'].parse(_dgs_get(parts, header_map, 'nlcir') or "0") or 0) obj.xy_e_SIZEROW = int(cls.properties['xy_e:SIZEROW'].parse(_dgs_get(parts, header_map, 'xy_e:SIZEROW') or "0") or 0) obj.xy_e_SIZECOL = int(cls.properties['xy_e:SIZECOL'].parse(_dgs_get(parts, header_map, 'xy_e:SIZECOL') or "0") or 0) obj.xy_c_SIZEROW = int(cls.properties['xy_c:SIZEROW'].parse(_dgs_get(parts, header_map, 'xy_c:SIZEROW') or "0") or 0) obj.xy_c_SIZECOL = int(cls.properties['xy_c:SIZECOL'].parse(_dgs_get(parts, header_map, 'xy_c:SIZECOL') or "0") or 0) row_values: List[float] = list() for idx in range(7): key = f'xy_c:0:{idx}' value = float(cls.properties[key].parse(_dgs_get(parts, header_map, key) or "0") or 0.0) row_values.append(value) obj.xy_c_0_0 = row_values[0] obj.xy_c_0_1 = row_values[1] obj.xy_c_0_2 = row_values[2] obj.xy_c_0_3 = row_values[3] obj.xy_c_0_4 = row_values[4] obj.xy_c_0_5 = row_values[5] obj.xy_c_0_6 = row_values[6] obj.xy_c_row_0 = row_values return obj
[docs] class TypVt(DGSElement): element_type = 'TypVt' properties_list = [ DgsProperty('ID', 'a:40', 'Unique identifier of the voltage transformer type', py_name='ID'), DgsProperty('OP', 'a:1', 'DGS operation marker for the voltage transformer type', py_name='OP'), DgsProperty('loc_name', 'a:80', 'Name of the voltage transformer type', py_name='loc_name'), DgsProperty('fold_id', 'p', 'Folder containing the voltage transformer type', py_name='fold_id'), DgsProperty('primtaps:SIZEROW', 'i', 'Number of available primary tap values', py_name='primtaps_SIZEROW'), DgsProperty('primtaps:0', 'r', 'Primary tap value 0', py_name='primtaps_0'), DgsProperty('primtaps:1', 'r', 'Primary tap value 1', py_name='primtaps_1'), DgsProperty('primtaps:2', 'r', 'Primary tap value 2', py_name='primtaps_2'), DgsProperty('primtaps:3', 'r', 'Primary tap value 3', py_name='primtaps_3'), DgsProperty('primtaps:4', 'r', 'Primary tap value 4', py_name='primtaps_4'), DgsProperty('primtaps:5', 'r', 'Primary tap value 5', py_name='primtaps_5'), DgsProperty('primtaps:6', 'r', 'Primary tap value 6', py_name='primtaps_6'), DgsProperty('primtaps:7', 'r', 'Primary tap value 7', py_name='primtaps_7'), DgsProperty('primtaps:8', 'r', 'Primary tap value 8', py_name='primtaps_8'), DgsProperty('primtaps:9', 'r', 'Primary tap value 9', py_name='primtaps_9'), DgsProperty('primtaps:10', 'r', 'Primary tap value 10', py_name='primtaps_10'), DgsProperty('primtaps:11', 'r', 'Primary tap value 11', py_name='primtaps_11'), DgsProperty('primtaps:12', 'r', 'Primary tap value 12', py_name='primtaps_12'), DgsProperty('primtaps:13', 'r', 'Primary tap value 13', py_name='primtaps_13'), DgsProperty('primtaps:14', 'r', 'Primary tap value 14', py_name='primtaps_14'), DgsProperty('primtaps:15', 'r', 'Primary tap value 15', py_name='primtaps_15'), DgsProperty('primtaps:16', 'r', 'Primary tap value 16', py_name='primtaps_16'), DgsProperty('primtaps:17', 'r', 'Primary tap value 17', py_name='primtaps_17'), DgsProperty('primtaps:18', 'r', 'Primary tap value 18', py_name='primtaps_18'), DgsProperty('primtaps:19', 'r', 'Primary tap value 19', py_name='primtaps_19'), DgsProperty('primtaps:20', 'r', 'Primary tap value 20', py_name='primtaps_20'), DgsProperty('primtaps:21', 'r', 'Primary tap value 21', py_name='primtaps_21'), DgsProperty('primtaps:22', 'r', 'Primary tap value 22', py_name='primtaps_22'), DgsProperty('primtaps:23', 'r', 'Primary tap value 23', py_name='primtaps_23'), DgsProperty('primtaps:24', 'r', 'Primary tap value 24', py_name='primtaps_24'), DgsProperty('primtaps:25', 'r', 'Primary tap value 25', py_name='primtaps_25'), DgsProperty('primtaps:26', 'r', 'Primary tap value 26', py_name='primtaps_26'), DgsProperty('primtaps:27', 'r', 'Primary tap value 27', py_name='primtaps_27'), DgsProperty('primtaps:28', 'r', 'Primary tap value 28', py_name='primtaps_28'), DgsProperty('primtaps:29', 'r', 'Primary tap value 29', py_name='primtaps_29'), DgsProperty('primtaps:30', 'r', 'Primary tap value 30', py_name='primtaps_30'), DgsProperty('primtaps:31', 'r', 'Primary tap value 31', py_name='primtaps_31'), DgsProperty('primtaps:32', 'r', 'Primary tap value 32', py_name='primtaps_32'), DgsProperty('primtaps:33', 'r', 'Primary tap value 33', py_name='primtaps_33'), DgsProperty('primtaps:34', 'r', 'Primary tap value 34', py_name='primtaps_34'), DgsProperty('primtaps:35', 'r', 'Primary tap value 35', py_name='primtaps_35'), DgsProperty('primtaps:36', 'r', 'Primary tap value 36', py_name='primtaps_36'), DgsProperty('primtaps:37', 'r', 'Primary tap value 37', py_name='primtaps_37'), DgsProperty('primtaps:38', 'r', 'Primary tap value 38', py_name='primtaps_38'), ] def __init__(self) -> None: self.ID: str = "" self.OP: str = "" self.loc_name: str = "" self.fold_id: str = "" self.primtaps_SIZEROW: int = 0 self.primtaps: List[float] = list()
[docs] @classmethod def parse_line(cls, line: str, header_map: dict[str, int]): parts = line.rstrip('\n').split(';') obj = cls() obj.ID = str(cls.properties['ID'].parse(_dgs_get(parts, header_map, 'ID') or "")) obj.OP = str(cls.properties['OP'].parse(_dgs_get(parts, header_map, 'OP') or "")) obj.loc_name = str(cls.properties['loc_name'].parse(_dgs_get(parts, header_map, 'loc_name') or "")) fold_raw = _dgs_get(parts, header_map, 'fold_id') obj.fold_id = str(cls.properties['fold_id'].parse(fold_raw or "")) if fold_raw is not None else "" obj.primtaps_SIZEROW = int(cls.properties['primtaps:SIZEROW'].parse(_dgs_get(parts, header_map, 'primtaps:SIZEROW') or "0") or 0) for idx in range(39): key = f'primtaps:{idx}' raw = _dgs_get(parts, header_map, key) value = float(cls.properties[key].parse(raw or "0") or 0.0) obj.primtaps.append(value) return obj
[docs] def to_dgs_line(self) -> str: values: List[str] = list() values.append(self.properties['ID'].format(self.ID)) values.append(self.properties['OP'].format(self.OP)) values.append(self.properties['loc_name'].format(self.loc_name)) values.append(self.properties['fold_id'].format(self.fold_id)) values.append(self.properties['primtaps:SIZEROW'].format(self.primtaps_SIZEROW)) for idx in range(39): if idx < len(self.primtaps): values.append(self.properties[f'primtaps:{idx}'].format(self.primtaps[idx])) else: values.append(self.properties[f'primtaps:{idx}'].format(0.0)) return ';'.join(values)
[docs] class TypTow(DGSElement): """PowerFactory tower type (TypTow) mapped to VeraGrid OverheadLineType.""" element_type = 'TypTow' properties_list = [ DgsProperty(name='FID', dgs_type='a:40', description='Unique identifier for DGS file', py_name='ID'), DgsProperty(name='OP', dgs_type='a:1', description='Operation', py_name='OP'), DgsProperty(name='loc_name', dgs_type='a:80', description='Name', py_name='loc_name'), DgsProperty(name='fold_id', dgs_type='p', description='In Folder', py_name='fold_id'), DgsProperty(name='frnom', dgs_type='r', description='Nominal Frequency in Hz', py_name='frnom'), DgsProperty(name='nlear', dgs_type='i', description='Number of Earth Wires', py_name='nlear'), DgsProperty(name='nlcir', dgs_type='i', description='Number of Line Circuits', py_name='nlcir'), DgsProperty(name='gearth', dgs_type='r', description='Earth conductivity in uS/cm', py_name='gearth'), DgsProperty(name='i_mode', dgs_type='i', description='Tower model mode code', py_name='i_mode'), DgsProperty(name='pcond_e:SIZEROW', dgs_type='i', description='Earth conductor vector size', py_name='pcond_e_SIZEROW'), DgsProperty(name='pcond_e:0', dgs_type='p', description='Earth conductor pointer 0', py_name='pcond_e_0'), DgsProperty(name='pcond_e:1', dgs_type='p', description='Earth conductor pointer 1', py_name='pcond_e_1'), DgsProperty(name='nphas:SIZEROW', dgs_type='i', description='Phase-count vector size', py_name='nphas_SIZEROW'), DgsProperty(name='nphas:0', dgs_type='r', description='Phase count value 0', py_name='nphas_0'), DgsProperty(name='nphas:1', dgs_type='r', description='Phase count value 1', py_name='nphas_1'), DgsProperty(name='ktrto:SIZEROW', dgs_type='i', description='Transposition vector size', py_name='ktrto_SIZEROW'), DgsProperty(name='ktrto:0', dgs_type='r', description='Transposition value 0', py_name='ktrto_0'), DgsProperty(name='ktrto:1', dgs_type='r', description='Transposition value 1', py_name='ktrto_1'), DgsProperty(name='pcond_c:SIZEROW', dgs_type='i', description='Circuit conductor vector size', py_name='pcond_c_SIZEROW'), DgsProperty(name='pcond_c:0', dgs_type='p', description='Circuit conductor pointer 0', py_name='pcond_c_0'), DgsProperty(name='pcond_c:1', dgs_type='p', description='Circuit conductor pointer 1', py_name='pcond_c_1'), DgsProperty(name='xy_e:SIZEROW', dgs_type='i', description='Earth coordinate matrix rows', py_name='xy_e_SIZEROW'), DgsProperty(name='xy_e:SIZECOL', dgs_type='i', description='Earth coordinate matrix columns', py_name='xy_e_SIZECOL'), DgsProperty(name='xy_e:0:0', dgs_type='r', description='Earth coordinate [0,0]', py_name='xy_e_0_0'), DgsProperty(name='xy_e:0:1', dgs_type='r', description='Earth coordinate [0,1]', py_name='xy_e_0_1'), DgsProperty(name='xy_e:1:0', dgs_type='r', description='Earth coordinate [1,0]', py_name='xy_e_1_0'), DgsProperty(name='xy_e:1:1', dgs_type='r', description='Earth coordinate [1,1]', py_name='xy_e_1_1'), DgsProperty(name='xy_c:SIZEROW', dgs_type='i', description='Circuit coordinate matrix rows', py_name='xy_c_SIZEROW'), DgsProperty(name='xy_c:SIZECOL', dgs_type='i', description='Circuit coordinate matrix columns', py_name='xy_c_SIZECOL'), DgsProperty(name='xy_c:0:0', dgs_type='r', description='Circuit coordinate [0,0]', py_name='xy_c_0_0'), DgsProperty(name='xy_c:0:1', dgs_type='r', description='Circuit coordinate [0,1]', py_name='xy_c_0_1'), DgsProperty(name='xy_c:0:2', dgs_type='r', description='Circuit coordinate [0,2]', py_name='xy_c_0_2'), DgsProperty(name='xy_c:0:3', dgs_type='r', description='Circuit coordinate [0,3]', py_name='xy_c_0_3'), DgsProperty(name='xy_c:0:4', dgs_type='r', description='Circuit coordinate [0,4]', py_name='xy_c_0_4'), DgsProperty(name='xy_c:0:5', dgs_type='r', description='Circuit coordinate [0,5]', py_name='xy_c_0_5'), DgsProperty(name='xy_c:1:0', dgs_type='r', description='Circuit coordinate [1,0]', py_name='xy_c_1_0'), DgsProperty(name='xy_c:1:1', dgs_type='r', description='Circuit coordinate [1,1]', py_name='xy_c_1_1'), DgsProperty(name='xy_c:1:2', dgs_type='r', description='Circuit coordinate [1,2]', py_name='xy_c_1_2'), DgsProperty(name='xy_c:1:3', dgs_type='r', description='Circuit coordinate [1,3]', py_name='xy_c_1_3'), DgsProperty(name='xy_c:1:4', dgs_type='r', description='Circuit coordinate [1,4]', py_name='xy_c_1_4'), DgsProperty(name='xy_c:1:5', dgs_type='r', description='Circuit coordinate [1,5]', py_name='xy_c_1_5'), DgsProperty(name='R_c0:SIZEROW', dgs_type='i', description='R_c0 matrix rows', py_name='R_c0_SIZEROW'), DgsProperty(name='R_c0:SIZECOL', dgs_type='i', description='R_c0 matrix cols', py_name='R_c0_SIZECOL'), DgsProperty(name='R_c0:0:0', dgs_type='r', description='R_c0 [0,0]', py_name='R_c0_0_0'), DgsProperty(name='R_c0:0:1', dgs_type='r', description='R_c0 [0,1]', py_name='R_c0_0_1'), DgsProperty(name='R_c0:1:0', dgs_type='r', description='R_c0 [1,0]', py_name='R_c0_1_0'), DgsProperty(name='R_c0:1:1', dgs_type='r', description='R_c0 [1,1]', py_name='R_c0_1_1'), DgsProperty(name='X_c0:SIZEROW', dgs_type='i', description='X_c0 matrix rows', py_name='X_c0_SIZEROW'), DgsProperty(name='X_c0:SIZECOL', dgs_type='i', description='X_c0 matrix cols', py_name='X_c0_SIZECOL'), DgsProperty(name='X_c0:0:0', dgs_type='r', description='X_c0 [0,0]', py_name='X_c0_0_0'), DgsProperty(name='X_c0:0:1', dgs_type='r', description='X_c0 [0,1]', py_name='X_c0_0_1'), DgsProperty(name='X_c0:1:0', dgs_type='r', description='X_c0 [1,0]', py_name='X_c0_1_0'), DgsProperty(name='X_c0:1:1', dgs_type='r', description='X_c0 [1,1]', py_name='X_c0_1_1'), DgsProperty(name='R_c1:SIZEROW', dgs_type='i', description='R_c1 matrix rows', py_name='R_c1_SIZEROW'), DgsProperty(name='R_c1:SIZECOL', dgs_type='i', description='R_c1 matrix cols', py_name='R_c1_SIZECOL'), DgsProperty(name='R_c1:0:0', dgs_type='r', description='R_c1 [0,0]', py_name='R_c1_0_0'), DgsProperty(name='R_c1:0:1', dgs_type='r', description='R_c1 [0,1]', py_name='R_c1_0_1'), DgsProperty(name='R_c1:1:0', dgs_type='r', description='R_c1 [1,0]', py_name='R_c1_1_0'), DgsProperty(name='R_c1:1:1', dgs_type='r', description='R_c1 [1,1]', py_name='R_c1_1_1'), DgsProperty(name='X_c1:SIZEROW', dgs_type='i', description='X_c1 matrix rows', py_name='X_c1_SIZEROW'), DgsProperty(name='X_c1:SIZECOL', dgs_type='i', description='X_c1 matrix cols', py_name='X_c1_SIZECOL'), DgsProperty(name='X_c1:0:0', dgs_type='r', description='X_c1 [0,0]', py_name='X_c1_0_0'), DgsProperty(name='X_c1:0:1', dgs_type='r', description='X_c1 [0,1]', py_name='X_c1_0_1'), DgsProperty(name='X_c1:1:0', dgs_type='r', description='X_c1 [1,0]', py_name='X_c1_1_0'), DgsProperty(name='X_c1:1:1', dgs_type='r', description='X_c1 [1,1]', py_name='X_c1_1_1'), DgsProperty(name='B_c0:SIZEROW', dgs_type='i', description='B_c0 matrix rows', py_name='B_c0_SIZEROW'), DgsProperty(name='B_c0:SIZECOL', dgs_type='i', description='B_c0 matrix cols', py_name='B_c0_SIZECOL'), DgsProperty(name='B_c0:0:0', dgs_type='r', description='B_c0 [0,0]', py_name='B_c0_0_0'), DgsProperty(name='B_c0:0:1', dgs_type='r', description='B_c0 [0,1]', py_name='B_c0_0_1'), DgsProperty(name='B_c0:1:0', dgs_type='r', description='B_c0 [1,0]', py_name='B_c0_1_0'), DgsProperty(name='B_c0:1:1', dgs_type='r', description='B_c0 [1,1]', py_name='B_c0_1_1'), DgsProperty(name='B_c1:SIZEROW', dgs_type='i', description='B_c1 matrix rows', py_name='B_c1_SIZEROW'), DgsProperty(name='B_c1:SIZECOL', dgs_type='i', description='B_c1 matrix cols', py_name='B_c1_SIZECOL'), DgsProperty(name='B_c1:0:0', dgs_type='r', description='B_c1 [0,0]', py_name='B_c1_0_0'), DgsProperty(name='B_c1:0:1', dgs_type='r', description='B_c1 [0,1]', py_name='B_c1_0_1'), DgsProperty(name='B_c1:1:0', dgs_type='r', description='B_c1 [1,0]', py_name='B_c1_1_0'), DgsProperty(name='B_c1:1:1', dgs_type='r', description='B_c1 [1,1]', py_name='B_c1_1_1'), DgsProperty(name='G_c0:SIZEROW', dgs_type='i', description='G_c0 matrix rows', py_name='G_c0_SIZEROW'), DgsProperty(name='G_c0:SIZECOL', dgs_type='i', description='G_c0 matrix cols', py_name='G_c0_SIZECOL'), DgsProperty(name='G_c0:0:0', dgs_type='r', description='G_c0 [0,0]', py_name='G_c0_0_0'), DgsProperty(name='G_c0:0:1', dgs_type='r', description='G_c0 [0,1]', py_name='G_c0_0_1'), DgsProperty(name='G_c0:1:0', dgs_type='r', description='G_c0 [1,0]', py_name='G_c0_1_0'), DgsProperty(name='G_c0:1:1', dgs_type='r', description='G_c0 [1,1]', py_name='G_c0_1_1'), DgsProperty(name='G_c1:SIZEROW', dgs_type='i', description='G_c1 matrix rows', py_name='G_c1_SIZEROW'), DgsProperty(name='G_c1:SIZECOL', dgs_type='i', description='G_c1 matrix cols', py_name='G_c1_SIZECOL'), DgsProperty(name='G_c1:0:0', dgs_type='r', description='G_c1 [0,0]', py_name='G_c1_0_0'), DgsProperty(name='G_c1:0:1', dgs_type='r', description='G_c1 [0,1]', py_name='G_c1_0_1'), DgsProperty(name='G_c1:1:0', dgs_type='r', description='G_c1 [1,0]', py_name='G_c1_1_0'), DgsProperty(name='G_c1:1:1', dgs_type='r', description='G_c1 [1,1]', py_name='G_c1_1_1'), ] def __init__(self): # Base scalar fields self.ID: str = '' self.OP: str = '' self.loc_name: str = '' self.fold_id: str | None = None self.frnom: float = 50.0 self.nlear: int = 0 self.nlcir: int = 1 self.gearth: float = 0.0 self.i_mode: int = 0 # Dynamic fields (variable-size vectors/matrices) self.pcond_e_SIZEROW: int = 0 self.pcond_e: List[str | None] = list() self.nphas_SIZEROW: int = 0 self.pcond_c: List[str | None] = list() self.pcond_c_SIZEROW: int = 0 self.nphas: List[float] = list() self.ktrto_SIZEROW: int = 0 self.ktrto: List[float] = list() self.xy_e_SIZEROW: int = 0 self.xy_e_SIZECOL: int = 0 self.xy_e: List[List[float]] = list() # Each row: [x, y] self.xy_c_SIZEROW: int = 0 self.xy_c_SIZECOL: int = 0 self.xy_c: List[List[float]] = list() # Each row: [xA, xB, xC, yA, yB, yC] self.R_c0_SIZEROW: int = 0 self.R_c0_SIZECOL: int = 0 self.R_c0: List[List[float]] = list() self.X_c0_SIZEROW: int = 0 self.X_c0_SIZECOL: int = 0 self.X_c0: List[List[float]] = list() self.R_c1_SIZEROW: int = 0 self.R_c1_SIZECOL: int = 0 self.R_c1: List[List[float]] = list() self.X_c1_SIZEROW: int = 0 self.X_c1_SIZECOL: int = 0 self.X_c1: List[List[float]] = list() self.B_c0_SIZEROW: int = 0 self.B_c0_SIZECOL: int = 0 self.B_c0: List[List[float]] = list() self.B_c1_SIZEROW: int = 0 self.B_c1_SIZECOL: int = 0 self.B_c1: List[List[float]] = list() self.G_c0_SIZEROW: int = 0 self.G_c0_SIZECOL: int = 0 self.G_c0: List[List[float]] = list() self.G_c1_SIZEROW: int = 0 self.G_c1_SIZECOL: int = 0 self.G_c1: List[List[float]] = list()
[docs] @classmethod def parse_line(cls, line: str, header_map: dict[str, int]): """Parse TypTow data line including variable-sized arrays/matrices.""" parts = line.rstrip('\n').split(';') obj = cls() # Parse the scalar fields via the base schema for prop in cls.properties_list: idx = header_map.get(prop.name) if idx is None and prop.name == 'FID': idx = header_map.get('ID') if idx is not None and 0 <= idx < len(parts): raw = parts[idx] val = prop.parse(raw) setattr(obj, prop.py_name, val) # Variable-size vectors # Conductor types for earth wires raw_n = _dgs_get(parts, header_map, 'pcond_e:SIZEROW') n = int(float(raw_n.replace(',', '.'))) if raw_n is not None and raw_n.strip() != '' else 0 obj.pcond_e_SIZEROW = n obj.pcond_e = list() for i in range(n): raw_ptr = _dgs_get(parts, header_map, f'pcond_e:{i}') raw_ptr = raw_ptr.strip() if raw_ptr is not None else '' obj.pcond_e.append(raw_ptr if raw_ptr != '' and raw_ptr != '*' else None) # Num. of phases per circuit (often 3) raw_nphas = _dgs_get(parts, header_map, 'nphas:SIZEROW') nphas_n = int(float(raw_nphas.replace(',', '.'))) if raw_nphas is not None and raw_nphas.strip() != '' else 0 obj.nphas_SIZEROW = nphas_n obj.nphas = list() for i in range(nphas_n): raw_v = _dgs_get(parts, header_map, f'nphas:{i}') raw_v = raw_v.strip() if raw_v is not None else '' obj.nphas.append(float(raw_v.replace(',', '.')) if raw_v != '' and raw_v != '*' else 0.0) # Transposition flags per circuit raw_ktrto = _dgs_get(parts, header_map, 'ktrto:SIZEROW') ktrto_n = int(float(raw_ktrto.replace(',', '.'))) if raw_ktrto is not None and raw_ktrto.strip() != '' else 0 obj.ktrto_SIZEROW = ktrto_n obj.ktrto = list() for i in range(ktrto_n): raw_v = _dgs_get(parts, header_map, f'ktrto:{i}') raw_v = raw_v.strip() if raw_v is not None else '' obj.ktrto.append(float(raw_v.replace(',', '.')) if raw_v != '' and raw_v != '*' else 0.0) # Conductor types for line circuits raw_pc = _dgs_get(parts, header_map, 'pcond_c:SIZEROW') pc_n = int(float(raw_pc.replace(',', '.'))) if raw_pc is not None and raw_pc.strip() != '' else 0 obj.pcond_c_SIZEROW = pc_n obj.pcond_c = list() for i in range(pc_n): raw_ptr = _dgs_get(parts, header_map, f'pcond_c:{i}') raw_ptr = raw_ptr.strip() if raw_ptr is not None else '' obj.pcond_c.append(raw_ptr if raw_ptr != '' and raw_ptr != '*' else None) # Earth wire coordinates: xy_e is a matrix with 2 columns (x, y) in meters raw_xy_e_rows = _dgs_get(parts, header_map, 'xy_e:SIZEROW') xy_e_rows = int(float(raw_xy_e_rows.replace(',', '.'))) if raw_xy_e_rows is not None and raw_xy_e_rows.strip() != '' else 0 raw_xy_e_cols = _dgs_get(parts, header_map, 'xy_e:SIZECOL') xy_e_cols = int(float(raw_xy_e_cols.replace(',', '.'))) if raw_xy_e_cols is not None and raw_xy_e_cols.strip() != '' else 0 obj.xy_e_SIZEROW = xy_e_rows obj.xy_e_SIZECOL = xy_e_cols obj.xy_e = list() for r in range(xy_e_rows): row: List[float] = list() for c in range(xy_e_cols): raw_v = _dgs_get(parts, header_map, f'xy_e:{r}:{c}') raw_v = raw_v.strip() if raw_v is not None else '' row.append(float(raw_v.replace(',', '.')) if raw_v != '' and raw_v != '*' else 0.0) obj.xy_e.append(row) # Circuit coordinates: xy_c is a matrix; in this dataset it uses 6 columns: # [xA, xB, xC, yA, yB, yC] in meters. raw_xy_c_rows = _dgs_get(parts, header_map, 'xy_c:SIZEROW') xy_c_rows = int(float(raw_xy_c_rows.replace(',', '.'))) if raw_xy_c_rows is not None and raw_xy_c_rows.strip() != '' else 0 raw_xy_c_cols = _dgs_get(parts, header_map, 'xy_c:SIZECOL') xy_c_cols = int(float(raw_xy_c_cols.replace(',', '.'))) if raw_xy_c_cols is not None and raw_xy_c_cols.strip() != '' else 0 obj.xy_c_SIZEROW = xy_c_rows obj.xy_c_SIZECOL = xy_c_cols obj.xy_c = list() for r in range(xy_c_rows): row: List[float] = list() for c in range(xy_c_cols): raw_v = _dgs_get(parts, header_map, f'xy_c:{r}:{c}') raw_v = raw_v.strip() if raw_v is not None else '' row.append(float(raw_v.replace(',', '.')) if raw_v != '' and raw_v != '*' else 0.0) obj.xy_c.append(row) raw_R_c0_rows = _dgs_get(parts, header_map, 'R_c0:SIZEROW') R_c0_rows = int(float(raw_R_c0_rows.replace(',', '.'))) if raw_R_c0_rows is not None and raw_R_c0_rows.strip() != '' else 0 raw_R_c0_cols = _dgs_get(parts, header_map, 'R_c0:SIZECOL') R_c0_cols = int(float(raw_R_c0_cols.replace(',', '.'))) if raw_R_c0_cols is not None and raw_R_c0_cols.strip() != '' else 0 obj.R_c0_SIZEROW = R_c0_rows obj.R_c0_SIZECOL = R_c0_cols obj.R_c0 = list() for r in range(R_c0_rows): row = list() for c in range(R_c0_cols): raw_v = _dgs_get(parts, header_map, f'R_c0:{r}:{c}') raw_v = raw_v.strip() if raw_v is not None else '' row.append(float(raw_v.replace(',', '.')) if raw_v != '' and raw_v != '*' else 0.0) obj.R_c0.append(row) raw_X_c0_rows = _dgs_get(parts, header_map, 'X_c0:SIZEROW') X_c0_rows = int(float(raw_X_c0_rows.replace(',', '.'))) if raw_X_c0_rows is not None and raw_X_c0_rows.strip() != '' else 0 raw_X_c0_cols = _dgs_get(parts, header_map, 'X_c0:SIZECOL') X_c0_cols = int(float(raw_X_c0_cols.replace(',', '.'))) if raw_X_c0_cols is not None and raw_X_c0_cols.strip() != '' else 0 obj.X_c0_SIZEROW = X_c0_rows obj.X_c0_SIZECOL = X_c0_cols obj.X_c0 = list() for r in range(X_c0_rows): row = list() for c in range(X_c0_cols): raw_v = _dgs_get(parts, header_map, f'X_c0:{r}:{c}') raw_v = raw_v.strip() if raw_v is not None else '' row.append(float(raw_v.replace(',', '.')) if raw_v != '' and raw_v != '*' else 0.0) obj.X_c0.append(row) raw_R_c1_rows = _dgs_get(parts, header_map, 'R_c1:SIZEROW') R_c1_rows = int(float(raw_R_c1_rows.replace(',', '.'))) if raw_R_c1_rows is not None and raw_R_c1_rows.strip() != '' else 0 raw_R_c1_cols = _dgs_get(parts, header_map, 'R_c1:SIZECOL') R_c1_cols = int(float(raw_R_c1_cols.replace(',', '.'))) if raw_R_c1_cols is not None and raw_R_c1_cols.strip() != '' else 0 obj.R_c1_SIZEROW = R_c1_rows obj.R_c1_SIZECOL = R_c1_cols obj.R_c1 = list() for r in range(R_c1_rows): row = list() for c in range(R_c1_cols): raw_v = _dgs_get(parts, header_map, f'R_c1:{r}:{c}') raw_v = raw_v.strip() if raw_v is not None else '' row.append(float(raw_v.replace(',', '.')) if raw_v != '' and raw_v != '*' else 0.0) obj.R_c1.append(row) raw_X_c1_rows = _dgs_get(parts, header_map, 'X_c1:SIZEROW') X_c1_rows = int(float(raw_X_c1_rows.replace(',', '.'))) if raw_X_c1_rows is not None and raw_X_c1_rows.strip() != '' else 0 raw_X_c1_cols = _dgs_get(parts, header_map, 'X_c1:SIZECOL') X_c1_cols = int(float(raw_X_c1_cols.replace(',', '.'))) if raw_X_c1_cols is not None and raw_X_c1_cols.strip() != '' else 0 obj.X_c1_SIZEROW = X_c1_rows obj.X_c1_SIZECOL = X_c1_cols obj.X_c1 = list() for r in range(X_c1_rows): row = list() for c in range(X_c1_cols): raw_v = _dgs_get(parts, header_map, f'X_c1:{r}:{c}') raw_v = raw_v.strip() if raw_v is not None else '' row.append(float(raw_v.replace(',', '.')) if raw_v != '' and raw_v != '*' else 0.0) obj.X_c1.append(row) raw_B_c0_rows = _dgs_get(parts, header_map, 'B_c0:SIZEROW') B_c0_rows = int(float(raw_B_c0_rows.replace(',', '.'))) if raw_B_c0_rows is not None and raw_B_c0_rows.strip() != '' else 0 raw_B_c0_cols = _dgs_get(parts, header_map, 'B_c0:SIZECOL') B_c0_cols = int(float(raw_B_c0_cols.replace(',', '.'))) if raw_B_c0_cols is not None and raw_B_c0_cols.strip() != '' else 0 obj.B_c0_SIZEROW = B_c0_rows obj.B_c0_SIZECOL = B_c0_cols obj.B_c0 = list() for r in range(B_c0_rows): row = list() for c in range(B_c0_cols): raw_v = _dgs_get(parts, header_map, f'B_c0:{r}:{c}') raw_v = raw_v.strip() if raw_v is not None else '' row.append(float(raw_v.replace(',', '.')) if raw_v != '' and raw_v != '*' else 0.0) obj.B_c0.append(row) raw_B_c1_rows = _dgs_get(parts, header_map, 'B_c1:SIZEROW') B_c1_rows = int(float(raw_B_c1_rows.replace(',', '.'))) if raw_B_c1_rows is not None and raw_B_c1_rows.strip() != '' else 0 raw_B_c1_cols = _dgs_get(parts, header_map, 'B_c1:SIZECOL') B_c1_cols = int(float(raw_B_c1_cols.replace(',', '.'))) if raw_B_c1_cols is not None and raw_B_c1_cols.strip() != '' else 0 obj.B_c1_SIZEROW = B_c1_rows obj.B_c1_SIZECOL = B_c1_cols obj.B_c1 = list() for r in range(B_c1_rows): row = list() for c in range(B_c1_cols): raw_v = _dgs_get(parts, header_map, f'B_c1:{r}:{c}') raw_v = raw_v.strip() if raw_v is not None else '' row.append(float(raw_v.replace(',', '.')) if raw_v != '' and raw_v != '*' else 0.0) obj.B_c1.append(row) raw_G_c0_rows = _dgs_get(parts, header_map, 'G_c0:SIZEROW') G_c0_rows = int(float(raw_G_c0_rows.replace(',', '.'))) if raw_G_c0_rows is not None and raw_G_c0_rows.strip() != '' else 0 raw_G_c0_cols = _dgs_get(parts, header_map, 'G_c0:SIZECOL') G_c0_cols = int(float(raw_G_c0_cols.replace(',', '.'))) if raw_G_c0_cols is not None and raw_G_c0_cols.strip() != '' else 0 obj.G_c0_SIZEROW = G_c0_rows obj.G_c0_SIZECOL = G_c0_cols obj.G_c0 = list() for r in range(G_c0_rows): row = list() for c in range(G_c0_cols): raw_v = _dgs_get(parts, header_map, f'G_c0:{r}:{c}') raw_v = raw_v.strip() if raw_v is not None else '' row.append(float(raw_v.replace(',', '.')) if raw_v != '' and raw_v != '*' else 0.0) obj.G_c0.append(row) raw_G_c1_rows = _dgs_get(parts, header_map, 'G_c1:SIZEROW') G_c1_rows = int(float(raw_G_c1_rows.replace(',', '.'))) if raw_G_c1_rows is not None and raw_G_c1_rows.strip() != '' else 0 raw_G_c1_cols = _dgs_get(parts, header_map, 'G_c1:SIZECOL') G_c1_cols = int(float(raw_G_c1_cols.replace(',', '.'))) if raw_G_c1_cols is not None and raw_G_c1_cols.strip() != '' else 0 obj.G_c1_SIZEROW = G_c1_rows obj.G_c1_SIZECOL = G_c1_cols obj.G_c1 = list() for r in range(G_c1_rows): row = list() for c in range(G_c1_cols): raw_v = _dgs_get(parts, header_map, f'G_c1:{r}:{c}') raw_v = raw_v.strip() if raw_v is not None else '' row.append(float(raw_v.replace(',', '.')) if raw_v != '' and raw_v != '*' else 0.0) obj.G_c1.append(row) return obj
[docs] class ElmTow(DGSElement): """PowerFactory line coupling (ElmTow) that binds ElmLne circuits to a tower geometry.""" element_type = 'ElmTow' properties_list = [ DgsProperty(name='ID', dgs_type='a:40', description='Unique identifier for DGS file', py_name='ID'), DgsProperty(name='OP', dgs_type='a:1', description='Operation', py_name='OP'), DgsProperty(name='loc_name', dgs_type='a:80', description='Name', py_name='loc_name'), DgsProperty(name='fold_id', dgs_type='p', description='In Folder', py_name='fold_id'), DgsProperty(name='outserv', dgs_type='i', description='Out of Service', py_name='outserv'), DgsProperty(name='i_dist', dgs_type='i', description='Line Model', py_name='i_dist'), DgsProperty(name='ngeo', dgs_type='i', description='Number of overhead line systems', py_name='ngeo'), ] def __init__(self): self.ID: str = '' self.OP: str = '' self.loc_name: str = '' self.fold_id: str | None = None self.outserv: int = 0 self.i_dist: int = 0 self.ngeo: int = 0 # Dynamic vectors self.pGeo: List[str | None] = list() # Pointers to TypTow/TypGeo self.plines: List[str | None] = list() # Pointers to ElmLne / ElmLneRoute self.dpolar: List[float] = list() # Polarity flags
[docs] @classmethod def parse_line(cls, line: str, header_map: dict[str, int]): """Parse ElmTow data line including variable-sized vectors.""" parts = line.rstrip('\n').split(';') obj = cls() # Parse scalars for prop in cls.properties_list: idx = header_map.get(prop.name) if idx is None and prop.name == 'ID': idx = header_map.get('FID') if idx is not None and 0 <= idx < len(parts): raw = parts[idx] val = prop.parse(raw) setattr(obj, prop.py_name, val) # Geometry pointers raw_ng = _dgs_get(parts, header_map, 'pGeo:SIZEROW') ng = int(float(raw_ng.replace(',', '.'))) if raw_ng is not None and raw_ng.strip() != '' else 0 obj.pGeo = list() for i in range(ng): raw_ptr = _dgs_get(parts, header_map, f'pGeo:{i}') raw_ptr = raw_ptr.strip() if raw_ptr is not None else '' obj.pGeo.append(raw_ptr if raw_ptr != '' and raw_ptr != '*' else None) # Circuit pointers (ElmLne) raw_nl = _dgs_get(parts, header_map, 'plines:SIZEROW') nl = int(float(raw_nl.replace(',', '.'))) if raw_nl is not None and raw_nl.strip() != '' else 0 obj.plines = list() for i in range(nl): raw_ptr = _dgs_get(parts, header_map, f'plines:{i}') raw_ptr = raw_ptr.strip() if raw_ptr is not None else '' obj.plines.append(raw_ptr if raw_ptr != '' and raw_ptr != '*' else None) # Polarity flags (optional) raw_np = _dgs_get(parts, header_map, 'dpolar:SIZEROW') np = int(float(raw_np.replace(',', '.'))) if raw_np is not None and raw_np.strip() != '' else 0 obj.dpolar = list() for i in range(np): raw_v = _dgs_get(parts, header_map, f'dpolar:{i}') raw_v = raw_v.strip() if raw_v is not None else '' obj.dpolar.append(float(raw_v.replace(',', '.')) if raw_v != '' and raw_v != '*' else 0.0) return obj