From 763dc937637ad60ea6c1b49d4356f8807d248ed9 Mon Sep 17 00:00:00 2001 From: ngensoll Date: Tue, 14 Aug 2018 13:31:36 -0600 Subject: [PATCH 1/5] Change API to remove rated power and emergency power from windings --- ditto/models/powertransformer.py | 10 +++++++--- ditto/models/regulator.py | 5 +++++ ditto/models/winding.py | 8 -------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/ditto/models/powertransformer.py b/ditto/models/powertransformer.py index ff95e86f..79708269 100644 --- a/ditto/models/powertransformer.py +++ b/ditto/models/powertransformer.py @@ -11,9 +11,13 @@ class PowerTransformer(DiTToHasTraits): name = Unicode(help="""Name of the transformer object""", default_value="") - # Modification: Nicolas (August 2017) - # Moved the rated_power from the transformer down to the windings - # rated_power = Float(help='''The rated power of the entire transformer''', default_value=None) + rated_power = Float( + help="""The rated power of the entire transformer""", default_value=None + ) + + emergency_power = Float( + help="""The emergency power of the entire transformer""", default_value=None + ) install_type = Unicode( help="""The mounting type of the transformer: one of {POLETOP, PADMOUNT, VAULT}""", diff --git a/ditto/models/regulator.py b/ditto/models/regulator.py index 9c8d95fb..fbd5762d 100644 --- a/ditto/models/regulator.py +++ b/ditto/models/regulator.py @@ -10,6 +10,11 @@ class Regulator(DiTToHasTraits): name = Unicode(help="""Name of the regulator object""", default_value="") + rated_power = Float(help="""The rated power of the regulator""", default_value=None) + + emergency_power = Float( + help="""The emergency power of the regulator""", default_value=None + ) delay = Float( help="""The delay for first tap change operation""", default_value=None ) diff --git a/ditto/models/winding.py b/ditto/models/winding.py index a73e723a..02db3d7a 100644 --- a/ditto/models/winding.py +++ b/ditto/models/winding.py @@ -36,13 +36,5 @@ class Winding(DiTToHasTraits): default_value=None, ) - # Added by Nicolas (August 2017) - # Better results are obtained if the rated power is specified at the windings rather - # than for the whole transformer - rated_power = Float(help="""The rated power of the winding""", default_value=None) - emergency_power = Float( - help="""The emergency power of the winding""", default_value=None - ) - def build(self, model): self._model = model From e2bfc1fec82e24efcb7db1b7bfc21c279ab6ae15 Mon Sep 17 00:00:00 2001 From: ngensoll Date: Tue, 14 Aug 2018 13:32:46 -0600 Subject: [PATCH 2/5] Update tests to new API --- tests/test_writer.py | 338 +++++++++++++++++++++++++++++++++---------- 1 file changed, 259 insertions(+), 79 deletions(-) diff --git a/tests/test_writer.py b/tests/test_writer.py index 1684b031..b79e6f22 100644 --- a/tests/test_writer.py +++ b/tests/test_writer.py @@ -20,6 +20,7 @@ logger = logging.getLogger(__name__) + def test_cyme_writer(): from ditto.writers.cyme.write import Writer from ditto.models.node import Node @@ -38,26 +39,63 @@ def test_cyme_writer(): from ditto.models.feeder_metadata import Feeder_metadata m = Store() - src = PowerSource(m, name='f1_src', phases=[Unicode('A'),Unicode('B'),Unicode('C')], nominal_voltage=12470, connecting_element='n1') - meta = Feeder_metadata(m, name='f1', nominal_voltage=12470, headnode='f1_src', substation='f1_src') - node1 = Node(m, name='n1', feeder_name='f1') - node2 = Node(m, name='n2', feeder_name='f1') - node3 = Node(m, name='n3', feeder_name='f1') - wirea = Wire(m, gmr=1.3, X=2, Y = 20) - wiren = Wire(m, gmr=1.2, X=2, Y = 20) - line1 = Line(m, name='l1', wires=[wirea, wiren], from_element='n1', to_element='n2', feeder_name='f1') - load1 = Load(m, name='load1', p=5400, q=2615.3394, feeder_name='f1') - - phase_winding = PhaseWinding(m, phase=u'A') - winding1 = Winding(m, phase_windings=[phase_winding], connecting_element='n2', connection_type='Y', nominal_voltage=12.47, rated_power=25, resistance=10) - winding2 = Winding(m, phase_windings=[phase_winding], connecting_element='l1', connection_type='Y', nominal_voltage=6.16, rated_power=25, resistance=10) - transformer1 = PowerTransformer(m, name='t1', from_element='n2', to_element='n3', windings=[winding1, winding2], feeder_name='f1') + src = PowerSource( + m, + name="f1_src", + phases=[Unicode("A"), Unicode("B"), Unicode("C")], + nominal_voltage=12470, + connecting_element="n1", + ) + meta = Feeder_metadata( + m, name="f1", nominal_voltage=12470, headnode="f1_src", substation="f1_src" + ) + node1 = Node(m, name="n1", feeder_name="f1") + node2 = Node(m, name="n2", feeder_name="f1") + node3 = Node(m, name="n3", feeder_name="f1") + wirea = Wire(m, gmr=1.3, X=2, Y=20) + wiren = Wire(m, gmr=1.2, X=2, Y=20) + line1 = Line( + m, + name="l1", + wires=[wirea, wiren], + from_element="n1", + to_element="n2", + feeder_name="f1", + ) + load1 = Load(m, name="load1", p=5400, q=2615.3394, feeder_name="f1") + + phase_winding = PhaseWinding(m, phase=u"A") + winding1 = Winding( + m, + phase_windings=[phase_winding], + connecting_element="n2", + connection_type="Y", + nominal_voltage=12.47, + resistance=10, + ) + winding2 = Winding( + m, + phase_windings=[phase_winding], + connecting_element="l1", + connection_type="Y", + nominal_voltage=6.16, + resistance=10, + ) + transformer1 = PowerTransformer( + m, + name="t1", + from_element="n2", + to_element="n3", + rated_power=50, + windings=[winding1, winding2], + feeder_name="f1", + ) transformer1.reactances.append(6) - #reg1 = Regulator(m, name='t1_reg', connected_transformer='t1', connected_winding=2, pt_ratio=60, delay=2) - #cap1 = Capacitor(m, name='cap1', connecting_element='n2', num_phases=3, nominal_voltage=7.2, var=300, connection_type='Y') + # reg1 = Regulator(m, name='t1_reg', connected_transformer='t1', connected_winding=2, pt_ratio=60, delay=2) + # cap1 = Capacitor(m, name='cap1', connecting_element='n2', num_phases=3, nominal_voltage=7.2, var=300, connection_type='Y') m.set_names() t = tempfile.TemporaryDirectory() - writer = Writer(output_path=t.name, log_path='./') + writer = Writer(output_path=t.name, log_path="./") writer.write(m) @@ -71,7 +109,8 @@ def test_opendss_writer(): from ditto.models.capacitor import Capacitor from ditto.models.powertransformer import PowerTransformer from ditto.models.winding import Winding - #from ditto.model import Model + + # from ditto.model import Model from ditto.store import Store from ditto.models.storage import Storage from ditto.models.phase_storage import PhaseStorage @@ -81,39 +120,105 @@ def test_opendss_writer(): from ditto.models.phase_load import PhaseLoad m = Store() - node1 = Node(m, name='n1') - node2 = Node(m, name='n2') - node3 = Node(m, name='n3') - wirea = Wire(m, gmr=1.3, X=2, Y = 20) - wiren = Wire(m, gmr=1.2, X=2, Y = 20) - line1 = Line(m, name='l1', wires=[wirea, wiren]) - phase_load1= PhaseLoad(m,p=5400, q=2615.3394) - load1 = Load(m, name='load1', phase_loads=[phase_load1]) - - winding1 = Winding(m, connecting_element='n2', connection_type='W', num_phases=3, nominal_voltage=12.47, rated_power=25, tap_percentage=1) - winding2 = Winding(m, connecting_element='l1', connection_type='W', num_phases=3, nominal_voltage=6.16, rated_power=25, tap_percentage=1.2) - transformer1 = PowerTransformer(m, name='t1', from_element='n2', to_element='n3', windings=[winding1, winding2], feeder_name='f1') + node1 = Node(m, name="n1") + node2 = Node(m, name="n2") + node3 = Node(m, name="n3") + wirea = Wire(m, gmr=1.3, X=2, Y=20) + wiren = Wire(m, gmr=1.2, X=2, Y=20) + line1 = Line(m, name="l1", wires=[wirea, wiren]) + phase_load1 = PhaseLoad(m, p=5400, q=2615.3394) + load1 = Load(m, name="load1", phase_loads=[phase_load1]) + + winding1 = Winding( + m, + connecting_element="n2", + connection_type="W", + num_phases=3, + nominal_voltage=12.47, + tap_percentage=1, + ) + winding2 = Winding( + m, + connecting_element="l1", + connection_type="W", + num_phases=3, + nominal_voltage=6.16, + tap_percentage=1.2, + ) + transformer1 = PowerTransformer( + m, + name="t1", + from_element="n2", + to_element="n3", + rated_power=50, + windings=[winding1, winding2], + feeder_name="f1", + ) transformer1.reactances.append(6) - reg1 = Regulator(m, name='t1_reg', connected_transformer='t1', connected_winding=2, pt_ratio=60, delay=2) - cap1 = Capacitor(m, name='cap1', connecting_element='n2', num_phases=3, nominal_voltage=7.2, var=300, connection_type='Y') + reg1 = Regulator( + m, + name="t1_reg", + connected_transformer="t1", + connected_winding=2, + pt_ratio=60, + delay=2, + ) + cap1 = Capacitor( + m, + name="cap1", + connecting_element="n2", + num_phases=3, + nominal_voltage=7.2, + var=300, + connection_type="Y", + ) print(line1.impedance_matrix) - #Storage testing - phase_storage_A = PhaseStorage(m, phase='A', p=15.0, q=5.0) - phase_storage_B = PhaseStorage(m, phase='B', p=16.0, q=6.0) - storage = Storage(m, name='store1', connecting_element='n3', nominal_voltage=12470.0, rated_power=10000.0, rated_kWh=100.0, stored_kWh=75.5, - reserve=20.0, discharge_rate=25.0, charge_rate=18.7, charging_efficiency=15.3, discharging_efficiency=22.0, resistance=20, - reactance=10, model_=1, phase_storages=[phase_storage_A, phase_storage_B] ) + # Storage testing + phase_storage_A = PhaseStorage(m, phase="A", p=15.0, q=5.0) + phase_storage_B = PhaseStorage(m, phase="B", p=16.0, q=6.0) + storage = Storage( + m, + name="store1", + connecting_element="n3", + nominal_voltage=12470.0, + rated_power=10000.0, + rated_kWh=100.0, + stored_kWh=75.5, + reserve=20.0, + discharge_rate=25.0, + charge_rate=18.7, + charging_efficiency=15.3, + discharging_efficiency=22.0, + resistance=20, + reactance=10, + model_=1, + phase_storages=[phase_storage_A, phase_storage_B], + ) - #PV systems testing - PV_system = PowerSource(m, name='PV1', is_sourcebus=0, nominal_voltage=12470, phases=[Unicode('A'),Unicode('C')], rated_power=20000.0, connection_type='D', - cutout_percent=30.0, cutin_percent=15.3, resistance=14.0, reactance=5.2, v_max_pu=100, v_min_pu=60, power_factor=.9) + # PV systems testing + PV_system = PowerSource( + m, + name="PV1", + is_sourcebus=0, + nominal_voltage=12470, + phases=[Unicode("A"), Unicode("C")], + rated_power=20000.0, + connection_type="D", + cutout_percent=30.0, + cutin_percent=15.3, + resistance=14.0, + reactance=5.2, + v_max_pu=100, + v_min_pu=60, + power_factor=.9, + ) t = tempfile.TemporaryDirectory() writer = Writer(output_path=t.name) - #writer.write_wiredata(m) - #writer.write_linegeometry(m) - #writer.write_linecodes(m) + # writer.write_wiredata(m) + # writer.write_linegeometry(m) + # writer.write_linecodes(m) writer.write_storages(m) writer.write_PVs(m) writer.write_lines(m) @@ -122,6 +227,7 @@ def test_opendss_writer(): writer.write_regulators(m) writer.write_capacitors(m) + def test_gridlabd_writer(): from ditto.writers.gridlabd.write import Writer from ditto.models.node import Node @@ -140,26 +246,63 @@ def test_gridlabd_writer(): from ditto.models.feeder_metadata import Feeder_metadata m = Store() - src = PowerSource(m, name='f1_src', phases=[Unicode('A'),Unicode('B'),Unicode('C')], nominal_voltage=12470, connecting_element='n1') - meta = Feeder_metadata(m, name='f1', nominal_voltage=12470, headnode='f1_src', substation='f1_src') - node1 = Node(m, name='n1', feeder_name='f1') - node2 = Node(m, name='n2', feeder_name='f1') - node3 = Node(m, name='n3', feeder_name='f1') - wirea = Wire(m, gmr=1.3, X=2, Y = 20) - wiren = Wire(m, gmr=1.2, X=2, Y = 20) - line1 = Line(m, name='l1', wires=[wirea, wiren], from_element='n1', to_element='n2', feeder_name='f1') - load1 = Load(m, name='load1', p=5400, q=2615.3394, feeder_name='f1') - - phase_winding = PhaseWinding(m, phase=u'A') - winding1 = Winding(m, phase_windings=[phase_winding], connecting_element='n2', connection_type='Y', nominal_voltage=12.47, rated_power=25, resistance=10) - winding2 = Winding(m, phase_windings=[phase_winding], connecting_element='l1', connection_type='Y', nominal_voltage=6.16, rated_power=25, resistance=10) - transformer1 = PowerTransformer(m, name='t1', from_element='n2', to_element='n3', windings=[winding1, winding2], feeder_name='f1') + src = PowerSource( + m, + name="f1_src", + phases=[Unicode("A"), Unicode("B"), Unicode("C")], + nominal_voltage=12470, + connecting_element="n1", + ) + meta = Feeder_metadata( + m, name="f1", nominal_voltage=12470, headnode="f1_src", substation="f1_src" + ) + node1 = Node(m, name="n1", feeder_name="f1") + node2 = Node(m, name="n2", feeder_name="f1") + node3 = Node(m, name="n3", feeder_name="f1") + wirea = Wire(m, gmr=1.3, X=2, Y=20) + wiren = Wire(m, gmr=1.2, X=2, Y=20) + line1 = Line( + m, + name="l1", + wires=[wirea, wiren], + from_element="n1", + to_element="n2", + feeder_name="f1", + ) + load1 = Load(m, name="load1", p=5400, q=2615.3394, feeder_name="f1") + + phase_winding = PhaseWinding(m, phase=u"A") + winding1 = Winding( + m, + phase_windings=[phase_winding], + connecting_element="n2", + connection_type="Y", + nominal_voltage=12.47, + resistance=10, + ) + winding2 = Winding( + m, + phase_windings=[phase_winding], + connecting_element="l1", + connection_type="Y", + nominal_voltage=6.16, + resistance=10, + ) + transformer1 = PowerTransformer( + m, + name="t1", + from_element="n2", + to_element="n3", + rated_power=50, + windings=[winding1, winding2], + feeder_name="f1", + ) transformer1.reactances.append(6) - #reg1 = Regulator(m, name='t1_reg', connected_transformer='t1', connected_winding=2, pt_ratio=60, delay=2) - #cap1 = Capacitor(m, name='cap1', connecting_element='n2', num_phases=3, nominal_voltage=7.2, var=300, connection_type='Y') + # reg1 = Regulator(m, name='t1_reg', connected_transformer='t1', connected_winding=2, pt_ratio=60, delay=2) + # cap1 = Capacitor(m, name='cap1', connecting_element='n2', num_phases=3, nominal_voltage=7.2, var=300, connection_type='Y') m.set_names() t = tempfile.TemporaryDirectory() - writer = Writer(output_path=t.name, log_path='./') + writer = Writer(output_path=t.name, log_path="./") writer.write(m) @@ -180,25 +323,62 @@ def test_ephasor_writer(): from ditto.models.feeder_metadata import Feeder_metadata m = Store() - src = PowerSource(m, name='f1_src', phases=[Unicode('A'),Unicode('B'),Unicode('C')], nominal_voltage=12470, connecting_element='n1') - meta = Feeder_metadata(m, name='f1', nominal_voltage=12470, headnode='f1_src', substation='f1_src') - node1 = Node(m, name='n1', feeder_name='f1') - node2 = Node(m, name='n2', feeder_name='f1') - node3 = Node(m, name='n3', feeder_name='f1') - wirea = Wire(m, gmr=1.3, X=2, Y = 20) - wiren = Wire(m, gmr=1.2, X=2, Y = 20) - line1 = Line(m, name='l1', wires=[wirea, wiren], from_element='n1', to_element='n2', feeder_name='f1') - load1 = Load(m, name='load1', p=5400, q=2615.3394, feeder_name='f1') - - phase_winding = PhaseWinding(m, phase=u'A') - - winding1 = Winding(m, phase_windings=[phase_winding], connecting_element='n2', connection_type='Y', nominal_voltage=12.47, rated_power=25, resistance=10) - winding2 = Winding(m, phase_windings=[phase_winding], connecting_element='l1', connection_type='Y', nominal_voltage=6.16, rated_power=25, resistance=10) - transformer1 = PowerTransformer(m, name='t1', from_element='n2', to_element='n3', windings=[winding1, winding2], feeder_name='f1') + src = PowerSource( + m, + name="f1_src", + phases=[Unicode("A"), Unicode("B"), Unicode("C")], + nominal_voltage=12470, + connecting_element="n1", + ) + meta = Feeder_metadata( + m, name="f1", nominal_voltage=12470, headnode="f1_src", substation="f1_src" + ) + node1 = Node(m, name="n1", feeder_name="f1") + node2 = Node(m, name="n2", feeder_name="f1") + node3 = Node(m, name="n3", feeder_name="f1") + wirea = Wire(m, gmr=1.3, X=2, Y=20) + wiren = Wire(m, gmr=1.2, X=2, Y=20) + line1 = Line( + m, + name="l1", + wires=[wirea, wiren], + from_element="n1", + to_element="n2", + feeder_name="f1", + ) + load1 = Load(m, name="load1", p=5400, q=2615.3394, feeder_name="f1") + + phase_winding = PhaseWinding(m, phase=u"A") + + winding1 = Winding( + m, + phase_windings=[phase_winding], + connecting_element="n2", + connection_type="Y", + nominal_voltage=12.47, + resistance=10, + ) + winding2 = Winding( + m, + phase_windings=[phase_winding], + connecting_element="l1", + connection_type="Y", + nominal_voltage=6.16, + resistance=10, + ) + transformer1 = PowerTransformer( + m, + name="t1", + from_element="n2", + to_element="n3", + rated_power=50, + windings=[winding1, winding2], + feeder_name="f1", + ) transformer1.reactances.append(6) - #reg1 = Regulator(m, name='t1_reg', connected_transformer='t1', connected_winding=2, pt_ratio=60, delay=2) - #cap1 = Capacitor(m, name='cap1', connecting_element='n2', num_phases=3, nominal_voltage=7.2, var=300, connection_type='Y') + # reg1 = Regulator(m, name='t1_reg', connected_transformer='t1', connected_winding=2, pt_ratio=60, delay=2) + # cap1 = Capacitor(m, name='cap1', connecting_element='n2', num_phases=3, nominal_voltage=7.2, var=300, connection_type='Y') m.set_names() t = tempfile.TemporaryDirectory() - writer = Writer(output_path=t.name, log_path='./') + writer = Writer(output_path=t.name, log_path="./") writer.write(m) From 3cf92254a45f314293460f8a74d29470d1d0c580 Mon Sep 17 00:00:00 2001 From: ngensoll Date: Tue, 14 Aug 2018 13:38:16 -0600 Subject: [PATCH 3/5] Update writers to new API --- ditto/writers/cyme/write.py | 98 ++++++++++++--------------------- ditto/writers/ephasor/write.py | 10 ++-- ditto/writers/gridlabd/write.py | 8 +-- ditto/writers/json/write.py | 6 +- ditto/writers/opendss/write.py | 89 +++++++----------------------- 5 files changed, 66 insertions(+), 145 deletions(-) diff --git a/ditto/writers/cyme/write.py b/ditto/writers/cyme/write.py index 3f42b134..98ac0038 100644 --- a/ditto/writers/cyme/write.py +++ b/ditto/writers/cyme/write.py @@ -1755,13 +1755,13 @@ def write_network_file(self, model, **kwargs): RH = ( winding1.resistance * 10 ** -2 - * winding1.rated_power + * i.rated_power * 10 ** -3 ) RL = ( winding2.resistance * 10 ** -2 - * winding2.rated_power + * i.rated_power * 10 ** -3 ) except: @@ -1790,19 +1790,16 @@ def write_network_file(self, model, **kwargs): # # Expressed in percentage of the KVA base try: - Z1 = _ZHL_ * 100.0 / (winding1.rated_power * 10 ** -3) + Z1 = _ZHL_ * 100.0 / (i.rated_power * 10 ** -3) except: Z1 = 0 pass Z0 = Z1 # Total kva - KVA = 0 + KVA = i.rated_power * 10 ** -3 # DiTTo in var + for w, winding in enumerate(windings_local): - try: - KVA += winding.rated_power * 10 ** -3 - except: - pass if hasattr(winding, "nominal_voltage"): try: @@ -1944,17 +1941,14 @@ def write_network_file(self, model, **kwargs): else: new_regulator_string += "," - _KVA = 0 + _KVA = i.rated_power * 10 ** -3 # DiTTo in var + _KVLN = 0 _Rset = {"A": 0, "B": 0, "C": 0} _Xset = {"A": 0, "B": 0, "C": 0} if len(windings_local) >= 2: - for winding in windings_local: - try: - _KVA += winding.rated_power * 10 ** -3 - except: - pass - _KVLN = winding.nominal_voltage * 10 ** -3 + + _KVLN = windings_local[0].nominal_voltage * 10 ** -3 if ( hasattr(winding1, "phase_windings") @@ -2343,8 +2337,7 @@ def write_network_file(self, model, **kwargs): for w in transformer_object.windings ] KVA_BASE = ( - transformer_object.windings[0].rated_power - * 10 ** -3 + transformer_object.rated_power * 10 ** -3 ) XR, Z1 = self.get_center_tap_impedances( R0, R1, R2, XHL, XHT, XLT, KVA_BASE @@ -2364,7 +2357,7 @@ def write_network_file(self, model, **kwargs): XHL = ( XHL_perct * 10 ** -2 - * transformer_object.windings[0].rated_power + * transformer_object.rated_power * 10 ** -3 ) except: @@ -2388,13 +2381,13 @@ def write_network_file(self, model, **kwargs): RH = ( transformer_object.windings[0].resistance * 10 ** -2 - * transformer_object.windings[0].rated_power + * transformer_object.rated_power * 10 ** -3 ) RL = ( transformer_object.windings[1].resistance * 10 ** -2 - * transformer_object.windings[1].rated_power + * transformer_object.rated_power * 10 ** -3 ) except: @@ -2426,10 +2419,7 @@ def write_network_file(self, model, **kwargs): Z1 = ( _ZHL_ * 100.0 - / ( - transformer_object.windings[0].rated_power - * 10 ** -3 - ) + / (transformer_object.rated_power * 10 ** -3) ) except: Z1 = 0 @@ -2438,10 +2428,7 @@ def write_network_file(self, model, **kwargs): # Total kva try: - KVA = ( - transformer_object.windings[0].rated_power - * 10 ** -3 - ) + KVA = transformer_object.rated_power * 10 ** -3 except: KVA = "DEFAULT" pass @@ -2636,9 +2623,19 @@ def write_network_file(self, model, **kwargs): new_transformer_line += ",," pass - _primary_rated_capacity = None - _secondary_rated_capacity = None - _tertiary_rated_capacity = None + # NOTE: This is probably the only case where moving back the kva to the transformer + # might result in information losses. Assuming kva is evenly distributed here... + # + _primary_rated_capacity = str( + 1.0 / 3.0 * transformer_object.rated_power * 10 ** -3 + ) + _secondary_rated_capacity = str( + 1.0 / 3.0 * transformer_object.rated_power * 10 ** -3 + ) + _tertiary_rated_capacity = str( + 1.0 / 3.0 * transformer_object.rated_power * 10 ** -3 + ) + _primary_voltage = None _secondary_voltage = None _tertiary_voltage = None @@ -2648,22 +2645,6 @@ def write_network_file(self, model, **kwargs): R = {} XHL_perct, XLT_perct, XHT_perct = None, None, None for w, winding in enumerate(transformer_object.windings): - if ( - hasattr(winding, "rated_power") - and winding.rated_power is not None - ): - if w == 0: - _primary_rated_capacity = str( - winding.rated_power * 10 ** -3 - ) - if w == 1: - _secondary_rated_capacity = str( - winding.rated_power * 10 ** -3 - ) - if w == 2: - _tertiary_rated_capacity = str( - winding.rated_power * 10 ** -3 - ) if ( hasattr(winding, "connection_type") @@ -2710,7 +2691,7 @@ def write_network_file(self, model, **kwargs): try: R[w] = ( winding.resistance - * winding.rated_power + * transformer_object.rated_power * 10 ** -3 ) except: @@ -2731,7 +2712,7 @@ def write_network_file(self, model, **kwargs): XHL = ( XHL_perct * 10 ** -2 - * transformer_object.windings[0].rated_power + * transformer_object.rated_power * 10 ** -3 ) except: @@ -2742,7 +2723,7 @@ def write_network_file(self, model, **kwargs): XLT = ( XLT_perct * 10 ** -2 - * transformer_object.windings[0].rated_power + * transformer_object.rated_power * 10 ** -3 ) except: @@ -2753,7 +2734,7 @@ def write_network_file(self, model, **kwargs): XHT = ( XHT_perct * 10 ** -2 - * transformer_object.windings[0].rated_power + * transformer_object.rated_power * 10 ** -3 ) except: @@ -2782,30 +2763,21 @@ def write_network_file(self, model, **kwargs): _PrimaryToSecondaryZ1 = ( math.sqrt(ZHL.real ** 2 + ZHL.imag ** 2) * 100.0 - / ( - transformer_object.windings[0].rated_power - * 10 ** -3 - ) + / (transformer_object.rated_power * 10 ** -3) ) _PrimaryToSecondaryZ0 = _PrimaryToSecondaryZ1 _PrimaryToTertiaryZ1 = ( math.sqrt(ZHT.real ** 2 + ZHT.imag ** 2) * 100.0 - / ( - transformer_object.windings[0].rated_power - * 10 ** -3 - ) + / (transformer_object.rated_power * 10 ** -3) ) _PrimaryToTertiaryZ0 = _PrimaryToTertiaryZ1 _SecondaryToTertiaryZ1 = ( math.sqrt(ZLT.real ** 2 + ZLT.imag ** 2) * 100.0 - / ( - transformer_object.windings[0].rated_power - * 10 ** -3 - ) + / (transformer_object.rated_power * 10 ** -3) ) _SecondaryToTertiaryZ0 = _SecondaryToTertiaryZ1 diff --git a/ditto/writers/ephasor/write.py b/ditto/writers/ephasor/write.py index 1744e436..15b4c11c 100644 --- a/ditto/writers/ephasor/write.py +++ b/ditto/writers/ephasor/write.py @@ -591,9 +591,9 @@ def transformer(self): self._transformer_dict[i.from_element]["kv1"] += i.windings[ 0 ].nominal_voltage - self._transformer_dict[i.from_element]["kva"] += i.windings[ - 0 - ].rated_power + self._transformer_dict[i.from_element][ + "kva" + ] += i.rated_power # Units?? self._transformer_dict[i.from_element]["Tap " + pp] = ( i.windings[0].phase_windings[0].tap_position, ) @@ -608,7 +608,7 @@ def transformer(self): "i": index, "kv1": i.windings[0].nominal_voltage, "Tap " + pp: i.windings[0].phase_windings[0].tap_position, - "kva": i.windings[0].rated_power, + "kva": i.rated_power, # Units?? } else: for key, value in obj_dict.items(): @@ -671,7 +671,7 @@ def transformer(self): else: obj_dict["W" + str(winding_num + 1) + "S_base (kVA)"][ index - ] = (winding.rated_power / 1000) + ] = (i.rated_power / 1000) obj_dict["W" + str(winding_num + 1) + "V (kV)"][index] = ( winding.nominal_voltage / 1000 ) diff --git a/ditto/writers/gridlabd/write.py b/ditto/writers/gridlabd/write.py index 023ef9bf..cbbbd3a1 100644 --- a/ditto/writers/gridlabd/write.py +++ b/ditto/writers/gridlabd/write.py @@ -393,6 +393,8 @@ def write_transformer_configurations(self, model, fp): dic["install_type"] = i.install_type if hasattr(i, "noload_loss") and i.noload_loss is not None: dic["no_load_loss"] = i.noload_loss + if hasattr(i, "rated_power") and i.rated_power is not None: + dic["power_rating"] = i.rated_power * 10 ** -3 # DiTTo in var n_windings = 0 if ( @@ -457,12 +459,6 @@ def write_transformer_configurations(self, model, fp): else: dic["secondary_voltage"] = winding2.nominal_voltage - if ( - hasattr(winding1, "rated_power") - and winding1.rated_power is not None - ): - dic["power_rating"] = winding1.rated_power / 1000.0 - n_windings = len(i.windings) else: logger.debug("Warning - No windings included in the transformer") diff --git a/ditto/writers/json/write.py b/ditto/writers/json/write.py index 3f8e6de6..f835962e 100644 --- a/ditto/writers/json/write.py +++ b/ditto/writers/json/write.py @@ -47,9 +47,9 @@ class Writer(AbstractWriter): }, 'windings':{'klass':'list', 'value':[{'klass':'Winding', - 'rated_power':{'klass':'float', - 'value':'1000' - } + 'nominal_voltage':{'klass':'float', + 'value':'12470' + } 'phase_windings':{'klass':'list', 'value':[{'klass':'PhaseWinding', 'phase':{'klass':'Unicode', diff --git a/ditto/writers/opendss/write.py b/ditto/writers/opendss/write.py index 296b8367..df62bc3c 100644 --- a/ditto/writers/opendss/write.py +++ b/ditto/writers/opendss/write.py @@ -481,13 +481,14 @@ def write_transformers(self, model): buses = None # Rated power - # if hasattr(i, 'rated_power') and i.rated_power is not None: - # fp.write(' kva='+str(i.rated_power*10**-3)) #OpenDSS in kWatts + if hasattr(i, "rated_power") and i.rated_power is not None: + txt += " kva={}".format(i.rated_power * 10 ** -3) # DiTTo in var # Emergency power - # Emergency_power removed from powerTransformers and added to windings by Tarek - # if hasattr(i, 'emergency_power') and i.emergency_power is not None: - # fp.write(' EmergHKVA='+str(i.emergency_power*10**-3)) #OpenDSS in kWatts + if hasattr(i, "emergency_power") and i.emergency_power is not None: + txt += " EmergHKVA={}".format( + i.emergency_power * 10 ** -3 + ) # DiTTo in var # Loadloss if hasattr(i, "loadloss") and i.loadloss is not None: @@ -585,25 +586,6 @@ def write_transformers(self, model): ) # OpenDSS in kvolts self._baseKV_.add(winding.nominal_voltage * 10 ** -3) - # rated power - if ( - hasattr(winding, "rated_power") - and winding.rated_power is not None - ): - txt += " kva={kva}".format( - kva=winding.rated_power * 10 ** -3 - ) - - # emergency_power - # Was added to windings by Tarek - if ( - hasattr(winding, "emergency_power") - and winding.emergency_power is not None - ): - txt += " EmergHKVA={}".format( - winding.emergency_power * 10 ** -3 - ) # OpenDSS in kWatts - # resistance if ( hasattr(winding, "resistance") @@ -744,25 +726,6 @@ def write_transformers(self, model): ) # OpenDSS in kvolts self._baseKV_.add(winding.nominal_voltage * 10 ** -3) - # rated power - if ( - hasattr(winding, "rated_power") - and winding.rated_power is not None - ): - txt += " kva={kva}".format( - kva=winding.rated_power * 10 ** -3 - ) - - # emergency_power - # Was added to windings by Tarek - if ( - hasattr(winding, "emergency_power") - and winding.emergency_power is not None - ): - txt += " EmergHKVA={}".format( - winding.emergency_power * 10 ** -3 - ) # OpenDSS in kWatts - # Tap position if ( self.write_taps @@ -1682,6 +1645,21 @@ def write_regulators(self, model): conns += ")" transfo_creation_string += conns + # kva + if hasattr(i, "rated_power") and i.rated_power is not None: + transfo_creation_string += " kva={}".format( + i.rated_power * 10 ** -3 + ) + + # emergency power + if ( + hasattr(i, "emergency_power") + and i.emergency_power is not None + ): + transfo_creation_string += " EmerghKVA={}".format( + i.emergency_power * 10 ** -3 + ) + # kvs if hasattr(i, "windings") and i.windings is not None: kvs = " kvs=(" @@ -1693,31 +1671,6 @@ def write_regulators(self, model): kvs += ")" transfo_creation_string += kvs - # kvas - if hasattr(i, "windings") and i.windings is not None: - kvas = " kvas=(" - for w, winding in enumerate(i.windings): - if ( - hasattr(i.windings[w], "rated_power") - and i.windings[w].rated_power is not None - ): - kvas += ( - str(i.windings[w].rated_power * 10 ** -3) + ", " - ) - kvas = kvas[:-2] - kvas += ")" - transfo_creation_string += kvas - - # emergency_power - if hasattr(i, "windings") and i.windings is not None: - if ( - hasattr(i.windings[0], "emergency_power") - and i.windings[0].emergency_power is not None - ): - transfo_creation_string += " EmerghKVA={}".format( - i.windings[0].emergency_power - ) - # reactances: if hasattr(i, "reactances") and i.reactances is not None: # XHL: From f9aa0cb389d45bf91643fe60b7526898e2d49c85 Mon Sep 17 00:00:00 2001 From: ngensoll Date: Tue, 14 Aug 2018 13:42:42 -0600 Subject: [PATCH 4/5] Update readers to the new API --- ditto/readers/cyme/read.py | 82 ++++++++++++++-------------------- ditto/readers/gridlabd/read.py | 81 +++++++++++++++++---------------- ditto/readers/json/read.py | 10 ++--- ditto/readers/opendss/read.py | 62 +++++++++---------------- ditto/readers/synergi/read.py | 42 +++++++---------- 5 files changed, 113 insertions(+), 164 deletions(-) diff --git a/ditto/readers/cyme/read.py b/ditto/readers/cyme/read.py index b77fefba..d6455a1d 100644 --- a/ditto/readers/cyme/read.py +++ b/ditto/readers/cyme/read.py @@ -4383,21 +4383,24 @@ def parse_transformers(self, model): pass # Set the rated power - try: - if w == 0: - api_winding.rated_power = ( - float(settings["primaryratedcapacity"]) * 10 ** 3 - ) # DiTTo in volt ampere - if w == 1: - api_winding.rated_power = ( - float(settings["secondaryratedcapacity"]) * 10 ** 3 - ) # DiTTo in volt ampere - if w == 2: - api_winding.rated_power = ( - float(settings["tertiaryratedcapacity"]) * 10 ** 3 - ) # DiTTo in volt ampere - except: - pass + total_kva = 0 + if ( + "primaryratedcapacity" in settings + and settings["primaryratedcapacity"] is not None + ): + total_kva += float(settings["primaryratedcapacity"]) + if ( + "secondaryratedcapacity" in settings + and settings["secondaryratedcapacity"] is not None + ): + total_kva += float(settings["secondaryratedcapacity"]) + if ( + "tertiaryratedcapacity" in settings + and settings["tertiaryratedcapacity"] is not None + ): + total_kva += float(settings["tertiaryratedcapacity"]) + total_kva *= 10 ** 3 # DiTTo in var + api_transformer.rated_power = total_kva # Create the phase windings for p in phases: @@ -4522,6 +4525,11 @@ def parse_transformers(self, model): except: pass + # Set the rated power + api_transformer.rated_power = ( + float(transformer_data["kva"]) * 10 ** 3 + ) # DiTTo in var + # Here we know that we have two windings... for w in range(2): @@ -4531,19 +4539,6 @@ def parse_transformers(self, model): except: raise ValueError("Unable to instanciate Winding DiTTo object.") - # Set the rated power - try: - if w == 0: - api_winding.rated_power = ( - float(transformer_data["kva"]) * 10 ** 3 - ) # DiTTo in volt ampere - if w == 1: - api_winding.rated_power = ( - float(transformer_data["kva"]) * 10 ** 3 - ) # DiTTo in volt ampere - except: - pass - # Set the nominal voltage try: if w == 0: @@ -4604,6 +4599,11 @@ def parse_transformers(self, model): else: transformer_data = {} + # Set the rated power + api_transformer.rated_power = ( + float(transformer_data["ratedcapacity"]) * 10 ** 3 + ) # DiTTo in var + # Here we know that we have two windings... for w in range(2): @@ -4613,19 +4613,6 @@ def parse_transformers(self, model): except: raise ValueError("Unable to instanciate Winding DiTTo object.") - # Set the rated power - try: - if w == 0: - api_winding.rated_power = ( - float(transformer_data["ratedcapacity"]) * 10 ** 3 - ) # DiTTo in volt ampere - if w == 1: - api_winding.rated_power = ( - float(transformer_data["ratedcapacity"]) * 10 ** 3 - ) # DiTTo in volt ampere - except: - pass - # Set the nominal voltage try: if w == 0: @@ -4936,6 +4923,11 @@ def parse_regulators(self, model): except: pass + # Set the rated power of the regulator + api_regulator.rated_power = ( + float(regulator_data["kva"]) * 10 ** 3 + ) # DiTTo in var + for w in range(2): # Instanciate a Winding DiTTo object @@ -4944,14 +4936,6 @@ def parse_regulators(self, model): except: raise ValueError("Unable to instanciate Winding DiTTo object.") - # Set the rated power - try: - api_winding.rated_power = ( - float(regulator_data["kva"]) * 10 ** 3 - ) # DiTTo in volt ampere - except: - pass - # Set the connection type try: api_winding.connection_type = self.connection_configuration_mapping( diff --git a/ditto/readers/gridlabd/read.py b/ditto/readers/gridlabd/read.py index df88ad33..45a4a1f5 100644 --- a/ditto/readers/gridlabd/read.py +++ b/ditto/readers/gridlabd/read.py @@ -744,6 +744,12 @@ def parse(self, model, origin_datetime="2017 Jun 1 2:00PM"): except AttributeError: pass + try: + power_rating = float(config["power_rating"]) * 1000 + api_transformer.rated_power = power_rating + except AttributeError: + pass + try: high_voltage = config["primary_voltage"] winding1.nominal_voltage = float(high_voltage) @@ -832,47 +838,40 @@ def parse(self, model, origin_datetime="2017 Jun 1 2:00PM"): for x in reactances: api_transformer.reactances.append(x) - try: - power_rating = float(config["power_rating"]) * 1000 - winding1.rated_power = power_rating - if num_windings == 3: - winding2.rated_power = power_rating / 2.0 - winding3.rated_power = power_rating / 2.0 - else: - winding2.rated_power = power_rating - except AttributeError: - pass - try: - power_rating = float(config["powerA_rating"]) * 1000 - winding1.rated_power = power_rating - if num_windings == 3: - winding2.rated_power = power_rating / 2.0 - winding3.rated_power = power_rating / 2.0 - else: - winding2.rated_power = power_rating - except AttributeError: - pass - - try: - power_rating = float(config["powerB_rating"]) * 1000 - winding1.rated_power = power_rating - if num_windings == 3: - winding2.rated_power = power_rating / 2.0 - winding3.rated_power = power_rating / 2.0 - else: - winding2.rated_power = power_rating - except AttributeError: - pass - try: - power_rating = float(config["powerC_rating"]) * 1000 - winding1.rated_power = power_rating - if num_windings == 3: - winding2.rated_power = power_rating / 2.0 - winding3.rated_power = power_rating / 2.0 - else: - winding2.rated_power = power_rating - except AttributeError: - pass + # IS THIS RIGHT? + # IT LOOKS LIKE THE RATED_POWER WOULD BE OVERWRITTEN + # + # try: + # power_rating = float(config["powerA_rating"]) * 1000 + # winding1.rated_power = power_rating + # if num_windings == 3: + # winding2.rated_power = power_rating / 2.0 + # winding3.rated_power = power_rating / 2.0 + # else: + # winding2.rated_power = power_rating + # except AttributeError: + # pass + + # try: + # power_rating = float(config["powerB_rating"]) * 1000 + # winding1.rated_power = power_rating + # if num_windings == 3: + # winding2.rated_power = power_rating / 2.0 + # winding3.rated_power = power_rating / 2.0 + # else: + # winding2.rated_power = power_rating + # except AttributeError: + # pass + # try: + # power_rating = float(config["powerC_rating"]) * 1000 + # winding1.rated_power = power_rating + # if num_windings == 3: + # winding2.rated_power = power_rating / 2.0 + # winding3.rated_power = power_rating / 2.0 + # else: + # winding2.rated_power = power_rating + # except AttributeError: + # pass except AttributeError: pass diff --git a/ditto/readers/json/read.py b/ditto/readers/json/read.py index d9507eda..1b1f006a 100644 --- a/ditto/readers/json/read.py +++ b/ditto/readers/json/read.py @@ -57,9 +57,9 @@ class Reader(AbstractReader): }, 'windings':{'klass':'list', 'value':[{'klass':'Winding', - 'rated_power':{'klass':'float', - 'value':'1000' - } + 'nominal_voltage':{'klass':'float', + 'value':'12470' + } 'phase_windings':{'klass':'list', 'value':[{'klass':'PhaseWinding', 'phase':{'klass':'Unicode', @@ -161,7 +161,7 @@ def parse(self): list_first_level = [] # Loop over the element in the list - # Ex: element will be a dict {'klass':Winding, 'rated_power':{'klass':'float','value':10},...} + # Ex: element will be a dict {'klass':Winding, 'nominal_voltage':{'klass':'float','value':10},...} for element in property_value["value"]: # Get the type of each element @@ -180,7 +180,7 @@ def parse(self): ) # Loop over the winding properties - # Ex: rated_power... + # Ex: nominal_voltage... for element_property, element_value in element.items(): if element_property != "klass": diff --git a/ditto/readers/opendss/read.py b/ditto/readers/opendss/read.py index 79dacbbc..494cca08 100644 --- a/ditto/readers/opendss/read.py +++ b/ditto/readers/opendss/read.py @@ -1448,6 +1448,14 @@ def parse_transformers(self, model): except: pass + # rated power + api_transformer.rated_power = float(data["kVA"]) * 10 ** 3 # DiTTo in var + + # emergency power + api_transformer.emergency_power = ( + float(data["emerghkVA"]) * 10 ** 3 + ) # DiTTo in var + # from_element and to_element try: bus_data = data["buses"] @@ -1553,26 +1561,6 @@ def parse_transformers(self, model): except: pass - # rated power - # rated_power removed from powerTransformer and added to Winding by Nicolas - try: - windings[w].rated_power = ( - float(data["kVAs"][w]) * 10 ** 3 - ) # DiTTo in volt ampere - except: - windings[w].rated_power = None - pass - - # emergency_power - # emergency_power removed from powerTransformer and added to Winding by Tarek - try: - windings[w].emergency_power = ( - float(data["emerghkVA"]) * 10 ** 3 - ) # DiTTo in volt ampere - except: - windings[w].emergency_power = None - pass - # nominal_voltage try: windings[w].nominal_voltage = ( @@ -1691,6 +1679,18 @@ def parse_regulators(self, model): # Total number of windings N_windings = int(trans["windings"]) + # rated power + if "kVA" in trans: + api_regulator.rated_power = ( + float(trans["kVA"]) * 10 ** 3 + ) # DiTTo in var + + # emergency power + if "emerghkVA" in trans: + api_regulator.emergency_power = ( + float(trans["emerghkVA"]) * 10 ** 3 + ) # DiTTo in var + # Initialize the list of Windings api_regulator.windings = [Winding(model) for _ in range(N_windings)] @@ -1724,28 +1724,6 @@ def parse_regulators(self, model): except: pass - # rated_power - for w in range(N_windings): - if "kVAs" in trans: - try: - api_regulator.windings[w].rated_power = ( - float(trans["kVAs"][w]) * 10 ** 3 - ) # DiTTo in volt ampere - except: - pass - - # emergency_power - for w in range(N_windings): - if "emerghkVA" in trans: - try: - api_regulator.windings[w].emergency_power = ( - float(trans["emerghkVA"][w]) - * 10 ** 3 - / float(N_windings) - ) # DiTTo in volt ampere - except: - pass - # phase_windings for w in range(N_windings): # Get the phase diff --git a/ditto/readers/synergi/read.py b/ditto/readers/synergi/read.py index 453a181d..8ac26115 100644 --- a/ditto/readers/synergi/read.py +++ b/ditto/readers/synergi/read.py @@ -1257,6 +1257,16 @@ def parse(self, model): # Set the NoLoadLosses api_transformer.noload_loss = NoLoadLosses[Count] + # Set the rated power + api_transformer.rated_power = ( + TransformerRatedKva[Count] * 10 ** 3 + ) # DiTTo in var + + # Set the emergency power + api_transformer.emergency_power = ( + EmergencyKvaRating[Count] * 10 ** 3 + ) # DiTTo in var + # Number of windings # TODO: IS THIS RIGHT??? # @@ -1324,26 +1334,6 @@ def parse(self, model): TertiaryRatedKv[Count] * 10 ** 3 ) # DiTTo in volts - # Set the rated power - if winding == 0 or winding == 1: - w.rated_power = ( - TransformerRatedKva[Count] - / float(n_windings) - * 10 - ** 3 # TODO: Fix this once the KVA Bug in DiTTo is fixed!! - ) # DiTTo in Vars - elif winding == 2: - w.rated_power = ( - TertiaryKva * 10 ** 3 - ) # TODO: Check that this is correct... - - # Set the emergency power - w.emergency_power = ( - EmergencyKvaRating[Count] - / float(n_windings) - * 10 ** 3 # TODO: Fix this once the KVA Bug in DiTTo is fixed!! - ) # DiTTo in Vars - # Create the PhaseWindings for phase in phases: if phase != "N": @@ -1555,6 +1545,11 @@ def parse(self, model): # Set the LowStep of the regulator api_regulator.lowstep = -int(RegulatorTapLimiterLowSetting[i]) + # Set the rated power of the regulator + api_regulator.rated_power = ( + float(RegulatorRatedKva[Count]) * 10 ** 3 + ) # DiTTo in var + # Get the phases regulator_phases = list(RegulagorPhases[i]) @@ -1651,13 +1646,6 @@ def parse(self, model): # Set the Nominal voltage w.nominal_voltage = RegulatorRatedVoltage[Count] - # Set the Rated Power - w.rated_power = ( - RegulatorRatedKva[Count] - / float(n_windings) - * 10 ** 3 # TODO: Fix this once the KVA Bug in DiTTo is fixed!! - ) - # Create the PhaseWindings # for phase in regulator_phases: From 248552ac053114484a7c7326378b9bd061f2227f Mon Sep 17 00:00:00 2001 From: ngensoll Date: Tue, 14 Aug 2018 13:44:00 -0600 Subject: [PATCH 5/5] Update metrics to new API --- ditto/metrics/network_analysis.py | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/ditto/metrics/network_analysis.py b/ditto/metrics/network_analysis.py index 1b60b1ac..8405ada3 100644 --- a/ditto/metrics/network_analysis.py +++ b/ditto/metrics/network_analysis.py @@ -591,7 +591,7 @@ def setup_results_data_structure(self, *args): sub_MVA = None for su in self.__substations: if _src in su.name.replace(".", ""): - sub_MVA = min([z.rated_power for z in su.windings]) * 10 ** -6 + sub_MVA = su.rated_power * 10 ** -6 # DiTTo in var # Create the results dictionary. # Note: All metrics relying on networkX calls are computed here. @@ -1214,17 +1214,14 @@ def analyze_object(self, obj, feeder_name): ): total_load_kva += math.sqrt(pl.p ** 2 + pl.q ** 2) # ...compute the transformer KVA - if hasattr(obj, "windings") and obj.windings is not None: - transformer_kva = max( - [ - wdg.rated_power - for wdg in obj.windings - if wdg.rated_power is not None - ] # The kva values should be the same on all windings but we take the max - ) + if obj.rated_power is not None: + transformer_kva = obj.rated_power self.results[feeder_name]["transformer_kva_distribution"].append( transformer_kva ) + else: + transformer_kva = 0 + # ...and, compare the two values if total_load_kva > transformer_kva: self.results[feeder_name]["num_overloaded_transformers"] += 1 @@ -1256,15 +1253,9 @@ def analyze_object(self, obj, feeder_name): # If we use the transformers to compute the kva distribution if self.compute_kva_density_with_transformers: - if ( - hasattr(obj.windings[0], "rated_power") - and obj.windings[0].rated_power is not None - ): - self.results[feeder_name][ - "sum_distribution_transformer_mva" - ] += ( - obj.windings[0].rated_power * 10 ** -6 - ) # DiTTo in va + self.results[feeder_name][ + "sum_distribution_transformer_mva" + ] += (obj.rated_power * 10 ** -6) # DiTTo in var if ( hasattr(obj.windings[0], "phase_windings")