diff --git a/src/power_grid_model_io/config/excel/vision_en.yaml b/src/power_grid_model_io/config/excel/vision_en.yaml index 3b38835e..c3cc61ec 100644 --- a/src/power_grid_model_io/config/excel/vision_en.yaml +++ b/src/power_grid_model_io/config/excel/vision_en.yaml @@ -942,3 +942,4 @@ substitutions: Measuring side: 1: 0 2: 1 + 3: 2 diff --git a/src/power_grid_model_io/config/excel/vision_en_9_7.yaml b/src/power_grid_model_io/config/excel/vision_en_9_7.yaml index d8ad0a69..dd3f7ed4 100644 --- a/src/power_grid_model_io/config/excel/vision_en_9_7.yaml +++ b/src/power_grid_model_io/config/excel/vision_en_9_7.yaml @@ -937,6 +937,7 @@ substitutions: Measure side: 1: 0 2: 1 + 3: 2 At: FALSE: 0 TRUE: 1 diff --git a/src/power_grid_model_io/config/excel/vision_en_9_8.yaml b/src/power_grid_model_io/config/excel/vision_en_9_8.yaml new file mode 100644 index 00000000..52d7b531 --- /dev/null +++ b/src/power_grid_model_io/config/excel/vision_en_9_8.yaml @@ -0,0 +1,947 @@ +# SPDX-FileCopyrightText: Contributors to the Power Grid Model project +# +# SPDX-License-Identifier: MPL-2.0 +--- +id_reference: + nodes_table: Nodes + number: Number + node_number: Node.Number + sub_number: Subnumber +grid: + Nodes: + node: + id: + auto_id: + key: Number + u_rated: Unom + extra: + - ID + - Name + - GUID + Cables: + line: + id: + auto_id: + key: Number + from_node: + auto_id: + table: Nodes + key: + Number: From.Number + from_status: From.Switch state + to_node: + auto_id: + table: Nodes + key: + Number: To.Number + to_status: To.Switch state + r1: R + x1: X + c1: C + tan1: 0 + r0: + power_grid_model_io.functions.both_zeros_to_nan: + value: R0 + other_value: X0 + x0: + power_grid_model_io.functions.both_zeros_to_nan: + value: X0 + other_value: R0 + c0: C0 + tan0: 0 + i_n: Inom' + extra: + - ID + - Name + Lines: + line: + id: + auto_id: + key: Number + from_node: + auto_id: + table: Nodes + key: + Number: From.Number + from_status: From.Switch state + to_node: + auto_id: + table: Nodes + key: + Number: To.Number + to_status: To.Switch state + r1: R + x1: X + c1: C + tan1: 0 + r0: + power_grid_model_io.functions.both_zeros_to_nan: + value: R0 + other_value: X0 + x0: + power_grid_model_io.functions.both_zeros_to_nan: + value: X0 + other_value: R0 + c0: C0 + tan0: 0 + i_n: Inom' + extra: + - ID + - Name + Links: + link: + id: + auto_id: + key: Number + from_node: + auto_id: + table: Nodes + key: + Number: From.Number + from_status: From.Switch state + to_node: + auto_id: + table: Nodes + key: + Number: To.Number + to_status: To.Switch state + extra: + - ID + - Name + Reactance coils: + line: + id: + auto_id: + key: Number + from_node: + auto_id: + table: Nodes + key: + Number: From.Number + from_status: From.Switch state + to_node: + auto_id: + table: Nodes + key: + Number: To.Number + to_status: To.Switch state + r1: R + x1: X + c1: 0 + tan1: 0 + r0: + power_grid_model_io.functions.both_zeros_to_nan: + value: R0 + other_value: X0 + x0: + power_grid_model_io.functions.both_zeros_to_nan: + value: X0 + other_value: R0 + c0: 0 + tan0: 0 + i_n: Inom + extra: + - ID + - Name + Transformers: + transformer: + id: + auto_id: + key: Number + from_node: + auto_id: + table: Nodes + key: + Number: From.Number + from_status: From.Switch state + to_node: + auto_id: + table: Nodes + key: + Number: To.Number + to_status: To.Switch state + u1: Unom1 + u2: Unom2 + sn: Snom + uk: + max: + - divide: + - Pk + - Snom + - power_grid_model_io.functions.value_or_default: + value: uk + default: 0.001 + - 0.001 + pk: Pk + i0: + power_grid_model_io.functions.phase_to_phase.relative_no_load_current: + i_0: Io + p_0: Po + s_nom: Snom + u_nom: Unom2 + p0: Po + winding_from: + power_grid_model_io.functions.phase_to_phase.get_winding_from: + conn_str: Connection + neutral_grounding: Grounding1 + winding_to: + power_grid_model_io.functions.phase_to_phase.get_winding_to: + conn_str: Connection + neutral_grounding: Earthing2 + clock: + power_grid_model_io.functions.phase_to_phase.get_clock: + conn_str: Connection + tap_side: Tap side + tap_pos: Tap + tap_min: Tap min + tap_max: Tap max + tap_nom: Tap nom + tap_size: Tap size + uk_min: + max: + - divide: + - Pk + - Snom + - power_grid_model_io.functions.value_or_default: + value: uk + default: 0.001 + - 0.001 + uk_max: + max: + - divide: + - Pk + - Snom + - power_grid_model_io.functions.value_or_default: + value: uk + default: 0.001 + - 0.001 + pk_min: Pk + pk_max: Pk + r_grounding_from: Re1 + x_grounding_from: Xe1 + r_grounding_to: Re2 + x_grounding_to: Xe2 + extra: + - ID + - Name + transformer_tap_regulator: + id: + auto_id: + name: transformer_tap_regulator + key: Number + regulated_object: + auto_id: + key: + Number: Number + status: State + control_side: Measure side + u_set: Uset + u_band: Uband + line_drop_compensation_r: Rc + line_drop_compensation_x: Xc + extra: + - ID + - Name + filters: + - power_grid_model_io.functions.filters.exclude_value: + col: Own control + value: FALSE + Special transformers: + transformer: + id: + auto_id: + key: Number + from_node: + auto_id: + table: Nodes + key: + Number: From.Number + from_status: From.Switch state + to_node: + auto_id: + table: Nodes + key: + Number: To.Number + to_status: To.Switch state + u1: Unom1 + u2: Unom2 + sn: Snom + uk: + max: + - divide: + - Pknom + - Snom + - power_grid_model_io.functions.value_or_default: + value: uknom + default: 0.001 + - 0.001 + pk: Pknom + i0: + power_grid_model_io.functions.phase_to_phase.relative_no_load_current: + i_0: Io + p_0: Po + s_nom: Snom + u_nom: Unom2 + p0: Po + winding_from: 0 + winding_to: 0 + clock: 0 + tap_side: Tap side + tap_pos: Tap + tap_min: Tap min + tap_max: Tap max + tap_nom: Tap nom + tap_size: Tap size + uk_min: + max: + - divide: + - Pkmin + - Snom + - power_grid_model_io.functions.value_or_default: + value: ukmin + default: 0.001 + - 0.001 + uk_max: + max: + - divide: + - Pkmax + - Snom + - power_grid_model_io.functions.value_or_default: + value: ukmax + default: 0.001 + - 0.001 + pk_min: Pkmin + pk_max: Pkmax + r_grounding_from: 0 + x_grounding_from: 0 + r_grounding_to: 0 + x_grounding_to: 0 + extra: + - ID + - Name + transformer_tap_regulator: + id: + auto_id: + name: transformer_tap_regulator + key: Number + regulated_object: + auto_id: + key: + Number: Number + status: At + control_side: Measure side + u_set: Uset + u_band: Uband + line_drop_compensation_r: Rc + line_drop_compensation_x: Xc + extra: + - ID + - Name + filters: + - power_grid_model_io.functions.filters.exclude_value: + col: Control + value: FALSE + Transformer loads: + transformer: + id: + auto_id: + name: transformer + key: + - Node.Number + - Subnumber + from_node: + auto_id: + table: Nodes + key: + Number: Node.Number + to_node: + auto_id: + name: internal_node + key: + - Node.Number + - Subnumber + from_status: Switch state + to_status: 1 + u1: Unom1 + u2: Unom2 + sn: Snom + uk: + max: + - divide: + - Pk + - Snom + - power_grid_model_io.functions.value_or_default: + value: uk + default: 0.001 + - 0.001 + pk: Pk + p0: Po + i0: + power_grid_model_io.functions.phase_to_phase.relative_no_load_current: + i_0: 0 + p_0: Po + s_nom: Snom + u_nom: Unom2 + winding_from: + power_grid_model_io.functions.phase_to_phase.get_winding_from: + conn_str: Connection + winding_to: + power_grid_model_io.functions.phase_to_phase.get_winding_to: + conn_str: Connection + clock: + power_grid_model_io.functions.phase_to_phase.get_clock: + conn_str: Connection + tap_side: Tap side + tap_pos: Tap + tap_min: Tap min + tap_max: Tap max + tap_nom: Tap nom + tap_size: Tap size + uk_min: + max: + - divide: + - Pk + - Snom + - power_grid_model_io.functions.value_or_default: + value: uk + default: 0.001 + - 0.001 + uk_max: + max: + - divide: + - Pk + - Snom + - power_grid_model_io.functions.value_or_default: + value: uk + default: 0.001 + - 0.001 + pk_min: Pk + pk_max: Pk + r_grounding_from: 0 + x_grounding_from: 0 + r_grounding_to: 0 + x_grounding_to: 0 + extra: + - ID + - Name + node: + id: + auto_id: + name: internal_node + key: + - Node.Number + - Subnumber + u_rated: Unom2 + extra: + - ID + - Name + sym_load: + id: + auto_id: + name: load + key: + - Node.Number + - Subnumber + node: + auto_id: + name: internal_node + key: + - Node.Number + - Subnumber + status: Switch state + type: Load.Behaviour + p_specified: + multiply: + - Load.P + - reference: + query_column: Node.Number + other_table: Nodes + key_column: Number + value_column: Simultaneity + q_specified: + multiply: + - Load.Q + - reference: + query_column: Node.Number + other_table: Nodes + key_column: Number + value_column: Simultaneity + extra: + - ID + - Name + sym_gen: + - id: + auto_id: + name: generation + key: + - Node.Number + - Subnumber + node: + auto_id: + name: internal_node + key: + - Node.Number + - Subnumber + status: Switch state + type: 0 + p_specified: Generation.P + q_specified: Generation.Q + extra: + - ID + - Name + - id: + auto_id: + name: pv_generation + key: + - Node.Number + - Subnumber + node: + auto_id: + name: internal_node + key: + - Node.Number + - Subnumber + status: Switch state + type: 0 + p_specified: PV.Pnom + q_specified: + power_grid_model_io.functions.phase_to_phase.reactive_power: + p: PV.Pnom + cos_phi: 1 + extra: + - ID + - Name + Sources: + source: + id: + auto_id: + key: + - Node.Number + - Subnumber + node: + auto_id: + table: Nodes + key: + Number: Node.Number + status: Switch state + u_ref: Uref + sk: Sk"nom + rx_ratio: R/X + z01_ratio: Z0/Z1 + extra: + - ID + - Name + Synchronous generators: + sym_gen: + id: + auto_id: + key: + - Node.Number + - Subnumber + node: + auto_id: + table: Nodes + key: + Number: Node.Number + status: Switch state + type: 0 + p_specified: Pref + q_specified: + multiply: + - power_grid_model_io.functions.phase_to_phase.reactive_power: + p: Pref + cos_phi: cos phi + - Q + extra: + - ID + - Name + Wind turbines: + sym_gen: + id: + auto_id: + key: + - Node.Number + - Subnumber + node: + auto_id: + table: Nodes + key: + Number: Node.Number + status: Switch state + type: 0 + p_specified: + power_grid_model_io.functions.value_or_default: + value: Pref + default: + power_grid_model_io.functions.phase_to_phase.power_wind_speed: + p_nom: Pnom + wind_speed: Wind speed + q_specified: + power_grid_model_io.functions.phase_to_phase.reactive_power: + p: + power_grid_model_io.functions.value_or_default: + value: Pref + default: + power_grid_model_io.functions.phase_to_phase.power_wind_speed: + p_nom: Pnom + wind_speed: Wind speed + cos_phi: cos phi + extra: + - ID + - Name + Loads: + sym_load: + id: + auto_id: + key: + - Node.Number + - Subnumber + node: + auto_id: + table: Nodes + key: + Number: Node.Number + status: Switch state + type: Behaviour + p_specified: + multiply: + - P + - reference: + query_column: Node.Number + other_table: Nodes + key_column: Number + value_column: Simultaneity + q_specified: + multiply: + - Q + - reference: + query_column: Node.Number + other_table: Nodes + key_column: Number + value_column: Simultaneity + extra: + - ID + - Name + Earthing transformers: + shunt: + id: + auto_id: + key: Number + node: + auto_id: + table: Nodes + key: + Number: Node.Number + status: Switch state + g1: 0 + b1: 0 + g0: + power_grid_model_io.functions.complex_inverse_real_part: + real: R0 + imag: X0 + b0: + power_grid_model_io.functions.complex_inverse_imaginary_part: + real: R0 + imag: X0 + extra: + - ID + - Name + Shunt capacitors: + shunt: + id: + auto_id: + key: Number + node: + auto_id: + table: Nodes + key: + Number: Node.Number + status: Switch state + g1: 0 + b1: + power_grid_model_io.functions.phase_to_phase.reactive_power_to_susceptance: + q: Q + u_nom: Unom + g0: 0 + b0: 0 + extra: + - ID + - Name + Shunt reactors: + shunt: + id: + auto_id: + key: Number + node: + auto_id: + table: Nodes + key: + Number: Node.Number + status: Switch state + g1: 0 + b1: + multiply: + - power_grid_model_io.functions.phase_to_phase.reactive_power_to_susceptance: + q: Q + u_nom: Unom + - -1 + g0: 0 + b0: 0 + extra: + - ID + - Name + Pvs: + sym_gen: + id: + auto_id: + key: + - Node.Number + - Subnumber + node: + auto_id: + table: Nodes + key: + Number: Node.Number + status: Switch state + type: 0 + p_specified: + power_grid_model_io.functions.phase_to_phase.pvs_power_adjustment: + p: + multiply: + - min: + - Pnom + - Inverter.Pnom | Inverter.Snom + - Scaling + efficiency_type: Inverter.efficiency type + q_specified: + multiply: + - power_grid_model_io.functions.phase_to_phase.reactive_power: + p: + min: + - Pnom + - Inverter.Pnom | Inverter.Snom + cos_phi: Inverter.cos phi + - Scaling + extra: + - ID + - Name + Three winding transformers: + three_winding_transformer: + id: + auto_id: + key: Number + node_1: + auto_id: + table: Nodes + key: + Number: Node1.Number + status_1: Switch state 1 + node_2: + auto_id: + table: Nodes + key: + Number: Node2.Number + status_2: Switch state 2 + node_3: + auto_id: + table: Nodes + key: + Number: Node3.Number + status_3: Switch state 3 + u1: Unom1 + u2: Unom2 + u3: Unom3 + sn_1: Snom1 + sn_2: Snom2 + sn_3: Snom3 + uk_12: + max: + - divide: + - Pk12 + - min: + - Snom1 + - Snom2 + - power_grid_model_io.functions.value_or_default: + value: uk12 + default: 0.001 + - 0.001 + uk_13: + max: + - divide: + - Pk13 + - min: + - Snom1 + - Snom3 + - power_grid_model_io.functions.value_or_default: + value: uk13 + default: 0.001 + - 0.001 + uk_23: + max: + - divide: + - Pk23 + - min: + - Snom2 + - Snom3 + - power_grid_model_io.functions.value_or_default: + value: uk23 + default: 0.001 + - 0.001 + pk_12: Pk12 + pk_13: Pk13 + pk_23: Pk23 + i0: + power_grid_model_io.functions.phase_to_phase.relative_no_load_current: + i_0: Io + p_0: Po + s_nom: Snom3 + u_nom: Unom3 + p0: Po + winding_1: + power_grid_model_io.functions.phase_to_phase.get_winding_1: + conn_str: Connection + neutral_grounding: Grounding1 + winding_2: + power_grid_model_io.functions.phase_to_phase.get_winding_2: + conn_str: Connection + neutral_grounding: Earthing2 + winding_3: + power_grid_model_io.functions.phase_to_phase.get_winding_3: + conn_str: Connection + neutral_grounding: Grounding3 + clock_12: + power_grid_model_io.functions.phase_to_phase.get_clock_12: + conn_str: Connection + clock_13: + power_grid_model_io.functions.phase_to_phase.get_clock_13: + conn_str: Connection + tap_side: Tap side a + tap_pos: Tap a + tap_min: Tap min a + tap_max: Tap max a + tap_nom: Tap nom a + tap_size: Tap size a + r_grounding_1: Re1 + x_grounding_1: Xe1 + r_grounding_2: Re2 + x_grounding_2: Xe2 + r_grounding_3: Re3 + x_grounding_3: Xe3 + extra: + - ID + - Name + transformer_tap_regulator: + id: + auto_id: + name: transformer_tap_regulator + key: Number + regulated_object: + auto_id: + key: + Number: Number + status: 1 + control_side: Measure side + u_set: Uset + u_band: Uband + line_drop_compensation_r: Rc + line_drop_compensation_x: Xc + extra: + - ID + - Name + filters: + - power_grid_model_io.functions.filters.exclude_value: + col: Control + value: 0 +units: + A: null + F: + µF: 0.000_001 + V: + kV: 1_000.0 + VA: + kVA: 1_000.0 + MVA: 1_000_000.0 + VAR: + kvar: 1_000.0 + Mvar: 1_000_000.0 + W: + kW: 1_000.0 + MW: 1_000_000.0 + Wp: + kWp: 1_000.0 + MWp: 1_000_000.0 + m/s: null + ohm: + Ohm: 1.0 + ohm/m: + ohm/km: 0.001 + one: + pu: 1.0 + "%": 0.01 + "‰": 0.001 + +substitutions: + ".*Switch state": + "off": 0 + "in": 1 + "on": 1 + "Switch state .*": + "off": 0 + "in": 1 + "on": 1 + Grounding1: + 0: false + 1: true + none: false + own: true + Earthing2: + 0: false + 1: true + none: false + own: true + Grounding3: + 0: false + 1: true + none: false + own: true + Load.Behaviour: + Constant admittance: 1 + Constant impedance: 1 + ~Constant current: 2 + Constant power: 0 + Default: 0 + Industry: 0 + Business: 0 + Residential: 0 + Living: 0 + Behaviour: + Constant admittance: 1 + Constant impedance: 1 + ~Constant current: 2 + Constant power: 0 + Default: 0 + Industry: 0 + Business: 0 + Residential: 0 + Living: 0 + Tap side: + 1: 0 + 2: 1 + Tap side a: + 1: 0 + 2: 1 + 3: 2 + Tap side c: + 1: 0 + 2: 1 + 3: 2 + Synchronous generators.Q: + absorb: -1 + supply: 1 + Measure side: + 1: 0 + 2: 1 + 3: 2 + At: + FALSE: 0 + TRUE: 1 diff --git a/src/power_grid_model_io/config/excel/vision_nl.yaml b/src/power_grid_model_io/config/excel/vision_nl.yaml index 01f797e3..1cc89c7e 100644 --- a/src/power_grid_model_io/config/excel/vision_nl.yaml +++ b/src/power_grid_model_io/config/excel/vision_nl.yaml @@ -925,4 +925,5 @@ substitutions: leveren: 1 Meetzijde: 1: 0 - 2: 1 \ No newline at end of file + 2: 1 + 3: 2 \ No newline at end of file diff --git a/src/power_grid_model_io/functions/phase_to_phase.py b/src/power_grid_model_io/functions/phase_to_phase.py index f46da0a9..af1a7f05 100644 --- a/src/power_grid_model_io/functions/phase_to_phase.py +++ b/src/power_grid_model_io/functions/phase_to_phase.py @@ -90,7 +90,8 @@ def _get_clock_impl(conn_str: str) -> int: """ Extract the clock part of the conn_str """ - return int(trafo_connection_parser(conn_str)[clock_ref]) + + return int(trafo_connection_parser(conn_str)[clock_ref]) % 12 return _get_clock_impl diff --git a/src/power_grid_model_io/utils/parsing.py b/src/power_grid_model_io/utils/parsing.py index 9d7d3400..074241f8 100644 --- a/src/power_grid_model_io/utils/parsing.py +++ b/src/power_grid_model_io/utils/parsing.py @@ -8,7 +8,7 @@ import re from typing import Dict -_TRAFO_CONNECTION_RE = re.compile(r"^(Y|YN|D|Z|ZN)(y|yn|d|z|zn)(\d|1[0-2])?$") +_TRAFO_CONNECTION_RE = re.compile(r"^(Y|YN|D|Z|ZN)(y|yn|d|z|zn)(-?\d|1[0-2]|-1[0-2])?$") def parse_trafo_connection(string: str) -> Dict[str, str]: @@ -17,11 +17,11 @@ def parse_trafo_connection(string: str) -> Dict[str, str]: Matches the following regular expression to the winding_from and winding_to codes. Optionally checks the clock number: - ^ Start of the string - (Y|YN|D|Z|ZN) From winding type - (y|yn|d|z|zn) To winding type - (\d|1[0-2])? Optional clock number (0-12) - $ End of the string + ^ Start of the string + (Y|YN|D|Z|ZN) From winding type + (y|yn|d|z|zn) To winding type + (-?\d|1[0-2]|-1[0-2])? Optional clock number (-12-12) + $ End of the string Args: string (str): The input string. @@ -39,7 +39,9 @@ def parse_trafo_connection(string: str) -> Dict[str, str]: return {"winding_from": match.group(1), "winding_to": match.group(2), "clock": match.group(3)} -_TRAFO3_CONNECTION_RE = re.compile(r"^(Y|YN|D|Z|ZN)(y|yn|d|z|zn)(\d|1[0-2])?(y|yn|d|z|zn)(\d|1[0-2])?$") +_TRAFO3_CONNECTION_RE = re.compile( + r"^(Y|YN|D|Z|ZN)(y|yn|d|z|zn)(-?\d|1[0-2]|-1[0-2])?(y|yn|d|z|zn)(-?\d|1[0-2]|-1[0-2])?$" +) def parse_trafo3_connection(string: str) -> Dict[str, str]: @@ -48,13 +50,13 @@ def parse_trafo3_connection(string: str) -> Dict[str, str]: Matches the following regular expression to the winding_1, winding_2 and winding_3 codes. Optionally checks the clock numbers: - ^ Start of the string - (Y|YN|D|Z|ZN) First winding type - (y|yn|d|z|zn) Second winding type - (\d|1[0-2]) Clock number (0-12) - (y|yn|d|z|zn) Third winding type - (\d|1[0-2]) Clock number (0-12) - $ End of the string + ^ Start of the string + (Y|YN|D|Z|ZN) First winding type + (y|yn|d|z|zn) Second winding type + (-?\d|1[0-2]|-1[0-2]) Clock number (-12-12) + (y|yn|d|z|zn) Third winding type + (-?\d|1[0-2]|-1[0-2]) Clock number (-12-12) + $ End of the string Args: string (str): The input string. diff --git a/tests/unit/functions/test_phase_to_phase.py b/tests/unit/functions/test_phase_to_phase.py index a12e57f1..e1818942 100644 --- a/tests/unit/functions/test_phase_to_phase.py +++ b/tests/unit/functions/test_phase_to_phase.py @@ -179,14 +179,16 @@ def test_get_winding_to__exception(): [ ("YNd0", 0), ("YNyn5", 5), - ("YNd12", 12), + ("YNd12", 0), + ("Dyn-1", 11), + ("Dd-4", 8), ], ) def test_get_clock(code: str, clock: int): assert get_clock(code) == clock -@mark.parametrize("code", ["YNd-1", "YNd13"]) +@mark.parametrize("code", ["YNd-15", "YNd13"]) def test_get_clock__exception(code): with raises(ValueError): get_clock(code) @@ -344,7 +346,8 @@ def test_get_winding_3__exception(): [ ("YNd0y4", 0), ("YNyn5d3", 5), - ("YNd12d1", 12), + ("YNd12d1", 0), + ("YNd-5d1", 7), ], ) def test_get_clock_12(code: str, clock: int): @@ -363,6 +366,7 @@ def test_get_clock_12__exception(code): ("YNd0y4", 4), ("YNyn5d3", 3), ("YNd12d1", 1), + ("YNd12d-1", 11), ], ) def test_get_clock_13(code: str, clock: int): diff --git a/tests/unit/utils/test_parsing.py b/tests/unit/utils/test_parsing.py index e2c9ca13..268cbb2a 100644 --- a/tests/unit/utils/test_parsing.py +++ b/tests/unit/utils/test_parsing.py @@ -21,6 +21,7 @@ def test_parse_trafo_connection__pos(): assert parse_trafo_connection("YNy") == {"winding_from": "YN", "winding_to": "y", "clock": None} assert parse_trafo_connection("Dy5") == {"winding_from": "D", "winding_to": "y", "clock": "5"} assert parse_trafo_connection("Dy11") == {"winding_from": "D", "winding_to": "y", "clock": "11"} + assert parse_trafo_connection("Dyn-1") == {"winding_from": "D", "winding_to": "yn", "clock": "-1"} def test_parse_trafo_connection__neg(): @@ -34,8 +35,6 @@ def test_parse_trafo_connection__neg(): parse_trafo_connection("YNx") with pytest.raises(ValueError, match="Invalid transformer connection string: 'Dy13'"): parse_trafo_connection("Dy13") - with pytest.raises(ValueError, match="Invalid transformer connection string: 'Dy-1'"): - parse_trafo_connection("Dy-1") def test_parse_trafo3_connection__pos(): @@ -81,6 +80,13 @@ def test_parse_trafo3_connection__pos(): "winding_3": "d", "clock_13": "11", } + assert parse_trafo3_connection("Dyn-1yn-1") == { + "winding_1": "D", + "winding_2": "yn", + "clock_12": "-1", + "winding_3": "yn", + "clock_13": "-1", + } def test_parse_trafo3_connection__neg(): @@ -96,8 +102,6 @@ def test_parse_trafo3_connection__neg(): parse_trafo3_connection("Dyd13") with pytest.raises(ValueError, match="Invalid three winding transformer connection string: 'DyD10'"): parse_trafo3_connection("DyD10") - with pytest.raises(ValueError, match="Invalid three winding transformer connection string: 'Dynd-1'"): - parse_trafo3_connection("Dynd-1") with pytest.raises(ValueError, match=re.escape("Invalid three winding transformer connection string: 'Dyn+5d-1'")): parse_trafo3_connection("Dyn+5d-1") with pytest.raises(ValueError, match="Invalid three winding transformer connection string: 'Dy1d13'"):