From d768e55bb1ee63d6584de6d79e20c746b84fd769 Mon Sep 17 00:00:00 2001 From: ARNER Kevin Date: Tue, 19 Mar 2019 10:45:54 +0100 Subject: [PATCH] PSSE_PF_Eficas OK --- InterfaceQT4/editor.py | 3 +- InterfaceQT4/qtEficas.py | 6 +- PSSE_PF_Eficas/PSEN/PSENconfig.py | 10 +- PSSE_PF_Eficas/PSEN/TEST.py | 92 + PSSE_PF_Eficas/PSEN/absence0.txt | 1 + PSSE_PF_Eficas/PSEN/comfile.py | 6 +- PSSE_PF_Eficas/PSEN/data_dico | Bin 0 -> 521494 bytes PSSE_PF_Eficas/PSEN/support_functionsPF.py | 30 +- PSSE_PF_Eficas/com.py | 13 +- PSSE_PF_Eficas/opsPSEN_PF.py | 10 +- PSSE_PF_Eficas/report.txt | 1 + PSSE_PF_Eficas/temp.txt | 6 +- PSSE_PF_Eficas/temp1.txt | 1 + ...FExtractGeneratorLoadLineandTransfoDico.py | 392 ++++ ProcessOutputs_Eficas/PSEN_Cata_N1_PF.py | 245 +++ ProcessOutputs_Eficas/TreatOutputs/RunPF.py | 1890 +++++++++++++++++ .../TreatOutputs/UpdateOptionsPF.py | 298 +++ ProcessOutputs_Eficas/TreatOutputs/UtilsPF.py | 394 ++++ ProcessOutputs_Eficas/com_base.py | 586 +++++ ProcessOutputs_Eficas/dico_print.py | 30 - ProcessOutputs_Eficas/opsPSEN_N1_PF.py | 272 +++ ProcessOutputs_Eficas/prefs_PSEN_N1.py | 5 +- generator/generator_PSEN.py | 2 +- 23 files changed, 4225 insertions(+), 68 deletions(-) create mode 100644 PSSE_PF_Eficas/PSEN/TEST.py create mode 100644 PSSE_PF_Eficas/PSEN/absence0.txt create mode 100644 PSSE_PF_Eficas/PSEN/data_dico create mode 100644 PSSE_PF_Eficas/report.txt create mode 100644 PSSE_PF_Eficas/temp1.txt create mode 100644 ProcessOutputs_Eficas/PFExtractGeneratorLoadLineandTransfoDico.py create mode 100644 ProcessOutputs_Eficas/PSEN_Cata_N1_PF.py create mode 100644 ProcessOutputs_Eficas/TreatOutputs/RunPF.py create mode 100644 ProcessOutputs_Eficas/TreatOutputs/UpdateOptionsPF.py create mode 100644 ProcessOutputs_Eficas/TreatOutputs/UtilsPF.py create mode 100644 ProcessOutputs_Eficas/com_base.py delete mode 100644 ProcessOutputs_Eficas/dico_print.py create mode 100644 ProcessOutputs_Eficas/opsPSEN_N1_PF.py diff --git a/InterfaceQT4/editor.py b/InterfaceQT4/editor.py index 1959b08b..14457437 100755 --- a/InterfaceQT4/editor.py +++ b/InterfaceQT4/editor.py @@ -260,7 +260,8 @@ class JDCEditor(Ui_baseWidget,QWidget): self.saveFile() # lancement avec le .bat - path1 = os.path.abspath(os.path.join(os.path.abspath(__file__), '../', '../', 'PSEN_Eficas', 'PSEN')) + # path1 = os.path.abspath(os.path.join(os.path.abspath(__file__), '../', '../', 'PSEN_Eficas', 'PSEN')) + path1 = os.path.abspath(os.path.join(os.path.abspath(__file__), '../', '../', 'PSSE_PF_Eficas', 'PSEN')) filer = open('temp.txt', 'r') _path = [] for line in filer: diff --git a/InterfaceQT4/qtEficas.py b/InterfaceQT4/qtEficas.py index 2c84c375..69ba0d24 100755 --- a/InterfaceQT4/qtEficas.py +++ b/InterfaceQT4/qtEficas.py @@ -73,8 +73,10 @@ class Appli(Ui_Eficas,QMainWindow): self.ficRecents={} self.mesScripts={} self.listeAEnlever=[] - self.ListePathCode=['Adao','ADAO','Carmel3D','Telemac','CF','MAP','ZCracks', 'SEP','SPECA','PSEN_Eficas','PSEN_N1'] - self.listeCode=['Adao','ADAO','Carmel3D','Telemac','CF','MAP','ZCracks', 'SEP','SPECA','PSEN_Eficas','PSEN_N1'] + # self.ListePathCode=['Adao','ADAO','Carmel3D','Telemac','CF','MAP','ZCracks', 'SEP','SPECA','PSEN_Eficas','PSEN_N1'] + # self.listeCode=['Adao','ADAO','Carmel3D','Telemac','CF','MAP','ZCracks', 'SEP','SPECA','PSEN_Eficas','PSEN_N1'] + self.ListePathCode=['Adao','ADAO','Carmel3D','Telemac','CF','MAP','ZCracks', 'SEP','SPECA','PSSE_PF_Eficas','PSEN_N1'] + self.listeCode=['Adao','ADAO','Carmel3D','Telemac','CF','MAP','ZCracks', 'SEP','SPECA','PSSE_PF_Eficas','PSEN_N1'] self.repIcon=os.path.join( os.path.dirname(os.path.abspath(__file__)),'..','Editeur','icons') diff --git a/PSSE_PF_Eficas/PSEN/PSENconfig.py b/PSSE_PF_Eficas/PSEN/PSENconfig.py index 24aee8d7..33668a85 100644 --- a/PSSE_PF_Eficas/PSEN/PSENconfig.py +++ b/PSSE_PF_Eficas/PSEN/PSENconfig.py @@ -1,7 +1,7 @@ -MachineDico = {'WIND30__Gr1': {'PMIN': 0.0, 'EXNAME': 'WIND30 30.000', 'NAME': 'WIND30', 'NUMBER': 18, 'QMAX': 0.0, 'Q': 0.0, 'P': 20.0, 'QMIN': 0.0, 'ID': '1 ', 'PMAX': 20.0}, 'NDIESELG1__Gr1': {'PMIN': 0.0, 'EXNAME': 'NDIESELG1 11.000', 'NAME': 'NDIESELG1', 'NUMBER': 6, 'QMAX': 10.235971450805664, 'Q': 0.14257816970348358, 'P': 10.647665023803711, 'QMIN': -7.048243522644043, 'ID': '1 ', 'PMAX': 17.100000381469727}, 'HYDRO30__Gr1': {'PMIN': 0.0, 'EXNAME': 'HYDRO30 30.000', 'NAME': 'HYDRO30', 'NUMBER': 16, 'QMAX': 24.0, 'Q': 0.0001832990237744525, 'P': 40.0, 'QMIN': 0.0, 'ID': '1 ', 'PMAX': 40.0}, 'SOLAR30__Gr1': {'PMIN': 0.0, 'EXNAME': 'SOLAR30 30.000', 'NAME': 'SOLAR30', 'NUMBER': 19, 'QMAX': 0.0, 'Q': 0.0, 'P': 15.000000953674316, 'QMIN': 0.0, 'ID': '1 ', 'PMAX': 15.000000953674316}, 'NDIESELG3__Gr1': {'PMIN': 0.0, 'EXNAME': 'NDIESELG3 11.000', 'NAME': 'NDIESELG3', 'NUMBER': 8, 'QMAX': 10.235971450805664, 'Q': 0.14257816970348358, 'P': 10.647665023803711, 'QMIN': -7.048243522644043, 'ID': '1 ', 'PMAX': 17.100000381469727}, 'NDIESELG2__Gr1': {'PMIN': 0.0, 'EXNAME': 'NDIESELG2 11.000', 'NAME': 'NDIESELG2', 'NUMBER': 7, 'QMAX': 10.235971450805664, 'Q': 0.14257816970348358, 'P': 10.647665023803711, 'QMIN': -7.048243522644043, 'ID': '1 ', 'PMAX': 17.100000381469727}, 'NDIESELG4__Gr1': {'PMIN': 0.0, 'EXNAME': 'NDIESELG4 11.000', 'NAME': 'NDIESELG4', 'NUMBER': 9, 'QMAX': 10.235971450805664, 'Q': 0.14257816970348358, 'P': 10.647665023803711, 'QMIN': -7.048243522644043, 'ID': '1 ', 'PMAX': 17.100000381469727}, 'ODIESELG2__Gr1': {'PMIN': 0.0, 'EXNAME': 'ODIESELG2 11.000', 'NAME': 'ODIESELG2', 'NUMBER': 2, 'QMAX': 8.220000267028809, 'Q': 3.820113182067871, 'P': 4.771888484356168e-07, 'QMIN': -6.849999904632568, 'ID': '1 ', 'PMAX': 13.699999809265137}, 'ODIESELG4__Gr1': {'PMIN': 0.0, 'EXNAME': 'ODIESELG4 11.000', 'NAME': 'ODIESELG4', 'NUMBER': 4, 'QMAX': 8.220000267028809, 'Q': 3.820113182067871, 'P': 4.771888484356168e-07, 'QMIN': -6.849999904632568, 'ID': '1 ', 'PMAX': 13.699999809265137}, 'ODIESELG3__Gr1': {'PMIN': 0.0, 'EXNAME': 'ODIESELG3 11.000', 'NAME': 'ODIESELG3', 'NUMBER': 3, 'QMAX': 8.220000267028809, 'Q': 3.820113182067871, 'P': 4.771888484356168e-07, 'QMIN': -6.849999904632568, 'ID': '1 ', 'PMAX': 13.699999809265137}, 'ODIESELG1__Gr1': {'PMIN': 0.0, 'EXNAME': 'ODIESELG1 11.000', 'NAME': 'ODIESELG1', 'NUMBER': 1, 'QMAX': 8.220000267028809, 'Q': 3.8200631141662598, 'P': 4.771888484356168e-07, 'QMIN': -6.849999904632568, 'ID': '1 ', 'PMAX': 13.699999809265137}} -LoadDico = {'ODIESEL__Lo1': {'EXNAME': 'ODIESEL 30.000', 'NAME': 'ODIESEL', 'NUMBER': 5, 'Q': 14.5, 'P': 30.000001907348633, 'ID': '1 '}, 'CITYB30__Lo1': {'EXNAME': 'CITYB30 30.000', 'NAME': 'CITYB30', 'NUMBER': 12, 'Q': 24.5, 'P': 50.0, 'ID': '1 '}, 'CITYD30__Lo1': {'EXNAME': 'CITYD30 30.000', 'NAME': 'CITYD30', 'NUMBER': 15, 'Q': 7.25, 'P': 15.000000953674316, 'ID': '1 '}, 'CITYC30__Lo1': {'EXNAME': 'CITYC30 30.000', 'NAME': 'CITYC30', 'NUMBER': 14, 'Q': 9.75, 'P': 20.0, 'ID': '1 '}} -LineDico = {'NDIESEL__HYDRO90__Li1': {'TONAME': 'HYDRO90', 'FROMNUMBER': 10, 'FROMEXNAME': 'NDIESEL 90.000', 'FROMNAME': 'NDIESEL', 'TOEXNAME': 'HYDRO90 90.000', 'TONUMBER': 17, 'ID': '1 '}, 'CITYC90__SOLAR90__Li1': {'TONAME': 'SOLAR90', 'FROMNUMBER': 13, 'FROMEXNAME': 'CITYC90 90.000', 'FROMNAME': 'CITYC90', 'TOEXNAME': 'SOLAR90 90.000', 'TONUMBER': 20, 'ID': '1 '}, 'NDIESEL__CITYB90__Li1': {'TONAME': 'CITYB90', 'FROMNUMBER': 10, 'FROMEXNAME': 'NDIESEL 90.000', 'FROMNAME': 'NDIESEL', 'TOEXNAME': 'CITYB90 90.000', 'TONUMBER': 11, 'ID': '1 '}, 'NDIESEL__CITYB90__Li2': {'TONAME': 'CITYB90', 'FROMNUMBER': 10, 'FROMEXNAME': 'NDIESEL 90.000', 'FROMNAME': 'NDIESEL', 'TOEXNAME': 'CITYB90 90.000', 'TONUMBER': 11, 'ID': '2 '}, 'CITYC90__HYDRO90__Li1': {'TONAME': 'HYDRO90', 'FROMNUMBER': 13, 'FROMEXNAME': 'CITYC90 90.000', 'FROMNAME': 'CITYC90', 'TOEXNAME': 'HYDRO90 90.000', 'TONUMBER': 17, 'ID': '1 '}, 'ODIESEL__JUNCTION30__Li1': {'TONAME': 'JUNCTION30', 'FROMNUMBER': 5, 'FROMEXNAME': 'ODIESEL 30.000', 'FROMNAME': 'ODIESEL', 'TOEXNAME': 'JUNCTION30 30.000', 'TONUMBER': 21, 'ID': '1 '}, 'CITYB90__CITYC90__Li1': {'TONAME': 'CITYC90', 'FROMNUMBER': 11, 'FROMEXNAME': 'CITYB90 90.000', 'FROMNAME': 'CITYB90', 'TOEXNAME': 'CITYC90 90.000', 'TONUMBER': 13, 'ID': '1 '}, 'WIND30__JUNCTION30__Li1': {'TONAME': 'JUNCTION30', 'FROMNUMBER': 18, 'FROMEXNAME': 'WIND30 30.000', 'FROMNAME': 'WIND30', 'TOEXNAME': 'JUNCTION30 30.000', 'TONUMBER': 21, 'ID': '1 '}, 'CITYD30__JUNCTION30__Li1': {'TONAME': 'JUNCTION30', 'FROMNUMBER': 15, 'FROMEXNAME': 'CITYD30 30.000', 'FROMNAME': 'CITYD30', 'TOEXNAME': 'JUNCTION30 30.000', 'TONUMBER': 21, 'ID': '1 '}, 'HYDRO90__SOLAR90__Li1': {'TONAME': 'SOLAR90', 'FROMNUMBER': 17, 'FROMEXNAME': 'HYDRO90 90.000', 'FROMNAME': 'HYDRO90', 'TOEXNAME': 'SOLAR90 90.000', 'TONUMBER': 20, 'ID': '1 '}, 'CITYD30__SOLAR30__Li1': {'TONAME': 'SOLAR30', 'FROMNUMBER': 15, 'FROMEXNAME': 'CITYD30 30.000', 'FROMNAME': 'CITYD30', 'TOEXNAME': 'SOLAR30 30.000', 'TONUMBER': 19, 'ID': '1 '}, 'HYDRO30__WIND30__Li2': {'TONAME': 'WIND30', 'FROMNUMBER': 16, 'FROMEXNAME': 'HYDRO30 30.000', 'FROMNAME': 'HYDRO30', 'TOEXNAME': 'WIND30 30.000', 'TONUMBER': 18, 'ID': '2 '}, 'HYDRO30__WIND30__Li1': {'TONAME': 'WIND30', 'FROMNUMBER': 16, 'FROMEXNAME': 'HYDRO30 30.000', 'FROMNAME': 'HYDRO30', 'TOEXNAME': 'WIND30 30.000', 'TONUMBER': 18, 'ID': '1 '}} -TransfoDico = {'ODIESELG2__ODIESEL__Tr1': {'TONAME': 'ODIESEL', 'FROMNUMBER': 2, '#WIND': 2, 'FROMEXNAME': 'ODIESELG2 11.000', 'FROMNAME': 'ODIESELG2', 'TOEXNAME': 'ODIESEL 30.000', 'TONUMBER': 5, 'ID': '1 '}, 'NDIESELG3__NDIESEL__Tr1': {'TONAME': 'NDIESEL', 'FROMNUMBER': 8, '#WIND': 2, 'FROMEXNAME': 'NDIESELG3 11.000', 'FROMNAME': 'NDIESELG3', 'TOEXNAME': 'NDIESEL 90.000', 'TONUMBER': 10, 'ID': '1 '}, 'ODIESEL__NDIESEL__Tr1': {'TONAME': 'NDIESEL', 'FROMNUMBER': 5, '#WIND': 2, 'FROMEXNAME': 'ODIESEL 30.000', 'FROMNAME': 'ODIESEL', 'TOEXNAME': 'NDIESEL 90.000', 'TONUMBER': 10, 'ID': '1 '}, 'SOLAR30__SOLAR90__Tr1': {'TONAME': 'SOLAR90', 'FROMNUMBER': 19, '#WIND': 2, 'FROMEXNAME': 'SOLAR30 30.000', 'FROMNAME': 'SOLAR30', 'TOEXNAME': 'SOLAR90 90.000', 'TONUMBER': 20, 'ID': '1 '}, 'NDIESELG2__NDIESEL__Tr1': {'TONAME': 'NDIESEL', 'FROMNUMBER': 7, '#WIND': 2, 'FROMEXNAME': 'NDIESELG2 11.000', 'FROMNAME': 'NDIESELG2', 'TOEXNAME': 'NDIESEL 90.000', 'TONUMBER': 10, 'ID': '1 '}, 'HYDRO30__HYDRO90__Tr1': {'TONAME': 'HYDRO90', 'FROMNUMBER': 16, '#WIND': 2, 'FROMEXNAME': 'HYDRO30 30.000', 'FROMNAME': 'HYDRO30', 'TOEXNAME': 'HYDRO90 90.000', 'TONUMBER': 17, 'ID': '1 '}, 'CITYC90__CITYC30__Tr1': {'TONAME': 'CITYC30', 'FROMNUMBER': 13, '#WIND': 2, 'FROMEXNAME': 'CITYC90 90.000', 'FROMNAME': 'CITYC90', 'TOEXNAME': 'CITYC30 30.000', 'TONUMBER': 14, 'ID': '1 '}, 'NDIESELG1__NDIESEL__Tr1': {'TONAME': 'NDIESEL', 'FROMNUMBER': 6, '#WIND': 2, 'FROMEXNAME': 'NDIESELG1 11.000', 'FROMNAME': 'NDIESELG1', 'TOEXNAME': 'NDIESEL 90.000', 'TONUMBER': 10, 'ID': '1 '}, 'HYDRO30__HYDRO90__Tr2': {'TONAME': 'HYDRO90', 'FROMNUMBER': 16, '#WIND': 2, 'FROMEXNAME': 'HYDRO30 30.000', 'FROMNAME': 'HYDRO30', 'TOEXNAME': 'HYDRO90 90.000', 'TONUMBER': 17, 'ID': '2 '}, 'CITYB90__CITYB30__Tr1': {'TONAME': 'CITYB30', 'FROMNUMBER': 11, '#WIND': 2, 'FROMEXNAME': 'CITYB90 90.000', 'FROMNAME': 'CITYB90', 'TOEXNAME': 'CITYB30 30.000', 'TONUMBER': 12, 'ID': '1 '}, 'CITYB90__CITYB30__Tr2': {'TONAME': 'CITYB30', 'FROMNUMBER': 11, '#WIND': 2, 'FROMEXNAME': 'CITYB90 90.000', 'FROMNAME': 'CITYB90', 'TOEXNAME': 'CITYB30 30.000', 'TONUMBER': 12, 'ID': '2 '}, 'HYDRO30__HYDRO90__Tr3': {'TONAME': 'HYDRO90', 'FROMNUMBER': 16, '#WIND': 2, 'FROMEXNAME': 'HYDRO30 30.000', 'FROMNAME': 'HYDRO30', 'TOEXNAME': 'HYDRO90 90.000', 'TONUMBER': 17, 'ID': '3 '}, 'SOLAR30__SOLAR90__Tr2': {'TONAME': 'SOLAR90', 'FROMNUMBER': 19, '#WIND': 2, 'FROMEXNAME': 'SOLAR30 30.000', 'FROMNAME': 'SOLAR30', 'TOEXNAME': 'SOLAR90 90.000', 'TONUMBER': 20, 'ID': '2 '}, 'ODIESELG3__ODIESEL__Tr1': {'TONAME': 'ODIESEL', 'FROMNUMBER': 3, '#WIND': 2, 'FROMEXNAME': 'ODIESELG3 11.000', 'FROMNAME': 'ODIESELG3', 'TOEXNAME': 'ODIESEL 30.000', 'TONUMBER': 5, 'ID': '1 '}, 'NDIESELG4__NDIESEL__Tr1': {'TONAME': 'NDIESEL', 'FROMNUMBER': 9, '#WIND': 2, 'FROMEXNAME': 'NDIESELG4 11.000', 'FROMNAME': 'NDIESELG4', 'TOEXNAME': 'NDIESEL 90.000', 'TONUMBER': 10, 'ID': '1 '}, 'ODIESELG4__ODIESEL__Tr1': {'TONAME': 'ODIESEL', 'FROMNUMBER': 4, '#WIND': 2, 'FROMEXNAME': 'ODIESELG4 11.000', 'FROMNAME': 'ODIESELG4', 'TOEXNAME': 'ODIESEL 30.000', 'TONUMBER': 5, 'ID': '1 '}, 'ODIESELG1__ODIESEL__Tr1': {'TONAME': 'ODIESEL', 'FROMNUMBER': 1, '#WIND': 2, 'FROMEXNAME': 'ODIESELG1 11.000', 'FROMNAME': 'ODIESELG1', 'TOEXNAME': 'ODIESEL 30.000', 'TONUMBER': 5, 'ID': '1 '}} +MachineDico = {'Champagne_G1_Ugen_genstat_Gr_HighDam_Champagne_G1': {'Q': 0.0, 'EXNAME': 'Champagne_G1_Ugen_66.0KV', 'NAME': 'HighDam_Champagne_G1', 'NUMBER': 26, 'QMAX': 10.200000762939453, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -7.309999942779541, 'ID': 'HighDam_Champagne_G1', 'PMAX': 13.600000381469727}, 'StLouis_Ugen_9_syn_Gr_SLPS_G9': {'Q': 0.0, 'EXNAME': 'StLouis_Ugen_9_66.0KV', 'NAME': 'SLPS_G9', 'NUMBER': 105, 'QMAX': 6.578999996185303, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -6.578999996185303, 'ID': 'SLPS_G9', 'PMAX': 13.770000457763672}, 'Sarako_22kV_genstat_Gr_PV_Sarako': {'Q': 0.0, 'EXNAME': 'Sarako_22kV_66.0KV', 'NAME': 'PV_Sarako', 'NUMBER': 91, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Sarako', 'PMAX': 15.0}, 'Ebene_22kV_1_genstat_Gr_PV_Ebene_1': {'Q': 0.0, 'EXNAME': 'Ebene_22kV_1_66.0KV', 'NAME': 'PV_Ebene_1', 'NUMBER': 33, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Ebene_1', 'PMAX': 0.5}, 'FVPS_22kV_3_genstat_Gr_PV_FVPS_3': {'Q': 0.0, 'EXNAME': 'FVPS_22kV_3_66.0KV', 'NAME': 'PV_FVPS_3', 'NUMBER': 44, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_FVPS_3', 'PMAX': 0.5}, 'Henrietta_22kV_2_genstat_Gr_PV_Henrietta_2': {'Q': 0.0, 'EXNAME': 'Henrietta_22kV_2_66.0KV', 'NAME': 'PV_Henrietta_2', 'NUMBER': 63, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Henrietta_2', 'PMAX': 0.5}, 'Terminal_1__syn_Gr_FVPS_G5': {'Q': 0.0, 'EXNAME': 'Terminal_1__66.0KV', 'NAME': 'FVPS_G5', 'NUMBER': 108, 'QMAX': 9.894586563110352, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -8.088730812072754, 'ID': 'FVPS_G5', 'PMAX': 15.979999542236328}, 'CaseNoyale_22kV_1_genstat_Gr_PV_CaseNoyale_1': {'Q': 0.0, 'EXNAME': 'CaseNoyale_22kV_1_66.0KV', 'NAME': 'PV_CaseNoyale_1', 'NUMBER': 19, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_CaseNoyale_1', 'PMAX': 0.5}, 'Sottise_22kV_2_genstat_Gr_PV_MonChoisy': {'Q': 0.0, 'EXNAME': 'Sottise_22kV_2_66.0KV', 'NAME': 'PV_MonChoisy', 'NUMBER': 94, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_MonChoisy', 'PMAX': 2.0}, 'Sottise_22kV_1_genstat_Gr_PV_Sottise_1': {'Q': 0.0, 'EXNAME': 'Sottise_22kV_1_66.0KV', 'NAME': 'PV_Sottise_1', 'NUMBER': 93, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Sottise_1', 'PMAX': 0.5}, 'LaFerme_G1_Ugen_genstat_Gr_RoR_LaFerme': {'Q': 0.0, 'EXNAME': 'LaFerme_G1_Ugen_66.0KV', 'NAME': 'RoR_LaFerme', 'NUMBER': 75, 'QMAX': 0.9000000357627869, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.6449999809265137, 'ID': 'RoR_LaFerme', 'PMAX': 1.2000000476837158}, 'Amaury_22kV_2_genstat_Gr_PV_Amaury_2': {'Q': 0.0, 'EXNAME': 'Amaury_22kV_2_66.0KV', 'NAME': 'PV_Amaury_2', 'NUMBER': 1, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Amaury_2', 'PMAX': 0.5}, 'Magenta_G1_Ugen_genstat_Gr_RoR_Magenta': {'Q': 0.0, 'EXNAME': 'Magenta_G1_Ugen_66.0KV', 'NAME': 'RoR_Magenta', 'NUMBER': 79, 'QMAX': 0.6000000238418579, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.4300000071525574, 'ID': 'RoR_Magenta', 'PMAX': 0.800000011920929}, 'StLouis_Ugen_11_syn_Gr_SLPS_G11': {'Q': 0.0, 'EXNAME': 'StLouis_Ugen_11_66.0KV', 'NAME': 'SLPS_G11', 'NUMBER': 100, 'QMAX': 12.898200035095215, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -9.2437105178833, 'ID': 'SLPS_G11', 'PMAX': 17.197599411010742}, 'Bellevue_G2_Ugen_syn_Gr_IPP_Bellevue_G2': {'Q': 0.0, 'EXNAME': 'Bellevue_G2_Ugen_66.0KV', 'NAME': 'IPP_Bellevue_G2', 'NUMBER': 12, 'QMAX': 26.700000762939453, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -20.91499900817871, 'ID': 'IPP_Bellevue_G2', 'PMAX': 31.0}, 'Fuel_22kV_2_genstat_Gr_PV_Fuel_2': {'Q': 0.0, 'EXNAME': 'Fuel_22kV_2_66.0KV', 'NAME': 'PV_Fuel_2', 'NUMBER': 57, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Fuel_2', 'PMAX': 0.5}, 'TourKoening_22kV_2_genstat_Gr_PV_TourKoening_2': {'Q': 0.0, 'EXNAME': 'TourKoening_22kV_2_66.0KV', 'NAME': 'PV_TourKoening_2', 'NUMBER': 116, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_TourKoening_2', 'PMAX': 0.5}, 'Fuel_G2_Ugen_syn_Gr_IPP_Fuel_G2': {'Q': 0.0, 'EXNAME': 'Fuel_G2_Ugen_66.0KV', 'NAME': 'IPP_Fuel_G2', 'NUMBER': 60, 'QMAX': 14.100000381469727, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -11.045000076293945, 'ID': 'IPP_Fuel_G2', 'PMAX': 13.5}, 'Bellevue_22kV_1_genstat_Gr_PV_Bellevue_1': {'Q': 0.0, 'EXNAME': 'Bellevue_22kV_1_66.0KV', 'NAME': 'PV_Bellevue_1', 'NUMBER': 8, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Bellevue_1', 'PMAX': 0.5}, 'LeVal_G2_Ugen_genstat_Gr_RoR_LeVal_G2': {'Q': 0.0, 'EXNAME': 'LeVal_G2_Ugen_66.0KV', 'NAME': 'RoR_LeVal_G2', 'NUMBER': 78, 'QMAX': 1.5, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -1.0750000476837158, 'ID': 'RoR_LeVal_G2', 'PMAX': 2.0}, 'NIPS_G3_Ugen_syn_Gr_NIPS_G3': {'Q': 0.0, 'EXNAME': 'NIPS_G3_Ugen_66.0KV', 'NAME': 'NIPS_G3', 'NUMBER': 87, 'QMAX': 28.260000228881836, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -20.253000259399414, 'ID': 'NIPS_G3', 'PMAX': 37.68000030517578}, 'FGPS_Ugen2_syn_Gr_FGPS_G2': {'Q': 0.0, 'EXNAME': 'FGPS_Ugen2_66.0KV', 'NAME': 'FGPS_G2', 'NUMBER': 38, 'QMAX': 17.56800079345703, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -14.640000343322754, 'ID': 'FGPS_G2', 'PMAX': 15.399999618530273}, 'FGPS_Ugen1_syn_Gr_FGPS_G1': {'Q': 0.0, 'EXNAME': 'FGPS_Ugen1_66.0KV', 'NAME': 'FGPS_G1', 'NUMBER': 37, 'QMAX': 17.56800079345703, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -14.640000343322754, 'ID': 'FGPS_G1', 'PMAX': 15.399999618530273}, 'UnionVale_22kV_1_genstat_Gr_PV_UnionVale_1': {'Q': 0.0, 'EXNAME': 'UnionVale_22kV_1_66.0KV', 'NAME': 'PV_UnionVale_1', 'NUMBER': 118, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_UnionVale_1', 'PMAX': 0.5}, 'FortGeorge_22kV_1_genstat_Gr_PV_FortGeorge_1': {'Q': 0.0, 'EXNAME': 'FortGeorge_22kV_1_66.0KV', 'NAME': 'PV_FortGeorge_1', 'NUMBER': 53, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_FortGeorge_1', 'PMAX': 0.5}, 'Wooton_22kV_1_genstat_Gr_PV_Esperance': {'Q': 0.0, 'EXNAME': 'Wooton_22kV_1_66.0KV', 'NAME': 'PV_Esperance', 'NUMBER': 121, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Esperance', 'PMAX': 2.0}, 'StLouis_22kV_1_genstat_Gr_PV_StLouis_1': {'Q': 0.0, 'EXNAME': 'StLouis_22kV_1_66.0KV', 'NAME': 'PV_StLouis_1', 'NUMBER': 96, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_StLouis_1', 'PMAX': 0.5}, 'Cecile_G1_Ugen_genstat_Gr_RoR_Cecile': {'Q': 0.0, 'EXNAME': 'Cecile_G1_Ugen_66.0KV', 'NAME': 'RoR_Cecile', 'NUMBER': 23, 'QMAX': 0.75, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.5375000238418579, 'ID': 'RoR_Cecile', 'PMAX': 1.0}, 'Combo_22kV_1_genstat_Gr_PV_Combo_1': {'Q': 0.0, 'EXNAME': 'Combo_22kV_1_66.0KV', 'NAME': 'PV_Combo_1', 'NUMBER': 28, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Combo_1', 'PMAX': 0.5}, 'CTDS_G1_Ugen_syn_Gr_IPP_CTDS_G1': {'Q': 0.0, 'EXNAME': 'CTDS_G1_Ugen_66.0KV', 'NAME': 'IPP_CTDS_G1', 'NUMBER': 14, 'QMAX': 29.439998626708984, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -21.6200008392334, 'ID': 'IPP_CTDS_G1', 'PMAX': 30.0}, 'Terminal_7__syn_Gr_FVPS_G12_MAN': {'Q': 0.0, 'EXNAME': 'Terminal_7__66.0KV', 'NAME': 'FVPS_G12_MAN', 'NUMBER': 114, 'QMAX': 7.390200614929199, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -5.2963104248046875, 'ID': 'FVPS_G12_MAN', 'PMAX': 8.0}, 'FVPS_22kV_1_genstat_Gr_PV_FVPS_1': {'Q': 0.0, 'EXNAME': 'FVPS_22kV_1_66.0KV', 'NAME': 'PV_FVPS_1', 'NUMBER': 42, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_FVPS_1', 'PMAX': 0.5}, 'FGPS_Ugen3_syn_Gr_FGPS_G3': {'Q': 0.0, 'EXNAME': 'FGPS_Ugen3_66.0KV', 'NAME': 'FGPS_G3', 'NUMBER': 39, 'QMAX': 22.374000549316406, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -16.780500411987305, 'ID': 'FGPS_G3', 'PMAX': 21.0}, 'Combo_22kV_2_genstat_Gr_PV_Combo_2': {'Q': 0.0, 'EXNAME': 'Combo_22kV_2_66.0KV', 'NAME': 'PV_Combo_2', 'NUMBER': 29, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Combo_2', 'PMAX': 0.5}, 'Ebene_22kV_3_genstat_Gr_PV_Ebene_3': {'Q': 0.0, 'EXNAME': 'Ebene_22kV_3_66.0KV', 'NAME': 'PV_Ebene_3', 'NUMBER': 35, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Ebene_3', 'PMAX': 0.5}, 'FGPS_Ugen4_syn_Gr_FGPS_G4': {'Q': 0.0, 'EXNAME': 'FGPS_Ugen4_66.0KV', 'NAME': 'FGPS_G4', 'NUMBER': 40, 'QMAX': 22.44000244140625, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -18.700000762939453, 'ID': 'FGPS_G4', 'PMAX': 21.0}, 'Jin_Fei_22kV_2_genstat_Gr_PV_Jin_Fei_1': {'Q': 0.0, 'EXNAME': 'Jin_Fei_22kV_2_66.0KV', 'NAME': 'PV_Jin_Fei_1', 'NUMBER': 70, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Jin_Fei_1', 'PMAX': 0.5}, 'NIPS_G2_Ugen_syn_Gr_NIPS_G2': {'Q': 0.0, 'EXNAME': 'NIPS_G2_Ugen_66.0KV', 'NAME': 'NIPS_G2', 'NUMBER': 86, 'QMAX': 17.025001525878906, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -12.201250076293945, 'ID': 'NIPS_G2', 'PMAX': 22.700000762939453}, 'Nicolay_22kV_2_genstat_Gr_PV_Nicolay_2': {'Q': 0.0, 'EXNAME': 'Nicolay_22kV_2_66.0KV', 'NAME': 'PV_Nicolay_2', 'NUMBER': 89, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Nicolay_2', 'PMAX': 0.5}, 'Wooton_22kV_1_genstat_Gr_PV_Wooton_2': {'Q': 0.0, 'EXNAME': 'Wooton_22kV_1_66.0KV', 'NAME': 'PV_Wooton_2', 'NUMBER': 121, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Wooton_2', 'PMAX': 0.5}, 'Jin_Fei_22kV_1_genstat_Gr_PV_Jin_Fei_2': {'Q': 0.0, 'EXNAME': 'Jin_Fei_22kV_1_66.0KV', 'NAME': 'PV_Jin_Fei_2', 'NUMBER': 69, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Jin_Fei_2', 'PMAX': 0.5}, 'Fuel_G1_Ugen_syn_Gr_IPP_Fuel_G1': {'Q': 0.0, 'EXNAME': 'Fuel_G1_Ugen_66.0KV', 'NAME': 'IPP_Fuel_G1', 'NUMBER': 59, 'QMAX': 16.275001525878906, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -12.748749732971191, 'ID': 'IPP_Fuel_G1', 'PMAX': 13.5}, 'LeVal_G1_Ugen_genstat_Gr_RoR_LeVal_G1': {'Q': 0.0, 'EXNAME': 'LeVal_G1_Ugen_66.0KV', 'NAME': 'RoR_LeVal_G1', 'NUMBER': 77, 'QMAX': 1.5, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -1.0750000476837158, 'ID': 'RoR_LeVal_G1', 'PMAX': 2.0}, 'StLouis_22kV_2_genstat_Gr_PV_StLouis_2': {'Q': 0.0, 'EXNAME': 'StLouis_22kV_2_66.0KV', 'NAME': 'PV_StLouis_2', 'NUMBER': 97, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_StLouis_2', 'PMAX': 0.5}, 'TourKoening_22kV_1_genstat_Gr_PV_TourKoening_1': {'Q': 0.0, 'EXNAME': 'TourKoening_22kV_1_66.0KV', 'NAME': 'PV_TourKoening_1', 'NUMBER': 115, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_TourKoening_1', 'PMAX': 0.5}, 'StLouis_Ugen_10_syn_Gr_SLPS_G10': {'Q': 0.0, 'EXNAME': 'StLouis_Ugen_10_66.0KV', 'NAME': 'SLPS_G10', 'NUMBER': 99, 'QMAX': 12.898200035095215, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -9.2437105178833, 'ID': 'SLPS_G10', 'PMAX': 17.197599411010742}, 'LaChaumiere_22kV_2_genstat_Gr_PV_LaChaumiere_2': {'Q': 0.0, 'EXNAME': 'LaChaumiere_22kV_2_66.0KV', 'NAME': 'PV_LaChaumiere_2', 'NUMBER': 73, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_LaChaumiere_2', 'PMAX': 0.5}, 'FGPS_Ugen5_syn_Gr_FGPS_G5': {'Q': 0.0, 'EXNAME': 'FGPS_Ugen5_66.0KV', 'NAME': 'FGPS_G5', 'NUMBER': 41, 'QMAX': 22.44000244140625, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -18.700000762939453, 'ID': 'FGPS_G5', 'PMAX': 21.0}, 'Bellevue_22kV_2_genstat_Gr_PV_Bellevue_2': {'Q': 0.0, 'EXNAME': 'Bellevue_22kV_2_66.0KV', 'NAME': 'PV_Bellevue_2', 'NUMBER': 9, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Bellevue_2', 'PMAX': 0.5}, 'StLouis_Ugen_13_syn_Gr_SLPS_G13': {'Q': 0.0, 'EXNAME': 'StLouis_Ugen_13_66.0KV', 'NAME': 'SLPS_G13', 'NUMBER': 102, 'QMAX': 12.898200035095215, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -9.2437105178833, 'ID': 'SLPS_G13', 'PMAX': 17.197599411010742}, 'Wooton_22kV_2_genstat_Gr_PV_Wooton_1': {'Q': 0.0, 'EXNAME': 'Wooton_22kV_2_66.0KV', 'NAME': 'PV_Wooton_1', 'NUMBER': 122, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Wooton_1', 'PMAX': 0.5}, 'Sottise_22kV_2_genstat_Gr_PV_Sottise_2': {'Q': 0.0, 'EXNAME': 'Sottise_22kV_2_66.0KV', 'NAME': 'PV_Sottise_2', 'NUMBER': 94, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Sottise_2', 'PMAX': 0.5}, 'Nicolay_22kV_1_genstat_Gr_PV_Nicolay_1': {'Q': 0.0, 'EXNAME': 'Nicolay_22kV_1_66.0KV', 'NAME': 'PV_Nicolay_1', 'NUMBER': 88, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Nicolay_1', 'PMAX': 0.5}, 'StLouis_Ugen_8_syn_Gr_SLPS_G8': {'Q': 0.0, 'EXNAME': 'StLouis_Ugen_8_66.0KV', 'NAME': 'SLPS_G8', 'NUMBER': 104, 'QMAX': 6.578999996185303, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -6.578999996185303, 'ID': 'SLPS_G8', 'PMAX': 13.770000457763672}, 'Ferney_G2_Ugen_genstat_Gr_HighDam_Ferney_G2': {'Q': 0.0, 'EXNAME': 'Ferney_G2_Ugen_66.0KV', 'NAME': 'HighDam_Ferney_G2', 'NUMBER': 52, 'QMAX': 3.2875001430511475, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -2.6875, 'ID': 'HighDam_Ferney_G2', 'PMAX': 5.3125}, 'Ferney_G1_Ugen_genstat_Gr_HighDam_Ferney_G1': {'Q': 0.0, 'EXNAME': 'Ferney_G1_Ugen_66.0KV', 'NAME': 'HighDam_Ferney_G1', 'NUMBER': 51, 'QMAX': 3.2875001430511475, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -2.6875, 'ID': 'HighDam_Ferney_G1', 'PMAX': 5.3125}, 'Champagne_G2_Ugen_genstat_Gr_HighDam_Champagne_G2': {'Q': 0.0, 'EXNAME': 'Champagne_G2_Ugen_66.0KV', 'NAME': 'HighDam_Champagne_G2', 'NUMBER': 27, 'QMAX': 10.200000762939453, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -7.309999942779541, 'ID': 'HighDam_Champagne_G2', 'PMAX': 13.600000381469727}, 'PlaineDesRochesPowerStation_22kV_genstat_Gr_EOL_PlaindesRoches': {'Q': 0.0, 'EXNAME': 'PlaineDesRochesPowerStation_22kV_66.0KV', 'NAME': 'EOL_PlaindesRoches', 'NUMBER': 90, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'EOL_PlaindesRoches', 'PMAX': 9.399999618530273}, 'FVPS_22kV_2_genstat_Gr_PV_FVPS_2': {'Q': 0.0, 'EXNAME': 'FVPS_22kV_2_66.0KV', 'NAME': 'PV_FVPS_2', 'NUMBER': 43, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_FVPS_2', 'PMAX': 0.5}, 'Terminal_6__syn_Gr_FVPS_G6': {'Q': 0.0, 'EXNAME': 'Terminal_6__66.0KV', 'NAME': 'FVPS_G6', 'NUMBER': 113, 'QMAX': 9.894586563110352, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -8.088730812072754, 'ID': 'FVPS_G6', 'PMAX': 15.989350318908691}, 'Ebene_22kV_2_genstat_Gr_PV_Ebene_2': {'Q': 0.0, 'EXNAME': 'Ebene_22kV_2_66.0KV', 'NAME': 'PV_Ebene_2', 'NUMBER': 34, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Ebene_2', 'PMAX': 0.5}, 'LaChaumiere_22kV_1_genstat_Gr_PV_LaChaumiere_1': {'Q': 0.0, 'EXNAME': 'LaChaumiere_22kV_1_66.0KV', 'NAME': 'PV_LaChaumiere_1', 'NUMBER': 72, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_LaChaumiere_1', 'PMAX': 0.5}, 'Amaury_22kV_2_genstat_Gr_PV_PetiteRetraite': {'Q': 0.0, 'EXNAME': 'Amaury_22kV_2_66.0KV', 'NAME': 'PV_PetiteRetraite', 'NUMBER': 1, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_PetiteRetraite', 'PMAX': 2.0}, 'Terminal_2__syn_Gr_FVPS_G1': {'Q': 0.0, 'EXNAME': 'Terminal_2__66.0KV', 'NAME': 'FVPS_G1', 'NUMBER': 109, 'QMAX': 9.460636138916016, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -7.733980178833008, 'ID': 'FVPS_G1', 'PMAX': 15.288100242614746}, 'StLouis_Ugen_7_syn_Gr_SLPS_G7': {'Q': 0.0, 'EXNAME': 'StLouis_Ugen_7_66.0KV', 'NAME': 'SLPS_G7', 'NUMBER': 103, 'QMAX': 6.578999996185303, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -6.578999996185303, 'ID': 'SLPS_G7', 'PMAX': 13.770000457763672}, 'Beauchamp_G1_Ugen_syn_Gr_IPP_Beauchamp_G1': {'Q': 0.0, 'EXNAME': 'Beauchamp_G1_Ugen_66.0KV', 'NAME': 'IPP_Beauchamp_G1', 'NUMBER': 7, 'QMAX': 18.479999542236328, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -13.243999481201172, 'ID': 'IPP_Beauchamp_G1', 'PMAX': 22.0}, 'Terminal_3__syn_Gr_FVPS_G3': {'Q': 0.0, 'EXNAME': 'Terminal_3__66.0KV', 'NAME': 'FVPS_G3', 'NUMBER': 110, 'QMAX': 9.894586563110352, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -8.088730812072754, 'ID': 'FVPS_G3', 'PMAX': 15.989350318908691}, 'Tamarind_G1_Ugen_genstat_Gr_RoR_Tamarind': {'Q': 0.0, 'EXNAME': 'Tamarind_G1_Ugen_66.0KV', 'NAME': 'RoR_Tamarind', 'NUMBER': 106, 'QMAX': 3.2160003185272217, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -2.304800033569336, 'ID': 'RoR_Tamarind', 'PMAX': 4.288000106811523}, 'Terminal_4__syn_Gr_FVPS_G4': {'Q': 0.0, 'EXNAME': 'Terminal_4__66.0KV', 'NAME': 'FVPS_G4', 'NUMBER': 111, 'QMAX': 9.894586563110352, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -8.088730812072754, 'ID': 'FVPS_G4', 'PMAX': 15.989350318908691}, 'Amaury_22kV_1_genstat_Gr_PV_Amaury_1': {'Q': 0.0, 'EXNAME': 'Amaury_22kV_1_66.0KV', 'NAME': 'PV_Amaury_1', 'NUMBER': 0, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Amaury_1', 'PMAX': 0.5}, 'UnionVale_22kV_2_genstat_Gr_PV_UnionVale_2': {'Q': 0.0, 'EXNAME': 'UnionVale_22kV_2_66.0KV', 'NAME': 'PV_UnionVale_2', 'NUMBER': 119, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_UnionVale_2', 'PMAX': 0.5}, 'FortGeorge_22kV_2_genstat_Gr_PV_FortGeorge_2': {'Q': 0.0, 'EXNAME': 'FortGeorge_22kV_2_66.0KV', 'NAME': 'PV_FortGeorge_2', 'NUMBER': 54, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_FortGeorge_2', 'PMAX': 0.5}, 'Terminal_5__syn_Gr_FVPS_G2': {'Q': 0.0, 'EXNAME': 'Terminal_5__66.0KV', 'NAME': 'FVPS_G2', 'NUMBER': 112, 'QMAX': 9.460636138916016, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -7.733980178833008, 'ID': 'FVPS_G2', 'PMAX': 15.288100242614746}, 'Henrietta_22kV_1_genstat_Gr_PV_Henrietta_1': {'Q': 0.0, 'EXNAME': 'Henrietta_22kV_1_66.0KV', 'NAME': 'PV_Henrietta_1', 'NUMBER': 62, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Henrietta_1', 'PMAX': 0.5}, 'StLouis_Ugen_12_syn_Gr_SLPS_G12': {'Q': 0.0, 'EXNAME': 'StLouis_Ugen_12_66.0KV', 'NAME': 'SLPS_G12', 'NUMBER': 101, 'QMAX': 12.898200035095215, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -9.2437105178833, 'ID': 'SLPS_G12', 'PMAX': 17.197599411010742}, 'Curepipe_22kV_genstat_Gr_EOL_PlaineSophie': {'Q': 0.0, 'EXNAME': 'Curepipe_22kV_66.0KV', 'NAME': 'EOL_PlaineSophie', 'NUMBER': 31, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'EOL_PlaineSophie', 'PMAX': 30.0}, 'Medine_G2_Ugen_syn_Gr_IPP_Medine_G2': {'Q': 0.0, 'EXNAME': 'Medine_G2_Ugen_66.0KV', 'NAME': 'IPP_Medine_G2', 'NUMBER': 83, 'QMAX': 9.15000057220459, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -6.557499885559082, 'ID': 'IPP_Medine_G2', 'PMAX': 11.0}, 'Fuel_22kV_1_genstat_Gr_PV_Fuel_1': {'Q': 0.0, 'EXNAME': 'Fuel_22kV_1_66.0KV', 'NAME': 'PV_Fuel_1', 'NUMBER': 56, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Fuel_1', 'PMAX': 0.5}, 'CTSAV_G1_Ugen_syn_Gr_IPP_CTSAV_G1': {'Q': 0.0, 'EXNAME': 'CTSAV_G1_Ugen_66.0KV', 'NAME': 'IPP_CTSAV_G1', 'NUMBER': 16, 'QMAX': 39.60000228881836, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -25.80000114440918, 'ID': 'IPP_CTSAV_G1', 'PMAX': 37.0}, 'Terminal_syn_Gr_FVPS_G11_MAN': {'Q': 0.0, 'EXNAME': 'Terminal_66.0KV', 'NAME': 'FVPS_G11_MAN', 'NUMBER': 107, 'QMAX': 7.390200614929199, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -5.2963104248046875, 'ID': 'FVPS_G11_MAN', 'PMAX': 8.0}, 'Bellevue_G1_Ugen_syn_Gr_IPP_Bellevue_G1': {'Q': 0.0, 'EXNAME': 'Bellevue_G1_Ugen_66.0KV', 'NAME': 'IPP_Bellevue_G1', 'NUMBER': 11, 'QMAX': 26.700000762939453, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -20.91499900817871, 'ID': 'IPP_Bellevue_G1', 'PMAX': 31.0}, 'Ferney_22kV_genstat_Gr_PV_Ferney_1': {'Q': 0.0, 'EXNAME': 'Ferney_22kV_66.0KV', 'NAME': 'PV_Ferney_1', 'NUMBER': 50, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Ferney_1', 'PMAX': 0.5}, 'Anahita_22kV_1_genstat_Gr_PV_Anahita_1': {'Q': 0.0, 'EXNAME': 'Anahita_22kV_1_66.0KV', 'NAME': 'PV_Anahita_1', 'NUMBER': 3, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Anahita_1', 'PMAX': 0.5}, 'Medine_G1_Ugen_syn_Gr_IPP_Medine_G1': {'Q': 0.0, 'EXNAME': 'Medine_G1_Ugen_66.0KV', 'NAME': 'IPP_Medine_G1', 'NUMBER': 82, 'QMAX': 12.5, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -12.5, 'ID': 'IPP_Medine_G1', 'PMAX': 10.0}, 'CaseNoyale_22kV_2_genstat_Gr_PV_CaseNoyale_2': {'Q': 0.0, 'EXNAME': 'CaseNoyale_22kV_2_66.0KV', 'NAME': 'PV_CaseNoyale_2', 'NUMBER': 20, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_CaseNoyale_2', 'PMAX': 0.5}, 'NIPS_G1_Ugen_syn_Gr_NIPS_G1': {'Q': 0.0, 'EXNAME': 'NIPS_G1_Ugen_66.0KV', 'NAME': 'NIPS_G1', 'NUMBER': 85, 'QMAX': 16.356000900268555, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -11.721799850463867, 'ID': 'NIPS_G1', 'PMAX': 21.808000564575195}, 'Anahita_22kV_2_genstat_Gr_PV_Anahita_2': {'Q': 0.0, 'EXNAME': 'Anahita_22kV_2_66.0KV', 'NAME': 'PV_Anahita_2', 'NUMBER': 4, 'QMAX': 0.0, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -0.0, 'ID': 'PV_Anahita_2', 'PMAX': 0.5}, 'CTSAV_G2_Ugen_syn_Gr_IPP_CTSAV_G2': {'Q': 0.0, 'EXNAME': 'CTSAV_G2_Ugen_66.0KV', 'NAME': 'IPP_CTSAV_G2', 'NUMBER': 18, 'QMAX': 39.60000228881836, 'PMIN': 0.0, 'P': 0.0, 'QMIN': -25.80000114440918, 'ID': 'IPP_CTSAV_G2', 'PMAX': 37.0}} +LoadDico = {'Combo_22kV_2_Lo1': {'EXNAME': 'Combo_22kV_2_22.0KV', 'NAME': 'Combo_Load_2', 'NUMBER': 29, 'Q': 2.3155798440790565, 'P': 7.045000076293945, 'ID': 1}, 'CaseNoyale_22kV_2_Lo1': {'EXNAME': 'CaseNoyale_22kV_2_22.0KV', 'NAME': 'CaseNoyale_Load_2', 'NUMBER': 20, 'Q': 2.3155798440790565, 'P': 7.045000076293945, 'ID': 1}, 'FVPS_22kV_1_Lo1': {'EXNAME': 'FVPS_22kV_1_22.0KV', 'NAME': 'FortVictoria_Load_1', 'NUMBER': 42, 'Q': 4.999285895721721, 'P': 15.210000038146973, 'ID': 1}, 'Nicolay_22kV_1_Lo1': {'EXNAME': 'Nicolay_22kV_1_22.0KV', 'NAME': 'Nicolay_Load_1', 'NUMBER': 88, 'Q': 4.830013446924353, 'P': 14.694999694824219, 'ID': 1}, 'FVPS_22kV_2_Lo1': {'EXNAME': 'FVPS_22kV_2_22.0KV', 'NAME': 'FortVictoria_Load_2', 'NUMBER': 43, 'Q': 4.999285895721721, 'P': 15.210000038146973, 'ID': 1}, 'Anahita_22kV_1_Lo1': {'EXNAME': 'Anahita_22kV_1_22.0KV', 'NAME': 'Anahita_Load_1', 'NUMBER': 3, 'Q': 1.7370967871121035, 'P': 5.284999847412109, 'ID': 1}, 'Amaury_22kV_2_Lo1': {'EXNAME': 'Amaury_22kV_2_22.0KV', 'NAME': 'Amaury_Load_2', 'NUMBER': 1, 'Q': 2.4815653761717926, 'P': 7.550000190734863, 'ID': 1}, 'StLouis_22kV_2_Lo1': {'EXNAME': 'StLouis_22kV_2_22.0KV', 'NAME': 'StLouis_Load_2', 'NUMBER': 97, 'Q': 4.432305615934249, 'P': 13.484999656677246, 'ID': 1}, 'Nicolay_22kV_2_Lo1': {'EXNAME': 'Nicolay_22kV_2_22.0KV', 'NAME': 'Nicolay_Load_2', 'NUMBER': 89, 'Q': 4.830013446924353, 'P': 14.694999694824219, 'ID': 1}, 'Sottise_22kV_1_Lo1': {'EXNAME': 'Sottise_22kV_1_22.0KV', 'NAME': 'Sottise_Load_1', 'NUMBER': 93, 'Q': 4.217017587102438, 'P': 12.829999923706055, 'ID': 1}, 'Fuel_22kV_2_Lo1': {'EXNAME': 'Fuel_22kV_2_22.0KV', 'NAME': 'Fuel_Load_2', 'NUMBER': 57, 'Q': 3.6845493057984093, 'P': 11.210000038146973, 'ID': 1}, 'StLouis_22kV_1_Lo1': {'EXNAME': 'StLouis_22kV_1_22.0KV', 'NAME': 'StLouis_Load_1', 'NUMBER': 96, 'Q': 4.432305615934249, 'P': 13.484999656677246, 'ID': 1}, 'Jin_Fei_22kV_2_Lo1': {'EXNAME': 'Jin_Fei_22kV_2_22.0KV', 'NAME': 'Jin_Fei_Load_2', 'NUMBER': 70, 'Q': 2.0838575451816834, 'P': 6.340000152587891, 'ID': 1}, 'FortGeorge_22kV_2_Lo1': {'EXNAME': 'FortGeorge_22kV_2_22.0KV', 'NAME': 'FortGeorge_Load_2', 'NUMBER': 54, 'Q': 4.41587165932631, 'P': 13.4350004196167, 'ID': 1}, 'UnionVale_22kV_1_Lo1': {'EXNAME': 'UnionVale_22kV_1_22.0KV', 'NAME': 'UnionVale_Load_1', 'NUMBER': 118, 'Q': 3.83081365112094, 'P': 11.654999732971191, 'ID': 1}, 'Bellevue_22kV_1_Lo1': {'EXNAME': 'Bellevue_22kV_1_22.0KV', 'NAME': 'Bellevue_Load_1', 'NUMBER': 8, 'Q': 4.631159688158113, 'P': 14.09000015258789, 'ID': 1}, 'FVPS_22kV_3_Lo1': {'EXNAME': 'FVPS_22kV_3_22.0KV', 'NAME': 'FortVictoria_Load_3', 'NUMBER': 44, 'Q': 4.999285895721721, 'P': 15.210000038146973, 'ID': 1}, 'Henrietta_22kV_1_Lo1': {'EXNAME': 'Henrietta_22kV_1_22.0KV', 'NAME': 'Henrietta_Load_1', 'NUMBER': 62, 'Q': 3.972147934844134, 'P': 12.085000038146973, 'ID': 1}, 'FortGeorge_22kV_1_Lo1': {'EXNAME': 'FortGeorge_22kV_1_22.0KV', 'NAME': 'FortGeorge_Load_1', 'NUMBER': 53, 'Q': 4.41587165932631, 'P': 13.4350004196167, 'ID': 1}, 'Wooton_22kV_2_Lo1': {'EXNAME': 'Wooton_22kV_2_22.0KV', 'NAME': 'Wooton_Load_2', 'NUMBER': 122, 'Q': 6.701869566521236, 'P': 20.389999389648438, 'ID': 1}, 'Ebene_22kV_2_Lo1': {'EXNAME': 'Ebene_22kV_2_22.0KV', 'NAME': 'Ebene_Load_2', 'NUMBER': 34, 'Q': 6.284437131607226, 'P': 19.1200008392334, 'ID': 1}, 'LaChaumiere_22kV_2_Lo1': {'EXNAME': 'LaChaumiere_22kV_2_22.0KV', 'NAME': 'LaChaumiere_Load_2', 'NUMBER': 73, 'Q': 5.355908208276737, 'P': 16.295000076293945, 'ID': 1}, 'Sottise_22kV_2_Lo1': {'EXNAME': 'Sottise_22kV_2_22.0KV', 'NAME': 'Sottise_Load_2', 'NUMBER': 94, 'Q': 4.217017587102438, 'P': 12.829999923706055, 'ID': 1}, 'Fuel_22kV_1_Lo1': {'EXNAME': 'Fuel_22kV_1_22.0KV', 'NAME': 'Fuel_Load_1', 'NUMBER': 56, 'Q': 3.6845493057984093, 'P': 11.210000038146973, 'ID': 1}, 'TourKoening_22kV_2_Lo1': {'EXNAME': 'TourKoening_22kV_2_22.0KV', 'NAME': 'TourKoening_Load_2', 'NUMBER': 116, 'Q': 2.976233140523389, 'P': 9.055000305175781, 'ID': 1}, 'Amaury_22kV_1_Lo1': {'EXNAME': 'Amaury_22kV_1_22.0KV', 'NAME': 'Amaury_Load_1', 'NUMBER': 0, 'Q': 2.4815653761717926, 'P': 7.550000190734863, 'ID': 1}, 'Anahita_22kV_2_Lo1': {'EXNAME': 'Anahita_22kV_2_22.0KV', 'NAME': 'Anahita_Load_2', 'NUMBER': 4, 'Q': 1.7370967871121035, 'P': 5.284999847412109, 'ID': 1}, 'TourKoening_22kV_1_Lo1': {'EXNAME': 'TourKoening_22kV_1_22.0KV', 'NAME': 'TourKoening_Load_1', 'NUMBER': 115, 'Q': 2.976233140523389, 'P': 9.055000305175781, 'ID': 1}, 'UnionVale_22kV_2_Lo1': {'EXNAME': 'UnionVale_22kV_2_22.0KV', 'NAME': 'UnionVale_Load_2', 'NUMBER': 119, 'Q': 3.83081365112094, 'P': 11.654999732971191, 'ID': 1}, 'Bellevue_22kV_2_Lo1': {'EXNAME': 'Bellevue_22kV_2_22.0KV', 'NAME': 'Bellevue_Load_2', 'NUMBER': 9, 'Q': 4.631159688158113, 'P': 14.09000015258789, 'ID': 1}, 'Ebene_22kV_3_Lo1': {'EXNAME': 'Ebene_22kV_3_22.0KV', 'NAME': 'Ebene_Load_3', 'NUMBER': 35, 'Q': 6.284437131607226, 'P': 19.1200008392334, 'ID': 1}, 'Henrietta_22kV_2_Lo1': {'EXNAME': 'Henrietta_22kV_2_22.0KV', 'NAME': 'Henrietta_Load_2', 'NUMBER': 63, 'Q': 3.972147934844134, 'P': 12.085000038146973, 'ID': 1}, 'Jin_Fei_22kV_1_Lo1': {'EXNAME': 'Jin_Fei_22kV_1_22.0KV', 'NAME': 'Jin_Fei_Load_1', 'NUMBER': 69, 'Q': 2.0838575451816834, 'P': 6.340000152587891, 'ID': 1}, 'Ferney_22kV_Lo1': {'EXNAME': 'Ferney_22kV_22.0KV', 'NAME': 'Ferney_Load_1', 'NUMBER': 50, 'Q': 1.4462093496179527, 'P': 4.400000095367432, 'ID': 1}, 'LaChaumiere_22kV_1_Lo1': {'EXNAME': 'LaChaumiere_22kV_1_22.0KV', 'NAME': 'LaChaumiere_Load_1', 'NUMBER': 72, 'Q': 5.355908208276737, 'P': 16.295000076293945, 'ID': 1}, 'Ebene_22kV_1_Lo1': {'EXNAME': 'Ebene_22kV_1_22.0KV', 'NAME': 'Ebene_Load_1', 'NUMBER': 33, 'Q': 6.284437131607226, 'P': 19.1200008392334, 'ID': 1}, 'CaseNoyale_22kV_1_Lo1': {'EXNAME': 'CaseNoyale_22kV_1_22.0KV', 'NAME': 'CaseNoyale_Load_1', 'NUMBER': 19, 'Q': 2.3155798440790565, 'P': 7.045000076293945, 'ID': 1}, 'Combo_22kV_1_Lo1': {'EXNAME': 'Combo_22kV_1_22.0KV', 'NAME': 'Combo_Load_1', 'NUMBER': 28, 'Q': 2.3155798440790565, 'P': 7.045000076293945, 'ID': 1}, 'Wooton_22kV_1_Lo1': {'EXNAME': 'Wooton_22kV_1_22.0KV', 'NAME': 'Wooton_Load_1', 'NUMBER': 121, 'Q': 6.701869566521236, 'P': 20.389999389648438, 'ID': 1}} +LineDico = {'Medine_22kV_2_Henrietta_22kV_1_22kV_Henrietta_Medine_22kV_Li': {'TONAME': 'Henrietta_22kV_1', 'FROMNUMBER': 81, 'FROMEXNAME': 'Medine_22kV_2_22.0', 'FROMNAME': 'Medine_22kV_2', 'ID': '22kV_Henrietta_Medine_22kV', 'TONUMBER': 62, 'TOEXNAME': 'Henrietta_22kV_1_22.0'}, 'Terminal_1__FVPS_Ugen_1_Line11kV_1__Li': {'TONAME': 'FVPS_Ugen_1', 'FROMNUMBER': 108, 'FROMEXNAME': 'Terminal_1__11.0', 'FROMNAME': 'Terminal_1_', 'ID': 'Line11kV(1)', 'TONUMBER': 46, 'TOEXNAME': 'FVPS_Ugen_1_11.0'}, 'Amaury_66kV_Fuel_66kV_66kV_Amaury_Fuel_1_Li': {'TONAME': 'Fuel_66kV', 'FROMNUMBER': 2, 'FROMEXNAME': 'Amaury_66kV_66.0', 'FROMNAME': 'Amaury_66kV', 'ID': '66kV_Amaury_Fuel_1', 'TONUMBER': 58, 'TOEXNAME': 'Fuel_66kV_66.0'}, 'Henrietta_66kV_LaChaumiere_66kV_66kV_LaChaumiere_Henrietta_1_Li': {'TONAME': 'LaChaumiere_66kV', 'FROMNUMBER': 64, 'FROMEXNAME': 'Henrietta_66kV_66.0', 'FROMNAME': 'Henrietta_66kV', 'ID': '66kV_LaChaumiere_Henrietta_1', 'TONUMBER': 74, 'TOEXNAME': 'LaChaumiere_66kV_66.0'}, 'Cecile_22kV_Combo_22kV_2_22kV_Combo_Cecile_Li': {'TONAME': 'Combo_22kV_2', 'FROMNUMBER': 22, 'FROMEXNAME': 'Cecile_22kV_22.0', 'FROMNAME': 'Cecile_22kV', 'ID': '22kV_Combo_Cecile', 'TONUMBER': 29, 'TOEXNAME': 'Combo_22kV_2_22.0'}, 'Henrietta_66kV_Combo_66kV_66kV_Combo_Henrietta_Li': {'TONAME': 'Combo_66kV', 'FROMNUMBER': 64, 'FROMEXNAME': 'Henrietta_66kV_66.0', 'FROMNAME': 'Henrietta_66kV', 'ID': '66kV_Combo_Henrietta', 'TONUMBER': 30, 'TOEXNAME': 'Combo_66kV_66.0'}, 'StLouis_66kV_Dumas_66kV_66kV_Dumas_StLouis_2_Li': {'TONAME': 'Dumas_66kV', 'FROMNUMBER': 98, 'FROMEXNAME': 'StLouis_66kV_66.0', 'FROMNAME': 'StLouis_66kV', 'ID': '66kV_Dumas_StLouis_2', 'TONUMBER': 32, 'TOEXNAME': 'Dumas_66kV_66.0'}, 'Terminal_6__FVPS_Ugen_4_Line11kV_6__Li': {'TONAME': 'FVPS_Ugen_4', 'FROMNUMBER': 113, 'FROMEXNAME': 'Terminal_6__11.0', 'FROMNAME': 'Terminal_6_', 'ID': 'Line11kV(6)', 'TONUMBER': 49, 'TOEXNAME': 'FVPS_Ugen_4_11.0'}, 'Amaury_66kV_Bellevue_66kV_66kV_Amaury_Bellevue_1_Li': {'TONAME': 'Bellevue_66kV', 'FROMNUMBER': 2, 'FROMEXNAME': 'Amaury_66kV_66.0', 'FROMNAME': 'Amaury_66kV', 'ID': '66kV_Amaury_Bellevue_1', 'TONUMBER': 10, 'TOEXNAME': 'Bellevue_66kV_66.0'}, 'Dumas_66kV_FortGeorge_66kV_66kV_FortGeorge_Dumas_1_Li': {'TONAME': 'FortGeorge_66kV', 'FROMNUMBER': 32, 'FROMEXNAME': 'Dumas_66kV_66.0', 'FROMNAME': 'Dumas_66kV', 'ID': '66kV_FortGeorge_Dumas_1', 'TONUMBER': 55, 'TOEXNAME': 'FortGeorge_66kV_66.0'}, 'Champagne_66kV_Wooton_66kV_66kV_Champagne_Wooton_2_Li': {'TONAME': 'Wooton_66kV', 'FROMNUMBER': 25, 'FROMEXNAME': 'Champagne_66kV_66.0', 'FROMNAME': 'Champagne_66kV', 'ID': '66kV_Champagne_Wooton_2', 'TONUMBER': 123, 'TOEXNAME': 'Wooton_66kV_66.0'}, 'Amaury_66kV_Wooton_66kV_66kV_Wooton_Amaury_Li': {'TONAME': 'Wooton_66kV', 'FROMNUMBER': 2, 'FROMEXNAME': 'Amaury_66kV_66.0', 'FROMNAME': 'Amaury_66kV', 'ID': '66kV_Wooton_Amaury', 'TONUMBER': 123, 'TOEXNAME': 'Wooton_66kV_66.0'}, 'Wooton_66kV_Ebene_66kV_66kV_Ebene_Wooton_2_Li': {'TONAME': 'Ebene_66kV', 'FROMNUMBER': 123, 'FROMEXNAME': 'Wooton_66kV_66.0', 'FROMNAME': 'Wooton_66kV', 'ID': '66kV_Ebene_Wooton_2', 'TONUMBER': 36, 'TOEXNAME': 'Ebene_66kV_66.0'}, 'UnionVale_66kV_CTSAV_G1_66kV_66kV_CTSAVG1_UnionVale_Li': {'TONAME': 'CTSAV_G1_66kV', 'FROMNUMBER': 120, 'FROMEXNAME': 'UnionVale_66kV_66.0', 'FROMNAME': 'UnionVale_66kV', 'ID': '66kV_CTSAVG1_UnionVale', 'TONUMBER': 15, 'TOEXNAME': 'CTSAV_G1_66kV_66.0'}, 'Combo_66kV_Inter_CN_CO_66kV_66kV_Combo_CaseNoyale_PartOHL_Li': {'TONAME': 'Inter_CN_CO_66kV', 'FROMNUMBER': 30, 'FROMEXNAME': 'Combo_66kV_66.0', 'FROMNAME': 'Combo_66kV', 'ID': '66kV_Combo_CaseNoyale_PartOHL', 'TONUMBER': 66, 'TOEXNAME': 'Inter_CN_CO_66kV_66.0'}, 'Ebene_66kV_StLouis_66kV_66kV_StLouis_Ebene_1_Li': {'TONAME': 'StLouis_66kV', 'FROMNUMBER': 36, 'FROMEXNAME': 'Ebene_66kV_66.0', 'FROMNAME': 'Ebene_66kV', 'ID': '66kV_StLouis_Ebene_1', 'TONUMBER': 98, 'TOEXNAME': 'StLouis_66kV_66.0'}, 'StLouis_66kV_Dumas_66kV_66kV_Dumas_StLouis_1_Li': {'TONAME': 'Dumas_66kV', 'FROMNUMBER': 98, 'FROMEXNAME': 'StLouis_66kV_66.0', 'FROMNAME': 'StLouis_66kV', 'ID': '66kV_Dumas_StLouis_1', 'TONUMBER': 32, 'TOEXNAME': 'Dumas_66kV_66.0'}, 'CTDS_G1_66kV_Combo_66kV_66kV_CTDS_Combo_Li': {'TONAME': 'Combo_66kV', 'FROMNUMBER': 13, 'FROMEXNAME': 'CTDS_G1_66kV_66.0', 'FROMNAME': 'CTDS_G1_66kV', 'ID': '66kV_CTDS_Combo', 'TONUMBER': 30, 'TOEXNAME': 'Combo_66kV_66.0'}, 'CaseNoyale_66kV_Henrietta_66kV_66kV_Henrietta_CaseNoyale_Li': {'TONAME': 'Henrietta_66kV', 'FROMNUMBER': 21, 'FROMEXNAME': 'CaseNoyale_66kV_66.0', 'FROMNAME': 'CaseNoyale_66kV', 'ID': '66kV_Henrietta_CaseNoyale', 'TONUMBER': 64, 'TOEXNAME': 'Henrietta_66kV_66.0'}, 'Dumas_66kV_Jin_Fei_66kV_66kV_Dumas_Jin_Fei_Li': {'TONAME': 'Jin_Fei_66kV', 'FROMNUMBER': 32, 'FROMEXNAME': 'Dumas_66kV_66.0', 'FROMNAME': 'Dumas_66kV', 'ID': '66kV_Dumas_Jin_Fei', 'TONUMBER': 71, 'TOEXNAME': 'Jin_Fei_66kV_66.0'}, 'Inter_NI_DU_2_66kV_NIPS_66kV_66kV_Nicolay_Dumas_2_Li': {'TONAME': 'NIPS_66kV', 'FROMNUMBER': 68, 'FROMEXNAME': 'Inter_NI_DU_2_66kV_66.0', 'FROMNAME': 'Inter_NI_DU_2_66kV', 'ID': '66kV_Nicolay_Dumas_2', 'TONUMBER': 84, 'TOEXNAME': 'NIPS_66kV_66.0'}, 'Ferney_22kV_Champagne_22kV_22kV_Champagne_Ferney_Li': {'TONAME': 'Champagne_22kV', 'FROMNUMBER': 50, 'FROMEXNAME': 'Ferney_22kV_22.0', 'FROMNAME': 'Ferney_22kV', 'ID': '22kV_Champagne_Ferney', 'TONUMBER': 24, 'TOEXNAME': 'Champagne_22kV_22.0'}, 'Amaury_66kV_Bellevue_66kV_66kV_Amaury_Bellevue_2_Li': {'TONAME': 'Bellevue_66kV', 'FROMNUMBER': 2, 'FROMEXNAME': 'Amaury_66kV_66.0', 'FROMNAME': 'Amaury_66kV', 'ID': '66kV_Amaury_Bellevue_2', 'TONUMBER': 10, 'TOEXNAME': 'Bellevue_66kV_66.0'}, 'Dumas_66kV_Wooton_66kV_66kV_Dumas_Wooton_Li': {'TONAME': 'Wooton_66kV', 'FROMNUMBER': 32, 'FROMEXNAME': 'Dumas_66kV_66.0', 'FROMNAME': 'Dumas_66kV', 'ID': '66kV_Dumas_Wooton', 'TONUMBER': 123, 'TOEXNAME': 'Wooton_66kV_66.0'}, 'Bellevue_66kV_Sottise_66kV_66kV_Bellevue_Sottise_2_Li': {'TONAME': 'Sottise_66kV', 'FROMNUMBER': 10, 'FROMEXNAME': 'Bellevue_66kV_66.0', 'FROMNAME': 'Bellevue_66kV', 'ID': '66kV_Bellevue_Sottise_2', 'TONUMBER': 95, 'TOEXNAME': 'Sottise_66kV_66.0'}, 'Terminal_FVPS_Ugen_1_Line11kV_Li': {'TONAME': 'FVPS_Ugen_1', 'FROMNUMBER': 107, 'FROMEXNAME': 'Terminal_11.0', 'FROMNAME': 'Terminal', 'ID': 'Line11kV', 'TONUMBER': 46, 'TOEXNAME': 'FVPS_Ugen_1_11.0'}, 'Wooton_66kV_Ebene_66kV_66kV_Ebene_Wooton_1_Li': {'TONAME': 'Ebene_66kV', 'FROMNUMBER': 123, 'FROMEXNAME': 'Wooton_66kV_66.0', 'FROMNAME': 'Wooton_66kV', 'ID': '66kV_Ebene_Wooton_1', 'TONUMBER': 36, 'TOEXNAME': 'Ebene_66kV_66.0'}, 'Terminal_5__FVPS_Ugen_3_Line11kV_5__Li': {'TONAME': 'FVPS_Ugen_3', 'FROMNUMBER': 112, 'FROMEXNAME': 'Terminal_5__11.0', 'FROMNAME': 'Terminal_5_', 'ID': 'Line11kV(5)', 'TONUMBER': 48, 'TOEXNAME': 'FVPS_Ugen_3_11.0'}, 'StLouis_66kV_FVPS_66kV_66kV_SL_FVPS_Cable2_Li': {'TONAME': 'FVPS_66kV', 'FROMNUMBER': 98, 'FROMEXNAME': 'StLouis_66kV_66.0', 'FROMNAME': 'StLouis_66kV', 'ID': '66kV_SL_FVPS_Cable2', 'TONUMBER': 45, 'TOEXNAME': 'FVPS_66kV_66.0'}, 'Medine_22kV_1_LaChaumiere_22kV_1_22kV_LaChaumiere_Medine_22kV_Li': {'TONAME': 'LaChaumiere_22kV_1', 'FROMNUMBER': 80, 'FROMEXNAME': 'Medine_22kV_1_22.0', 'FROMNAME': 'Medine_22kV_1', 'ID': '22kV_LaChaumiere_Medine_22kV', 'TONUMBER': 72, 'TOEXNAME': 'LaChaumiere_22kV_1_22.0'}, 'Terminal_2__FVPS_Ugen_2_Line11kV_2__Li': {'TONAME': 'FVPS_Ugen_2', 'FROMNUMBER': 109, 'FROMEXNAME': 'Terminal_2__11.0', 'FROMNAME': 'Terminal_2_', 'ID': 'Line11kV(2)', 'TONUMBER': 47, 'TOEXNAME': 'FVPS_Ugen_2_11.0'}, 'LaChaumiere_66kV_StLouis_66kV_66kV_StLouis_LaChaumiere_Li': {'TONAME': 'StLouis_66kV', 'FROMNUMBER': 74, 'FROMEXNAME': 'LaChaumiere_66kV_66.0', 'FROMNAME': 'LaChaumiere_66kV', 'ID': '66kV_StLouis_LaChaumiere', 'TONUMBER': 98, 'TOEXNAME': 'StLouis_66kV_66.0'}, 'Dumas_66kV_Bellevue_66kV_66kV_Dumas_Bellevue_Li': {'TONAME': 'Bellevue_66kV', 'FROMNUMBER': 32, 'FROMEXNAME': 'Dumas_66kV_66.0', 'FROMNAME': 'Dumas_66kV', 'ID': '66kV_Dumas_Bellevue', 'TONUMBER': 10, 'TOEXNAME': 'Bellevue_66kV_66.0'}, 'Henrietta_66kV_LaChaumiere_66kV_66kV_LaChaumiere_Henrietta_2_Li': {'TONAME': 'LaChaumiere_66kV', 'FROMNUMBER': 64, 'FROMEXNAME': 'Henrietta_66kV_66.0', 'FROMNAME': 'Henrietta_66kV', 'ID': '66kV_LaChaumiere_Henrietta_2', 'TONUMBER': 74, 'TOEXNAME': 'LaChaumiere_66kV_66.0'}, 'StLouis_66kV_FVPS_66kV_66kV_SL_FVPS_Cable3_Li': {'TONAME': 'FVPS_66kV', 'FROMNUMBER': 98, 'FROMEXNAME': 'StLouis_66kV_66.0', 'FROMNAME': 'StLouis_66kV', 'ID': '66kV_SL_FVPS_Cable3', 'TONUMBER': 45, 'TOEXNAME': 'FVPS_66kV_66.0'}, 'LeVal_22kV_Wooton_22kV_2_22kV_Wooton_LeVal_Li': {'TONAME': 'Wooton_22kV_2', 'FROMNUMBER': 76, 'FROMEXNAME': 'LeVal_22kV_22.0', 'FROMNAME': 'LeVal_22kV', 'ID': '22kV_Wooton_LeVal', 'TONUMBER': 122, 'TOEXNAME': 'Wooton_22kV_2_22.0'}, 'Inter_NI_DU_1_66kV_NIPS_66kV_66kV_Nicolay_Dumas_1_Li': {'TONAME': 'NIPS_66kV', 'FROMNUMBER': 67, 'FROMEXNAME': 'Inter_NI_DU_1_66kV_66.0', 'FROMNAME': 'Inter_NI_DU_1_66kV', 'ID': '66kV_Nicolay_Dumas_1', 'TONUMBER': 84, 'TOEXNAME': 'NIPS_66kV_66.0'}, 'Inter_Anahita_Fuel_66kV_Anahita_66kV_66kV_Anahita_Fuel_OHL_Li': {'TONAME': 'Anahita_66kV', 'FROMNUMBER': 65, 'FROMEXNAME': 'Inter_Anahita_Fuel_66kV_66.0', 'FROMNAME': 'Inter_Anahita_Fuel_66kV', 'ID': '66kV_Anahita_Fuel_OHL', 'TONUMBER': 5, 'TOEXNAME': 'Anahita_66kV_66.0'}, 'Terminal_7__FVPS_Ugen_4_Line11kV_7__Li': {'TONAME': 'FVPS_Ugen_4', 'FROMNUMBER': 114, 'FROMEXNAME': 'Terminal_7__11.0', 'FROMNAME': 'Terminal_7_', 'ID': 'Line11kV(7)', 'TONUMBER': 49, 'TOEXNAME': 'FVPS_Ugen_4_11.0'}, 'Dumas_66kV_FortGeorge_66kV_66kV_FortGeorge_Dumas_2_Li': {'TONAME': 'FortGeorge_66kV', 'FROMNUMBER': 32, 'FROMEXNAME': 'Dumas_66kV_66.0', 'FROMNAME': 'Dumas_66kV', 'ID': '66kV_FortGeorge_Dumas_2', 'TONUMBER': 55, 'TOEXNAME': 'FortGeorge_66kV_66.0'}, 'UnionVale_66kV_Champagne_66kV_66kV_UnionVale_Champagne_Li': {'TONAME': 'Champagne_66kV', 'FROMNUMBER': 120, 'FROMEXNAME': 'UnionVale_66kV_66.0', 'FROMNAME': 'UnionVale_66kV', 'ID': '66kV_UnionVale_Champagne', 'TONUMBER': 25, 'TOEXNAME': 'Champagne_66kV_66.0'}, 'Terminal_3__FVPS_Ugen_2_Line11kV_3__Li': {'TONAME': 'FVPS_Ugen_2', 'FROMNUMBER': 110, 'FROMEXNAME': 'Terminal_3__11.0', 'FROMNAME': 'Terminal_3_', 'ID': 'Line11kV(3)', 'TONUMBER': 47, 'TOEXNAME': 'FVPS_Ugen_2_11.0'}, 'Terminal_4__FVPS_Ugen_3_Line11kV_4__Li': {'TONAME': 'FVPS_Ugen_3', 'FROMNUMBER': 111, 'FROMEXNAME': 'Terminal_4__11.0', 'FROMNAME': 'Terminal_4_', 'ID': 'Line11kV(4)', 'TONUMBER': 48, 'TOEXNAME': 'FVPS_Ugen_3_11.0'}, 'Amaury_66kV_Fuel_66kV_66kV_Amaury_Fuel_2_Li': {'TONAME': 'Fuel_66kV', 'FROMNUMBER': 2, 'FROMEXNAME': 'Amaury_66kV_66.0', 'FROMNAME': 'Amaury_66kV', 'ID': '66kV_Amaury_Fuel_2', 'TONUMBER': 58, 'TOEXNAME': 'Fuel_66kV_66.0'}, 'Curepipe_22kV_Henrietta_22kV_1_22kV_PlaineSophie_Henrietta_Li': {'TONAME': 'Henrietta_22kV_1', 'FROMNUMBER': 31, 'FROMEXNAME': 'Curepipe_22kV_22.0', 'FROMNAME': 'Curepipe_22kV', 'ID': '22kV_PlaineSophie_Henrietta', 'TONUMBER': 62, 'TOEXNAME': 'Henrietta_22kV_1_22.0'}, 'Ebene_66kV_StLouis_66kV_66kV_StLouis_Ebene_2_Li': {'TONAME': 'StLouis_66kV', 'FROMNUMBER': 36, 'FROMEXNAME': 'Ebene_66kV_66.0', 'FROMNAME': 'Ebene_66kV', 'ID': '66kV_StLouis_Ebene_2', 'TONUMBER': 98, 'TOEXNAME': 'StLouis_66kV_66.0'}, 'Fuel_PowerStation_66kV_Fuel_66kV_66kV_FuelPowerStation_Fuel_Li': {'TONAME': 'Fuel_66kV', 'FROMNUMBER': 61, 'FROMEXNAME': 'Fuel_PowerStation_66kV_66.0', 'FROMNAME': 'Fuel_PowerStation_66kV', 'ID': '66kV_FuelPowerStation_Fuel', 'TONUMBER': 58, 'TOEXNAME': 'Fuel_66kV_66.0'}, 'Dumas_66kV_Amaury_66kV_66kV_Dumas_Amaury_Li': {'TONAME': 'Amaury_66kV', 'FROMNUMBER': 32, 'FROMEXNAME': 'Dumas_66kV_66.0', 'FROMNAME': 'Dumas_66kV', 'ID': '66kV_Dumas_Amaury', 'TONUMBER': 2, 'TOEXNAME': 'Amaury_66kV_66.0'}, 'StLouis_66kV_FVPS_66kV_66kV_SL_FVPS_Cable4_Li': {'TONAME': 'FVPS_66kV', 'FROMNUMBER': 98, 'FROMEXNAME': 'StLouis_66kV_66.0', 'FROMNAME': 'StLouis_66kV', 'ID': '66kV_SL_FVPS_Cable4', 'TONUMBER': 45, 'TOEXNAME': 'FVPS_66kV_66.0'}, 'Champagne_66kV_Wooton_66kV_66kV_Champagne_Wooton_1_Li': {'TONAME': 'Wooton_66kV', 'FROMNUMBER': 25, 'FROMEXNAME': 'Champagne_66kV_66.0', 'FROMNAME': 'Champagne_66kV', 'ID': '66kV_Champagne_Wooton_1', 'TONUMBER': 123, 'TOEXNAME': 'Wooton_66kV_66.0'}, 'TourKoening_66kV_StLouis_66kV_66kV_StLouis_TourKoening_Li': {'TONAME': 'StLouis_66kV', 'FROMNUMBER': 117, 'FROMEXNAME': 'TourKoening_66kV_66.0', 'FROMNAME': 'TourKoening_66kV', 'ID': '66kV_StLouis_TourKoening', 'TONUMBER': 98, 'TOEXNAME': 'StLouis_66kV_66.0'}, 'StLouis_66kV_FVPS_66kV_66kV_SL_FVPS_Cable1_Li': {'TONAME': 'FVPS_66kV', 'FROMNUMBER': 98, 'FROMEXNAME': 'StLouis_66kV_66.0', 'FROMNAME': 'StLouis_66kV', 'ID': '66kV_SL_FVPS_Cable1', 'TONUMBER': 45, 'TOEXNAME': 'FVPS_66kV_66.0'}, 'UnionVale_66kV_CTSAV_G2_66kV_66kV_CTSAVG2_UnionVale_Li': {'TONAME': 'CTSAV_G2_66kV', 'FROMNUMBER': 120, 'FROMEXNAME': 'UnionVale_66kV_66.0', 'FROMNAME': 'UnionVale_66kV', 'ID': '66kV_CTSAVG2_UnionVale', 'TONUMBER': 17, 'TOEXNAME': 'CTSAV_G2_66kV_66.0'}, 'TourKoening_66kV_LaChaumiere_66kV_66kV_LaChaumiere_TourKoening_Li': {'TONAME': 'LaChaumiere_66kV', 'FROMNUMBER': 117, 'FROMEXNAME': 'TourKoening_66kV_66.0', 'FROMNAME': 'TourKoening_66kV', 'ID': '66kV_LaChaumiere_TourKoening', 'TONUMBER': 74, 'TOEXNAME': 'LaChaumiere_66kV_66.0'}, 'Sarako_66kV_LaChaumiere_66kV_66kV_Sarako_LaChaumiere_Li': {'TONAME': 'LaChaumiere_66kV', 'FROMNUMBER': 92, 'FROMEXNAME': 'Sarako_66kV_66.0', 'FROMNAME': 'Sarako_66kV', 'ID': '66kV_Sarako_LaChaumiere', 'TONUMBER': 74, 'TOEXNAME': 'LaChaumiere_66kV_66.0'}, 'Combo_66kV_UnionVale_66kV_66kV_UnionVale_Combo_Li': {'TONAME': 'UnionVale_66kV', 'FROMNUMBER': 30, 'FROMEXNAME': 'Combo_66kV_66.0', 'FROMNAME': 'Combo_66kV', 'ID': '66kV_UnionVale_Combo', 'TONUMBER': 120, 'TOEXNAME': 'UnionVale_66kV_66.0'}, 'BeauchampPowerStation_66kV_Anahita_66kV_66kV_Anahita_Beauchamp_Li': {'TONAME': 'Anahita_66kV', 'FROMNUMBER': 6, 'FROMEXNAME': 'BeauchampPowerStation_66kV_66.0', 'FROMNAME': 'BeauchampPowerStation_66kV', 'ID': '66kV_Anahita_Beauchamp', 'TONUMBER': 5, 'TOEXNAME': 'Anahita_66kV_66.0'}, 'Bellevue_66kV_Sottise_66kV_66kV_Bellevue_Sottise_1_Li': {'TONAME': 'Sottise_66kV', 'FROMNUMBER': 10, 'FROMEXNAME': 'Bellevue_66kV_66.0', 'FROMNAME': 'Bellevue_66kV', 'ID': '66kV_Bellevue_Sottise_1', 'TONUMBER': 95, 'TOEXNAME': 'Sottise_66kV_66.0'}, 'Amaury_22kV_1_PlaineDesRochesPowerStation_22kV_22kV_PlaineDesRochesPowerStation_Li': {'TONAME': 'PlaineDesRochesPowerStation_22kV', 'FROMNUMBER': 0, 'FROMEXNAME': 'Amaury_22kV_1_22.0', 'FROMNAME': 'Amaury_22kV_1', 'ID': '22kV_PlaineDesRochesPowerStation', 'TONUMBER': 90, 'TOEXNAME': 'PlaineDesRochesPowerStation_22kV_22.0'}, 'Jin_Fei_66kV_Bellevue_66kV_66kV_Bellevue_Jin_Fei_Li': {'TONAME': 'Bellevue_66kV', 'FROMNUMBER': 71, 'FROMEXNAME': 'Jin_Fei_66kV_66.0', 'FROMNAME': 'Jin_Fei_66kV', 'ID': '66kV_Bellevue_Jin_Fei', 'TONUMBER': 10, 'TOEXNAME': 'Bellevue_66kV_66.0'}, 'Inter_CN_CO_66kV_CaseNoyale_66kV_66kV_Combo_CaseNoyale_PartUGC_Li': {'TONAME': 'CaseNoyale_66kV', 'FROMNUMBER': 66, 'FROMEXNAME': 'Inter_CN_CO_66kV_66.0', 'FROMNAME': 'Inter_CN_CO_66kV', 'ID': '66kV_Combo_CaseNoyale_PartUGC', 'TONUMBER': 21, 'TOEXNAME': 'CaseNoyale_66kV_66.0'}, 'Champagne_66kV_Fuel_66kV_66kV_Champagne_Fuel_Li': {'TONAME': 'Fuel_66kV', 'FROMNUMBER': 25, 'FROMEXNAME': 'Champagne_66kV_66.0', 'FROMNAME': 'Champagne_66kV', 'ID': '66kV_Champagne_Fuel', 'TONUMBER': 58, 'TOEXNAME': 'Fuel_66kV_66.0'}, 'Inter_Anahita_Fuel_66kV_Fuel_66kV_66kV_Anahita_Fuel_UGC_Li': {'TONAME': 'Fuel_66kV', 'FROMNUMBER': 65, 'FROMEXNAME': 'Inter_Anahita_Fuel_66kV_66.0', 'FROMNAME': 'Inter_Anahita_Fuel_66kV', 'ID': '66kV_Anahita_Fuel_UGC', 'TONUMBER': 58, 'TOEXNAME': 'Fuel_66kV_66.0'}} +TransfoDico = {'Anahita_66kV_Anahita_22kV_1_Anahita_TS1_Tr': {'TONAME': 'Anahita_22kV_1', 'FROMNUMBER': 5, '#WIND': 2, 'FROMEXNAME': 'Anahita_66kV_66.0', 'FROMNAME': 'Anahita_66kV', 'ID': 'Anahita_TS1', 'TONUMBER': 3, 'TOEXNAME': 'Anahita_22kV_122.0'}, 'FVPS_66kV_FVPS_Ugen_3_FVPS_TP_2_Tr': {'TONAME': 'FVPS_Ugen_3', 'FROMNUMBER': 45, '#WIND': 2, 'FROMEXNAME': 'FVPS_66kV_66.0', 'FROMNAME': 'FVPS_66kV', 'ID': 'FVPS_TP_2', 'TONUMBER': 48, 'TOEXNAME': 'FVPS_Ugen_311.0'}, 'NIPS_66kV_NIPS_G1_Ugen_NIPS_TP1_Tr': {'TONAME': 'NIPS_G1_Ugen', 'FROMNUMBER': 84, '#WIND': 2, 'FROMEXNAME': 'NIPS_66kV_66.0', 'FROMNAME': 'NIPS_66kV', 'ID': 'NIPS_TP1', 'TONUMBER': 85, 'TOEXNAME': 'NIPS_G1_Ugen11.0'}, 'CTSAV_G1_66kV_CTSAV_G1_Ugen_CTSAV_G1_TP_Tr': {'TONAME': 'CTSAV_G1_Ugen', 'FROMNUMBER': 15, '#WIND': 2, 'FROMEXNAME': 'CTSAV_G1_66kV_66.0', 'FROMNAME': 'CTSAV_G1_66kV', 'ID': 'CTSAV_G1_TP', 'TONUMBER': 16, 'TOEXNAME': 'CTSAV_G1_Ugen11.0'}, 'FortGeorge_66kV_FGPS_Ugen1_FGPS_TP1_Tr': {'TONAME': 'FGPS_Ugen1', 'FROMNUMBER': 55, '#WIND': 2, 'FROMEXNAME': 'FortGeorge_66kV_66.0', 'FROMNAME': 'FortGeorge_66kV', 'ID': 'FGPS_TP1', 'TONUMBER': 37, 'TOEXNAME': 'FGPS_Ugen111.0'}, 'StLouis_66kV_StLouis_Ugen_12_StLouisG12_TP_Tr': {'TONAME': 'StLouis_Ugen_12', 'FROMNUMBER': 98, '#WIND': 2, 'FROMEXNAME': 'StLouis_66kV_66.0', 'FROMNAME': 'StLouis_66kV', 'ID': 'StLouisG12_TP', 'TONUMBER': 101, 'TOEXNAME': 'StLouis_Ugen_1211.0'}, 'Henrietta_22kV_1_Tamarind_G1_Ugen_Tamarind_G1_TP_Tr': {'TONAME': 'Tamarind_G1_Ugen', 'FROMNUMBER': 62, '#WIND': 2, 'FROMEXNAME': 'Henrietta_22kV_1_22.0', 'FROMNAME': 'Henrietta_22kV_1', 'ID': 'Tamarind_G1_TP', 'TONUMBER': 106, 'TOEXNAME': 'Tamarind_G1_Ugen6.599999904632568'}, 'FortGeorge_66kV_FGPS_Ugen5_FGPS_TP5_Tr': {'TONAME': 'FGPS_Ugen5', 'FROMNUMBER': 55, '#WIND': 2, 'FROMEXNAME': 'FortGeorge_66kV_66.0', 'FROMNAME': 'FortGeorge_66kV', 'ID': 'FGPS_TP5', 'TONUMBER': 41, 'TOEXNAME': 'FGPS_Ugen511.0'}, 'Sarako_66kV_Sarako_22kV_Sarako_TP_Tr': {'TONAME': 'Sarako_22kV', 'FROMNUMBER': 92, '#WIND': 2, 'FROMEXNAME': 'Sarako_66kV_66.0', 'FROMNAME': 'Sarako_66kV', 'ID': 'Sarako_TP', 'TONUMBER': 91, 'TOEXNAME': 'Sarako_22kV22.0'}, 'Sottise_66kV_Sottise_22kV_1_Sottise_TS1_Tr': {'TONAME': 'Sottise_22kV_1', 'FROMNUMBER': 95, '#WIND': 2, 'FROMEXNAME': 'Sottise_66kV_66.0', 'FROMNAME': 'Sottise_66kV', 'ID': 'Sottise_TS1', 'TONUMBER': 93, 'TOEXNAME': 'Sottise_22kV_122.0'}, 'FortGeorge_66kV_FortGeorge_22kV_1_FortGeorge_TS3_Tr': {'TONAME': 'FortGeorge_22kV_1', 'FROMNUMBER': 55, '#WIND': 2, 'FROMEXNAME': 'FortGeorge_66kV_66.0', 'FROMNAME': 'FortGeorge_66kV', 'ID': 'FortGeorge_TS3', 'TONUMBER': 53, 'TOEXNAME': 'FortGeorge_22kV_122.0'}, 'CTDS_G1_66kV_CTDS_G1_Ugen_CTDS_G1_TP_Tr': {'TONAME': 'CTDS_G1_Ugen', 'FROMNUMBER': 13, '#WIND': 2, 'FROMEXNAME': 'CTDS_G1_66kV_66.0', 'FROMNAME': 'CTDS_G1_66kV', 'ID': 'CTDS_G1_TP', 'TONUMBER': 14, 'TOEXNAME': 'CTDS_G1_Ugen11.0'}, 'BeauchampPowerStation_66kV_Beauchamp_G1_Ugen_Beauchamp_G1_TP_Tr': {'TONAME': 'Beauchamp_G1_Ugen', 'FROMNUMBER': 6, '#WIND': 2, 'FROMEXNAME': 'BeauchampPowerStation_66kV_66.0', 'FROMNAME': 'BeauchampPowerStation_66kV', 'ID': 'Beauchamp_G1_TP', 'TONUMBER': 7, 'TOEXNAME': 'Beauchamp_G1_Ugen15.0'}, 'CTSAV_G2_66kV_CTSAV_G2_Ugen_CTSAV_G2_TP_Tr': {'TONAME': 'CTSAV_G2_Ugen', 'FROMNUMBER': 17, '#WIND': 2, 'FROMEXNAME': 'CTSAV_G2_66kV_66.0', 'FROMNAME': 'CTSAV_G2_66kV', 'ID': 'CTSAV_G2_TP', 'TONUMBER': 18, 'TOEXNAME': 'CTSAV_G2_Ugen11.0'}, 'FVPS_22kV_3_FVPS_Ugen_3_FVPS_TS3_Tr': {'TONAME': 'FVPS_Ugen_3', 'FROMNUMBER': 44, '#WIND': 2, 'FROMEXNAME': 'FVPS_22kV_3_22.0', 'FROMNAME': 'FVPS_22kV_3', 'ID': 'FVPS_TS3', 'TONUMBER': 48, 'TOEXNAME': 'FVPS_Ugen_311.0'}, 'Cecile_22kV_Cecile_G1_Ugen_Cecile_G2_TP2_Tr': {'TONAME': 'Cecile_G1_Ugen', 'FROMNUMBER': 22, '#WIND': 2, 'FROMEXNAME': 'Cecile_22kV_22.0', 'FROMNAME': 'Cecile_22kV', 'ID': 'Cecile_G2_TP2', 'TONUMBER': 23, 'TOEXNAME': 'Cecile_G1_Ugen6.599999904632568'}, 'Medine_22kV_1_Medine_G1_Ugen_Medine_G1_TP_Tr': {'TONAME': 'Medine_G1_Ugen', 'FROMNUMBER': 80, '#WIND': 2, 'FROMEXNAME': 'Medine_22kV_1_22.0', 'FROMNAME': 'Medine_22kV_1', 'ID': 'Medine_G1_TP', 'TONUMBER': 82, 'TOEXNAME': 'Medine_G1_Ugen6.599999904632568'}, 'Champagne_66kV_Champagne_22kV_Champagne_TS1_Tr': {'TONAME': 'Champagne_22kV', 'FROMNUMBER': 25, '#WIND': 2, 'FROMEXNAME': 'Champagne_66kV_66.0', 'FROMNAME': 'Champagne_66kV', 'ID': 'Champagne_TS1', 'TONUMBER': 24, 'TOEXNAME': 'Champagne_22kV22.0'}, 'Henrietta_22kV_2_Magenta_G1_Ugen_Magenta_G1_TP_Tr': {'TONAME': 'Magenta_G1_Ugen', 'FROMNUMBER': 63, '#WIND': 2, 'FROMEXNAME': 'Henrietta_22kV_2_22.0', 'FROMNAME': 'Henrietta_22kV_2', 'ID': 'Magenta_G1_TP', 'TONUMBER': 79, 'TOEXNAME': 'Magenta_G1_Ugen6.599999904632568'}, 'UnionVale_66kV_UnionVale_22kV_2_UnionVale_TS2_Tr': {'TONAME': 'UnionVale_22kV_2', 'FROMNUMBER': 120, '#WIND': 2, 'FROMEXNAME': 'UnionVale_66kV_66.0', 'FROMNAME': 'UnionVale_66kV', 'ID': 'UnionVale_TS2', 'TONUMBER': 119, 'TOEXNAME': 'UnionVale_22kV_222.0'}, 'StLouis_66kV_StLouis_Ugen_10_StLouisG10_TP_Tr': {'TONAME': 'StLouis_Ugen_10', 'FROMNUMBER': 98, '#WIND': 2, 'FROMEXNAME': 'StLouis_66kV_66.0', 'FROMNAME': 'StLouis_66kV', 'ID': 'StLouisG10_TP', 'TONUMBER': 99, 'TOEXNAME': 'StLouis_Ugen_1011.0'}, 'Amaury_66kV_Amaury_22kV_2_Amaury_TS2_Tr': {'TONAME': 'Amaury_22kV_2', 'FROMNUMBER': 2, '#WIND': 2, 'FROMEXNAME': 'Amaury_66kV_66.0', 'FROMNAME': 'Amaury_66kV', 'ID': 'Amaury_TS2', 'TONUMBER': 1, 'TOEXNAME': 'Amaury_22kV_222.0'}, 'Bellevue_66kV_Bellevue_22kV_1_Bellevue_TS1_Tr': {'TONAME': 'Bellevue_22kV_1', 'FROMNUMBER': 10, '#WIND': 2, 'FROMEXNAME': 'Bellevue_66kV_66.0', 'FROMNAME': 'Bellevue_66kV', 'ID': 'Bellevue_TS1', 'TONUMBER': 8, 'TOEXNAME': 'Bellevue_22kV_122.0'}, 'Medine_22kV_2_Medine_G2_Ugen_Medine_G2_TP_Tr': {'TONAME': 'Medine_G2_Ugen', 'FROMNUMBER': 81, '#WIND': 2, 'FROMEXNAME': 'Medine_22kV_2_22.0', 'FROMNAME': 'Medine_22kV_2', 'ID': 'Medine_G2_TP', 'TONUMBER': 83, 'TOEXNAME': 'Medine_G2_Ugen6.599999904632568'}, 'NIPS_66kV_Nicolay_22kV_1_Nicolay_TS1_Tr': {'TONAME': 'Nicolay_22kV_1', 'FROMNUMBER': 84, '#WIND': 2, 'FROMEXNAME': 'NIPS_66kV_66.0', 'FROMNAME': 'NIPS_66kV', 'ID': 'Nicolay_TS1', 'TONUMBER': 88, 'TOEXNAME': 'Nicolay_22kV_122.0'}, 'Fuel_66kV_Fuel_22kV_2_Fuel_TS2_Tr': {'TONAME': 'Fuel_22kV_2', 'FROMNUMBER': 58, '#WIND': 2, 'FROMEXNAME': 'Fuel_66kV_66.0', 'FROMNAME': 'Fuel_66kV', 'ID': 'Fuel_TS2', 'TONUMBER': 57, 'TOEXNAME': 'Fuel_22kV_222.0'}, 'FVPS_66kV_FVPS_Ugen_3_FVPS_TP_4_Tr': {'TONAME': 'FVPS_Ugen_3', 'FROMNUMBER': 45, '#WIND': 2, 'FROMEXNAME': 'FVPS_66kV_66.0', 'FROMNAME': 'FVPS_66kV', 'ID': 'FVPS_TP_4', 'TONUMBER': 48, 'TOEXNAME': 'FVPS_Ugen_311.0'}, 'StLouis_66kV_StLouis_22kV_1_StLouis_TS1_Tr': {'TONAME': 'StLouis_22kV_1', 'FROMNUMBER': 98, '#WIND': 2, 'FROMEXNAME': 'StLouis_66kV_66.0', 'FROMNAME': 'StLouis_66kV', 'ID': 'StLouis_TS1', 'TONUMBER': 96, 'TOEXNAME': 'StLouis_22kV_122.0'}, 'StLouis_66kV_StLouis_Ugen_7_StLouisG7_TP_Tr': {'TONAME': 'StLouis_Ugen_7', 'FROMNUMBER': 98, '#WIND': 2, 'FROMEXNAME': 'StLouis_66kV_66.0', 'FROMNAME': 'StLouis_66kV', 'ID': 'StLouisG7_TP', 'TONUMBER': 103, 'TOEXNAME': 'StLouis_Ugen_711.0'}, 'UnionVale_66kV_UnionVale_22kV_1_UnionVale_TS1_Tr': {'TONAME': 'UnionVale_22kV_1', 'FROMNUMBER': 120, '#WIND': 2, 'FROMEXNAME': 'UnionVale_66kV_66.0', 'FROMNAME': 'UnionVale_66kV', 'ID': 'UnionVale_TS1', 'TONUMBER': 118, 'TOEXNAME': 'UnionVale_22kV_122.0'}, 'Bellevue_66kV_Bellevue_G1_Ugen_Bellevue_G1_TP_Tr': {'TONAME': 'Bellevue_G1_Ugen', 'FROMNUMBER': 10, '#WIND': 2, 'FROMEXNAME': 'Bellevue_66kV_66.0', 'FROMNAME': 'Bellevue_66kV', 'ID': 'Bellevue_G1_TP', 'TONUMBER': 11, 'TOEXNAME': 'Bellevue_G1_Ugen11.0'}, 'Bellevue_66kV_Bellevue_G2_Ugen_Bellevue_G2_TP_Tr': {'TONAME': 'Bellevue_G2_Ugen', 'FROMNUMBER': 10, '#WIND': 2, 'FROMEXNAME': 'Bellevue_66kV_66.0', 'FROMNAME': 'Bellevue_66kV', 'ID': 'Bellevue_G2_TP', 'TONUMBER': 12, 'TOEXNAME': 'Bellevue_G2_Ugen11.0'}, 'Fuel_PowerStation_66kV_Fuel_G1_Ugen_Fuel_G1_TP_Tr': {'TONAME': 'Fuel_G1_Ugen', 'FROMNUMBER': 61, '#WIND': 2, 'FROMEXNAME': 'Fuel_PowerStation_66kV_66.0', 'FROMNAME': 'Fuel_PowerStation_66kV', 'ID': 'Fuel_G1_TP', 'TONUMBER': 59, 'TOEXNAME': 'Fuel_G1_Ugen6.599999904632568'}, 'LeVal_22kV_LeVal_G1_Ugen_LeVal_TP1_Tr': {'TONAME': 'LeVal_G1_Ugen', 'FROMNUMBER': 76, '#WIND': 2, 'FROMEXNAME': 'LeVal_22kV_22.0', 'FROMNAME': 'LeVal_22kV', 'ID': 'LeVal_TP1', 'TONUMBER': 77, 'TOEXNAME': 'LeVal_G1_Ugen6.599999904632568'}, 'StLouis_66kV_StLouis_22kV_2_StLouis_TS2_Tr': {'TONAME': 'StLouis_22kV_2', 'FROMNUMBER': 98, '#WIND': 2, 'FROMEXNAME': 'StLouis_66kV_66.0', 'FROMNAME': 'StLouis_66kV', 'ID': 'StLouis_TS2', 'TONUMBER': 97, 'TOEXNAME': 'StLouis_22kV_222.0'}, 'Ebene_66kV_Ebene_22kV_3_Ebene_TS3_Tr': {'TONAME': 'Ebene_22kV_3', 'FROMNUMBER': 36, '#WIND': 2, 'FROMEXNAME': 'Ebene_66kV_66.0', 'FROMNAME': 'Ebene_66kV', 'ID': 'Ebene_TS3', 'TONUMBER': 35, 'TOEXNAME': 'Ebene_22kV_322.0'}, 'StLouis_66kV_StLouis_Ugen_9_StLouisG9_TP_Tr': {'TONAME': 'StLouis_Ugen_9', 'FROMNUMBER': 98, '#WIND': 2, 'FROMEXNAME': 'StLouis_66kV_66.0', 'FROMNAME': 'StLouis_66kV', 'ID': 'StLouisG9_TP', 'TONUMBER': 105, 'TOEXNAME': 'StLouis_Ugen_911.0'}, 'LaChaumiere_66kV_LaChaumiere_22kV_2_LaChaumiere_TS2_Tr': {'TONAME': 'LaChaumiere_22kV_2', 'FROMNUMBER': 74, '#WIND': 2, 'FROMEXNAME': 'LaChaumiere_66kV_66.0', 'FROMNAME': 'LaChaumiere_66kV', 'ID': 'LaChaumiere_TS2', 'TONUMBER': 73, 'TOEXNAME': 'LaChaumiere_22kV_222.0'}, 'StLouis_66kV_StLouis_Ugen_8_StLouisG8_TP_Tr': {'TONAME': 'StLouis_Ugen_8', 'FROMNUMBER': 98, '#WIND': 2, 'FROMEXNAME': 'StLouis_66kV_66.0', 'FROMNAME': 'StLouis_66kV', 'ID': 'StLouisG8_TP', 'TONUMBER': 104, 'TOEXNAME': 'StLouis_Ugen_811.0'}, 'Ferney_22kV_Ferney_G2_Ugen_Ferney_G2_TP_Tr': {'TONAME': 'Ferney_G2_Ugen', 'FROMNUMBER': 50, '#WIND': 2, 'FROMEXNAME': 'Ferney_22kV_22.0', 'FROMNAME': 'Ferney_22kV', 'ID': 'Ferney_G2_TP', 'TONUMBER': 52, 'TOEXNAME': 'Ferney_G2_Ugen6.599999904632568'}, 'Ebene_66kV_Ebene_22kV_2_Ebene_TS2_Tr': {'TONAME': 'Ebene_22kV_2', 'FROMNUMBER': 36, '#WIND': 2, 'FROMEXNAME': 'Ebene_66kV_66.0', 'FROMNAME': 'Ebene_66kV', 'ID': 'Ebene_TS2', 'TONUMBER': 34, 'TOEXNAME': 'Ebene_22kV_222.0'}, 'Combo_66kV_Combo_22kV_1_Combo_TS1_Tr': {'TONAME': 'Combo_22kV_1', 'FROMNUMBER': 30, '#WIND': 2, 'FROMEXNAME': 'Combo_66kV_66.0', 'FROMNAME': 'Combo_66kV', 'ID': 'Combo_TS1', 'TONUMBER': 28, 'TOEXNAME': 'Combo_22kV_122.0'}, 'Anahita_66kV_Anahita_22kV_2_Anahita_TS2_Tr': {'TONAME': 'Anahita_22kV_2', 'FROMNUMBER': 5, '#WIND': 2, 'FROMEXNAME': 'Anahita_66kV_66.0', 'FROMNAME': 'Anahita_66kV', 'ID': 'Anahita_TS2', 'TONUMBER': 4, 'TOEXNAME': 'Anahita_22kV_222.0'}, 'FortGeorge_66kV_FGPS_Ugen4_FGPS_TP4_Tr': {'TONAME': 'FGPS_Ugen4', 'FROMNUMBER': 55, '#WIND': 2, 'FROMEXNAME': 'FortGeorge_66kV_66.0', 'FROMNAME': 'FortGeorge_66kV', 'ID': 'FGPS_TP4', 'TONUMBER': 40, 'TOEXNAME': 'FGPS_Ugen411.0'}, 'CaseNoyale_66kV_CaseNoyale_22kV_1_CaseNoyale_TS1_Tr': {'TONAME': 'CaseNoyale_22kV_1', 'FROMNUMBER': 21, '#WIND': 2, 'FROMEXNAME': 'CaseNoyale_66kV_66.0', 'FROMNAME': 'CaseNoyale_66kV', 'ID': 'CaseNoyale_TS1', 'TONUMBER': 19, 'TOEXNAME': 'CaseNoyale_22kV_122.0'}, 'Sottise_66kV_Sottise_22kV_2_Sottise_TS2_Tr': {'TONAME': 'Sottise_22kV_2', 'FROMNUMBER': 95, '#WIND': 2, 'FROMEXNAME': 'Sottise_66kV_66.0', 'FROMNAME': 'Sottise_66kV', 'ID': 'Sottise_TS2', 'TONUMBER': 94, 'TOEXNAME': 'Sottise_22kV_222.0'}, 'Jin_Fei_66kV_Jin_Fei_22kV_1_Jin_Fei_TS1_Tr': {'TONAME': 'Jin_Fei_22kV_1', 'FROMNUMBER': 71, '#WIND': 2, 'FROMEXNAME': 'Jin_Fei_66kV_66.0', 'FROMNAME': 'Jin_Fei_66kV', 'ID': 'Jin_Fei_TS1', 'TONUMBER': 69, 'TOEXNAME': 'Jin_Fei_22kV_122.0'}, 'TourKoening_66kV_TourKoening_22kV_2_TourKoening_TS2_Tr': {'TONAME': 'TourKoening_22kV_2', 'FROMNUMBER': 117, '#WIND': 2, 'FROMEXNAME': 'TourKoening_66kV_66.0', 'FROMNAME': 'TourKoening_66kV', 'ID': 'TourKoening_TS2', 'TONUMBER': 116, 'TOEXNAME': 'TourKoening_22kV_222.0'}, 'FortGeorge_66kV_FGPS_Ugen3_FGPS_TP3_Tr': {'TONAME': 'FGPS_Ugen3', 'FROMNUMBER': 55, '#WIND': 2, 'FROMEXNAME': 'FortGeorge_66kV_66.0', 'FROMNAME': 'FortGeorge_66kV', 'ID': 'FGPS_TP3', 'TONUMBER': 39, 'TOEXNAME': 'FGPS_Ugen311.0'}, 'CaseNoyale_66kV_CaseNoyale_22kV_2_CaseNoyale_TS2_Tr': {'TONAME': 'CaseNoyale_22kV_2', 'FROMNUMBER': 21, '#WIND': 2, 'FROMEXNAME': 'CaseNoyale_66kV_66.0', 'FROMNAME': 'CaseNoyale_66kV', 'ID': 'CaseNoyale_TS2', 'TONUMBER': 20, 'TOEXNAME': 'CaseNoyale_22kV_222.0'}, 'FVPS_22kV_1_FVPS_Ugen_2_FVPS_TS1_Tr': {'TONAME': 'FVPS_Ugen_2', 'FROMNUMBER': 42, '#WIND': 2, 'FROMEXNAME': 'FVPS_22kV_1_22.0', 'FROMNAME': 'FVPS_22kV_1', 'ID': 'FVPS_TS1', 'TONUMBER': 47, 'TOEXNAME': 'FVPS_Ugen_211.0'}, 'NIPS_66kV_NIPS_G3_Ugen_NIPS_TP3_Tr': {'TONAME': 'NIPS_G3_Ugen', 'FROMNUMBER': 84, '#WIND': 2, 'FROMEXNAME': 'NIPS_66kV_66.0', 'FROMNAME': 'NIPS_66kV', 'ID': 'NIPS_TP3', 'TONUMBER': 87, 'TOEXNAME': 'NIPS_G3_Ugen11.0'}, 'Fuel_66kV_Fuel_22kV_1_Fuel_TS1_Tr': {'TONAME': 'Fuel_22kV_1', 'FROMNUMBER': 58, '#WIND': 2, 'FROMEXNAME': 'Fuel_66kV_66.0', 'FROMNAME': 'Fuel_66kV', 'ID': 'Fuel_TS1', 'TONUMBER': 56, 'TOEXNAME': 'Fuel_22kV_122.0'}, 'Amaury_66kV_Amaury_22kV_1_Amaury_TS1_Tr': {'TONAME': 'Amaury_22kV_1', 'FROMNUMBER': 2, '#WIND': 2, 'FROMEXNAME': 'Amaury_66kV_66.0', 'FROMNAME': 'Amaury_66kV', 'ID': 'Amaury_TS1', 'TONUMBER': 0, 'TOEXNAME': 'Amaury_22kV_122.0'}, 'TourKoening_66kV_TourKoening_22kV_1_TourKoening_TS1_Tr': {'TONAME': 'TourKoening_22kV_1', 'FROMNUMBER': 117, '#WIND': 2, 'FROMEXNAME': 'TourKoening_66kV_66.0', 'FROMNAME': 'TourKoening_66kV', 'ID': 'TourKoening_TS1', 'TONUMBER': 115, 'TOEXNAME': 'TourKoening_22kV_122.0'}, 'Wooton_66kV_Wooton_22kV_2_Wooton_TS2_Tr': {'TONAME': 'Wooton_22kV_2', 'FROMNUMBER': 123, '#WIND': 2, 'FROMEXNAME': 'Wooton_66kV_66.0', 'FROMNAME': 'Wooton_66kV', 'ID': 'Wooton_TS2', 'TONUMBER': 122, 'TOEXNAME': 'Wooton_22kV_222.0'}, 'Ebene_66kV_Ebene_22kV_1_Ebene_TS1_Tr': {'TONAME': 'Ebene_22kV_1', 'FROMNUMBER': 36, '#WIND': 2, 'FROMEXNAME': 'Ebene_66kV_66.0', 'FROMNAME': 'Ebene_66kV', 'ID': 'Ebene_TS1', 'TONUMBER': 33, 'TOEXNAME': 'Ebene_22kV_122.0'}, 'Jin_Fei_66kV_Jin_Fei_22kV_2_Jin_Fei_TS2_Tr': {'TONAME': 'Jin_Fei_22kV_2', 'FROMNUMBER': 71, '#WIND': 2, 'FROMEXNAME': 'Jin_Fei_66kV_66.0', 'FROMNAME': 'Jin_Fei_66kV', 'ID': 'Jin_Fei_TS2', 'TONUMBER': 70, 'TOEXNAME': 'Jin_Fei_22kV_222.0'}, 'Fuel_PowerStation_66kV_Fuel_G2_Ugen_Fuel_G2_TP_Tr': {'TONAME': 'Fuel_G2_Ugen', 'FROMNUMBER': 61, '#WIND': 2, 'FROMEXNAME': 'Fuel_PowerStation_66kV_66.0', 'FROMNAME': 'Fuel_PowerStation_66kV', 'ID': 'Fuel_G2_TP', 'TONUMBER': 60, 'TOEXNAME': 'Fuel_G2_Ugen6.599999904632568'}, 'NIPS_66kV_Nicolay_22kV_2_Nicolay_TS2_Tr': {'TONAME': 'Nicolay_22kV_2', 'FROMNUMBER': 84, '#WIND': 2, 'FROMEXNAME': 'NIPS_66kV_66.0', 'FROMNAME': 'NIPS_66kV', 'ID': 'Nicolay_TS2', 'TONUMBER': 89, 'TOEXNAME': 'Nicolay_22kV_222.0'}, 'FVPS_66kV_FVPS_Ugen_2_FVPS_TP_1_Tr': {'TONAME': 'FVPS_Ugen_2', 'FROMNUMBER': 45, '#WIND': 2, 'FROMEXNAME': 'FVPS_66kV_66.0', 'FROMNAME': 'FVPS_66kV', 'ID': 'FVPS_TP_1', 'TONUMBER': 47, 'TOEXNAME': 'FVPS_Ugen_211.0'}, 'FortGeorge_66kV_FortGeorge_22kV_1_FortGeorge_TS1_Tr': {'TONAME': 'FortGeorge_22kV_1', 'FROMNUMBER': 55, '#WIND': 2, 'FROMEXNAME': 'FortGeorge_66kV_66.0', 'FROMNAME': 'FortGeorge_66kV', 'ID': 'FortGeorge_TS1', 'TONUMBER': 53, 'TOEXNAME': 'FortGeorge_22kV_122.0'}, 'Henrietta_66kV_Henrietta_22kV_2_Henrietta_TS2_Tr': {'TONAME': 'Henrietta_22kV_2', 'FROMNUMBER': 64, '#WIND': 2, 'FROMEXNAME': 'Henrietta_66kV_66.0', 'FROMNAME': 'Henrietta_66kV', 'ID': 'Henrietta_TS2', 'TONUMBER': 63, 'TOEXNAME': 'Henrietta_22kV_222.0'}, 'Wooton_66kV_Wooton_22kV_1_Wooton_TS1_Tr': {'TONAME': 'Wooton_22kV_1', 'FROMNUMBER': 123, '#WIND': 2, 'FROMEXNAME': 'Wooton_66kV_66.0', 'FROMNAME': 'Wooton_66kV', 'ID': 'Wooton_TS1', 'TONUMBER': 121, 'TOEXNAME': 'Wooton_22kV_122.0'}, 'NIPS_66kV_NIPS_G2_Ugen_NIPS_TP2_Tr': {'TONAME': 'NIPS_G2_Ugen', 'FROMNUMBER': 84, '#WIND': 2, 'FROMEXNAME': 'NIPS_66kV_66.0', 'FROMNAME': 'NIPS_66kV', 'ID': 'NIPS_TP2', 'TONUMBER': 86, 'TOEXNAME': 'NIPS_G2_Ugen11.0'}, 'FortGeorge_66kV_FortGeorge_22kV_2_FortGeorge_TS2_Tr': {'TONAME': 'FortGeorge_22kV_2', 'FROMNUMBER': 55, '#WIND': 2, 'FROMEXNAME': 'FortGeorge_66kV_66.0', 'FROMNAME': 'FortGeorge_66kV', 'ID': 'FortGeorge_TS2', 'TONUMBER': 54, 'TOEXNAME': 'FortGeorge_22kV_222.0'}, 'StLouis_66kV_StLouis_Ugen_11_StLouisG11_TP_Tr': {'TONAME': 'StLouis_Ugen_11', 'FROMNUMBER': 98, '#WIND': 2, 'FROMEXNAME': 'StLouis_66kV_66.0', 'FROMNAME': 'StLouis_66kV', 'ID': 'StLouisG11_TP', 'TONUMBER': 100, 'TOEXNAME': 'StLouis_Ugen_1111.0'}, 'Combo_66kV_Combo_22kV_2_Combo_TS2_Tr': {'TONAME': 'Combo_22kV_2', 'FROMNUMBER': 30, '#WIND': 2, 'FROMEXNAME': 'Combo_66kV_66.0', 'FROMNAME': 'Combo_66kV', 'ID': 'Combo_TS2', 'TONUMBER': 29, 'TOEXNAME': 'Combo_22kV_222.0'}, 'Ferney_22kV_Ferney_G1_Ugen_Ferney_G1_TP_Tr': {'TONAME': 'Ferney_G1_Ugen', 'FROMNUMBER': 50, '#WIND': 2, 'FROMEXNAME': 'Ferney_22kV_22.0', 'FROMNAME': 'Ferney_22kV', 'ID': 'Ferney_G1_TP', 'TONUMBER': 51, 'TOEXNAME': 'Ferney_G1_Ugen6.599999904632568'}, 'Henrietta_66kV_Henrietta_22kV_1_Henrietta_TS1_Tr': {'TONAME': 'Henrietta_22kV_1', 'FROMNUMBER': 64, '#WIND': 2, 'FROMEXNAME': 'Henrietta_66kV_66.0', 'FROMNAME': 'Henrietta_66kV', 'ID': 'Henrietta_TS1', 'TONUMBER': 62, 'TOEXNAME': 'Henrietta_22kV_122.0'}, 'Cecile_22kV_Cecile_G1_Ugen_Cecile_G1_TP1_Tr': {'TONAME': 'Cecile_G1_Ugen', 'FROMNUMBER': 22, '#WIND': 2, 'FROMEXNAME': 'Cecile_22kV_22.0', 'FROMNAME': 'Cecile_22kV', 'ID': 'Cecile_G1_TP1', 'TONUMBER': 23, 'TOEXNAME': 'Cecile_G1_Ugen6.599999904632568'}, 'Champagne_66kV_Champagne_G1_Ugen_Champagne_G1_TP_Tr': {'TONAME': 'Champagne_G1_Ugen', 'FROMNUMBER': 25, '#WIND': 2, 'FROMEXNAME': 'Champagne_66kV_66.0', 'FROMNAME': 'Champagne_66kV', 'ID': 'Champagne_G1_TP', 'TONUMBER': 26, 'TOEXNAME': 'Champagne_G1_Ugen6.599999904632568'}, 'FVPS_66kV_FVPS_Ugen_2_FVPS_TP_3_Tr': {'TONAME': 'FVPS_Ugen_2', 'FROMNUMBER': 45, '#WIND': 2, 'FROMEXNAME': 'FVPS_66kV_66.0', 'FROMNAME': 'FVPS_66kV', 'ID': 'FVPS_TP_3', 'TONUMBER': 47, 'TOEXNAME': 'FVPS_Ugen_211.0'}, 'LeVal_22kV_LeVal_G2_Ugen_LeVal_TP2_Tr': {'TONAME': 'LeVal_G2_Ugen', 'FROMNUMBER': 76, '#WIND': 2, 'FROMEXNAME': 'LeVal_22kV_22.0', 'FROMNAME': 'LeVal_22kV', 'ID': 'LeVal_TP2', 'TONUMBER': 78, 'TOEXNAME': 'LeVal_G2_Ugen6.599999904632568'}, 'FortGeorge_66kV_FGPS_Ugen2_FGPS_TP2_Tr': {'TONAME': 'FGPS_Ugen2', 'FROMNUMBER': 55, '#WIND': 2, 'FROMEXNAME': 'FortGeorge_66kV_66.0', 'FROMNAME': 'FortGeorge_66kV', 'ID': 'FGPS_TP2', 'TONUMBER': 38, 'TOEXNAME': 'FGPS_Ugen211.0'}, 'Champagne_66kV_Champagne_G2_Ugen_Champagne_G2_TP_Tr': {'TONAME': 'Champagne_G2_Ugen', 'FROMNUMBER': 25, '#WIND': 2, 'FROMEXNAME': 'Champagne_66kV_66.0', 'FROMNAME': 'Champagne_66kV', 'ID': 'Champagne_G2_TP', 'TONUMBER': 27, 'TOEXNAME': 'Champagne_G2_Ugen6.599999904632568'}, 'LaChaumiere_22kV_2_LaFerme_G1_Ugen_LaFerme_TP_Tr': {'TONAME': 'LaFerme_G1_Ugen', 'FROMNUMBER': 73, '#WIND': 2, 'FROMEXNAME': 'LaChaumiere_22kV_2_22.0', 'FROMNAME': 'LaChaumiere_22kV_2', 'ID': 'LaFerme_TP', 'TONUMBER': 75, 'TOEXNAME': 'LaFerme_G1_Ugen6.599999904632568'}, 'FVPS_22kV_2_FVPS_Ugen_2_FVPS_TS2_Tr': {'TONAME': 'FVPS_Ugen_2', 'FROMNUMBER': 43, '#WIND': 2, 'FROMEXNAME': 'FVPS_22kV_2_22.0', 'FROMNAME': 'FVPS_22kV_2', 'ID': 'FVPS_TS2', 'TONUMBER': 47, 'TOEXNAME': 'FVPS_Ugen_211.0'}, 'LaChaumiere_66kV_LaChaumiere_22kV_1_LaChaumiere_TS1_Tr': {'TONAME': 'LaChaumiere_22kV_1', 'FROMNUMBER': 74, '#WIND': 2, 'FROMEXNAME': 'LaChaumiere_66kV_66.0', 'FROMNAME': 'LaChaumiere_66kV', 'ID': 'LaChaumiere_TS1', 'TONUMBER': 72, 'TOEXNAME': 'LaChaumiere_22kV_122.0'}, 'Bellevue_66kV_Bellevue_22kV_2_Bellevue_TS2_Tr': {'TONAME': 'Bellevue_22kV_2', 'FROMNUMBER': 10, '#WIND': 2, 'FROMEXNAME': 'Bellevue_66kV_66.0', 'FROMNAME': 'Bellevue_66kV', 'ID': 'Bellevue_TS2', 'TONUMBER': 9, 'TOEXNAME': 'Bellevue_22kV_222.0'}, 'StLouis_66kV_StLouis_Ugen_13_StLouisG13_TP_Tr': {'TONAME': 'StLouis_Ugen_13', 'FROMNUMBER': 98, '#WIND': 2, 'FROMEXNAME': 'StLouis_66kV_66.0', 'FROMNAME': 'StLouis_66kV', 'ID': 'StLouisG13_TP', 'TONUMBER': 102, 'TOEXNAME': 'StLouis_Ugen_1311.0'}} MotorDico = {} -Dico ={'DIRECTORY': {'PSSPY_path': 'C:\\Program Files (x86)\\PTI\\PSSE34\\PSSPY27', 'PSSE_path': 'C:\\Program Files (x86)\\PTI\\PSSE34\\PSSBIN', 'sav_file': 'X:/Small Grid PSSE/TestIsland_2015_OPF - Areas.sav', 'results_folder': 'X:/Small Grid PSSE/Results'}, 'PSSE_PARAMETERS': {'UNIT_COMMITMENT': True, 'I_MAX': 'RateA', 'DECIMAL_SEPARATOR': '.', 'FUEL_COST': True, 'ALGORITHM': 'Optimum Power Flow', 'MVAR_COST': False, 'ITERATION_LIMIT': 20, 'SAVE_CASE_BEFORE_UNIT_COMMITMENT': False, 'LOCK_TAPS': True, 'LOADSHEDDING_COST': False}, 'CORRELATION': {'CorrelationMatrix': ["['load']", '[1.0]']}, 'DISTRIBUTIONload': {'Load': ['CITYB30__Lo1', 'CITYC30__Lo1', 'CITYD30__Lo1', 'ODIESEL__Lo1'], 'A': 0.8, 'B': 0.9, 'Activated': True, 'Sampling': 'Same sample for all loads', 'ComponentType': 'Load', 'Law': 'Uniform', 'Type': 'Load Level'}, 'SIMULATION': {'NUMBER_PACKAGE': 1, 'SIZE_PACKAGE': 10}} \ No newline at end of file +Dico ={'DISTRIBUTIONROR': {'Generator': ['Cecile_G1_Ugen_genstat_Gr_RoR_Cecile', 'LaFerme_G1_Ugen_genstat_Gr_RoR_LaFerme', 'LeVal_G1_Ugen_genstat_Gr_RoR_LeVal_G1', 'LeVal_G2_Ugen_genstat_Gr_RoR_LeVal_G2', 'Magenta_G1_Ugen_genstat_Gr_RoR_Magenta', 'Tamarind_G1_Ugen_genstat_Gr_RoR_Tamarind'], 'FileName': 'C:\\Users\\H92579\\Desktop\\Ile Maurice_bug_nbScenario\\Periode Jour/Jour_RoR.csv', 'Activated': True, 'Sampling': 'Same sample for all generators', 'ComponentType': 'Generator', 'Law': 'PDF_from_file', 'Type': 'Generator Power Level'}, 'DISTRIBUTIONFERNEY': {'Generator': ['Ferney_G1_Ugen_genstat_Gr_HighDam_Ferney_G1', 'Ferney_G2_Ugen_genstat_Gr_HighDam_Ferney_G2'], 'FileName': 'C:\\Users\\H92579\\Desktop\\Ile Maurice_bug_nbScenario\\Periode Jour/Jour_Ferney.csv', 'Activated': True, 'Sampling': 'Same sample for all generators', 'ComponentType': 'Generator', 'Law': 'PDF_from_file', 'Type': 'Generator Power Level'}, 'PF_PARAMETERS': {'UNIT_COMMITMENT': True, 'LS_Q_CONVERGENCE_CRITERIA': False, 'DECIMAL_SEPARATOR': ',', 'ALGORITHM': 'Optimum Power Flow', 'OBJECTIVE_FUNCTION': 'MINIMISATION_OF_COST', 'NON_COST_OPTIMAL_SOLUTION_ALLOWED': True, 'ITERATION_INTERIOR': 700, 'LOCK_TAPS': True, 'LOAD_SHEDDING_ALLOWED': False}, 'DISTRIBUTIONEOL': {'Generator': ['Curepipe_22kV_genstat_Gr_EOL_PlaineSophie', 'PlaineDesRochesPowerStation_22kV_genstat_Gr_EOL_PlaindesRoches'], 'FileName': 'C:\\Users\\H92579\\Desktop\\Ile Maurice_bug_nbScenario\\Periode Jour/Jour_EOL.csv', 'Activated': True, 'Sampling': 'Same sample for all generators', 'ComponentType': 'Generator', 'Law': 'PDF_from_file', 'Type': 'Generator Power Level'}, 'DISTRIBUTIONPV': {'Generator': ['Amaury_22kV_1_genstat_Gr_PV_Amaury_1', 'Amaury_22kV_2_genstat_Gr_PV_Amaury_2', 'Amaury_22kV_2_genstat_Gr_PV_PetiteRetraite', 'Anahita_22kV_1_genstat_Gr_PV_Anahita_1', 'Anahita_22kV_2_genstat_Gr_PV_Anahita_2', 'Bellevue_22kV_1_genstat_Gr_PV_Bellevue_1', 'Bellevue_22kV_2_genstat_Gr_PV_Bellevue_2', 'CaseNoyale_22kV_1_genstat_Gr_PV_CaseNoyale_1', 'CaseNoyale_22kV_2_genstat_Gr_PV_CaseNoyale_2', 'Combo_22kV_1_genstat_Gr_PV_Combo_1', 'Combo_22kV_2_genstat_Gr_PV_Combo_2', 'Ebene_22kV_1_genstat_Gr_PV_Ebene_1', 'Ebene_22kV_2_genstat_Gr_PV_Ebene_2', 'Ebene_22kV_3_genstat_Gr_PV_Ebene_3', 'FVPS_22kV_1_genstat_Gr_PV_FVPS_1', 'FVPS_22kV_2_genstat_Gr_PV_FVPS_2', 'FVPS_22kV_3_genstat_Gr_PV_FVPS_3', 'Ferney_22kV_genstat_Gr_PV_Ferney_1', 'FortGeorge_22kV_1_genstat_Gr_PV_FortGeorge_1', 'FortGeorge_22kV_2_genstat_Gr_PV_FortGeorge_2', 'Fuel_22kV_1_genstat_Gr_PV_Fuel_1', 'Fuel_22kV_2_genstat_Gr_PV_Fuel_2', 'Henrietta_22kV_1_genstat_Gr_PV_Henrietta_1', 'Henrietta_22kV_2_genstat_Gr_PV_Henrietta_2', 'Jin_Fei_22kV_1_genstat_Gr_PV_Jin_Fei_2', 'Jin_Fei_22kV_2_genstat_Gr_PV_Jin_Fei_1', 'LaChaumiere_22kV_1_genstat_Gr_PV_LaChaumiere_1', 'LaChaumiere_22kV_2_genstat_Gr_PV_LaChaumiere_2', 'Nicolay_22kV_1_genstat_Gr_PV_Nicolay_1', 'Nicolay_22kV_2_genstat_Gr_PV_Nicolay_2', 'Sarako_22kV_genstat_Gr_PV_Sarako', 'Sottise_22kV_1_genstat_Gr_PV_Sottise_1', 'Sottise_22kV_2_genstat_Gr_PV_MonChoisy', 'Sottise_22kV_2_genstat_Gr_PV_Sottise_2', 'StLouis_22kV_1_genstat_Gr_PV_StLouis_1', 'StLouis_22kV_2_genstat_Gr_PV_StLouis_2', 'TourKoening_22kV_1_genstat_Gr_PV_TourKoening_1', 'TourKoening_22kV_2_genstat_Gr_PV_TourKoening_2', 'UnionVale_22kV_1_genstat_Gr_PV_UnionVale_1', 'UnionVale_22kV_2_genstat_Gr_PV_UnionVale_2', 'Wooton_22kV_1_genstat_Gr_PV_Esperance', 'Wooton_22kV_1_genstat_Gr_PV_Wooton_2', 'Wooton_22kV_2_genstat_Gr_PV_Wooton_1'], 'FileName': 'C:\\Users\\H92579\\Desktop\\Ile Maurice_bug_nbScenario\\Periode Jour/Jour_PV.csv', 'Activated': True, 'Sampling': 'Same sample for all generators', 'ComponentType': 'Generator', 'Law': 'PDF_from_file', 'Type': 'Generator Power Level'}, 'SIMULATION': {'NUMBER_PACKAGE': 1, 'SIZE_PACKAGE': 20}, 'CORRELATION': {'CorrelationMatrix': ["['EOL', 'CHAMPAGNE', 'FERNEY', 'LOAD', 'PV', 'ROR']", '[1.0, 0.0098, 0.0005, -0.1805, 0.136, -0.033]', '[0.0098, 1.0, 0.5138, 0.2386, -0.0539, -0.0371]', '[0.0005, 0.5138, 1.0, 0.3026, -0.0625, 0.0098]', '[-0.1805, 0.2386, 0.3026, 1.0, 0.1982, 0.0972]', '[0.136, -0.0539, -0.0625, 0.1982, 1.0, 0.0572]', '[-0.033, -0.0371, 0.0098, 0.0972, 0.0572, 1.0]']}, 'DIRECTORY': {'Python3_path': 'C:\\Python35', 'pfd_file': 'C:\\Users\\H92579\\Desktop\\Ile Maurice_bug_nbScenario/Maurice_2017_CoalSeasonJour.pfd', 'results_folder': 'C:\\Users\\H92579\\Desktop\\Ile Maurice_bug_nbScenario', 'PF_path': 'C:\\Program Files\\DIgSILENT\\PowerFactory 2017 SP1\\Python/3.5'}, 'DISTRIBUTIONCHAMPAGNE': {'Generator': ['Champagne_G1_Ugen_genstat_Gr_HighDam_Champagne_G1', 'Champagne_G2_Ugen_genstat_Gr_HighDam_Champagne_G2'], 'FileName': 'C:\\Users\\H92579\\Desktop\\Ile Maurice_bug_nbScenario\\Periode Jour/Jour_Champagne.csv', 'Activated': True, 'Sampling': 'Same sample for all generators', 'ComponentType': 'Generator', 'Law': 'PDF_from_file', 'Type': 'Generator Power Level'}, 'DISTRIBUTIONLOAD': {'Load': ['Amaury_22kV_1_Lo1', 'Amaury_22kV_2_Lo1', 'Anahita_22kV_1_Lo1', 'Anahita_22kV_2_Lo1', 'Bellevue_22kV_1_Lo1', 'Bellevue_22kV_2_Lo1', 'CaseNoyale_22kV_1_Lo1', 'CaseNoyale_22kV_2_Lo1', 'Combo_22kV_1_Lo1', 'Combo_22kV_2_Lo1', 'Ebene_22kV_1_Lo1', 'Ebene_22kV_2_Lo1', 'Ebene_22kV_3_Lo1', 'FVPS_22kV_1_Lo1', 'FVPS_22kV_2_Lo1', 'FVPS_22kV_3_Lo1', 'Ferney_22kV_Lo1', 'FortGeorge_22kV_1_Lo1', 'FortGeorge_22kV_2_Lo1', 'Fuel_22kV_1_Lo1', 'Fuel_22kV_2_Lo1', 'Henrietta_22kV_1_Lo1', 'Henrietta_22kV_2_Lo1', 'Jin_Fei_22kV_1_Lo1', 'Jin_Fei_22kV_2_Lo1', 'LaChaumiere_22kV_1_Lo1', 'LaChaumiere_22kV_2_Lo1', 'Nicolay_22kV_1_Lo1', 'Nicolay_22kV_2_Lo1', 'Sottise_22kV_1_Lo1', 'Sottise_22kV_2_Lo1', 'StLouis_22kV_1_Lo1', 'StLouis_22kV_2_Lo1', 'TourKoening_22kV_1_Lo1', 'TourKoening_22kV_2_Lo1', 'UnionVale_22kV_1_Lo1', 'UnionVale_22kV_2_Lo1', 'Wooton_22kV_1_Lo1', 'Wooton_22kV_2_Lo1'], 'FileName': 'C:\\Users\\H92579\\Desktop\\Ile Maurice_bug_nbScenario\\Periode Jour/Jour_Load.csv', 'Activated': True, 'Sampling': 'Same sample for all loads', 'ComponentType': 'Load', 'Law': 'PDF_from_file', 'Type': 'Load Level'}} \ No newline at end of file diff --git a/PSSE_PF_Eficas/PSEN/TEST.py b/PSSE_PF_Eficas/PSEN/TEST.py new file mode 100644 index 00000000..3d7b83e1 --- /dev/null +++ b/PSSE_PF_Eficas/PSEN/TEST.py @@ -0,0 +1,92 @@ +import os +import sys +import PSENconfig +from support_functionsPF import read_pfd + + +PF_PATH = r'C:\Program Files\DIgSILENT\PowerFactory 2017 SP1\Python\3.5' +NetworkFile = r'C:\Users\H92579\Documents\Formation_PF\ex_PFD\Modele_Corse_PSEN_peak_good.pfd' + +(filepath, filename) = os.path.split(NetworkFile) +sys.path.append(PF_PATH) +os.environ['PATH'] += ';' + os.path.dirname(os.path.dirname(PF_PATH)) + ';' + +PFParams = PSENconfig.Dico['PF_PARAMETERS'] + +import powerfactory + +app = powerfactory.GetApplication() +#app.Show() +user = app.GetCurrentUser() +ComImp = user.CreateObject('ComPFDIMPORT') + +app.SetWriteCacheEnabled(1) # Disable consistency check +ComImp.g_file = PSENconfig.Dico['DIRECTORY']['pfd_file'] +ComImp.g_target = user # project is imported under the user account +err = ComImp.Execute() # Execute command starts the import process +app.SetWriteCacheEnabled(0) # Enable consistency check +if err: + app.PrintError('Project could not be imported...') + exit() +prjs = user.GetContents('*.IntPrj') +prjs.sort(key=lambda x: x.gnrl_modif, reverse=True) +prj = prjs[0] +app.ActivateProject(prj.loc_name) +prj = app.GetActiveProject() +studycase = app.GetActiveStudyCase() +studycase.loc_name = 'BaseCase' +app.PrintPlain('Project %s has been successfully imported.' % prj) +ComImp.Delete() + +all_inputs_init=read_pfd(app,prj.loc_name,recal=1) + +all_inputs_base=all_inputs_init + +buses_base=[] +[buses_base.append(bus[0:8]) for bus in all_inputs_base[0]] + +lines_base = [] +[lines_base.append(bus[0:11]) for bus in all_inputs_base[1]] + +trans_base = [] +[trans_base.append(bus[0:11]) for bus in all_inputs_base[2]] + +plants_base = [] +[plants_base.append(bus[0:11]) for bus in all_inputs_base[3]] + +loads_base = [] +[loads_base.append(bus[0:6]) for bus in all_inputs_base[4]] + +shunt_base = [] +[shunt_base.append(bus[0:6]) for bus in all_inputs_base[5]] + +motors_base = [] +[motors_base.append(bus[0:6]) for bus in all_inputs_base[6]] + +trans3_base = [] +[trans3_base.append(bus[0:14]) for bus in all_inputs_base[7]] + +swshunt_base = [] +[swshunt_base.append(bus[0:6]) for bus in all_inputs_base[8]] + +############################################################################## + +filer=open('temp1.txt','r') +_path=[] +for line in filer: + _path.append(line) +filer.close() +path_save = _path[0].replace('\n','') +ldf = app.GetFromStudyCase('ComLdf') +ldf.iopt_net = 0 # AC load flow +ldf.iopt_at = 1 # automatic tap transfos +ldf.iopt_asht = 1 # automatic shunt +ldf.iopt_lim = 1 # reactive power limit +ldf.iopt_plim = 1 # active power limit +ldf.iopt_limScale = 1 # scale factor +ldf.iopt_noinit = 1 # no initialisation load flow +ldf.iopt_initOPF = 0 # utiliser pour OPF +ldf.iShowOutLoopMsg = 0 # show off output +ldf.iopt_show = 0 # show off output +ldf.iopt_check = 0 # show off output +ldf.iopt_chctr = 0 # show off output \ No newline at end of file diff --git a/PSSE_PF_Eficas/PSEN/absence0.txt b/PSSE_PF_Eficas/PSEN/absence0.txt new file mode 100644 index 00000000..d6b24041 --- /dev/null +++ b/PSSE_PF_Eficas/PSEN/absence0.txt @@ -0,0 +1 @@ +19 diff --git a/PSSE_PF_Eficas/PSEN/comfile.py b/PSSE_PF_Eficas/PSEN/comfile.py index f3e0d010..d7be171b 100644 --- a/PSSE_PF_Eficas/PSEN/comfile.py +++ b/PSSE_PF_Eficas/PSEN/comfile.py @@ -4,9 +4,7 @@ ############################################################ import os,sys,pickle,time -# from support_functionsPF import *#Valentin from support_functionsPF import read_pfd,read_pfd_simple,np, config_contingency -# import PSENconfig # Valentin # sys.path.append(PSENconfig.Dico['DIRECTORY']['PF_path'])#Valentin # os.environ['PATH'] += ';' + os.path.dirname(os.path.dirname(PSENconfig.Dico['DIRECTORY']['PF_path'])) + ';'#Valentin import powerfactory @@ -19,7 +17,7 @@ tempdir = r'C:\Logiciels DER\PSEN_PF_V4\Example\Results' app = powerfactory.GetApplication() # app.ActivateProject('39 genstatpvmoteur(4)')#Valentin -prj = app.GetActiveProject() +prj = app.GetActiveProject() case = app.GetActiveStudyCase()#prj.GetContents('Case_0.IntCase',1)[0] # case = prj.GetContents('Case_46.IntCase',1)[0]#Valentin # case.Activate()#Valentin @@ -73,7 +71,7 @@ def saveOPFresults(plants): # return -nn=int(''.join(ele for ele in case.loc_name if ele.isdigit()))# cas number +nn = int(''.join(ele for ele in case.loc_name if ele.isdigit()))# case number cas = int(nn) scenario_temporaire = app.GetActiveScenario() if scenario_temporaire: diff --git a/PSSE_PF_Eficas/PSEN/data_dico b/PSSE_PF_Eficas/PSEN/data_dico new file mode 100644 index 0000000000000000000000000000000000000000..a5e1d95c848e2aff6f3382282ca8860ad8c83002 GIT binary patch literal 521494 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 UW5FgaHN3U+I8y+Vmh$lb2f*v=CIA2c literal 0 HcmV?d00001 diff --git a/PSSE_PF_Eficas/PSEN/support_functionsPF.py b/PSSE_PF_Eficas/PSEN/support_functionsPF.py index 88ce6e53..ad249c5d 100644 --- a/PSSE_PF_Eficas/PSEN/support_functionsPF.py +++ b/PSSE_PF_Eficas/PSEN/support_functionsPF.py @@ -205,44 +205,56 @@ def read_pfd(app,doc,recal=0): prj = app.GetActiveProject() studycase=app.GetActiveStudyCase() grids=studycase.GetChildren(1,'*.ElmNet',1)[0].contents + if recal == 1:#calculer load-flow ldf = app.GetFromStudyCase('ComLdf') ldf.Execute() #run + tous=[] for grid in grids: tous.extend(grid.obj_id.GetContents('*.ElmTerm', 1)) + bus = [] for noeud in tous: bus.append(noeud) + noeuds = sorted(bus, key=lambda x: x.cStatName) + buses = [] for ii in range(len(noeuds)): if noeuds[ii].HasResults(): - mu = noeuds[ii].GetAttribute('m:u') + mu = noeuds[ii].GetAttribute('m:u') mphiu = noeuds[ii].GetAttribute('m:phiu') else : - mu = 0 + mu = 0 mphiu = 0 + busname = noeuds[ii].cStatName.replace('/','_').replace(')','_').replace('(','_').replace(" ","_").replace("-","_").replace(".","_").replace("&","and").replace("%","pct").replace("=","eq").replace("#","_").replace("$","_") - aa = [ii, noeuds[ii].uknom, mu, busname, noeuds[ii].vmin, - noeuds[ii].vmax, noeuds[ii].GetBusType(), mphiu,noeuds[ii]] - # [numero,nominal KV,magnitude p.u, busname,Vmin,Vmax,type,angle degre,obj] + + aa = [ii, noeuds[ii].uknom, mu, busname, noeuds[ii].vmin, noeuds[ii].vmax, noeuds[ii].GetBusType(), mphiu,noeuds[ii]] # [numero,nominal KV,magnitude p.u, busname,Vmin,Vmax,type,angle degre,obj] + buses.append(aa) - ##== == == == == == == == == == = Line===================== Line===================== Line - # lignes = app.GetCalcRelevantObjects('*.ElmLne', 0) + + + ## Line ## + + tous=[] for grid in grids: tous.extend(grid.obj_id.GetContents( '*.ElmLne', 1)) + lines=[] for line in tous: - frombus_name=line.bus1.cBusBar.cStatName + frombus_name = line.bus1.cBusBar.cStatName frombus_name = frombus_name.replace('/','_').replace(')','_').replace('(','_').replace(" ","_").replace("-","_").replace(".","_").replace("&","and").replace("%","pct").replace("=","eq").replace("#","_").replace("$","_") + for ii in range(len(buses)): if frombus_name in buses[ii]: frombus_number=ii break - tobus_name=line.bus2.cBusBar.cStatName + + tobus_name = line.bus2.cBusBar.cStatName tobus_name = tobus_name.replace('/','_').replace(')','_').replace('(','_').replace(" ","_").replace("-","_").replace(".","_").replace("&","and").replace("%","pct").replace("=","eq").replace("#","_").replace("$","_") for ii in range(len(buses)): if tobus_name in buses[ii]: diff --git a/PSSE_PF_Eficas/com.py b/PSSE_PF_Eficas/com.py index 83ff246f..b51cae0f 100644 --- a/PSSE_PF_Eficas/com.py +++ b/PSSE_PF_Eficas/com.py @@ -22,7 +22,8 @@ def PFExtractData(NetworkFile, PF_PATH): (filepath, filename) = os.path.split(NetworkFile) sys.path.append(PF_PATH) os.environ['PATH'] += ';' + os.path.dirname(os.path.dirname(PF_PATH)) + ';' - + + import powerfactory import powerfactory as pf app = pf.GetApplication() @@ -605,11 +606,11 @@ PF_path=_path[1].replace('\n','') MachineDico, LoadDico, LineDico, TransfoDico, MotorDico = PFExtractData(pfd_file,PF_path) Data={} -Data['MachineDico']=MachineDico -Data['LoadDico']=LoadDico -Data['LineDico']=LineDico -Data['TransfoDico']=TransfoDico -Data['MotorDico']=MotorDico +Data['MachineDico'] = MachineDico +Data['LoadDico'] = LoadDico +Data['LineDico'] = LineDico +Data['TransfoDico'] = TransfoDico +Data['MotorDico'] = MotorDico import pickle diff --git a/PSSE_PF_Eficas/opsPSEN_PF.py b/PSSE_PF_Eficas/opsPSEN_PF.py index d3d945bf..9e9626ae 100644 --- a/PSSE_PF_Eficas/opsPSEN_PF.py +++ b/PSSE_PF_Eficas/opsPSEN_PF.py @@ -93,11 +93,11 @@ def INCLUDE(self, PF_path, pfd_file,Python3_path, **args): self.old_context_fichier_init = self.contexte_fichier_init self.parent.record_unit(unite, self) - self.jdc.MachineDico=MachineDico - self.jdc.LoadDico=LoadDico - self.jdc.LineDico=LineDico - self.jdc.TransfoDico=TransfoDico - self.jdc.MotorDico = MotorDico + self.jdc.MachineDico = MachineDico + self.jdc.LoadDico = LoadDico + self.jdc.LineDico = LineDico + self.jdc.TransfoDico = TransfoDico + self.jdc.MotorDico = MotorDico if toClean: diff --git a/PSSE_PF_Eficas/report.txt b/PSSE_PF_Eficas/report.txt new file mode 100644 index 00000000..4021b62a --- /dev/null +++ b/PSSE_PF_Eficas/report.txt @@ -0,0 +1 @@ +Starting time: 0.002446; Monte Carlo Size : 10.000000; Starting time: 0.293662; Monte Carlo Size : 10.000000; Starting time: 0.001656; Monte Carlo Size : 10.000000; Starting time: 0.249637; Monte Carlo Size : 2.000000; Starting time: 0.001503; Monte Carlo Size : 3.000000; Starting time: 0.001179; Monte Carlo Size : 10.000000; Starting time: 0.001271; Monte Carlo Size : 10.000000; Starting time: 0.300779; Monte Carlo Size : 10.000000; Starting time: 0.001302; Monte Carlo Size : 10.000000; Starting time: 0.237096; Monte Carlo Size : 750.000000; Starting time: 0.304474; Monte Carlo Size : 10.000000; Starting time: 0.238076; Monte Carlo Size : 10.000000; Starting time: 0.185095; Monte Carlo Size : 10.000000; Starting time: 0.225074; Monte Carlo Size : 10.000000; Starting time: 0.006847; Monte Carlo Size : 10.000000; Starting time: 0.008662; Monte Carlo Size : 10.000000; Starting time: 0.281258; Monte Carlo Size : 10.000000; Starting time: 0.006176; Monte Carlo Size : 10.000000; Starting time: 0.320835; Monte Carlo Size : 10.000000; Starting time: 0.008815; Monte Carlo Size : 10.000000; Starting time: 0.005938; Monte Carlo Size : 10.000000; Starting time: 0.006103; Monte Carlo Size : 20.000000; Starting time: 0.008669; Monte Carlo Size : 20.000000; \ No newline at end of file diff --git a/PSSE_PF_Eficas/temp.txt b/PSSE_PF_Eficas/temp.txt index 3818feec..5ff5a627 100644 --- a/PSSE_PF_Eficas/temp.txt +++ b/PSSE_PF_Eficas/temp.txt @@ -1,3 +1,3 @@ -C:/Users/H92579/Documents/Formation_PF/ex_PFD/Mayotte_Test.pfd -C:/Program Files/DIgSILENT/PowerFactory 2018 SP3/Python/3.5 -C:/Python35 +C:\Users\H92579\Desktop\Ile Maurice_bug_nbScenario/Maurice_2017_CoalSeasonJour.pfd +C:\Program Files\DIgSILENT\PowerFactory 2017 SP1\Python/3.5 +C:\Python35 diff --git a/PSSE_PF_Eficas/temp1.txt b/PSSE_PF_Eficas/temp1.txt new file mode 100644 index 00000000..eb3d431f --- /dev/null +++ b/PSSE_PF_Eficas/temp1.txt @@ -0,0 +1 @@ +C:\Users\H92579\Desktop\Ile Maurice_bug_nbScenario/N_20190319_09h16m37\package0_N_20190319_09h16m37 diff --git a/ProcessOutputs_Eficas/PFExtractGeneratorLoadLineandTransfoDico.py b/ProcessOutputs_Eficas/PFExtractGeneratorLoadLineandTransfoDico.py new file mode 100644 index 00000000..e81c9f2a --- /dev/null +++ b/ProcessOutputs_Eficas/PFExtractGeneratorLoadLineandTransfoDico.py @@ -0,0 +1,392 @@ +import os, sys, pickle, copy, subprocess, collections +# import sys +import numpy as np +# import copy +import pdb + +#sys.path.append(r'C:\PSEN_V16\Code\ProcessOutputs_Eficas\TreatOutputs') +path1 = os.path.abspath(os.path.join(os.path.abspath(__file__), '../','TreatOutputs')) +sys.path.append(path1) +import Options + + +def getNominalkV(NetworkFile): + + with open('Data_for_interface', 'rb') as fichier:#prendre les donnees dans fichier pickle + mon_depickler = pickle.Unpickler(fichier) + data_file = mon_depickler.load() + # def convert(data):#traitement Unicode + # # if isinstance(data, basestring): + # if isinstance(data, str): + # return str(data) + # elif isinstance(data, collections.Mapping): + # return dict(map(convert, data.iteritems())) + # elif isinstance(data, collections.Iterable): + # return type(data)(map(convert, data)) + # else: + # return data + # data = convert(data_file) + ##################################### + def convert_keys_to_string(dictionary): + """Recursively converts dictionary keys to strings.""" + if not isinstance(dictionary, dict): + return dictionary + return dict((str(k), convert_keys_to_string(v)) for k, v in dictionary.items()) + + data = convert_keys_to_string(data_file) + BusDico=data['BusDico'] + MachineDico = data['MachineDico'] + LoadDico = data['LoadDico'] + LineDico = data['LineDico'] + TfoDico = data['TransfoDico'] + # MotorDico = data['MotorDico'] + + bus_kv=[] + for bus in BusDico: + bus_kv.append(bus[1]) + Options.BusBase=bus_kv + bus_list={} + for bus in BusDico: + bus_list[bus[2]]=bus[1] + Options.BusBaseList=bus_list + BusList = [] + for item in bus_kv: + if item not in BusList: + BusList.append(item) + BusList = sorted(BusList) + for line in LineDico.keys(): + kv = bus_list[LineDico[line]['FROMNAME']] + Options.LinesBaseList[line]=kv + Options.LinesBase.append(kv) + LinesList = [] + for item in Options.LinesBase: + if item not in LinesList: + LinesList.append(item) + LinesList = sorted(LinesList) + + for tfo in TfoDico.keys(): + kv1 = bus_list[TfoDico[tfo]['FROMNAME']] + kv2 = bus_list[TfoDico[tfo]['TONAME']] + kv=[kv1,kv2] + if tfo[-3:]=='Tr3': + kv3=bus_list[TfoDico[tfo]['3NAME']] + kv = [kv1, kv2,kv3] + Options.TransfoBaseList[tfo]=kv + Options.TransfoBase.append(kv) + + TransfosList = [] + for item in Options.TransfoBase: + string = str(item[0]) + ' - ' + str(item[1]) + if len(item) == 3: # 3 winding transformer + string += ' - ' + str(item[2]) + if string not in TransfosList: + TransfosList.append(string) + TransfosList = sorted(TransfosList) + # Generators + for gen in MachineDico.keys(): + Options.GenBaseList[gen]=MachineDico[gen]['NUMBER'] + + return BusList, LinesList, TransfosList,BusDico + +def updateConts(): + Options.ContFullList = [] + tmp = list(Options.BusBaseList.keys()) + tmp.sort() + for key in tmp: + Options.ContFullList.append(key) + tmp = list(Options.GenBaseList.keys()) + tmp.sort() + for key in tmp: + Options.ContFullList.append(key) + tmp = list(Options.LinesBaseList.keys()) + tmp.sort() + for key in tmp: + Options.ContFullList.append(key) + tmp = list(Options.TransfoBaseList.keys()) +## trs = [] +## for tr in tmp: +## if tr.split("__")[-1].startswith("3WNDTR"): +## b = tr.split('__') +## for j,val in enumerate(b): +## if val.startswith("Wnd"): +## del b[j] +## tfo = '__'.join(b) +## trs.append(tfo) + tmp.sort() + for key in tmp: + Options.ContFullList.append(key) + #print Options.ContFullList + return Options.ContFullList + +def newContingency(MatList): + Options.CustomContingencies.append(MatList) + +def checkIfBorder(graph, key, depth, tmplist): + #print "in checkifBorder" + #print "depth ",depth + #print graph + if key in tmplist: + return True + if depth == 0: + return False + NonBorders = 0 + for item in graph[key]: + if not checkIfBorder(graph, item, depth - 1, tmplist): + NonBorders += 1 + if NonBorders < 2: # A generator is considered as isolated if it has less than two non-borders neighbours + if key not in tmplist: + tmplist.append(key) + return True + return False + +def getTrueLines(NetworkFile): + with open('Data_for_interface', 'rb') as fichier: + mon_depickler = pickle.Unpickler(fichier) + data_file = mon_depickler.load() + + # def convert(data): + # if isinstance(data, basestring): + # return str(data) + # elif isinstance(data, collections.Mapping): + # return dict(map(convert, data.iteritems())) + # elif isinstance(data, collections.Iterable): + # return type(data)(map(convert, data)) + # else: + # return data + # + # data = convert(data_file) + def convert_keys_to_string(dictionary): + """Recursively converts dictionary keys to strings.""" + if not isinstance(dictionary, dict): + return dictionary + return dict((str(k), convert_keys_to_string(v)) for k, v in dictionary.items()) + + data = convert_keys_to_string(data_file) + BusDico=data['BusDico'] + MachineDico = data['MachineDico'] + LoadDico = data['LoadDico'] + LineDico = data['LineDico'] + TfoDico = data['TransfoDico'] + MotorDico = data['MotorDico'] + + lst = [] + tmplist = [] + for line in LineDico.keys(): + aa = LineDico[line]['FROMNUMBER'] + bb = LineDico[line]['TONUMBER'] + if aa not in lst and aa not in tmplist: + tmplist.append(aa) + elif aa not in lst and aa in tmplist: + tmplist.remove(aa) + lst.append(aa) + if bb not in lst and bb not in tmplist: + tmplist.append(bb) + elif bb not in lst and bb in tmplist: + tmplist.remove(bb) + lst.append(bb) + for tfo in TfoDico.keys(): + aa = TfoDico[tfo]['FROMNUMBER'] + bb = TfoDico[tfo]['TONUMBER'] + if aa not in lst and aa not in tmplist: + tmplist.append(aa) + elif aa not in lst and aa in tmplist: + tmplist.remove(aa) + lst.append(aa) + if bb not in lst and bb not in tmplist: + tmplist.append(bb) + elif bb not in lst and bb in tmplist: + tmplist.remove(bb) + lst.append(bb) + if tfo[-3:]=='TR3': + cc = TfoDico[tfo]['3NUMBER'] + if cc not in lst and cc not in tmplist: + tmplist.append(cc) + elif cc not in lst and cc in tmplist: + tmplist.remove(cc) + lst.append(cc) + + # Create the graph + graph = {} + for ii in range(len(BusDico)): + graph[ii]=[] + for var in LineDico.keys(): + if LineDico[var]['TONUMBER'] not in graph[LineDico[var]['FROMNUMBER']]: + graph[LineDico[var]['FROMNUMBER']].append(LineDico[var]['TONUMBER']) + if LineDico[var]['FROMNUMBER'] not in graph[LineDico[var]['TONUMBER']]: + graph[LineDico[var]['TONUMBER']].append(LineDico[var]['FROMNUMBER']) + for var in TfoDico.keys(): + if TfoDico[var]['TONUMBER'] not in graph[TfoDico[var]['FROMNUMBER']]: + graph[TfoDico[var]['FROMNUMBER']].append(TfoDico[var]['TONUMBER']) + if TfoDico[var]['FROMNUMBER'] not in graph[TfoDico[var]['TONUMBER']]: + graph[TfoDico[var]['TONUMBER']].append(TfoDico[var]['FROMNUMBER']) + if var[-3:]=='TR3': + if TfoDico[var]['3NUMBER'] not in graph[TfoDico[var]['FROMNUMBER']]: + graph[TfoDico[var]['FROMNUMBER']].append(TfoDico[var]['3NUMBER']) + if TfoDico[var]['3NUMBER'] not in graph[TfoDico[var]['TONUMBER']]: + graph[TfoDico[var]['TONUMBER']].append(TfoDico[var]['3NUMBER']) + if TfoDico[var]['FROMNUMBER'] not in graph[TfoDico[var]['3NUMBER']]: + graph[TfoDico[var]['3NUMBER']].append(TfoDico[var]['FROMNUMBER']) + if TfoDico[var]['FROMNUMBER'] not in graph[TfoDico[var]['3NUMBER']]: + graph[TfoDico[var]['3NUMBER']].append(TfoDico[var]['TONUMBER']) + + + for key in sorted(graph.keys()): + #print key + checkIfBorder(graph, key, Options.RecursiveDepth, tmplist) + #print "out of Checkif 0" + #print "" + for key in reversed(sorted(graph.keys())):# + checkIfBorder(graph, key, Options.RecursiveDepth, tmplist) + + Options.IsolatedGenList = [] + + if Options.RecursiveDepth > 0 : + # Unfold it + for ii in BusDico: + if ii[0] in tmplist: + if ii[2] not in Options.IsolatedGenList: + Options.IsolatedGenList.append(ii[2]) + + # for i in range(len(carray[0])): + # if carray[0][i] in tmplist: + # if iarray[0][i] not in Options.IsolatedGenList: + # Options.IsolatedGenList.append(iarray[0][i]) + # if carray[1][i] in tmplist: + # if iarray[1][i] not in Options.IsolatedGenList: + # Options.IsolatedGenList.append(iarray[1][i]) + # + # for i in range(len(darray[0])): + # if darray[0][i] in tmplist: + # if jarray[0][i] not in Options.IsolatedGenList: + # Options.IsolatedGenList.append(jarray[0][i]) + # if darray[1][i] in tmplist: + # if jarray[1][i] not in Options.IsolatedGenList: + # Options.IsolatedGenList.append(jarray[1][i]) + # if darray[2][i] in tmplist: + # if jarray[1][i] not in Options.IsolatedGenList: + # Options.IsolatedGenList.append(jarray[1][i]) + + lines = [] + outLines = [] + for line in LineDico.keys(): + if '@' in LineDico[line] or '*' in LineDico[line]: #breaker or switch in PSSE + outLines.append(line) + elif LineDico[line]['FROMNAME'] not in Options.IsolatedGenList and LineDico[line]['TONAME'] not in Options.IsolatedGenList: + lines.append(line) + else: + outLines.append(line) + for line in TfoDico.keys(): + if line[-3:]!='TR3': + if '@' in TfoDico[line] or '*' in TfoDico[line]: + outLines.append(line) + elif TfoDico[line]['FROMNAME'] not in Options.IsolatedGenList and TfoDico[line]['TONAME'] not in Options.IsolatedGenList: + lines.append(line) + else: + outLines.append(line) + else: + if TfoDico[line]['FROMNAME'] not in Options.IsolatedGenList or TfoDico[line]['TONAME'] not in Options.IsolatedGenList or \ + TfoDico[line]['3NAME'] not in Options.IsolatedGenList: + lines.append(line) + else: + outLines.append(line) + # for i in range(len(iarray[0])): + # #name = iarray[0][i] + ' - ' + iarray[1][i] + # idname = iarray[2][i].strip() + # if '@' in idname: + # idname = idname.replace('@','BR') + # elif '*' in idname: + # idname = idname.replace('*','SW') + # else: + # #separate lines and transfos + # U1 = Options.BusBaseList[iarray[0][i]] + # U2 = Options.BusBaseList[iarray[1][i]] + # if U1==U2: + # typecode = 'LI' + # else: + # typecode= 'TR' + # try: + # idname = typecode + str(int(idname)) + # except: + # idname = typecode + idname + # linename = iarray[0][i].strip() + "__" + iarray[1][i].strip() + "__" + idname + # linename = linename.replace(" ","_") + # linename = linename.replace("-","_") + # linename = linename.replace(".","_") + # linename = linename.replace("&","and") + # try: + # int(linename[0]) + # linename="_" + linename + # except: + # pass + # + # if '@' in iarray[2][i] or '*' in iarray[2][i]: + # outLines.append(linename) + # elif iarray[0][i] not in Options.IsolatedGenList and iarray[1][i] not in Options.IsolatedGenList: + # lines.append(linename) + # else: + # outLines.append(linename) + + # for i in range(len(jarray[0])): + # idname = '3WNDTR' + darray[6][i].strip() + # tfoname = darray[0][i].strip() + "__" + darray[1][i].strip() + "__" + darray[2][i].strip() + "__" + idname + # tfoname = tfoname.replace(" ","_") + # tfoname = tfoname.replace("-","_") + # tfoname = tfoname.replace(".","_") + # tfoname = tfoname.replace("&","and") + # try: + # int(tfoname[0]) + # tfoname="_" + tfoname + # except: + # pass + # if jarray[0][i] not in Options.IsolatedGenList and jarray[1][i] not in Options.IsolatedGenList and jarray[2][i] not in Options.IsolatedGenList: + # lines.append(tfoname) + # else: + # outLines.append(tfoname) + + Options.TrueLines = lines + Options.RadialLines = outLines + #pdb.set_trace() + return lines, outLines + +NoBreakersandSwitches = True + +def PFExtractGeneratorLoadLineandTransfoDico(it, idx, NetworkFile, PF_PATH,Python3_path): + + + path1 = os.getcwd() + # path_temp=os.path.dirname(NetworkFile) + filew = open('temp.txt', 'w') + filew.write(NetworkFile + '\n') + filew.write(PF_PATH + '\n') + filew.write(Python3_path + '\n') + filew.close() + # print('changer le chemin de Python3 executable') + lancer = [Python3_path + '/python.exe', path1 + '/com_base.py'] # changer le chemin de Python3 executable + proc = subprocess.Popen(lancer) + proc.wait() + with open('Data_for_interface', 'rb') as fichier: + mon_depickler = pickle.Unpickler(fichier) + data_file = mon_depickler.load() + + + def convert_keys_to_string(dictionary): + """Recursively converts dictionary keys to strings.""" + if not isinstance(dictionary, dict): + return dictionary + return dict((str(k), convert_keys_to_string(v)) for k, v in dictionary.items()) + + data = convert_keys_to_string(data_file) + MachineDico = data['MachineDico'] + LoadDico = data['LoadDico'] + LineDico = data['LineDico'] + TfoDico = data['TransfoDico'] + MotorDico = data['MotorDico'] + # os.remove('Data_for_interface') + + return MachineDico, LoadDico, LineDico, TfoDico, MotorDico + + +#NetworkFile= "" +#PF_PATH= +#Python3_path= +#MachineDico, LoadDico, LineDico, TfoDico, MotorDico = PFExtractGeneratorLoadLineandTransfoDico(0, 0, NetworkFile, PF_PATH,Python3_path) \ No newline at end of file diff --git a/ProcessOutputs_Eficas/PSEN_Cata_N1_PF.py b/ProcessOutputs_Eficas/PSEN_Cata_N1_PF.py new file mode 100644 index 00000000..cce32aef --- /dev/null +++ b/ProcessOutputs_Eficas/PSEN_Cata_N1_PF.py @@ -0,0 +1,245 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2013 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# -------------------------------------------------- +# debut entete +# -------------------------------------------------- + +#from Accas import ASSD, JDC_CATA, AU_MOINS_UN, PROC, SIMP, FACT, OPER, MACRO, BLOC, A_VALIDATOR +from Accas import * +import opsPSEN_N1_PF +import pn +# +#class loi ( ASSD ) : pass +#class variable ( ASSD ) : pass +class sd_charge ( ASSD ) : pass +class sd_generateur ( ASSD ) : pass +class sd_ligne ( ASSD ) : pass +class sd_transfo ( ASSD ) : pass +class sd_moteur ( ASSD ) : pass +# + +# import types +class Tuple: + def __init__(self,ntuple): + self.ntuple=ntuple + + def __convert__(self,valeur): + import types + if type(valeur) == types.StringType: + return None + if len(valeur) != self.ntuple: + return None + return valeur + + def info(self): + return "Tuple de %s elements" % self.ntuple + + __repr__=info + __str__=info + +JdC = JDC_CATA ( code = 'PSEN', + execmodul = None, + regles = ( AU_MOINS_UN ( 'CASE_SELECTION', 'CONTINGENCY_PROCESSING' ), + AU_MOINS_UN ( 'CONTINGENCY_SELECTION','N_PROCESSING_OPTIONS','CONTINGENCY_PROCESSING' ), + PRESENT_PRESENT ( 'CONTINGENCY_SELECTION','CONTINGENCY_OPTIONS' ), + PRESENT_PRESENT ( 'CONTINGENCY_PROCESSING','CONTINGENCY_OPTIONS' ), + # AU_MOINS_UN ( 'SIMULATION' ), + # AU_PLUS_UN ( 'PSSE_PARAMETERS' ), + AU_PLUS_UN ( 'CASE_SELECTION' ), + AU_PLUS_UN ( 'CONTINGENCY_OPTIONS' ), + AU_PLUS_UN ( 'CONTINGENCY_SELECTION' ), + AU_PLUS_UN ( 'CONTINGENCY_PROCESSING' ), + AU_PLUS_UN ( 'N_PROCESSING_OPTIONS' ), + # AU_PLUS_UN ( 'N_1_LINES' ), + # AU_PLUS_UN ( 'N_1_LOADS' ), + # AU_PLUS_UN ( 'N_1_TRANSFORMERS' ), + + ), + ) # Fin JDC_CATA + +MODIFICATION_CATALOGUE = MACRO ( nom = "MODIFICATION_CATALOGUE", + sd_prod = pn.modification_catalogue, + op_init= pn.modification_catalogue2, + op=None, + UIinfo={"groupes":("CACHE")}, + Fonction=SIMP(statut='o', typ='TXM', into=['ajoutDefinitionMC']), + Etape=SIMP(statut='o', typ='TXM',), + Genea=SIMP(statut='o', typ='TXM', min=0, max='**'), + NomSIMP=SIMP(statut='o', typ='TXM',), + TypeSIMP=SIMP(statut='o', typ='TXM',), + PhraseArguments=SIMP(statut='o', typ='TXM',),) + + +# -------------------------------------------------- +# fin entete +# -------------------------------------------------- +## TODO : RUN +CASE_SELECTION = MACRO ( nom = "CASE_SELECTION", + sd_prod = opsPSEN_N1_PF.INCLUDE, + op_init = opsPSEN_N1_PF.INCLUDE_context, + fichier_ini = 1, + op = None, + fr = "Sélectionnez les cas à analyser", + ang = 'Select the cases to analyze', + PF_path = SIMP(statut="o",typ='Repertoire',defaut=r'C:\Program Files\DIgSILENT\PowerFactory 2017 SP1\Python\3.5'), + Python3_path=SIMP(statut="o",typ='Repertoire',defaut=r'C:\Anaconda3'), + PSEN_results_folder = SIMP(statut="o", typ="Repertoire"), + PSEN_results_csvfile = SIMP(statut='o', typ = ('Fichier', 'CSV file (*.csv);;All Files (*)',),), + PSEN_results_csvfile_cleaned = SIMP ( statut = "o",typ=bool,defaut=False,), + DecimalSeparator = SIMP(statut="o",typ='TXM',into=[',','.'],defaut='.',), + + BusesList = SIMP(statut = 'f', typ = 'R', min = 0, max = '**', defaut = (), homo = 'SansOrdreNiDoublon'), + LinesList = SIMP(statut = 'f', typ = 'R', min = 0, max = '**', defaut = (), homo = 'SansOrdreNiDoublon'), + TransformersList = SIMP(statut = 'f', typ = 'TXM', min = 0, max = '**', defaut = (), homo = 'SansOrdreNiDoublon'), + MaxDepth = SIMP(statut = 'o', typ = 'I', defaut = 5), + OutputNewCsv = SIMP ( statut = "o",typ=bool,defaut=False,), + NewCsvFile = SIMP(statut='o',typ='TXM', defaut='CleanedData.csv'), + ) + + +N_PROCESSING_OPTIONS = PROC ( nom = 'N_PROCESSING_OPTIONS', + op = None, + ang = "Select whether the program should be displaying data about the different categories.\nThe values displayed will be the min, max, and mean of each item, plus a chart.", + Output_bus_values = SIMP(statut = 'o', typ = bool, defaut = True), + Output_lines_values = SIMP(statut = 'o', typ = bool, defaut = True), + Output_transformer_values = SIMP(statut = 'o', typ = bool, defaut = True), + Threshold_selection_for_the_treated_cases = FACT( + statut = 'f', + Branches = SIMP(statut="o",typ=Tuple(3),defaut=(0,0,0),validators=VerifTypeTuple(('R','R','R'),),), + Transformers = SIMP(statut="o",typ=Tuple(3),defaut=(0,0,0),validators=VerifTypeTuple(('R','R','R'),),), + High_voltage = SIMP(statut="o",typ=Tuple(3),defaut=(0,0,0),validators=VerifTypeTuple(('R','R','R'),),), + Low_voltage = SIMP(statut="o",typ=Tuple(3),defaut=(0,0,0),validators=VerifTypeTuple(('R','R','R'),),), + ), + ) + + +CONTINGENCY_OPTIONS = PROC (nom = 'CONTINGENCY_OPTIONS', + op = None, + + GeneralOptions = FACT(statut='o', + Vmin = SIMP(statut = 'o', typ = 'R', defaut = 0.9, val_min = 0), + Vmax = SIMP(statut = 'o', typ = 'R', defaut = 1.1, val_min = 0), + # ContingencyRate = SIMP(statut = 'o', typ = 'TXM', defaut = 'a', into=['a', 'b']), + FlowLimitLines = SIMP(statut = 'o', typ = 'I', defaut = 120, val_min = 0), + FlowLimitTransformers = SIMP(statut = 'o', typ = 'I', defaut = 120, val_min = 0), + # Tolerance = SIMP(statut = 'o', typ = 'R', defaut = 0.5, val_min = 0), + ), + + LoadFlowOptions = FACT(statut='o', + AdjustTaps = SIMP(statut='o', typ=bool, defaut=False), + AdjustShunts = SIMP(statut='o', typ=bool, defaut=False), + # SolutionMethod = SIMP(statut = 'o', typ = 'TXM', into = ['0 - FDNS', '1 - FNSL', '2 - Optimized FDNS'], defaut = '1 - FNSL'), + # AdjustSwitchedShunts = SIMP(statut='o', typ=bool, defaut=False), + DispatchMode = SIMP(statut='o',typ='TXM',into=['ReferenceMachine','LoadAtReferenceBus','StaticGeneratorAtReferenceBus', 'DistributedSlackByLoads','DistributedSlackBySynchronousGenerators', 'DistributedSlackBySynchronousAndStaticGenerators'], defaut = 'ReferenceMachine'), + ActiveLimits = SIMP(statut='o', typ=bool, defaut=True), + FlatStart = SIMP(statut = 'o', typ = bool, defaut = False), + VarLimits = SIMP(statut='o', typ=bool, defaut=True), + + ), + output_file_format = SIMP(statut = 'o', typ = 'TXM', into = ['xls', 'csv'],defaut='xls'), + + process_directly = SIMP(statut = 'f', typ = bool, defaut = False), + + flush = SIMP ( statut = "f",typ="I",val_min=1,defaut=10,), + ) + + + + +CONTINGENCY_SELECTION = PROC(nom='CONTINGENCY_SELECTION',op = None, + SelectionMethod = SIMP(statut='o',typ='TXM',into=['CaseSelectionFromFile','SelectAllCases','SelectWorstCases'],), + + b_file = BLOC(condition="SelectionMethod=='CaseSelectionFromFile'", + + CaseSelectionFromFiles = FACT( + statut = 'o', + case = FACT(statut='o',max='**', + case_name=SIMP(statut='o',typ='TXM'), + csv_file= SIMP(statut='o', typ = ('Fichier', 'CSV file (*.csv);;All Files (*)',),), + ), + #consigne = SIMP(statut='o',homo='information',typ = "TXM",defaut = 'Enter the numbers of studycases separared by comma (i.e: 1,3,4 for the studycases: Case_1,Case_3 and Case_4)'), + ), + ), + + b_worst = BLOC(condition="SelectionMethod=='SelectWorstCases'", + SelectWorstCases = FACT( + regles = (AU_MOINS_UN('AvgLineLoad', 'AvgLineLoadPercent','AvgTransformerLoad','AvgTransformerLoadPercent','AvgHighVoltage', 'AvgHighVoltagePercent','AvgLowVoltage', 'AvgLowVoltagePercent'), + EXCLUS('AvgLineLoad', 'AvgLineLoadPercent'),EXCLUS('AvgTransformerLoad','AvgTransformerLoadPercent'),EXCLUS('AvgHighVoltage', 'AvgHighVoltagePercent'),EXCLUS('AvgLowVoltage', 'AvgLowVoltagePercent'),), + statut = 'o', + consigne = SIMP(statut='o',homo='information',typ = "TXM",defaut = 'Choose at least one of the potential selection criteria from the SelectWorstCases list on the right.'), + AvgLineLoad = SIMP(statut = 'f', typ = 'I', defaut = 0, val_min = 0), + AvgLineLoadPercent = SIMP(statut = 'f', typ = 'I', defaut = 0, val_min = 0, val_max = 100), + AvgTransformerLoad = SIMP(statut = 'f', typ = 'I', defaut = 0, val_min = 0), + AvgTransformerLoadPercent = SIMP(statut = 'f', typ = 'I', defaut = 0, val_min = 0, val_max = 100), + AvgHighVoltage = SIMP(statut = 'f', typ = 'I', defaut = 0, val_min = 0), + AvgHighVoltagePercent = SIMP(statut = 'f', typ = 'I', defaut = 0, val_min = 0, val_max = 100), + AvgLowVoltage = SIMP(statut = 'f', typ = 'I', defaut = 0, val_min = 0), + AvgLowVoltagePercent = SIMP(statut = 'f', typ = 'I', defaut = 0, val_min = 0, val_max = 100), + ), + ), + + Automatic_N_1_Selection = FACT(statut='o', + + TripLines = SIMP(statut = 'o', typ = bool, defaut = True), + TripTransfos = SIMP(statut = 'o', typ = bool, defaut = True), + TripGenerators = SIMP(statut = 'o', typ = bool, defaut = True), + #TripBuses = SIMP(statut = 'o', typ = bool, defaut = False), + + #consigne = SIMP(statut='o',homo='information',typ = "TXM",defaut = 'Once the TripComponent key is selected above, all voltage levels will be included in the creation of N-1 contingencies by default, unless specific voltage levels are selected below.'), + #N1AreaList = SIMP(statut = 'o', typ = 'I', min = 0, max = '**', defaut = (), homo = 'SansOrdreNiDoublon'), + #N1BusesList = SIMP(statut = 'o', typ = 'R', min = 0, max = '**', defaut = (), homo = 'SansOrdreNiDoublon'), + #N1LinesList = SIMP(statut = 'o', typ = 'R', min = 0, max = '**', defaut = (), homo = 'SansOrdreNiDoublon'), + #N1TransformersList = SIMP(statut = 'o', typ = 'TXM', min = 0, max = '**', defaut = (), homo = 'SansOrdreNiDoublon'), + + ), + + Automatic_N_2_Selection = FACT(statut='f', + MixType=SIMP(statut='o', typ=bool, defaut=False), + GenList=SIMP(statut='o', typ=bool, defaut=False), + # BusesList = SIMP(statut = 'o', typ = 'R', min = 0, max = '**', defaut = (), homo = 'SansOrdreNiDoublon'), + LinesList = SIMP(statut = 'o', typ = 'R', min = 0, max = '**', defaut = (), homo = 'SansOrdreNiDoublon'), + TransformersList = SIMP(statut = 'o', typ = 'TXM', min = 0, max = '**', defaut = (), homo = 'SansOrdreNiDoublon'), + ), + + MultipleContingencyList = FACT (statut='f', max="**", ComponentList=SIMP(statut='o', typ = 'TXM', max='**', homo = 'SansOrdreNiDoublon',), + ), + ) + +CONTINGENCY_PROCESSING = MACRO ( nom = 'CONTINGENCY_PROCESSING', + sd_prod = opsPSEN_N1_PF.PROCESS, + op_init = opsPSEN_N1_PF.PROCESS_context, + + #sd_prod=None, + + op = None, + fichier_ini = 1, + fr = "", + ang="", + XLS_file = SIMP(statut="o", typ = ('Fichier', 'XLS file (*.xls);;CSV file (*.csv);;All files (*)',),), + b_TabList = BLOC(condition="XLS_file != None and XLS_file != ''", + TabList = SIMP(statut = 'o', typ = 'TXM', min = 0, max = '**', defaut = (), homo = 'SansOrdreNiDoublon'), ), + + + + ) + +Ordre_Des_Commandes = ('CASE_SELECTION' , 'N_PROCESSING_OPTIONS' , 'CONTINGENCY_SELECTION', 'CONTINGENCY_OPTIONS' ,'CONTINGENCY_PROCESSING',) +Classement_Commandes_Ds_Arbre = ('CASE_SELECTION' , 'N_PROCESSING_OPTIONS' , 'CONTINGENCY_SELECTION', 'CONTINGENCY_OPTIONS' ,'CONTINGENCY_PROCESSING',) diff --git a/ProcessOutputs_Eficas/TreatOutputs/RunPF.py b/ProcessOutputs_Eficas/TreatOutputs/RunPF.py new file mode 100644 index 00000000..5602c2a1 --- /dev/null +++ b/ProcessOutputs_Eficas/TreatOutputs/RunPF.py @@ -0,0 +1,1890 @@ +#-*- coding:Utf-8 -*- + +## Misc +from __future__ import division +import os, sys,itertools,copy +import numpy as np +from functools import partial +import time + +## Excel file processing +import xlrd +import xlwt +import csv +import shutil +from win32com.client import Dispatch # XLSX write +import win32com.client as win32 + +## multiprocessing +import threading +# import thread +from multiprocessing.pool import ThreadPool +import pdb + +## Own imports +import Chart +#import Display +#import Menu +import Options +from UpdateOptionsPF import * +import UtilsPF as Utils +#from WriteFuncsPF import * +import WriteFuncs as WF +import WriteFuncsCsv as WFC +from Processor import * + + +#sys.path.append(r'C:\PSEN_V16\Code\ProcessOutputs_Eficas') +sys.path.append(os.path.dirname(os.path.dirname(__file__))) + +from PFExtractGeneratorLoadLineandTransfoDico import * + + + +def resetAll(): + Options.TotalStorage = [] + Options.TotalBusStorage = [] + Options.TotalTransfoStorage = [] + Options.TotalLinesStorage = [] + + Options.NamesStorage = [] + Options.ColsStorage = [] + Options.BusStorage = [] + Options.TransfoStorage = [] + Options.LinesStorage = [] + +def join_csv(outputfilepath, filelist): + f=open(outputfilepath,"a")#, newline='') + + for k,filepath in enumerate(filelist): + g = open(filepath,"r")#, newline='') + f.write(g.read()) + g.close() + + f.close() + +#if not Display.initialized: +def read_pfd(app,doc,recal=0): + ######################################################## + # ojectif de cette fonction: prendre les parametres du reseau + ######################################################## + # si recal==1, recalculer loadflow + prj = app.GetActiveProject() + studycase=app.GetActiveStudyCase() + grids=studycase.GetChildren(1,'*.ElmNet',1)[0].contents + if recal == 1:#calculer load-flow + ldf = app.GetFromStudyCase('ComLdf') + err = ldf.Execute() #run + #pdb.set_trace() + tous=[] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmTerm', 1)) + bus = [] + for noeud in tous: + bus.append(noeud) + noeuds = sorted(bus, key=lambda x: x.cStatName) + buses = [] + for ii in range(len(noeuds)): + busname = noeuds[ii].cStatName.replace('/','_').replace(')','_').replace('(','_') + aa = [ii, noeuds[ii].uknom, noeuds[ii].GetAttribute('m:u'), busname, noeuds[ii].vmin, + noeuds[ii].vmax, noeuds[ii].GetBusType(), noeuds[ii].GetAttribute('m:phiu'),noeuds[ii]] + # [numero,nominal KV,magnitude p.u, busname,Vmin,Vmax,type,angle degre,obj] + buses.append(aa) + ##== == == == == == == == == == = Line===================== Line===================== Line + # lignes = app.GetCalcRelevantObjects('*.ElmLne', 0) + tous=[] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmLne', 1)) + lines=[] + for line in tous: + frombus_name=line.bus1.cBusBar.cStatName + tobus_name=line.bus2.cBusBar.cStatName + frombus_name = frombus_name.replace('/','_').replace(')','_').replace('(','_') + tobus_name = tobus_name.replace('/','_').replace(')','_').replace('(','_') + for ii in range(len(buses)): + if frombus_name in buses[ii]: + frombus_number=ii + break + for ii in range(len(buses)): + if tobus_name in buses[ii]: + tobus_number=ii + break + + outs = line.GetChildren(1, 'outserv.Charef', 1) + if outs: + if outs[0].outserv==0: + outserv = outs[0].typ_id.curval + else: + outserv = line.outserv + else: + outserv = line.outserv + if outserv==1: + currentA = 0 + pourcent = 0 + flowP = 0 + flowQ = 0 + else: + currentA=line.GetAttribute('m:I:bus1') #courant en A de la ligne + pourcent=line.GetAttribute('c:loading') # taux de charge de la ligne + flowP=line.GetAttribute('m:P:bus1') + flowQ = line.GetAttribute('m:Q:bus1') + idline=line.loc_name#line.nlnum + linename = frombus_name + '_' + tobus_name + '_' + idline + "__LI" + linename = linename.replace(" ", "_") + linename = linename.replace("-", "_") + linename = linename.replace(".", "_") + linename = linename.replace("/", "_") + linename = linename.replace("&", "and") + try: + int(linename[0]) + linename = "L_" + linename + except: + pass + aa=[frombus_number,tobus_number,currentA,pourcent,pourcent,pourcent,flowP,flowQ,frombus_name,tobus_name,idline,line,linename] + lines.append(aa) + + # 2 windings transformers data (from, to, amps, rate%a, ploss, qloss)==============Transformateur2 + tous=[] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmTr2', 1)) + transf=[] + for trans in tous: + frombus_name=trans.bushv.cBusBar.cStatName + frombus_name = frombus_name.replace('/','_').replace(')','_').replace('(','_') + for ii in range(len(buses)): + if frombus_name in buses[ii]: + frombus_number=ii + break + tobus_name=trans.buslv.cBusBar.cStatName + tobus_name = tobus_name.replace('/','_').replace(')','_').replace('(','_') + for ii in range(len(buses)): + if tobus_name in buses[ii]: + tobus_number=ii + break + + outs = trans.GetChildren(1, 'outserv.Charef', 1) + if outs: + if outs[0].outserv==0: + outserv = outs[0].typ_id.curval + else: + outserv = trans.outserv + else: + outserv = trans.outserv + + if outserv==1: + currentA = 0 + pourcent = 0 + flowP = 0 + flowQ = 0 + else: + currentA=trans.GetAttribute('m:I:bushv') #courant en A du bus hv + pourcent=trans.GetAttribute('c:loading') # taux de charge + flowP=trans.GetAttribute('m:P:bushv') + flowQ = trans.GetAttribute('m:Q:bushv') + # idtr=trans.ntnum + idtr = trans.loc_name + tfoname = frombus_name+'_' + tobus_name + '_' + str(idtr) + "__TR" + tfoname = tfoname.replace(" ", "_") + tfoname = tfoname.replace("-", "_") + tfoname = tfoname.replace(".", "_") + tfoname = tfoname.replace("/", "_") + tfoname = tfoname.replace("&", "and") + try: + int(tfoname[0]) + tfoname = "_" + tfoname + except: + pass + aa=[frombus_number,tobus_number,currentA,pourcent,pourcent,pourcent,flowP,flowQ,frombus_name,tobus_name,idtr,trans,tfoname] + transf.append(aa) + #3 windings transformers data (from, to, amps, rate%a, ploss, qloss)==============Transformateur3 + tous=[] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmTr3', 1)) + transf3 = [] + for trans in tous: + wind1name = trans.bushv.cBusBar.cStatName + wind1name = wind1name.replace('/','_').replace(')','_').replace('(','_') + for ii in range(len(buses)): + if wind1name in buses[ii]: + wind1number = ii + break + wind2name = trans.busmv.cBusBar.cStatName + wind2name = wind2name.replace('/','_').replace(')','_').replace('(','_') + for ii in range(len(buses)): + if wind2name in buses[ii]: + wind2number = ii + break + wind3name = trans.buslv.cBusBar.cStatName + wind3name = wind3name.replace('/','_').replace(')','_').replace('(','_') + for ii in range(len(buses)): + if wind3name in buses[ii]: + wind3number = ii + break + outs = trans.GetChildren(1, 'outserv.Charef', 1) + if outs: + if outs[0].outserv==0: + outserv = outs[0].typ_id.curval + else: + outserv = trans.outserv + else: + outserv = trans.outserv + if outserv==1: + currentHV = 0 + currentMV = 0 + currentLV = 0 + pourcenthv = 0 + pourcentmv = 0 + pourcentlv = 0 + flowPh = 0 + flowPm = 0 + flowPl = 0 + flowQh = 0 + flowQm = 0 + flowQl = 0 + else: + currentHV = trans.GetAttribute('m:I:bushv') # courant en A du bus hv + currentMV = trans.GetAttribute('m:I:busmv') # courant en A du bus mv + currentLV = trans.GetAttribute('m:I:buslv') # courant en A du bus lv + pourcenthv = trans.GetAttribute('c:loading_h') # taux de charge + pourcentmv = trans.GetAttribute('c:loading_m') # taux de charge + pourcentlv = trans.GetAttribute('c:loading_l') # taux de charge + flowPh = trans.GetAttribute('m:P:bushv') + flowPm = trans.GetAttribute('m:P:busmv') + flowPl = trans.GetAttribute('m:P:buslv') + flowQh = trans.GetAttribute('m:Q:bushv') + flowQm = trans.GetAttribute('m:Q:busmv') + flowQl = trans.GetAttribute('m:Q:buslv') + # idtr3 = trans.nt3nm + idtr3 = trans.loc_name + tfoname = wind1name+ '_' + wind2name + '_' +wind3name+'_' + str(idtr3)+'__'+ 'TR3' + tfoname = tfoname.replace(" ", "_") + tfoname = tfoname.replace("-", "_") + tfoname = tfoname.replace(".", "_") + tfoname = tfoname.replace("/", "_") + tfoname = tfoname.replace("&", "and") + try: + int(tfoname[0]) + tfoname = "_" + tfoname + except: + pass + aa = [wind1number, wind2number,wind3number,1, currentHV, pourcenthv, pourcenthv, pourcenthv, flowPh, flowQh, wind1name,wind2name,wind3name,idtr3,trans,tfoname] + transf3.append(aa) + aa = [wind1number, wind2number, wind3number, 2, currentMV, pourcentmv, pourcentmv, pourcentmv, flowPm, flowQm, + wind1name, wind2name, wind3name, idtr3, trans,tfoname] + transf3.append(aa) + aa = [wind1number, wind2number, wind3number, 3, currentLV, pourcentlv, pourcentlv, pourcentlv, flowPl, flowQl, + wind1name, wind2name, wind3name, idtr3, trans,tfoname] + transf3.append(aa) + + #Machines data (bus, inservice, id, pgen, qgen, mvabase, pmax, qmax, name)==============Generator + tous=[] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmSym', 1)) + plants = [] + for plant in tous: + if plant.i_mot==0: + busname=plant.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_') + for ii in range(len(buses)): + if busname in buses[ii]: + busnumber = ii + break + idplant = plant.loc_name#plant.ngnum + outs=plant.GetChildren(1, 'outserv.Charef', 1) + if outs: + if outs[0].outserv == 0: + outserv = outs[0].typ_id.curval + else: + outserv = plant.outserv + else: + outserv = plant.outserv + if outserv == 1: + pgen = 0 + qgen = 0 + else: + pgen = plant.GetAttribute('m:P:bus1') + qgen = plant.GetAttribute('m:Q:bus1') + sn = plant.GetAttribute('t:sgn') + # pmax = plant.Pmax_uc + pmax = plant.P_max + pmin = plant.Pmin_uc + qmax = plant.cQ_max + qmin = plant.cQ_min + aa=[busnumber,outserv,idplant,pgen,qgen,sn,pmax,pmin,busname,pmin,qmin,plant] + plants.append(aa) + tous=[] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmAsm', 1)) + for plant in tous: + if plant.i_mot==0: + busname=plant.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_') + for ii in range(len(buses)): + if busname in buses[ii]: + busnumber = ii + break + idplant = plant.loc_name#plant.ngnum + outs = plant.GetChildren(1, 'outserv.Charef', 1) + if outs: + if outs[0].outserv == 0: + outserv = outs[0].typ_id.curval + else: + outserv = plant.outserv + else: + outserv = plant.outserv + if outserv==1: + pgen=0 + qgen = 0 + else: + pgen = plant.GetAttribute('m:P:bus1') + qgen = plant.GetAttribute('m:Q:bus1') + sn = plant.GetAttribute('t:sgn') + # pmax = plant.Pmax_uc + pmax = plant.P_max + pmin = plant.Pmin_uc + qmax = plant.cQ_max + qmin = plant.cQ_min + aa=[busnumber,outserv,idplant,pgen,qgen,sn,pmax,pmin,busname,pmin,qmin,plant] + plants.append(aa) + tous = [] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmGenstat', 1)) + for plant in tous: + busname = plant.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_') + for ii in range(len(buses)): + if busname in buses[ii]: + busnumber = ii + break + idplant = plant.loc_name # plant.ngnum + outs = plant.GetChildren(1, 'outserv.Charef', 1) + if outs: + if outs[0].outserv==0: + outserv = outs[0].typ_id.curval + else: + outserv = plant.outserv + else: + outserv = plant.outserv + if outserv == 1: + pgen = 0 + qgen = 0 + else: + pgen = plant.GetAttribute('m:P:bus1') + qgen = plant.GetAttribute('m:Q:bus1') + sn = plant.GetAttribute('e:sgn') + # pmax = plant.Pmax_uc + pmax = plant.P_max + pmin = plant.Pmin_uc + qmax = plant.cQ_max + qmin = plant.cQ_min + aa = [busnumber, outserv, idplant, pgen, qgen, sn, pmax, pmin, busname, pmin, qmin,plant] + plants.append(aa) + tous = [] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmPvsys', 1)) + for plant in tous: + busname = plant.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_') + for ii in range(len(buses)): + if busname in buses[ii]: + busnumber = ii + break + idplant = plant.loc_name # plant.ngnum + outs = plant.GetChildren(1, 'outserv.Charef', 1) + if outs: + if outs[0].outserv==0: + outserv = outs[0].typ_id.curval + else: + outserv = plant.outserv + else: + outserv = plant.outserv + if outserv == 1: + pgen = 0 + qgen = 0 + else: + pgen = plant.GetAttribute('m:P:bus1') + qgen = plant.GetAttribute('m:Q:bus1') + sn = plant.GetAttribute('e:sgn') + # pmax = plant.Pmax_uc + pmax = plant.P_max + pmin = plant.Pmin_uc + qmax = plant.cQ_max + qmin = plant.cQ_min + aa = [busnumber, outserv, idplant, pgen, qgen, sn, pmax, pmin, busname, pmin, qmin,plant] + plants.append(aa) + # Motors data (bus, active, reactive, status, name, id)===================== Motor + tous=[] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmSym', 1)) + motors = [] + for motor in tous: + if motor.i_mot == 1: + busname = motor.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_') + for ii in range(len(buses)): + if busname in buses[ii]: + busnumber = ii + break + idplant = motor.loc_name#motor.ngnum + outs = motor.GetChildren(1, 'outserv.Charef', 1) + if outs: + if outs[0].outserv == 0: + outserv = outs[0].typ_id.curval + else: + outserv = motor.outserv + else: + outserv = motor.outserv + if outserv == 1: + pgen = 0 + qgen = 0 + else: + pgen = motor.GetAttribute('m:P:bus1') + qgen = motor.GetAttribute('m:Q:bus1') + aa = [busnumber, pgen, qgen, outserv, busname,idplant,motor] + motors.append(aa) + tous=[] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmAsm', 1)) + for motor in tous: + if motor.i_mot == 1: + busname = motor.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_') + for ii in range(len(buses)): + if busname in buses[ii]: + busnumber = ii + break + idplant = motor.loc_name#motor.ngnum + outs = motor.GetChildren(1, 'outserv.Charef', 1) + if outs: + if outs[0].outserv == 0: + outserv = outs[0].typ_id.curval + else: + outserv = motor.outserv + else: + outserv = motor.outserv + # outserv = motor.outserv + if outserv == 1: + pgen = 0 + qgen = 0 + else: + pgen = motor.GetAttribute('m:P:bus1') + qgen = motor.GetAttribute('m:Q:bus1') + aa = [busnumber, pgen, qgen, outserv, busname,idplant,motor] + motors.append(aa) + + # Loads data (bus, active, reactive, status, name, id)===================== Load + tous=[] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmLod', 1)) + tous = sorted(tous, key=lambda x: x.bus1.cBusBar.cStatName) + loads = [] + for bus in buses: + idload = 0 + for load in tous: + busname = load.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_') + if busname == bus[3]: + idload += 1# cree id pour load + busnumber = bus[0] + # outserv = load.outserv + outs = load.GetChildren(1, 'outserv.Charef', 1) + if outs: + if outs[0].outserv == 0: + outserv = outs[0].typ_id.curval + else: + outserv = load.outserv + else: + outserv = load.outserv + if outserv == 1: + pload = 0 + qload = 0 + else: + pload = load.GetAttribute('m:P:bus1') + qload = load.GetAttribute('m:Q:bus1') # qlini_a + aa = [busnumber, pload, qload, outserv, busname, idload,load] + loads.append(aa) + + #Fixed shunt data (number, MVAR, name, ...)========================== Fixed Shunt + tous=[] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmShnt', 1)) + tous = sorted(tous, key=lambda x: x.bus1.cBusBar.cStatName) + shunt = [] + for bus in buses: + idshunt = 0 + for shunt1 in tous: + if shunt1.ncapx==1:# nombre de step =1, considerer comme fix shunt pour equivalent a l'ancien programme sous PSSE + busname = shunt1.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_') + if busname == bus[3]: + idshunt += 1 # cree id pour load + busnumber = bus[0] + qnom=shunt1.Qmax + outs = shunt1.GetChildren(1, 'outserv.Charef', 1) + if outs: + if outs[0].outserv == 0: + outserv = outs[0].typ_id.curval + else: + outserv = shunt1.outserv + else: + outserv = shunt1.outserv + if outserv == 1: + qshunt = 0 + else: + qshunt = shunt1.GetAttribute('m:Q:bus1') # qlini_a + aa = [busnumber, outserv, qshunt, busname,qnom, idshunt,bus,shunt1] + shunt.append(aa) + # Switched shunt data (number, status,MVAR, name,Qnom,id)================Swiched Shunt + swshunt = [] + for bus in buses: + idshunt = 0 + for shunt1 in tous: + if shunt1.ncapx != 1: # nombre de step #1, considerer comme switche shunt pour etre equivalent avec l'ancien programme sous PSSE + busname = shunt1.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_') + if busname == bus[3]: + idshunt += 1 # cree id pour load + busnumber = bus[0] + qnom = shunt1.Qmax + outs = shunt1.GetChildren(1, 'outserv.Charef', 1) + if outs: + if outs[0].outserv == 0: + outserv = outs[0].typ_id.curval + else: + outserv = shunt1.outserv + else: + outserv = shunt1.outserv + if outserv == 1: + qshunt = 0 + else: + qshunt = shunt1.GetAttribute('m:Q:bus1') # qlini_a + aa = [busnumber, outserv, qshunt, busname, qnom, idshunt,shunt1] + swshunt.append(aa) + + return buses, lines, transf, plants, loads, shunt, motors, transf3, swshunt +# Display.init() +def read_pfd_simple(app,doc): + ######################################################## + # ojectif de cette fonction: prendre les parametres du reseau + ######################################################## + # si recal==1, recalculer loadflow + prj = app.GetActiveProject() + studycase=app.GetActiveStudyCase() + grids=studycase.GetChildren(1,'*.ElmNet',1)[0].contents + # if recal == 1:#calculer load-flow + # ldf = app.GetFromStudyCase('ComLdf') + # ldf.Execute() #run + tous=[] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmTerm', 1)) + bus = [] + for noeud in tous: + bus.append(noeud) + noeuds = sorted(bus, key=lambda x: x.cStatName) + buses = [] + for ii in range(len(noeuds)): + busname = noeuds[ii].cStatName.replace('/','_').replace(')','_').replace('(','_') + aa = [ii, noeuds[ii].uknom, 1, busname, noeuds[ii].vmin, + noeuds[ii].vmax, noeuds[ii].GetBusType(), 0,noeuds[ii]] + # [numero,nominal KV,magnitude p.u, busname,Vmin,Vmax,type,angle degre,obj] + buses.append(aa) + + #Machines data (bus, inservice, id, pgen, qgen, mvabase, pmax, qmax, name)==============Generator + tous=[] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmSym', 1)) + plants = [] + for plant in tous: + if plant.i_mot==0: + busname=plant.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_') + for ii in range(len(buses)): + if busname in buses[ii]: + busnumber = ii + break + idplant = plant.loc_name#plant.ngnum + outs=plant.GetChildren(1, 'outserv.Charef', 1) + if outs: + if outs[0].outserv == 0: + outserv = outs[0].typ_id.curval + else: + outserv = plant.outserv + else: + outserv = plant.outserv + + aa=[busnumber,outserv,idplant,0,0,0,0,0,busname,0,0,plant] + plants.append(aa) + tous=[] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmAsm', 1)) + for plant in tous: + if plant.i_mot==0: + busname=plant.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_') + for ii in range(len(buses)): + if busname in buses[ii]: + busnumber = ii + break + idplant = plant.loc_name#plant.ngnum + outs = plant.GetChildren(1, 'outserv.Charef', 1) + if outs: + if outs[0].outserv == 0: + outserv = outs[0].typ_id.curval + else: + outserv = plant.outserv + else: + outserv = plant.outserv + aa=[busnumber,outserv,idplant,0,0,0,0,0,busname,0,0,plant] + plants.append(aa) + tous = [] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmGenstat', 1)) + for plant in tous: + busname = plant.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_') + for ii in range(len(buses)): + if busname in buses[ii]: + busnumber = ii + break + idplant = plant.loc_name # plant.ngnum + outs = plant.GetChildren(1, 'outserv.Charef', 1) + if outs: + if outs[0].outserv==0: + outserv = outs[0].typ_id.curval + else: + outserv = plant.outserv + else: + outserv = plant.outserv + + aa = [busnumber, outserv, idplant, 0, 0, 0, 0, 0, busname, 0, 0,plant] + plants.append(aa) + tous = [] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmPvsys', 1)) + for plant in tous: + busname = plant.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_') + for ii in range(len(buses)): + if busname in buses[ii]: + busnumber = ii + break + idplant = plant.loc_name # plant.ngnum + outs = plant.GetChildren(1, 'outserv.Charef', 1) + if outs: + if outs[0].outserv==0: + outserv = outs[0].typ_id.curval + else: + outserv = plant.outserv + else: + outserv = plant.outserv + + aa = [busnumber, outserv, idplant, 0, 0, 0, 0, 0, busname, 0, 0,plant] + plants.append(aa) + + # Loads data (bus, active, reactive, status, name, id)===================== Load + tous=[] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmLod', 1)) + tous = sorted(tous, key=lambda x: x.bus1.cBusBar.cStatName) + loads = [] + for bus in buses: + idload = 0 + for load in tous: + busname = load.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_') + if busname == bus[3]: + idload += 1# cree id pour load + busnumber = bus[0] + # outserv = load.outserv + outs = load.GetChildren(1, 'outserv.Charef', 1) + if outs: + if outs[0].outserv == 0: + outserv = outs[0].typ_id.curval + else: + outserv = load.outserv + else: + outserv = load.outserv + if outserv == 1: + pload = 0 + qload = 0 + else: + pload = load.plini_a + qload = load.qlini_a + aa = [busnumber, pload, qload, outserv, busname, idload,load] + loads.append(aa) + + #Fixed shunt data (number, MVAR, name, ...)========================== Fixed Shunt + tous=[] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmShnt', 1)) + tous = sorted(tous, key=lambda x: x.bus1.cBusBar.cStatName) + shunt = [] + for bus in buses: + idshunt = 0 + for shunt1 in tous: + if shunt1.ncapx==1:# nombre de step =1, considerer comme fix shunt pour equivalent a l'ancien programme sous PSSE + busname = shunt1.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_') + if busname == bus[3]: + idshunt += 1 # cree id pour load + busnumber = bus[0] + qnom=shunt1.Qmax + outs = shunt1.GetChildren(1, 'outserv.Charef', 1) + if outs: + if outs[0].outserv == 0: + outserv = outs[0].typ_id.curval + else: + outserv = shunt1.outserv + else: + outserv = shunt1.outserv + if outserv == 1: + qshunt = 0 + else: + qshunt = shunt1.Qact + aa = [busnumber, outserv, qshunt, busname,qnom, idshunt,bus,shunt1] + shunt.append(aa) + # Switched shunt data (number, status,MVAR, name,Qnom,id)================Swiched Shunt + swshunt = [] + for bus in buses: + idshunt = 0 + for shunt1 in tous: + if shunt1.ncapx != 1: # nombre de step #1, considerer comme switche shunt pour etre equivalent avec l'ancien programme sous PSSE + busname = shunt1.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_') + if busname == bus[3]: + idshunt += 1 # cree id pour load + busnumber = bus[0] + qnom = shunt1.Qmax + outs = shunt1.GetChildren(1, 'outserv.Charef', 1) + if outs: + if outs[0].outserv == 0: + outserv = outs[0].typ_id.curval + else: + outserv = shunt1.outserv + else: + outserv = shunt1.outserv + if outserv == 1: + qshunt = 0 + else: + qshunt = shunt1.Qact + aa = [busnumber, outserv, qshunt, busname, qnom, idshunt,shunt1] + swshunt.append(aa) + + return plants, loads, shunt, swshunt,buses + +def outputNewCsv(): + # Outputs a new .csv file with "cleansed" data (i.e same data than original .csv file, but without unselected branches / buses / etc) + path = os.path.join(Options.FolderList[0], Options.csvCleanedFileName) + with open(path, 'w', newline='') as csvfile: + writer = csv.writer(csvfile, delimiter = ';') + ignorelist = [] + colslist = [] + nameslist = [] + OptionsNamesStorage = Options.NamesStorage #to avoid calling multiple times + for col,header in enumerate(Options.ColsStorage): #remove P and Q columns because already have rate columns. + if (":TrP" in header or ":TrQ" in header or ":Tr3P" in header or ":Tr3Q" in header or ( + ":P " in header and ":PMachine" not in header) or (":Q " in header and ":QMachine" not in header)) and (" id" in header): + ignorelist.append(col) + else: + colslist.append(header) + nameslist.append(OptionsNamesStorage[col]) + writer.writerow(colslist) + writer.writerow(nameslist) + # Finally, write down all the associated values + for line in Options.TotalStorage: + cleanedline = [] + for it,li in enumerate(line): + if it not in ignorelist: + cleanedline.append(li) + if Options.DecimalSeparator[0]==',': + linewcommas = [] + for item in cleanedline: + try: + isnum = float(item)+1 + linewcommas.append(str(item).replace(".",",")) + except: + linewcommas.append(item) + writer.writerow(linewcommas) + else: + writer.writerow(cleanedline) + + +def separateLinesFromTr(Flows, TfoDico, LineDico): + # Separates Flows into two lists, one of transformers and one of lines + # First, get the branch list + branch_list = list(Flows.keys()) + TrList = [] + LineList = [] + for branch in branch_list: + if 'LI' in branch.split('__')[-1]: + try: + # Create the name of the line to compare it + #name = LineDico[branch]['FROMNAME'] + '-' + LineDico[branch]['TONAME'] + # Check if the line is non radial + if branch not in Options.TrueLines: # Skimming lines + continue + # Add the line to the list of the lines + LineList.append(branch) + except: + LineList.append(branch) +## elif '3WNDTR' in branch.split('__')[-1]: #was a bypass for 3wnd tfos because not integrated into checkifborder +## TrList.append(branch) + elif 'TR' in branch.split('__')[-1]: + try: + # Check if the transformer is in the list + #name = TfoDico[branch]['FROMNAME'] + '-' + TfoDico[branch]['TONAME'] + # if "3WNDTR" in branch.split('__')[-1]: + # b = branch.split('__') + # for j,val in enumerate(b): + # if val.startswith("Wnd"): + # del b[j] + # branchTr = '__'.join(b) + # else: #2 wnd transformer + # branchTr = branch + if branch not in Options.TrueLines: # Skimming transfos + continue + # if TrNoGSUorGNDOutput: # Careful: this is not portable, as it removes all "GND", "GSU" and "FMR" transformers systematically + # TrType = TfoDico[branch]['XFRNAME'].split('_')[-1][0:3] + # if TrType != 'GND' and TrType != 'GSU' and TrType != 'FMR': + # TrList.append(branch) + # else: + TrList.append(branch) + except: + TrList.append(branch) + + return TrList, LineList + +def getCases(): + CaseList = [] + # More readable options + AvgLineLoad = Options.AvgLineLoad[0] + AvgLineLoadPercent = Options.AvgLineLoadPercent[0] + AvgTransfoLoad = Options.AvgTransfoLoad[0] + AvgTransfoLoadPercent = Options.AvgTransfoLoadPercent[0] + AvgLowVoltage = Options.AvgLowVoltage[0] + AvgLowVoltagePercent = Options.AvgLowVoltagePercent[0] + AvgHighVoltage = Options.AvgHighVoltage[0] + AvgHighVoltagePercent = Options.AvgHighVoltagePercent[0] + + CaseSelectionMode = Options.CaseSelectionMode[0] + + # CaseSelectionMode can be either "Worst", "File" or "All". We handle those cases in different ways + if CaseSelectionMode == 'Worst': + # Must be "X worst cases" or "X % worst cases". If either of them is not 0 (i.e selected) we add the corresponding case + if AvgLineLoad != 0 or AvgLineLoadPercent != 0: + CaseList.append('MaxAvgLineLd') + if AvgTransfoLoad != 0 or AvgTransfoLoadPercent != 0: + CaseList.append('MaxAvgXfmrLd') + if AvgHighVoltage != 0 or AvgHighVoltagePercent != 0: + CaseList.append('MaxAvgVolt') + if AvgLowVoltage != 0 or AvgLowVoltagePercent != 0: + CaseList.append('MinAvgVolt') + + elif CaseSelectionMode == 'File': + # The case is considered as selected if the user entered a file name, so if the file name is not empty, we add the corresponding case. + # In the event where the user would have tried to select a number of cases before, we reset them. + if Options.NCasesfromFile[0] > 0: + for case in Options.CaseNamesfromFile: + if len(case) > 12: + CaseList.append(case[0:12]) + else: + CaseList.append(case) + + + elif CaseSelectionMode == 'All': + CaseList.append('All') + + tmp = [] + # In case some cases are duplicated in the case list, we create a new, clean list of cases + for item in CaseList: + if item not in tmp: + tmp.append(item) + CaseList = copy.deepcopy(tmp) + return CaseList + +def writeMultiContReport(accfiles, N_files): + accfiles = np.array(accfiles) + import sys + import psspy + + for i in range(int(np.ceil(N_files/22))): + if i == np.ceil(N_files/22)-1: + remainder = np.mod(N_files,22) + indices = np.arange(i*22,i*22+remainder) + nfiles = remainder + else: + indices = np.arange(i*22,i*22+22) + nfiles = 22 + + rate_base = 1 # 1 = rate A, 2=B, 3=C + rate_cont = 1 + Vlim_base = 1 #1=normal, 2=emergency + Vlim_cont = 1 + SummaryReport = 0 #0=no, 1=yes + NonConvergedContingencyReport = 1 #0=no, 1=yes + LoadingViolationsReport = 1 #0=no, 1=yes, 2, base case + worst case, 3=base case, worst case, and all violations + VoltageViolationsReport = 1 + options = [1,rate_base,rate_cont, Vlim_base, Vlim_cont, SummaryReport, 0, 0, 2, 0, NonConvergedContingencyReport, LoadingViolationsReport, VoltageViolationsReport, 1, 0, 0] + + BusMismatchTol = 0.5 + SystemMismatchTol = 5 + LoadingViolationPercent = 90 + WorstCaseContingencyViolationPercent = 100 + values = [BusMismatchTol, SystemMismatchTol, LoadingViolationPercent, WorstCaseContingencyViolationPercent,0,0,0] + + ierr = psspy.accc_multiple_run_report_2(options, values, nfiles, list(accfiles[indices])) + + +def run(dico): + #print dico + #print "je suis dans le run" + start_time = time.clock() + + PF_path=dico['CASE_SELECTION']['PF_path'] + Python3_path=dico['CASE_SELECTION']['Python3_path'] + CaseFile = '' + CaseFolder=dico['CASE_SELECTION']['PSEN_results_folder'] + FolderList = os.listdir(CaseFolder) + for folder in FolderList: + if folder[0:7] == 'package' or folder[0:4] == 'core': + # Get BaseCase.sav inside the first package folder we find + FolderContents = os.listdir(os.path.join(CaseFolder, folder)) + for file in FolderContents: + if file == 'BaseCase.pfd': + CaseFile = os.path.join(os.path.join(CaseFolder, folder), file) + break + break + + MachineDico, LoadDico, LineDico, TransfoDico, MotorDico = PFExtractGeneratorLoadLineandTransfoDico(0, 0, CaseFile, + PF_path, Python3_path)# creer Data_for_interface file + UpdateOptions(dico) + + PF_PATH = Options.PF_PATH[0] + FolderList = Options.FolderList + WriteIndivExcels = Options.WriteIndivExcels[0] + + LinesStorage = [] + BusStorage = [] + TransfoStorage = [] + + # Get the different files + FolderPath = FolderList[0] + FolderContents = os.listdir(FolderPath) + BaseCase = '' + # Get the BaseCase file to compute and eliminate all radial items + for fname in FolderContents: + # Browse all files in the main folder for a "package" folder + if fname[0:7] == 'package': + packNum = int(fname.split('_')[0][7:]) + PackageContents = os.listdir(os.path.join(FolderPath, fname)) + # Browse all files in the package folder for the BaseCase.sav file + for f in PackageContents: + if f[0:8] == 'BaseCase' and BaseCase == '': + # Found the BaseCase.sav file, load it and compute the radial items + BaseCase = os.path.join(os.path.join(FolderPath, fname), f) + BusList, LinesList, TransfosList,BusDico = getNominalkV(BaseCase) + updateConts() + getTrueLines(BaseCase) + break + break + + if Options.CaseSelectionMode[0] == 'Worst' or Options.AlreadyCleaned==False or Options.OutputNCSV==True or Options.Thresholds or sum(Options.OutputNValues)>0: + print('Reading data from PSEN results csv file.') + BusStorage, TransfoStorage, LinesStorage = Utils.getData(Options.csvPSENresults,TransfoDico,LineDico,BusDico) + + ############################### + # N processing + ############################### + if Options.OutputNCSV or Options.Thresholds: + print('Complete network processing') + + if Options.OutputNCSV: + outputNewCsv() + + # Output kept lines, transfos & buses (and which ones we've ignored because either isolated or not right voltage level) + if Options.Thresholds or sum(Options.OutputNValues)>0: #only do so if already have a reason to output this page + excel = Dispatch('Excel.Application') + wb_N = excel.Workbooks.Add() + + if Options.Thresholds: + print('Outputing threshold violations') + import Threshold + Threshold.processThresholds(wb_N) + + Utils.OutputKeptItems(wb_N) + Chart.outputChart(wb_N) + + ##################################### + # N-1 processing + ##################################### + + CaseList = getCases() + + if len(CaseList)>0: + print('Contingency calculations and processing') + + # Create the different N-1 output files + outputExcel = os.path.join(FolderList[0], "ACCCresults.xls") + Options.outFileName = os.path.join(FolderList[0], "ACCCresults_processed.xls") + if Options.ACCcsv: + ACCCresultsfolder = os.path.join(FolderList[0], "ACCCresults") + try: + os.mkdir(ACCCresultsfolder) + except: + pass + book = '' + else: + book = xlwt.Workbook() + + CaseFile = '' + for folder in os.listdir(FolderPath): + if folder[0:7] == 'package' or folder[0:4] == 'core': + # Get BaseCase.sav inside the first package folder we find + FolderContents = os.listdir(os.path.join(FolderPath, folder)) + for file in FolderContents: + if file == 'AllCase.pfd': + CaseFile0 = os.path.join(os.path.join(FolderPath, folder), file) + CaseFile = os.path.join(os.path.join(FolderPath, folder), file[0:-4]+'_ACCC.pfd') + shutil.copy2(CaseFile0, CaseFile) + break + break + + sys.path.append(PF_PATH) + os.environ['PATH'] += ';' + os.path.dirname(os.path.dirname(PF_PATH)) + ';' + + # import powerfactory + import powerfactory as pf + app = pf.GetApplication() + # app.Show() + user = app.GetCurrentUser() + ComImp = user.CreateObject('ComPFDIMPORT') # objet pour importer pfd file + + app.SetWriteCacheEnabled(1) # Disable consistency check + ComImp.g_file = CaseFile + ComImp.g_target = user # project is imported under the user account + err = ComImp.Execute() # Execute command starts the import process + ComImp.Delete() + app.SetWriteCacheEnabled(0) # Enable consistency check + prjs = user.GetContents('*.IntPrj') + prjs.sort(key=lambda x: x.gnrl_modif, reverse=True) + prj = prjs[0] + prj.Activate() + studycase0 = prj.GetContents('BaseCase.IntCase', 1)[0] # app.GetActiveStudyCase() + studycase0.Activate() + fScen = app.GetProjectFolder('scen') # Dossier contient triggers + scen = fScen.GetChildren(1, 'Base.IntScenario', 1)[0] + scen.Activate() + settrigger0 = studycase0.GetChildren(1, 'set_iteration.SetTrigger', 1) + if settrigger0: + settrigger0[0].outserv = 1 + all_inputs_base = read_pfd(app, prj.loc_name, recal=1) + scen.Deactivate() + + Ops = {} + for item in vars(Options): + if item.startswith('__'): + continue + Ops[item] = getattr(Options, item) + + for it, case in enumerate(CaseList): + treatCase(it, case, book, outputExcel,app,prj,all_inputs_base,os.path.dirname(CaseFile), Ops) + + Options.csvFileName = outputExcel + Options.sheets = [] + + if not Options.ACCcsv: + try: + book.save(outputExcel) + except: # nothing to save + pass + + stop_time=time.clock() + + if len(CaseList)>0: + print("Contingency calculations completed.") + print("Duration: %f minutes" \ + % (round(stop_time-start_time)/60.)) + + if Options.process_directly and len(CaseList)>0: + print("Starting contingency processing.") + if Options.ACCcsv: + FlowsCsvPath = os.path.join(FolderList[0], "ACCCresults", CaseList[0] + " Flows 0.csv") + Options.csvFileName = FlowsCsvPath + sheets = getCSVinfo(Options.csvFileName) + else: + Options.csvFileName = outputExcel + sheets = getXLSinfo(Options.csvFileName) + + sheets2 = sheets.copy() + for sheet in sheets2.keys(): + found=False + for case in CaseList: + if case in sheet: + found=True + break + if not found: + del sheets[sheet] + + if 'CONTINGENCY_PROCESSING' not in dico: + dico['CONTINGENCY_PROCESSING'] = {} + dico['CONTINGENCY_PROCESSING']['TabList']=sheets.keys() + for sheetname in sheets.keys(): + cplist = 'Component_List_For_'+sheetname + dico['CONTINGENCY_PROCESSING']["'" + cplist + "'"]=sheets[sheetname][0] + cnlist = 'Contingency_List_For_'+sheetname + dico['CONTINGENCY_PROCESSING']["'" + cnlist + "'"]=sheets[sheetname][1] + + processXLS(dico) + + + print('Treatment over.') + prj.Delete() + resetAll() + + return + + +def treatCase(it, case, book, outputExcel,app,prj,all_inputs_base,namefolder,Ops): + print('Case ' + case) + + # Rendering options more readable + flush = Ops['flush'] + AvgLineLoad = Ops['AvgLineLoad'][0] + AvgLineLoadPercent = Ops['AvgLineLoadPercent'][0] + AvgTransfoLoad = Ops['AvgTransfoLoad'][0] + AvgTransfoLoadPercent = Ops['AvgTransfoLoadPercent'][0] + AvgLowVoltage = Ops['AvgLowVoltage'][0] + AvgLowVoltagePercent = Ops['AvgLowVoltagePercent'][0] + AvgHighVoltage = Ops['AvgHighVoltage'][0] + AvgHighVoltagePercent = Ops['AvgHighVoltagePercent'][0] + + # PSEN output folder + FolderList = Ops['FolderList'] + OutFolder = Ops['OutFolder'][0] + + #user defined cases + CaseNamesfromFile= Ops['CaseNamesfromFile'] + CsvFiles=Ops['CsvFiles'] + + #input sav options + GetSavsfromFolder = Ops['GetSavsfromFolder'][0] + GetSavsfromFile = Ops['GetSavsfromFile'][0] + Ncases = Ops['Ncases'][0] + + #output options + TrNoGSUorGNDOutput = Ops['TrNoGSUorGNDOutput'][0] + ReportSpaces = Ops['ReportSpaces'][0] + RepeatComponentAllLines = Ops['RepeatComponentAllLines'][0] + MultipleContingencyReport = Ops['MultipleContingencyReport'][0] + WriteIndivExcels = Ops['WriteIndivExcels'][0] + #WriteFlowDifs = Ops['WriteFlowDifs'][0] + + + try: + FolderPath = FolderList[it] + except: + FolderPath = FolderList[0] + + ############################################# ######################### + studycases = prj.GetContents('*.IntCase', 1) + basecase=prj.GetContents('BaseCase.IntCase', 1)[0] + ############################################# ######################### + SavFileList = [] # studycase + if case == 'All': + for case1 in studycases: + # if case.loc_name!='BaseCase': + # table.append(case) + if case1!=basecase: + SavFileList.append(case1) + else: + for filename1 in os.listdir(FolderPath): + if filename1.startswith('simulationDClog_complete'): + if FolderPath[-1] != '\\': + FolderPath += '\\' + fname=filename1 + break + # Get the worst cases automatically or cases from the file + table = [] + numberToGet = 0 + #print case + if case == 'MaxAvgLineLd': + if AvgLineLoad != 0: + numberToGet = AvgLineLoad + elif AvgLineLoadPercent != 0: + numberToGet = Utils.rowNumber(Ops['csvPSENresults'], AvgLineLoadPercent) + if numberToGet != 0: + # Get X highest values + table = Utils.getHighestValue(Ops['LinesStorage'], numberToGet) + + elif case == 'MaxAvgXfmrLd': + if AvgTransfoLoad != 0: + numberToGet = AvgTransfoLoad + elif AvgTransfoLoadPercent != 0: + numberToGet = Utils.rowNumber(Ops['csvPSENresults'], AvgTransfoLoadPercent) + if numberToGet != 0: + table = Utils.getHighestValue(Ops['TransfoStorage'], numberToGet) + + elif case == 'MaxAvgVolt': + if AvgHighVoltage != 0: + numberToGet = AvgHighVoltage + elif AvgHighVoltagePercent != 0: + numberToGet = Utils.rowNumber(Ops['csvPSENresults'], AvgHighVoltagePercent) + if numberToGet != 0: + table = Utils.getHighestValue(Ops['BusStorage'], numberToGet) + + elif case == 'MinAvgVolt': + if AvgLowVoltage != 0: + numberToGet = AvgLowVoltage + elif AvgLowVoltagePercent != 0: + numberToGet = Utils.rowNumber(Ops['csvPSENresults'], AvgLowVoltagePercent) + if numberToGet != 0: + table = Utils.getLowestValue(Ops['BusStorage'], numberToGet) + + else: #case from file + + for i,name in enumerate(CaseNamesfromFile): + if name.startswith(case): + break + path = CsvFiles[i] + file = open(path, 'r') + data = csv.reader(file, delimiter = ';') + table0 = [row for row in data] + table = [] + for row in table0: + if isinstance(row, list): + value = row[0] + else: + value = row + try: + table.append(int(value)) + except: + pass + + for ii in table: + for obj in studycases: + try: + if obj.loc_name.split('_')[1]==str(ii): + SavFileList.append(obj) + break + except: + continue + + + N_files = len(SavFileList) + + + # Extract network component characteristics + # Still unsure if this is necessary for each case, as the gens, loads etc should be the same + # GenDico, LoadDico, LineDico, TfoDico, MotorDico, BusDico, BranchesDico, BusNominal = ExtractGeneratorLoadLineandTransfoDico(it, 0, os.path.join(FolderPath, SavFileList[0]), Ops['PSSE_PATH'][0]) + # GenDico, LoadDico, LineDico, TfoDico, MotorDico, BusDico, BranchesDico = PFExtractGeneratorLoadLineandTransfoDico( + # it, 0, os.path.join(FolderPath, SavFileList[0]), Ops['PF_PATH'][0]) + with open('Data_for_interface', 'rb') as fichier: + mon_depickler = pickle.Unpickler(fichier) + data_file = mon_depickler.load() + def convert_keys_to_string(dictionary): + """Recursively converts dictionary keys to strings.""" + if not isinstance(dictionary, dict): + return dictionary + return dict((str(k), convert_keys_to_string(v)) for k, v in dictionary.items()) + data = convert_keys_to_string(data_file) + BusDico=data['BusDico'] + GenDico = data['MachineDico'] + LoadDico = data['LoadDico'] + LineDico = data['LineDico'] + TfoDico = data['TransfoDico'] + MotorDico = data['MotorDico'] + BranchesDico= dict(list(LineDico.items()) + list(TfoDico.items())) + BusNominal=Ops['BusBaseList'] + + Voltages = {} + Flows = {} + FlowMax = {} + #LoadShed = {} + key = '' + accfiles = [] + ContList = [] + + books = [] + outputExcels = [] + + #create output folder for core + num_cores=1 + if num_cores >= 1: + for core in range(num_cores): + try: + #lock.acquire() + os.mkdir(os.path.join(FolderPath, "N_1_" + case + '_core' + str(core))) + #lock.release() + except: + #lock.release() + pass + #os.mkdir(os.path.join(FolderPath, "N_1_" + case + '_core' + str(core))) + + l = 0 #core number, only 1 core because currently no external multiprocessing in PF mode + if Ops['ACCcsv']: + FlowsCsvPath = os.path.join(FolderPath, "N_1_" + case + '_core' + str(l), case + " core " + str(l) + " Flows 0.csv") + VoltagesCsvPath = os.path.join(FolderPath, "N_1_" + case + '_core' + str(l), case + " core " + str(l) + " Voltage 0.csv") + #LoadShedCsvPath = os.path.join(FolderPath, "N_1_" + case + '_core' + str(l), case + " core " + str(l) + " LoadShed 0.csv") + outputCsv = [FlowsCsvPath,VoltagesCsvPath]#, LoadShedCsvPath] + FlowsCsv = open(FlowsCsvPath,'w', newline='') + VoltagesCsv = open(VoltagesCsvPath,'w', newline='') + #LoadShedCsv = open(LoadShedCsvPath,'w', newline='') + FlowsWriter = csv.writer(FlowsCsv, delimiter=';') + VoltagesWriter = csv.writer(VoltagesCsv, delimiter=';') + #LoadShedWriter = csv.writer(LoadShedCsv, delimiter=';') + book = [FlowsWriter, VoltagesWriter]#, LoadShedWriter] + outputExcel = outputCsv[:] + outputcsvhandles = [FlowsCsv, VoltagesCsv]#, LoadShedCsv] + + #currently not used b/c no external multiprocessing in PF (performed internally) + outputExcels.append(outputExcel) + books.append(book) + + for i in range(len(SavFileList)): + #sav_index = SavFileList.index(savfile) + print ('Case ' + case + ' Iteration ' + str(i + 1) )#str(sav_index + 1) + ret = treatPfds(namefolder, GenDico, LoadDico, LineDico, TfoDico, BusDico, BranchesDico, BusNominal, SavFileList[i],app, prj,all_inputs_base, Ops) + + # Aggregating data (append new info to Voltages, Flows, FlowDifs,BranchRates dictionaries for each new .sav treated) + for cont in list(ret[0]): #add "new" contingencies + if cont not in ContList: + ContList.append(cont) + + for k in ret[1].keys(): + if key == '': + key = k + if k not in Voltages.keys(): + Voltages[k] = {} + for cont_key in ret[1][k].keys(): # Run through ContList + #print "Voltages", k, cont_key, i + if cont_key not in Voltages[k].keys(): + Voltages[k][cont_key]=['']*min(flush,len(SavFileList)-int(np.floor(i/flush)*flush)) + Voltages[k][cont_key][i%flush]=ret[1][k][cont_key] + + for k in ret[2].keys(): + if key == '': + key = k + if k not in Flows.keys(): + Flows[k]={} + for cont_key in ret[2][k].keys(): + #print "Flows", k, cont_key, i + if cont_key not in Flows[k].keys(): + Flows[k][cont_key]=['']*min(flush,len(SavFileList)-int(np.floor(i/flush)*flush)) + Flows[k][cont_key][i%flush] = ret[2][k][cont_key] + + for k in ret[3]: + if key == '': + key = k + if k not in FlowMax.keys(): + FlowMax[k]=str(ret[3][k]) + +# for k in ret[4].keys(): +# if key == '': +# key = k +# if k not in LoadShed.keys(): +# LoadShed[k]={} +# for cont_key in ret[4][k].keys(): +# #print "LoadShed", k, cont_key, i +# if cont_key not in LoadShed[k].keys(): +# LoadShed[k][cont_key]=['']*min(flush,len(SavFileList)-int(np.floor(i/flush)*flush)) +# LoadShed[k][cont_key][i%flush] = ret[4][k][cont_key] + + accfiles.append(ret[5]) + + del ret + + if i % flush == flush - 1 or i == len(SavFileList) - 1: # flush variables to avoid memory errors + + # Separate lines from transformers + TrList, LineList = separateLinesFromTr(Flows, TfoDico, LineDico) + + # Create the first sheet. If it already exists, it will raise an exception which is caught; in this case all sheets of the book are iterated to get the first sheet + if not Ops['ACCcsv']: #Excel output files + sheet = False + try: + sheet = book.add_sheet(case + ' Flows 0') + except: # First sheet already exists + for idx in itertools.count(): # Browse all sheets for the one wanted + sheet = book.get_sheet(idx) + if sheet.name == case + ' Flows 0': + break + + if sheet != False: + row_index = WF.writeFlowsLines(book, outputExcel, case, accfiles, ContList, LineList, Flows, BranchesDico, FlowMax, sheet, Ops) + WF.writeFlowsTransfos(book, outputExcel, case, accfiles, ContList, TrList, Flows, TfoDico, FlowMax, row_index, Ops) + WF.writeVoltages(book, case, accfiles, ContList, Voltages, BusNominal, Ops) + #WF.writeLoadShed(book, case, accfiles, ContList, LoadShed, Ops) + + try: # Save the workbook in case something goes wrong + book.save(outputExcel) + except: # if nothing was output and nothing is to save + pass + + + else: #csv output files + row_index = WFC.writeFlowsLines(book, outputExcel, case, accfiles, ContList, LineList, Flows, BranchesDico, FlowMax, Ops) + WFC.writeFlowsTransfos(book, outputExcel, case, accfiles, ContList, TrList, Flows, TfoDico, FlowMax, row_index, Ops) + WFC.writeVoltages(book, case, accfiles, ContList, Voltages, BusNominal, Ops) + #WFC.writeLoadShed(book, case, accfiles, ContList, LoadShed, Ops) + + # Reset variables + Voltages = {} + Flows = {} + FlowMax = {} + key = '' + accfiles = [] + + if Ops['ACCcsv']: #close csv files written. + for handle in outputcsvhandles: + #handle.save() + handle.close() + + #concatenate ACCC results files (csv format) (for excel format, see PSSE version) + if Ops['ACCcsv']: + FlowsCsvPath = os.path.join(FolderList[0], "ACCCresults", case + " Flows 0.csv") + VoltagesCsvPath = os.path.join(FolderList[0], "ACCCresults", case + " Voltage 0.csv") + #LoadShedCsvPath = os.path.join(FolderList[0], "ACCCresults", case + " LoadShed 0.csv") + for fname in [FlowsCsvPath,VoltagesCsvPath]:#, LoadShedCsvPath]: + if os.path.isfile(fname): + os.remove(fname) + flowsfilelist = [] + voltagesfilelist = [] + #loadshedfilelist = [] + for outputcsv in outputExcels: + flowsfilelist.append(outputcsv[0]) + voltagesfilelist.append(outputcsv[1]) + #loadshedfilelist.append(outputcsv[2]) + join_csv(FlowsCsvPath, flowsfilelist) + join_csv(VoltagesCsvPath, voltagesfilelist) + #join_csv(LoadShedCsvPath, loadshedfilelist) + + + return + + + +def treatPfds(namefolder, GenDico, LoadDico, LineDico, TfoDico, BusDico, BranchesDico, BusNominal, study,app, prj, all_inputs_base, Ops): + Voltages = {} + Flows = {} + FlowMax = {} + LoadShed = {} + ContList = () + + #contingency options + Vmin = Ops['Vmin'][0] + Vmax = Ops['Vmax'][0] + ContRate = Ops['ContRate'][0] + flowlimitlines = Ops['flowlimitlines'][0] + flowlimittransfos = Ops['flowlimittransfos'][0] + Tolerance = Ops['Tolerance'][0] + TripLines = Ops['TripLines'][0] + TripTransfos = Ops['TripTransfos'][0] + TripGenerators = Ops['TripGenerators'][0] + TripBuses = Ops['TripBuses'][0] + IsolatedGen = Ops['IsolatedGen'][0] + + # Remove isolated branches (if a bus appears only once in branch list, its an isolated branch) + singleBuses = [] + notSingleBuses = [] + pairs = [] + for branch in BranchesDico: + branch = BranchesDico[branch] + ton = int(branch['TONUMBER']) + fromn = int(branch['FROMNUMBER']) + if [ton, fromn] in pairs: + continue + else: + pairs.append([ton, fromn]) + if fromn in notSingleBuses: + pass + elif fromn in singleBuses: + singleBuses.remove(fromn) + notSingleBuses.append(fromn) + else: + singleBuses.append(fromn) + if ton in notSingleBuses: + pass + elif ton in singleBuses: + singleBuses.remove(ton) + notSingleBuses.append(ton) + else: + singleBuses.append(ton) + newDict = {} + for branch in LineDico: + if int(LineDico[branch]['FROMNUMBER']) not in singleBuses and int( + LineDico[branch]['TONUMBER']) not in singleBuses: + newDict[branch] = LineDico[branch] + LineDico = copy.deepcopy(newDict) + + study.Activate() + with open(namefolder+'/data_dico', 'rb') as fichier: + mon_depickler = pickle.Unpickler(fichier) + dicopfd = mon_depickler.load() + + nn = int(''.join(ele for ele in study.loc_name if ele.isdigit())) # cas number + fScen = app.GetProjectFolder('scen') # Dossier contient triggers + #pdb.set_trace() + scenario = fScen.GetChildren(1, 'Case_'+str(nn)+'.IntScenario', 1) + scenario[0].Activate() + opf = app.GetFromStudyCase('ComOpf') + + if opf.iopt_obj=='shd': #update load levels + erropf = opf.Execute() # lancer opf, + all_inputs_base1 = read_pfd(app, prj.loc_name) + loads_base = all_inputs_base1[4] + Psetpoints = [] + Qsetpoints = [] + for load in loads_base: + LSscale = load[6].GetAttribute("s:scale") + P_setpoint = load[6].GetAttribute('e:plini')#('s:pini_set') + Q_setpoint = load[6].GetAttribute('e:qlini')#('s:qini_set') + Psetpoints.append(LSscale*P_setpoint) + Qsetpoints.append(LSscale*Q_setpoint) + + for it,load in enumerate(loads_base): +# try: #disactivate triggers if there are any +# loadPscale = load[6].GetChildren(1, 'plini.Charef', 1) +# loadQscale = load[6].GetChildren(1, 'qlini.Charef', 1) +# loadPscale[0].outserv = 1 +# loadQscale[0].outserv = 1 +# except: +# pass + load[6].plini = Psetpoints[it] + load[6].qlini = Qsetpoints[it] + +# #check to see if loads properly initialized +# all_inputs_base1 = read_pfd(app, prj.loc_name, 1) +# load_base = all_inputs_base1[4] +# print([l[1] for l in loads_base]) +# print([l[1] for l in load_base]) +# print('') +# for ind in range(len(load_base)): +# l0 = loads_base[ind] +# l1 = load_base[ind] +# if abs(l0[1]-l1[1])<0.01 and abs(l0[2]-l1[2])<0.01: +# pass +# else: +# print("loads not saved correctly after load-shedding") + #pdb.set_trace() + + all_inputs_base1 = read_pfd_simple(app, prj.loc_name) + plants_base = all_inputs_base1[0] + + try: + cntdef = study.GetContents('*.ComNmink', 1)[0] + except: + cntdef = study.CreateObject('ComNmink') + cntdef.optSel = 0 #all element + cntdef.iopt_n1 = 1 + cntdef.iopt_n2 = 0 + cntdef.iopt_cmd = 0 # 0: library; 1: direct + cntdef.optSel = 0 #0: whole cases, 1: selection + fFaults = app.GetProjectFolder('fault') # dossier Faults + try: + for obj in study.GetContents('*.ComSimoutage', 1): + obj.Delete() + except: + pass + try: + for obj in fFaults.GetContents('*.IntEvt', 1): + obj.Delete() + except: + pass + + # line N-1 contingencies + if TripLines: + cntdef.iopt_lne=1 + #transfo N-1 contingencies + if TripTransfos: + cntdef.iopt_trf = 1 + #generator N-1 contingencies + if TripGenerators: + cntdef.iopt_sym = 1 + if TripLines or TripTransfos or TripGenerators: + cntdef.iopt_n1 = 1#N_1 + cntdef.iopt_n2 = 0#N_2 + cntdef.iopt_nc = 0 # N_2 + cntdef.iopt_cmd = 0 # 0: library; 1: direct + cntdef.optSel = 0 # 0: whole cases, 1: selection + cntdef.Execute() + + plants_base_before = plants_base + buses_base = all_inputs_base[0] + lines_base = all_inputs_base[1] + transf_base = all_inputs_base[2] + plants_base = all_inputs_base[3] + transf3_base = all_inputs_base[7] + # buses_base ; lines_base; transf_base; plants_base; transf3_bas + + + + # settriger_iter = studycase.GetChildren(1, 'set_iteration.SetTrigger', 1)[0] + # settriger_iter.Activate() + # compy = studycase.GetContents('comp0.ComPython', 0)[0] + # compy.Execute() + + + # Automatic N-2 + try: + Set = study.GetContents('*.SetSelect',1)[0] + Set.Clear() + except: + Set = study.CreateObject('SetSelect') + if Ops['AutoN2Lines'] or Ops['AutoN2Transfos'] or Ops['AutoN2Gen']: + cntdef.iopt_n1 = 0 + cntdef.iopt_n2 = 1 + cntdef.iopt_cmd = 0 # 0: library; 1: direct + cntdef.optSel = 1 # 0: whole cases, 1: selection + cntdef.sel_user = Set + + # Automatic N-2 Lines + if Ops['AutoN2Lines']: + for key in LineDico: + if key[-3:-1] == 'BR' or key[-2:] == 'BR': + continue + if key[-3:-1] == 'Br' or key[-2:] == 'Br': + continue + if key[-3:-1] == 'SW' or key[-2:] == 'SW': + continue + if key[-3:-1] == 'Sw' or key[-2:] == 'Sw': + continue + aa = LineDico[key] + # Filling the automatic N-2's list if needed + voltage = BusNominal[aa['TONAME']] + if voltage in Ops['AutoN2Lines']: + for bb in lines_base: + if bb[0]==aa['FROMNUMBER'] and bb[1]==aa['TONUMBER']and bb[10]==aa['ID']: + Set.AddRef(bb[11]) + if Ops['AutoN2Melange']: + cntdef.Execute() + Set.Clear() + + # Automatic N-2 Transfos + if Ops['AutoN2Transfos']: + # verifier=False + for key in TfoDico: + tfo = TfoDico[key] + voltage1 = BusNominal[tfo['TONAME']] + voltage2 = BusNominal[tfo['FROMNAME']] + couple = (voltage1, voltage2) + couple2 = (voltage2, voltage1) + if tfo['#WIND'] == 2: + if couple in Ops['AutoN2Transfos'] or couple2 in Ops['AutoN2Transfos']: + # verifier=True + for bb in transf_base: + if bb[0] == tfo['FROMNUMBER'] and bb[1] == tfo['TONUMBER'] and bb[10] == tfo['ID']: + Set.AddRef(bb[11]) + if tfo['#WIND'] == 3: + voltage3 = BusNominal[tfo['3NAME']] + couple1 = (voltage1, voltage2, voltage3) + couple2 = (voltage3, voltage1, voltage2) + couple3 = (voltage2, voltage3, voltage1) + couple4 = (voltage1, voltage3, voltage2) + couple5 = (voltage2, voltage1, voltage3) + couple6 = (voltage3, voltage2, voltage1) + couples = (couple1, couple2, couple3, couple4, couple5, couple6) + AddKey = False + for couple in couples: + if couple in Ops['AutoN2Transfos']: + for bb in transf3_base: + if bb[0] == tfo['FROMNUMBER'] and bb[1] == tfo['TONUMBER'] and bb[2] == tfo['3NUMBER'] and bb[13] == tfo['ID']: + Set.AddRef(bb[14]) + break + if not Ops['AutoN2Melange']: + cntdef.Execute() + Set.Clear() + # Automatic N-2 Bus + if Ops['AutoN2Bus']: + for bus in BusDico: + name = bus[2] + voltage = BusNominal[name] + if voltage in Ops['AutoN2Bus']: + for bb in buses_base: + if bb[3]==name: + Set.AddRef(bb[8]) + if not Ops['AutoN2Melange']: + cntdef.Execute() + Set.Clear() + + if Ops['AutoN2Gen']: + for gen in plants_base_before: + Set.AddRef(gen[11]) + if not Ops['AutoN2Melange']: + cntdef.Execute() + Set.Clear() + # Execute + if Ops['AutoN2Melange']: + cntdef.Execute() + + cntana = study.CreateObject('ComSimoutage') + cntana.loadmax = min(Ops['flowlimitlines'][0], Ops['flowlimittransfos'][0]) # 0 pour afficher tous, si on met 90, afficher seulement les valeurs au dessus de 90 + cntana.vlmax = Ops['Vmax'][0] # 1 pour afficher tous + cntana.vlmin = Ops['Vmin'][0] # 1 pour afficher tous + cntana.iPerformOpt = 0 #0 monitor whole system, 1 monitor specific region + cntana.iEnableParallel = 1 + + paralcomp = study.CreateObject('SetParalman') + paralcomp.SlaveNum = 1 #use N-1 cores (not all) to allow for user to keep working on computer + + + nb = 0 + ContList=[] + rel = {} + rel['contigency']={} + + for obj in fFaults.GetContents('*.IntEvt', 1): + # stop = time.clock(); print('=== ' + str(round(stop - start, 3)) + ' seconds'); start = stop + if nb == 0: + aa = cntana.CreateObject('Comoutage', obj.loc_name) + cc = cntana.CreateObject('Comoutage', obj.loc_name) + else: + aa = cntana.AddCopy(cc, obj.loc_name) + ContList.append(obj.loc_name) + + # stop = time.clock(); print('aa ' + str(round(stop - start, 3)) + ' seconds'); # start = stop + temp = [] + for obj1 in obj.GetContents('*.EvtShc', 1): + temp.append(obj1.p_target) + # stop = time.clock(); print('bb ' + str(round(stop - start, 3)) + ' seconds'); start = stop + aa.SetObjs(temp) + # aa.cpCase=obj + nb += 1 + aa.number = nb + rel['contigency'][nb]=obj.loc_name + + cc.Delete() + ldf=study.GetContents('*.Comldf',1)[0] + + if Ops['AdjTaps']: + ldf.iopt_at = 1 # automatic tap transfos + else: + ldf.iopt_at=0 + if Ops['AdjustShunts']: + ldf.iopt_asht = 1 # automatic shunt + else: + ldf.iopt_asht = 0 + if Ops['VarLimits'][0]: + ldf.iopt_lim=1 + else: + ldf.iopt_lim=0 + if Ops['ActiveLimits']: + ldf.iopt_plim=1 + else: + ldf.iopt_plim = 0 + if Ops['FlatStart']: + ldf.iopt_noinit=1 + else: + ldf.iopt_noinit=0 + ldf.iPbalancing = Ops['DispatchMode'] + + #set active power of synchronous generators + #all_inputs_base1 = read_pfd_simple(app, prj.loc_name) + #plants_base = all_inputs_base1[0] + #all_inputs3 = read_pfd(app, prj.loc_name, recal=0) + #plants_base = all_inputs3[3] + + +# for plant in plants_base: +# try: +# print(plant[2],plant[3]) +# plant[11].pgini = plant[3] +# except: +# plant[11].pgini_a = plant[3] + + + # ldf.iopt_lim = Ops['VarLimits'] # reactive power limit + # ldf.iopt_plim = Ops['ActiveLimits'] # active power limit + # ldf.iopt_limScale = 1 # scale factor + # ldf.iopt_noinit = Ops['FlatStart'] # no initialisation load flow + + # Run Contingency Analysis + err = cntana.Execute() + + if (err!=0): + print('Error: Power Factory Contingency Analysis ended in error. Network probably does not converge for load-flows.') + + resFile = study.GetContents('Contingency Analysis*.ElmRes', 1)[0] + app.PrintPlain(resFile) + resFile.Load() + nbrow = resFile.GetNumberOfRows() + # bus1 = prj.GetChildren(1, 'Bus 1.ElmTerm', 1)[0] + + for bus in buses_base: + #Voltages[bus[3]]={} + col = resFile.FindColumn(bus[8], 'm:u') + for row in range(1,nbrow-1): + cntnumber=resFile.GetValue(row,1) + cntname = rel['contigency'][int(cntnumber[1])] + aa = resFile.GetValue(row , col) + if aa[0] == 0: + val = aa[1] +# else: +# val='' + if val < Vmin or val > Vmax: + if bus[3] not in Voltages.keys(): + Voltages[bus[3]] = {} + Voltages[bus[3]][cntname]=val + + for line in lines_base: + #aa=[frombus_number,tobus_number,currentA,pourcent,pourcent,pourcent,flowP,flowQ,frombus_name,tobus_name,idline,line] + #Flows[line[12]]={} + col = resFile.FindColumn(line[11], 'c:loading') + for row in range(1,nbrow-1): + cntnumber=resFile.GetValue(row,1) + cntname = rel['contigency'][int(cntnumber[1])] + aa = resFile.GetValue(row , col) + if aa[0] == 0: + val = aa[1] +# else: +# val='' + if val > flowlimitlines: + if line[12] not in Flows.keys(): + FlowMax[line[12]] = np.sqrt(3) * line[11].Unom * line[11].Irated + if line[12] not in Flows.keys(): + Flows[line[12]] = {} + Flows[line[12]][cntname]=val + + for tfo in transf_base: + FlowMax[tfo[12]] = tfo[11].Snom_a + Flows[tfo[12]]={} + col = resFile.FindColumn(tfo[11], 'c:loading') + for row in range(1,nbrow-1): + cntnumber=resFile.GetValue(row,1) + cntname = rel['contigency'][int(cntnumber[1])] + aa = resFile.GetValue(row , col) + if aa[0] == 0: + val = aa[1] +# else: +# val='' + if val > flowlimittransfos: + if tfo[12] not in Flows.keys(): + Flows[tfo[12]] = {} + Flows[tfo[12]][cntname]=val + + for tfo in transf3_base: + try: + FlowMax[tfo[15]]=max(tfo[14].typ_id.strn3_h,tfo[14].typ_id.strn3_m,tfo[14].typ_id.strn3_l)*tfo[14].nt3nm + except: + FlowMax[tfo[15]]='' + Flows[tfo[15]]={} + col = resFile.FindColumn(tfo[14], 'c:loading') + for row in range(1,nbrow-1): + cntnumber=resFile.GetValue(row,1) + cntname = rel['contigency'][int(cntnumber[1])] + aa = resFile.GetValue(row , col) + if aa[0] == 0: + val = aa[1] +# else: +# val='' + if val > flowlimittransfos: + if tfo[15] not in Flows.keys(): + Flows[tfo[15]] = {} + Flows[tfo[15]][cntname]=val + + return ContList, Voltages, Flows, FlowMax, LoadShed,study.loc_name + + + +if __name__ == '__main__': + from dicoN1 import Dico as dico + run(dico) diff --git a/ProcessOutputs_Eficas/TreatOutputs/UpdateOptionsPF.py b/ProcessOutputs_Eficas/TreatOutputs/UpdateOptionsPF.py new file mode 100644 index 00000000..1601f11a --- /dev/null +++ b/ProcessOutputs_Eficas/TreatOutputs/UpdateOptionsPF.py @@ -0,0 +1,298 @@ + +import Options +import csv +import sys +import os +import pdb + +def UpdateOptions(dico): + Options.SelectedBusBase=[] + Options.BusByNom = [False] + Options.LinesByNom = [False] + Options.SelectedLinesBase=[] + Options.TransfoByNom = [False] + Options.SelectedTransfoBase=[] + if 'CASE_SELECTION' in dico: + curdico = dico['CASE_SELECTION'] + for key in curdico.keys(): + if key=='OutputNewCsv': + Options.OutputNCSV = curdico[key] + elif key=='MaxDepth': + Options.RecursiveDepth = curdico[key] + elif key=='PSEN_results_folder': + Options.FolderList = [curdico[key]] + elif key=='PSEN_results_csvfile': + Options.csvPSENresults = curdico[key] + elif key=='PSEN_results_csvfile_cleaned': + Options.AlreadyCleaned = curdico[key] + elif key=='NewCsvFile': + Options.csvCleanedFileName = curdico[key] + elif key=='DecimalSeparator': + Options.DecimalSeparator = [curdico[key]] + elif key=='PSSE_path': + Options.PSSE_PATH = [curdico[key]] + elif key=='PF_path': + Options.PF_PATH = [curdico[key]] + elif key=='Python3_path': + Options.Python3_path = [curdico[key]] + elif key=='BusesList': + if curdico[key] != []: + Options.BusByNom = [True] + if isinstance(curdico[key], list): + Options.SelectedBusBase = [float(item) for item in curdico[key]] + else: + Options.SelectedBusBase = [float(curdico[key])] + elif key=='LinesList': + if curdico[key] != []: + Options.LinesByNom = [True] + if isinstance(curdico[key], list): + Options.SelectedLinesBase = [float(item) for item in curdico[key]] + else: + Options.SelectedLinesBase = [float(curdico[key])] + elif key=='TransformersList': + if curdico[key] != []: + Options.TransfoByNom = [True] + if isinstance(curdico[key], list): + newList = [] + for item in curdico[key]: + u1 = item.split('-')[0].strip("'").strip('"') + u2 = item.split('-')[1].strip("'").strip('"') + U1 = float(u1) + U2 = float(u2) + if len(item.split('-'))==3: + u3 = item.split('-')[2].strip("'").strip('"') + U3 = float(u3) + newList.append([U1,U2,U3]) + else: + newList.append([U1,U2]) + Options.SelectedTransfoBase = newList + else: + u1 = item.split('-')[0].strip("'").strip('"') + u2 = item.split('-')[1].strip("'").strip('"') + U1 = float(u1) + U2 = float(u2) + Options.SelectedTransfoBase = [[U1,U2]] + if len(item)==3: + u3 = item.split('-')[2].strip("'").strip('"') + U3 = float(u3) + Options.SelectedTransfoBase = [[U1,U2,U3]] + + else: + print('CASE_SELECTION ', key) + + if 'N_PROCESSING_OPTIONS' in dico: + curdico = dico['N_PROCESSING_OPTIONS'] + for key in curdico.keys(): + if key=='Branches': + if sum(x>0 for x in curdico[key])>0 and Options.Thresholds == False: + if Options.Thresholds ==False: + Options.Thresholds = True + Options.BranchThreshold = list(curdico[key]) + elif key=='Transformers': + if sum(x>0 for x in curdico[key])>0 and Options.Thresholds == False: + if Options.Thresholds ==False: + Options.Thresholds = True + Options.TransfoThreshold = list(curdico[key]) + elif key=='High_voltage': + if sum(x>0 for x in curdico[key])>0 and Options.Thresholds == False: + if Options.Thresholds ==False: + Options.Thresholds = True + Options.HighVoltageThreshold = list(curdico[key]) + elif key=='Low_voltage': + if sum(x>0 for x in curdico[key])>0 and Options.Thresholds == False: + if Options.Thresholds ==False: + Options.Thresholds = True + Options.LowVoltageThreshold = list(curdico[key]) + elif key=='Output_bus_values': + Options.OutputNValues[0]=curdico[key] + elif key=='Output_lines_values': + Options.OutputNValues[1]=curdico[key] + elif key=='Output_transformer_values': + Options.OutputNValues[2]=curdico[key] + else: + print('N_PROCESSING_OPTIONS ', key) + else: + Options.OutputNValues = [False,False,False] + Options.Thresholds = False + + if 'CONTINGENCY_SELECTION' in dico: + curdico = dico['CONTINGENCY_SELECTION'] + for key in curdico.keys(): + if key=='SelectionMethod': + if curdico[key]== None: + Options.CaseSelectionMode[0] = '' + elif curdico[key].lower()=='caseselectionfromfile': + Options.CaseSelectionMode[0] = "File" + elif curdico[key].lower()=='selectallcases': + Options.CaseSelectionMode[0] = "All" + elif curdico[key].lower()=='selectworstcases': + Options.CaseSelectionMode[0] = "Worst" + elif key.startswith('case_name'): + pass + elif key.startswith('csv_file'): + pass + elif key[0:3]=='Avg': + if "Transfo" not in key: + setattr(Options,key,[curdico[key]]) + elif key == "AvgTransformerLoad": + Options.AvgTransfoLoad = [curdico[key]] + elif key == "AvgTransformerLoadPercent": + Options.AvgTransfoLoadPercent = [curdico[key]] + + elif key[0:4]=="Trip": + setattr(Options,key,[curdico[key]]) + + elif key=="BusesList": + if isinstance(curdico[key], list): + Options.AutoN2Bus = [float(item) for item in curdico[key]] + else: + Options.AutoN2Bus = [float(curdico[key])] + elif key == "MixType": + Options.AutoN2Melange = curdico[key] + elif key == "GenList": + Options.AutoN2Gen = curdico[key] + elif key=="LinesList": + if isinstance(curdico[key], list): + Options.AutoN2Lines = [float(item) for item in curdico[key]] + else: + Options.AutoN2Lines = [float(curdico[key])] + elif key=="TransformersList": + if isinstance(curdico[key], list): + newList = [] + for item in curdico[key]: + u1 = item.split('-')[0].strip("'").strip('"') + u2 = item.split('-')[1].strip("'").strip('"') + U1 = float(u1) + U2 = float(u2) + if len(item)==3: + u3 = item.split('-')[2].strip("'").strip('"') + U3 = float(u3) + newList.append((U1,U2,U3)) + else: + newList.append((U1,U2)) + Options.AutoN2Transfos = newList + else: + u1 = item.split('-')[0].strip("'").strip('"') + u2 = item.split('-')[1].strip("'").strip('"') + U1 = float(u1) + U2 = float(u2) + Options.AutoN2Transfos = [(U1,U2)] + if len(item)==3: + u3 = item.split('-')[2].strip("'").strip('"') + U3 = float(u3) + Options.AutoN2Transfos = [(U1,U2,U3)] + + elif "ComponentList" in key: + lst = [] + for item in curdico[key]: + item2 = item.strip("'").strip('\"') + lst.append(item2) + Options.CustomContingencies.append(lst) + elif "consigne" in key: + pass + else: + print('CONTINGENCY_SELECTION ',key) + + #ensure the order of cases and files is correct + if 'case_name' in curdico: + name = 'case_name' + csvfile = 'csv_file' + Options.CaseNamesfromFile.append(curdico[name]) + Options.CsvFiles.append(curdico[csvfile]) + Options.NCasesfromFile[0] +=1 + else: + ite = 1 + stop = False + while not stop: + try: + name = 'case_name_' + str(ite) + csvfile = 'csv_file_' + str(ite) + Options.CaseNamesfromFile.append(curdico[name]) + Options.CsvFiles.append(curdico[csvfile]) + Options.NCasesfromFile[0] +=1 + ite += 1 + except: + stop = True + + if 'CONTINGENCY_OPTIONS' in dico: + curdico = dico['CONTINGENCY_OPTIONS'] + for key in curdico.keys(): + if key=='ContingencyRate': + Options.ContRate = [curdico[key]] + elif key=='FlowLimitLines': + Options.flowlimitlines = [curdico[key]] + elif key=='FlowLimitTransformers': + Options.flowlimittransfos = [curdico[key]] + elif key=="Vmin" or key=="Vmax" or key=="Tolerance" or key=='VarLimits': + setattr(Options,key,[curdico[key]]) + elif key=="AdjustTaps": + Options.AdjTaps = curdico[key] + elif key=="AdjustShunts": + Options.AdjustShunts = curdico[key] + elif key=="AdjustSwitchedShunts": + Options.AdjSwitchedShunts = curdico[key] + elif key=="SolutionMethod": + value = curdico[key].split("-")[0].strip('"').strip("'") + Options.SolutionMethod = [int(value)] + elif key=="ActiveLimits": + Options.ActiveLimits = curdico[key] + elif key=="FlatStart": + Options.FlatStart = curdico[key] + elif key=="DispatchMode": + if curdico[key]=="ReferenceMachine": + Options.DispatchMode = 0 + elif curdico[key]=='LoadAtReferenceBus': + Options.DispatchMode = 1 + elif curdico[key]=='StaticGeneratorAtReferenceBus': + Options.DispatchMode = 2 + elif curdico[key]=='DistributedSlackByLoads': + Options.DispatchMode = 3 + elif curdico[key]=='DistributedSlackBySynchronousGenerators': + Options.DispatchMode = 4 + elif curdico[key]=='DistributedSlackBySynchronousAndStaticGenerators': + Options.DispatchMode = 5 + elif key=="flush": + Options.flush = int(curdico["flush"]) + elif key=="output_file_format": + if curdico[key]=='csv': + Options.ACCcsv = True + elif curdico[key]=='xls': + Options.ACCcsv = False + elif key =="process_directly": + Options.process_directly = curdico[key] + else: + print('CONTINGENCY_OPTIONS ',key) + + #if dico.has_key('CONTINGENCY_PROCESSING'): + # curdico = dico['CONTINGENCY_PROCESSING'] + for key in dico.keys(): + if 'CONTINGENCY_PROCESSING' in key: + curdico = dico[key] + + Options.selectedDoubleCol = {} + Options.selectedDoubleRow = {} + for key in curdico.keys(): + if key=='XLS_file': + Options.csvFileName = curdico[key] + if Options.csvFileName.endswith('.csv'): + Options.ACCcsv = True + elif Options.csvFileName.endswith('.xls'): + Options.ACCcsv = False + elif key.strip("'").strip('"').startswith('Contingency_List_For_'): + tab = key.strip("'").strip('"').strip('Contingency_List_For_') + Options.selectedDoubleCol[tab]=[item.strip("'").strip('"') for item in curdico[key]] + elif key.strip("'").strip('"').startswith('Component_List_For_'): + tab = key.strip("'").strip('"').strip('Component_List_For_') + Options.selectedDoubleRow[tab]=[item.strip("'").strip('"') for item in curdico[key]] + elif key=='TabList': + pass + else: + print('CONTINGENCY_PROCESSING ', key) + + return +# for key in dico.keys(): +# atraiter=dico[key] +# for key2 in atraiter.keys(): +# param = atraiter[key2] +# Optionsparam=DicoTraduction[key][key2] +# setattr(Options, Optionsparam,param) \ No newline at end of file diff --git a/ProcessOutputs_Eficas/TreatOutputs/UtilsPF.py b/ProcessOutputs_Eficas/TreatOutputs/UtilsPF.py new file mode 100644 index 00000000..dfb2e4f8 --- /dev/null +++ b/ProcessOutputs_Eficas/TreatOutputs/UtilsPF.py @@ -0,0 +1,394 @@ +import Options +import csv +import sys +import os +import pdb +import shutil + +sys.path.append(os.path.dirname(os.path.dirname(__file__))) +#from ExtractGeneratorLoadLineandTransfoDico import * + +def OutputKeptItems(book): + + OKI = True + if OKI: + sheet = book.Worksheets.Add() + sheet.Name = 'Ignored summary' + + # Output kept & ignored lines/tfos + sheet.Cells(1, 1).Value = 'Kept branches' + sheet.Cells(1, 3).Value = 'Ignored branches' + + kbr = [] + ibr = Options.RadialLines + + for item in Options.TrueLines: + if 'LI' in item.split('__')[-1]:#Valentin + if Options.LinesByNom[0] and Options.LinesBaseList[item] not in Options.SelectedLinesBase: + ibr.append(item) + else: + kbr.append(item) + elif 'TR' in item.split('__')[-1]: + if Options.TransfoByNom[0] and Options.TransfoBaseList[item] not in Options.SelectedTransfoBase: + ibr.append(item) + else: + kbr.append(item) + + sheet.Cells(2, 1).Value = '(total: ' + str(len(kbr)) + ')' + sheet.Cells(2, 3).Value = '(total: ' + str(len(ibr)) + ')' + + for i in range(len(kbr)): + sheet.Cells(i + 3, 1).Value = kbr[i] + for i in range(len(ibr)): + sheet.Cells(i + 3, 3).Value = ibr[i] + + # Output kept & ignored buses + sheet.Cells(1, 6).Value = 'Kept buses' + sheet.Cells(1, 8).Value = 'Ignored buses' + + kb = [] + ib = [] + for item in Options.BusBaseList: + if item not in Options.IsolatedGenList: + if Options.BusByNom[0] and Options.BusBaseList[item] in Options.SelectedBusBase: + kb.append(item) + elif not Options.BusByNom[0]: + kb.append(item) + else: + ib.append(item) + else: + ib.append(item) + + sheet.Cells(2, 6).Value = '(total: ' + str(len(kb)) + ')' + sheet.Cells(2, 8).Value = '(total: ' + str(len(ib)) + ')' + + for i in range(len(kb)): + sheet.Cells(i + 3, 6).Value = kb[i] + for i in range(len(ib)): + sheet.Cells(i + 3, 8).Value = ib[i] + else: + pass + +def rowNumber(path, percent): + with open(path, 'r') as csvfile: + data = csv.reader(csvfile, delimiter=';') + count = 0 + for row in data: + try: + test = int(row[0])+1 + count += 1 + except: + pass + return int(float(percent * 0.01) * float(count)) + +def getData(path,TransfoDico,LineDico,BusDico): + + cols = [] + names = [] + BusStorage = [] + TransfoStorage = [] + LinesStorage = [] + BusMean = [] + TransfoMean = [] + LinesMean = [] + it = 0 + + Options.TotalBusStorage = [[]] + Options.TotalTransfoStorage = [[]] + Options.TotalLinesStorage = [[]] + Options.CaseIDStorage = [] + + #convert decimal separator to commas for csv files + if Options.DecimalSeparator[0]==",": + csvfilesave = path[0:-4] + "_comma" + ".csv" + shutil.copy2(path, csvfilesave) + os.remove(path) + + h = open(csvfilesave,"r") + crd = csv.reader(h,delimiter=";") + g = open(path, "w", newline='\n') + cwt = csv.writer(g, delimiter=";") + for row in crd: + rowwcommas = [] + for item in row: + try: + isnum = float(str(item).replace(",","."))+1 + rowwcommas.append(str(item).replace(",",".")) + except: + rowwcommas.append(item) + cwt.writerow(rowwcommas) + h.close() + g.close() + + with open(path, 'r') as csvfile: + data = csv.reader(csvfile, delimiter=';') + for row in data: + if len(row)>0: + if 'Summary Table' in row[0]: #dont mistake load shedding and shunt adjustment tables as their own iterations, break out of loop here + break + try: + #column number where individual element data is outputted in csv file + if names!=[]: + iGen=cols.index('Y:GenTot') + if float(row[iGen])==0: + continue + # if float(row[10]) == 0: + # continue + except: + pass + if cols == []: # first row -> fill the cols[] list + for item in row: + cols.append(item) + elif names == []: # Second row -> fill the names[] list + for i in range(len(row)): + names.append(row[i]) + else: # Store the data from the selected cols + tmpBus = [] + tmpTr = [] + tmpLine = [] + tmpAll = [] + for i in range(len(row)): + if i == 0: + it += 1 + # Check if this row is data + try: + int(row[i]) + except: + break + #try: + if 1: + if cols[i].find('VBus') != -1: + if (Options.BusByNom[0] and Options.BusBaseList[names[i]] not in Options.SelectedBusBase): + continue + elif names[i] in Options.IsolatedGenList: + continue + tmpAll.append(row[i]) + tmpBus.append(float(row[i])) + if it == 1: + Options.NamesStorage.append(names[i]) + Options.ColsStorage.append(cols[i]) + Options.TotalBusStorage[0].append(names[i]) + elif cols[i].find(':Tr%Rate') != -1: + if Options.AlreadyCleaned: + tfoname=names[i] + else: + idname = cols[i].strip().split(' id')[-1] # separer string par ' id' + name3 = cols[i].strip().split(' id')[0].split(' ')[1] + Bus1 = int(name3.split('-')[0]) + Bus2 = int(name3.split('-')[1]) + tfoname = BusDico[Bus1][2] + '_' + BusDico[Bus2][2] + '_' + str( + idname) + '__' + 'TR' + + # idname = cols[i].strip().split(' id')[-1] # separer string par ' id' + # Bus1 = names[i].split('-')[0].strip() + # Bus2 = names[i].split('-')[1].strip() + # # idname = 'TR' + cols[i].strip().split(' ')[-1][2:] + # # Bus1 = names[i].split(' - ')[0].strip() + # # Bus2 = names[i].split(' - ')[1].strip() + # tfoname = Bus1 + '_' + Bus2 + '_' + idname + '_' + 'Tr' + tfoname = tfoname.replace(" ", "_") + tfoname = tfoname.replace("-", "_") + tfoname = tfoname.replace(".", "_") + tfoname = tfoname.replace("/", "_") + tfoname = tfoname.replace("&", "and") + try: + int(tfoname[0]) + tfoname = "_" + tfoname + except: + pass + # tfoname = Bus1 + "__" + Bus2 + "__" + idname + # tfoname = tfoname.replace(" ","_") + # tfoname = tfoname.replace("-","_") + # tfoname = tfoname.replace(".","_") + # tfoname = tfoname.replace("&","and") + # try: + # int(tfoname[0]) + # tfoname="_" + tfoname + # except: + # pass + if (Options.TransfoByNom[0] and Options.TransfoBaseList[tfoname] not in Options.SelectedTransfoBase): + continue + elif Options.RecursiveDepth > 0 and tfoname not in Options.TrueLines: + continue + tmpAll.append(row[i]) + tmpTr.append(float(row[i])) + if it == 1: + Options.NamesStorage.append(tfoname) + Options.ColsStorage.append(cols[i]) + Options.TotalTransfoStorage[0].append(tfoname) + elif cols[i].find(':Tr3%Rate') != -1: + if Options.AlreadyCleaned: + tfoname=names[i] + [before, after] = names[i].split('__Wnd') + idname = after.split('__')[1] + tfoname_nownd = before + '__' + idname + else: + idname = cols[i].strip().split(' id')[-1].split(' wnd')[0] # separer string par ' id' + name3=cols[i].strip().split(' id')[0].split(' ')[1] + Bus1 = int(name3.split('-')[0]) + Bus2 = int(name3.split('-')[1]) + Bus3 = int(name3.split('-')[2]) + tfoname=BusDico[Bus1][2]+'_'+BusDico[Bus2][2]+'_'+BusDico[Bus3][2]+'_' + str(idname) + '__' + 'TR3' + + # tfoname=names[i]+str(idname)+ '_' + 'Tr3' + tfoname = tfoname.replace(" ", "_") + tfoname = tfoname.replace("-", "_") + tfoname = tfoname.replace(".", "_") + tfoname = tfoname.replace("/", "_") + tfoname = tfoname.replace("&", "and") + try: + int(tfoname[0]) + tfoname = "_" + tfoname + except: + pass + + if (Options.TransfoByNom[0] and Options.TransfoBaseList[tfoname] not in Options.SelectedTransfoBase): + continue +## elif Options.RecursiveDepth >0 and tfoname not in Options.TrueLines: #currently add all 3w transfos b/c Options.TrueLines doesnt have 3w tfos in it +## continue + tmpAll.append(row[i]) + tmpTr.append(float(row[i])) + if it == 1: + Options.NamesStorage.append(tfoname) + Options.ColsStorage.append(cols[i]) + Options.TotalTransfoStorage[0].append(tfoname) + elif cols[i].find(':%Rate') != -1: + if Options.AlreadyCleaned: + linename=names[i] + else: + idname = cols[i].strip().split(' id')[-1] # separer string par ' id' + name3 = cols[i].strip().split(' id')[0].split(' ')[1] + Bus1 = int(name3.split('-')[0]) + Bus2 = int(name3.split('-')[1]) + linename = BusDico[Bus1][2] + '_' + BusDico[Bus2][2] + '_' + str( idname) + '__' + 'LI' + + # idname = cols[i].strip().split(' id')[-1] # separer string par ' id' + # Bus1 = names[i].split('-')[0].strip() + # Bus2 = names[i].split('-')[1].strip() + if '@' in idname: + idname = idname.replace('@','BR') + elif '*' in idname: + idname = idname.replace('*','SW') + # else: + # try: + # idname = 'LI' + str(int(idname)) + # except: + # idname = 'LI' + idname + # linename = Bus1 + "_" + Bus2 + "_" + idname+'_Li' + linename = linename.replace(" ", "_") + linename = linename.replace("-", "_") + linename = linename.replace(".", "_") + linename = linename.replace("/", "_") + linename = linename.replace("&", "and") + + try: + int(linename[0]) + # linename="_" + linename + linename = "L_" + linename + except: + pass + + if (Options.LinesByNom[0] and Options.LinesBaseList[linename] not in Options.SelectedLinesBase): + continue + elif Options.RecursiveDepth > 0 and linename not in Options.TrueLines: + continue + tmpAll.append(row[i]) + tmpLine.append(float(row[i])) + if it == 1: + Options.NamesStorage.append(linename) + Options.ColsStorage.append(cols[i]) + Options.TotalLinesStorage[0].append(linename) + else: + tmpAll.append(row[i]) + if it == 1: + Options.NamesStorage.append(names[i]) + Options.ColsStorage.append(cols[i]) +# except Exception as e: +# print (e) + + def customAppend(fromCont, toCont, meanCont, row): + tmp = [] + if len(fromCont) > 0: + meanCont.append(sum(fromCont) / len(fromCont)) + tmp.append(sum(fromCont) / len(fromCont)) + tmp.append(min(fromCont)) + tmp.append(max(fromCont)) + tmp.append(int(row[0])) + else: + try: + int(row[0]) + except: + return + else: + meanCont.append(0) + tmp.append(0) + tmp.append(0) + tmp.append(0) + tmp.append(int(row[0])) + if tmp != []: + toCont.append(tmp) + customAppend(tmpBus, BusStorage, BusMean, row) + customAppend(tmpTr, TransfoStorage, TransfoMean, row) + customAppend(tmpLine, LinesStorage, LinesMean, row) + Options.TotalStorage.append(tmpAll) + Options.TotalBusStorage.append(tmpBus) + Options.TotalTransfoStorage.append(tmpTr) + Options.TotalLinesStorage.append(tmpLine) + try: + Options.CaseIDStorage.append(int(row[0])) + except: + pass + Options.BusStorage = BusStorage + Options.TransfoStorage = TransfoStorage + Options.LinesStorage = LinesStorage + #pdb.set_trace() + + #delete point version of csvfile + if Options.DecimalSeparator[0]==",": + csvfile.close() + os.remove(path) + csvfilesave = path[0:-4] + "_comma" + ".csv" + shutil.copy2(csvfilesave, path) + os.remove(csvfilesave) + + return BusMean, TransfoMean, LinesMean + +def getHighestValue(storage, numberToGet): + tmp = [] + table = [] + for i in range(len(storage)): + if len(table) < numberToGet: + table.append(Options.CaseIDStorage[i]) + tmp.append(storage[i]) + elif storage[i] > min(tmp): + try: + table.remove(Options.CaseIDStorage[storage.index(min(tmp))]) + except: + pass + table.append(Options.CaseIDStorage[i]) + try: + tmp.remove(min(tmp)) + except: + pass + tmp.append(storage[i]) + return table + +def getLowestValue(storage, numberToGet): + tmp = [] + table = [] + for i in range(len(storage)): + if len(table) < numberToGet: + table.append(Options.CaseIDStorage[i]) + tmp.append(storage[i]) + elif storage[i] < max(tmp): + try: + table.remove(Options.CaseIDStorage[storage.index(max(tmp))]) + except: + pass + table.append(Options.CaseIDStorage[i]) + try: + tmp.remove(max(tmp)) + except: + pass + tmp.append(storage[i]) + return table diff --git a/ProcessOutputs_Eficas/com_base.py b/ProcessOutputs_Eficas/com_base.py new file mode 100644 index 00000000..4e1e4b97 --- /dev/null +++ b/ProcessOutputs_Eficas/com_base.py @@ -0,0 +1,586 @@ +#!/usr/bin/python3 +######################################################################################################################## +# ojectif de ce module: extraire des donnes pour afficher dans l'interface Eficas. Subprocess dans la fonction PFExtractGeneratorLoadLineandTransfoDico +######################################################################################################################## +NoBreakersandSwitches = True + +def PFExtractData(NetworkFile, PF_PATH): + #PSEN sous PowerFactory, extraire des donnees de Gen, Load, Bus, Branch, Transfos,Motor + import os + import sys + import numpy as np + + (filepath, filename) = os.path.split(NetworkFile) + sys.path.append(PF_PATH) + os.environ['PATH'] += ';' + os.path.dirname(os.path.dirname(PF_PATH)) + ';' + + # import powerfactory + import powerfactory as pf + app = pf.GetApplication() + # app.Show() + user = app.GetCurrentUser() + ComImp = user.CreateObject('ComPFDIMPORT')# objet pour importer pfd file + + app.SetWriteCacheEnabled(1) # Disable consistency check + ComImp.g_file = NetworkFile + ComImp.g_target = user # project is imported under the user account + err = ComImp.Execute() # Execute command starts the import process + ComImp.Delete() + app.SetWriteCacheEnabled(0) # Enable consistency check + prjs = user.GetContents('*.IntPrj') + prjs.sort(key=lambda x: x.gnrl_modif, reverse=True) + prj = prjs[0] + prj.Activate() + studycase = app.GetActiveStudyCase() + grids = studycase.GetChildren(1, '*.ElmNet', 1)[0].contents + tous = [] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmTerm', 1)) + bus = [] + for noeud in tous: + # if ((noeud.iUsage == 0) and (noeud.outserv == 0)): # eliminer tous les noeuds out-service + # if ((noeud.iUsage == 0)or(noeud.iUsage == 1)) : + bus.append(noeud) + noeuds = sorted(bus, key=lambda x: x.cStatName) + buses = [] + for ii in range(len(noeuds)): + busname = noeuds[ii].cStatName.replace('/','_').replace(')','_').replace('(','_').replace(" ","_").replace("-","_").replace(".","_").replace("&","and").replace("%","pct").replace("=","eq").replace("#","_").replace("$","_") + aa = [ii, round(noeuds[ii].uknom,2), busname, noeuds[ii].GetBusType()] + # [numero,nominal KV,busname,bustype] + buses.append(aa) + # ==============================================================# + # Loads data (busnumber, active, reactive, status, name, id) + tous = [] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmLod', 1)) + tous = sorted(tous, key=lambda x: x.bus1.cBusBar.cStatName) + LoadDico = {} + for bus in buses: + idload = 0 + for load in tous: + busname = load.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_').replace(" ","_").replace("-","_").replace(".","_").replace("&","and").replace("%","pct").replace("=","eq").replace("#","_").replace("$","_") + if busname == bus[2]: + idload += 1 # cree id pour load + busnumber = bus[0] + loadname = busname + loadname = loadname.replace(" ", "_") + loadname = loadname.replace("-", "_") + loadname = loadname.replace(".", "_") + loadname = loadname.replace("/", "_") + loadname = loadname.replace("&", "and") + loadname = loadname.replace("%","pct") + loadname = loadname.replace("=","eq") + loadname = loadname.replace("#","_") + loadname = loadname.replace("$","_") + loadname = loadname.replace("\\","_") + loadname = loadname.replace("(","_") + loadname = loadname.replace(")","_") + try: + int(loadname[0]) + loadname = "C_" + loadname + except: + pass + loadname=loadname+'_Lo'+str(idload) + p = load.plini + q = load.qlini + LoadDico[loadname] = {} + LoadDico[loadname]['NAME'] = load.loc_name.strip() + LoadDico[loadname]['ID'] = idload + LoadDico[loadname]['EXNAME'] = busname + '_' + str(bus[1])+'KV' + LoadDico[loadname]['NUMBER'] = busnumber + LoadDico[loadname]['P'] = p + LoadDico[loadname]['Q'] = q + # ==============================================================#Generator + MachineDico = {} # [Bus name, machine ID, extended bus name, bus number] + tous = [] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmSym', 1)) + + for plant in tous: + if plant.i_mot == 0: + busname = plant.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_').replace(" ","_").replace("-","_").replace(".","_").replace("&","and").replace("%","pct").replace("=","eq").replace("#","_").replace("$","_") + for ii in range(len(buses)): + if busname in buses[ii]: + busnumber = ii + break + idplant = plant.loc_name#plant.ngnum + p = plant.pgini + q = plant.qgini + pmax = plant.Pmax_uc + pmin = plant.Pmin_uc + qmax = plant.cQ_max + qmin = plant.cQ_min + machinename = busname + '_' + 'syn_' + 'Gr_' + str(idplant) # generator synchrone + machinename = machinename.replace(" ", "_") + # machinename = machinename.replace("Generator", "gen") + machinename = machinename.replace("-", "_") + machinename = machinename.replace(".", "_") + machinename = machinename.replace("/", "_") + machinename = machinename.replace("&", "and") + machinename = machinename.replace("%","pct") + machinename = machinename.replace("=","eq") + machinename = machinename.replace("#","_") + machinename = machinename.replace("$","_") + machinename = machinename.replace("\\","_") + machinename = machinename.replace("(","_") + machinename = machinename.replace(")","_") + # machinename = machinename + '_' +'syn_' + 'Gr_' + str(idplant) # generator synchrone + try: + int(machinename[0]) + machinename = "G_" + machinename + except: + pass + + MachineDico[machinename] = {} + MachineDico[machinename]['NAME'] = plant.loc_name + MachineDico[machinename]['ID'] = idplant + MachineDico[machinename]['EXNAME'] = busname + '_' + str(bus[1])+'KV' + MachineDico[machinename]['NUMBER'] = busnumber + MachineDico[machinename]['P'] = p + MachineDico[machinename]['Q'] = q + MachineDico[machinename]['PMAX'] = pmax + MachineDico[machinename]['QMAX'] = qmax + MachineDico[machinename]['PMIN'] = pmin + MachineDico[machinename]['QMIN'] = qmin + tous = [] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmAsm', 1)) + + for plant in tous: + if plant.i_mot == 0: + busname = plant.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_').replace(" ","_").replace("-","_").replace(".","_").replace("&","and").replace("%","pct").replace("=","eq").replace("#","_").replace("$","_") + for ii in range(len(buses)): + if busname in buses[ii]: + busnumber = ii + break + idplant = plant.loc_name + p = plant.pgini + q = plant.qgini + pmax = plant.Pmax_uc + pmin = plant.Pmin_uc + qmax = plant.cQ_max + qmin = plant.cQ_min + machinename = busname + '_' + 'asyn_' + 'Gr_' + str(idplant) # generator asynchrone + machinename = machinename.replace(" ", "_") + machinename = machinename.replace("-", "_") + machinename = machinename.replace(".", "_") + machinename = machinename.replace("/", "_") + machinename = machinename.replace("&", "and") + machinename = machinename.replace("%","pct") + machinename = machinename.replace("=","eq") + machinename = machinename.replace("#","_") + machinename = machinename.replace("$","_") + machinename = machinename.replace("\\","_") + machinename = machinename.replace("(","_") + machinename = machinename.replace(")","_") + # machinename = machinename + '_' +'asyn_' + 'Gr_' + str(idplant) # generator asynchrone + try: + int(machinename[0]) + machinename = "G_" + machinename + except: + pass + + MachineDico[machinename] = {} + MachineDico[machinename]['NAME'] = plant.loc_name + MachineDico[machinename]['ID'] = idplant + MachineDico[machinename]['EXNAME'] = busname + '_' + str(bus[1])+'KV' + MachineDico[machinename]['NUMBER'] = busnumber + MachineDico[machinename]['P'] = p + MachineDico[machinename]['Q'] = q + MachineDico[machinename]['PMAX'] = pmax + MachineDico[machinename]['QMAX'] = qmax + MachineDico[machinename]['PMIN'] = pmin + MachineDico[machinename]['QMIN'] = qmin + tous = [] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmGenstat', 1)) + for plant in tous: + busname = plant.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_').replace(" ","_").replace("-","_").replace(".","_").replace("&","and").replace("%","pct").replace("=","eq").replace("#","_").replace("$","_") + for ii in range(len(buses)): + if busname in buses[ii]: + busnumber = ii + break + idplant = plant.loc_name + p = plant.pgini + q = plant.qgini + pmax = plant.Pmax_uc + pmin = plant.Pmin_uc + qmax = plant.cQ_max + qmin = plant.cQ_min + machinename = busname + '_' + 'genstat_' + 'Gr_' + str(idplant) # generator static + machinename = machinename.replace(" ", "_") + machinename = machinename.replace("-", "_") + machinename = machinename.replace(".", "_") + machinename = machinename.replace("/", "_") + machinename = machinename.replace("&", "and") + machinename = machinename.replace("%","pct") + machinename = machinename.replace("=","eq") + machinename = machinename.replace("#","_") + machinename = machinename.replace("$","_") + machinename = machinename.replace("\\","_") + machinename = machinename.replace("(","_") + machinename = machinename.replace(")","_") + + try: + int(machinename[0]) + machinename = "G_" + machinename + except: + pass + + MachineDico[machinename] = {} + MachineDico[machinename]['NAME'] = plant.loc_name + MachineDico[machinename]['ID'] = idplant + MachineDico[machinename]['EXNAME'] = busname + '_' + str(bus[1]) + 'KV' + MachineDico[machinename]['NUMBER'] = busnumber + MachineDico[machinename]['P'] = p + MachineDico[machinename]['Q'] = q + MachineDico[machinename]['PMAX'] = pmax + MachineDico[machinename]['QMAX'] = qmax + MachineDico[machinename]['PMIN'] = pmin + MachineDico[machinename]['QMIN'] = qmin + + tous = [] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmPvsys', 1)) + for plant in tous: + busname = plant.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_').replace(" ","_").replace("-","_").replace(".","_").replace("&","and").replace("%","pct").replace("=","eq").replace("#","_").replace("$","_") + for ii in range(len(buses)): + if busname in buses[ii]: + busnumber = ii + break + idplant = plant.loc_name#plant.ngnum + p = plant.pgini + q = plant.qgini + pmax = plant.Pmax_uc + pmin = plant.Pmin_uc + qmax = plant.cQ_max + qmin = plant.cQ_min + machinename = busname + '_' + 'pv_' + 'Gr_' + str(idplant) # generator PV + machinename = machinename.replace(" ", "_") + machinename = machinename.replace("-", "_") + machinename = machinename.replace(".", "_") + machinename = machinename.replace("/", "_") + machinename = machinename.replace("&", "and") + machinename = machinename.replace("%","pct") + machinename = machinename.replace("=","eq") + machinename = machinename.replace("#","_") + machinename = machinename.replace("$","_") + machinename = machinename.replace("\\","_") + machinename = machinename.replace("(","_") + machinename = machinename.replace(")","_") + + try: + int(machinename[0]) + machinename = "G_" + machinename + except: + pass + + MachineDico[machinename] = {} + MachineDico[machinename]['NAME'] = plant.loc_name + MachineDico[machinename]['ID'] = idplant + MachineDico[machinename]['EXNAME'] = busname + '_' + str(bus[1]) + 'KV' + MachineDico[machinename]['NUMBER'] = busnumber + MachineDico[machinename]['P'] = p + MachineDico[machinename]['Q'] = q + MachineDico[machinename]['PMAX'] = pmax + MachineDico[machinename]['QMAX'] = qmax + MachineDico[machinename]['PMIN'] = pmin + MachineDico[machinename]['QMIN'] = qmin + # ==============================================================#Motor + + MotorDico = {} # [Bus name, machine ID, extended bus name, bus number] + tous = [] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmSym', 1)) + + for plant in tous: + if plant.i_mot == 1: + busname = plant.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_').replace(" ","_").replace("-","_").replace(".","_").replace("&","and").replace("%","pct").replace("=","eq").replace("#","_").replace("$","_") + for ii in range(len(buses)): + if busname in buses[ii]: + busnumber = ii + break + idplant = plant.loc_name#plant.ngnum + p = plant.pgini + q = plant.qgini + pmax = plant.Pmax_uc + pmin = plant.Pmin_uc + qmax = plant.cQ_max + qmin = plant.cQ_min + machinename = busname + '_' + 'syn_' + 'Mo_' + str(idplant) # Motor synchrone + machinename = machinename.replace(" ", "_") + machinename = machinename.replace("-", "_") + machinename = machinename.replace(".", "_") + machinename = machinename.replace("/", "_") + machinename = machinename.replace("&", "and") + machinename = machinename.replace("%","pct") + machinename = machinename.replace("=","eq") + machinename = machinename.replace("#","_") + machinename = machinename.replace("$","_") + machinename = machinename.replace("\\","_") + machinename = machinename.replace("(","_") + machinename = machinename.replace(")","_") + + try: + int(machinename[0]) + machinename = "M_" + machinename + except: + pass + MotorDico[machinename] = {} + MotorDico[machinename]['NAME'] = plant.loc_name + MotorDico[machinename]['ID'] = idplant + MotorDico[machinename]['EXNAME'] = busname + '_' + str(bus[1])+'KV' + MotorDico[machinename]['NUMBER'] = busnumber + MotorDico[machinename]['P'] = p + MotorDico[machinename]['Q'] = q + MotorDico[machinename]['PMAX'] = pmax + MotorDico[machinename]['QMAX'] = qmax + MotorDico[machinename]['PMIN'] = pmin + MotorDico[machinename]['QMIN'] = qmin + tous = [] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmAsm', 1)) + + for plant in tous: + if plant.i_mot == 1: + busname = plant.bus1.cBusBar.cStatName + busname = busname.replace('/','_').replace(')','_').replace('(','_').replace(" ","_").replace("-","_").replace(".","_").replace("&","and").replace("%","pct").replace("=","eq").replace("#","_").replace("$","_") + for ii in range(len(buses)): + if busname in buses[ii]: + busnumber = ii + break + idplant = plant.loc_name#plant.ngnum + p = plant.pgini + q = plant.qgini + # pmax = plant.Pmax_uc + pmax = plant.P_max + pmin = plant.Pmin_uc + qmax = plant.cQ_max + qmin = plant.cQ_min + machinename = busname + '_' + 'asyn_' + 'Mo_' + str(idplant) # moteur asynchrone + machinename = machinename.replace(" ", "_") + machinename = machinename.replace("-", "_") + machinename = machinename.replace(".", "_") + machinename = machinename.replace("/", "_") + machinename = machinename.replace("&", "and") + machinename = machinename.replace("%","pct") + machinename = machinename.replace("=","eq") + machinename = machinename.replace("#","_") + machinename = machinename.replace("$","_") + machinename = machinename.replace("\\","_") + machinename = machinename.replace("(","_") + machinename = machinename.replace(")","_") + + try: + int(machinename[0]) + machinename = "M_" + machinename + except: + pass + MotorDico[machinename] = {} + MotorDico[machinename]['NAME'] = plant.loc_name + MotorDico[machinename]['ID'] = idplant + MotorDico[machinename]['EXNAME'] = busname + '_' + str(bus[1]) + 'KV' + MotorDico[machinename]['NUMBER'] = busnumber + MotorDico[machinename]['P'] = p + MotorDico[machinename]['Q'] = q + MotorDico[machinename]['PMAX'] = pmax + MotorDico[machinename]['QMAX'] = qmax + MotorDico[machinename]['PMIN'] = pmin + MotorDico[machinename]['QMIN'] = qmin + # ==============================================================# + LineDico = {} # [linename, Bus name 1, Bus name 2, ID, extended bus name 1, extended bus name 2, bus number 1, bus number 2] + tous = [] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmLne', 1)) + for line in tous: + linename = line.loc_name + frombus_name = line.bus1.cBusBar.cStatName + tobus_name = line.bus2.cBusBar.cStatName + frombus_name = frombus_name.replace('/','_').replace(')','_').replace('(','_').replace(" ","_").replace("-","_").replace(".","_").replace("&","and").replace("%","pct").replace("=","eq").replace("#","_").replace("$","_") + tobus_name = tobus_name.replace('/','_').replace(')','_').replace('(','_').replace(" ","_").replace("-","_").replace(".","_").replace("&","and").replace("%","pct").replace("=","eq").replace("#","_").replace("$","_") + for ii in range(len(buses)): + if frombus_name in buses[ii]: + frombus_number = ii + frombus_KV=buses[ii][1] + break + for ii in range(len(buses)): + if tobus_name in buses[ii]: + tobus_number = ii + tobus_KV=buses[ii][1] + break + idline = line.loc_name#line.nlnum + linename=frombus_name+'_'+tobus_name+'_'+idline+'__LI' + linename = linename.replace(" ", "_") + linename = linename.replace("-", "_") + linename = linename.replace(".", "_") + linename = linename.replace("/", "_") + linename = linename.replace("&", "and") + linename = linename.replace("%","pct") + linename = linename.replace("=","eq") + linename = linename.replace("#","_") + linename = linename.replace("$","_") + linename = linename.replace("\\","_") + linename = linename.replace("(","_") + linename = linename.replace(")","_") + try: + int(linename[0]) + linename = "L_" + linename + except: + pass + if NoBreakersandSwitches: + LineDico[linename] = {} + LineDico[linename]['FROMNAME'] = frombus_name + LineDico[linename]['TONAME'] = tobus_name + LineDico[linename]['ID'] = idline + LineDico[linename]['FROMEXNAME'] = frombus_name+'_'+str(frombus_KV) + LineDico[linename]['TOEXNAME'] = tobus_name+'_'+str(tobus_KV) + LineDico[linename]['FROMNUMBER'] = frombus_number # il n'y a pas de bus number dans PowerFactory + LineDico[linename]['TONUMBER'] = tobus_number + + + # print ("Read lines") + # Extract Transfos + TfoDico = {} # [tranlinename, Bus name 1, Bus name 2, machine ID, extended bus name 1, extended bus name 2, bus number 1, bus number 2] + tous = [] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmTr2', 1)) + + for tfo in tous: + # tfosname = tfo.loc_name + id_tfo=tfo.loc_name#tfo.ntnum + frombus_name=tfo.bushv.cBusBar.cStatName + tobus_name=tfo.buslv.cBusBar.cStatName + frombus_name = frombus_name.replace('/','_').replace(')','_').replace('(','_').replace(" ","_").replace("-","_").replace(".","_").replace("&","and").replace("%","pct").replace("=","eq").replace("#","_").replace("$","_") + tobus_name = tobus_name.replace('/','_').replace(')','_').replace('(','_').replace(" ","_").replace("-","_").replace(".","_").replace("&","and").replace("%","pct").replace("=","eq").replace("#","_").replace("$","_") + for ii in range(len(buses)): + if frombus_name in buses[ii]: + frombus_number = ii + frombus_KV=buses[ii][1] + break + for ii in range(len(buses)): + if tobus_name in buses[ii]: + tobus_number = ii + tobus_KV=buses[ii][1] + break + + tfoname = frombus_name+'_' +tobus_name+'_' + str(id_tfo)+'__'+'TR' + tfoname = tfoname.replace(" ", "_") + tfoname = tfoname.replace("-", "_") + tfoname = tfoname.replace(".", "_") + tfoname = tfoname.replace("/", "_") + tfoname = tfoname.replace("&", "and") + tfoname = tfoname.replace("%","pct") + tfoname = tfoname.replace("=","eq") + tfoname = tfoname.replace("#","_") + tfoname = tfoname.replace("$","_") + tfoname = tfoname.replace("\\","_") + tfoname = tfoname.replace("(","_") + tfoname = tfoname.replace(")","_") + try: + int(tfoname[0]) + tfoname = "_" + tfoname + except: + pass + if NoBreakersandSwitches: + TfoDico[tfoname] = {} + TfoDico[tfoname]['FROMNAME'] = frombus_name + TfoDico[tfoname]['TONAME'] = tobus_name + TfoDico[tfoname]['ID'] = id_tfo + TfoDico[tfoname]['FROMEXNAME'] = frombus_name+'_'+str(frombus_KV) + TfoDico[tfoname]['TOEXNAME'] = tobus_name+'_'+str(tobus_KV) + TfoDico[tfoname]['FROMNUMBER'] = frombus_number # il n'y a pas de bus number dans PowerFactory + TfoDico[tfoname]['TONUMBER'] = tobus_number + TfoDico[tfoname]['#WIND'] = 2 + + # Extract 3 winding Transfos + tous = [] + for grid in grids: + tous.extend(grid.obj_id.GetContents( '*.ElmTr3', 1)) + for tfo in tous: + # tfosname = tfo.loc_name + id_tfo = tfo.loc_name#tfo.nt3nm + frombus_name = tfo.bushv.cBusBar.cStatName + tobus_name = tfo.busmv.cBusBar.cStatName + bus3 = tfo.buslv.cBusBar.cStatName + frombus_name = frombus_name.replace('/','_').replace(')','_').replace('(','_').replace(" ","_").replace("-","_").replace(".","_").replace("&","and").replace("%","pct").replace("=","eq").replace("#","_").replace("$","_") + tobus_name = tobus_name.replace('/','_').replace(')','_').replace('(','_').replace(" ","_").replace("-","_").replace(".","_").replace("&","and").replace("%","pct").replace("=","eq").replace("#","_").replace("$","_") + bus3 = bus3.replace('/','_').replace(')','_').replace('(','_').replace(" ","_").replace("-","_").replace(".","_").replace("&","and").replace("%","pct").replace("=","eq").replace("#","_").replace("$","_") + for ii in range(len(buses)): + if frombus_name in buses[ii]: + frombus_number = ii + frombus_KV=buses[ii][1] + break + for ii in range(len(buses)): + if tobus_name in buses[ii]: + tobus_number = ii + tobus_KV=buses[ii][1] + break + for ii in range(len(buses)): + if bus3 in buses[ii]: + bus3_number = ii + bus3_KV=buses[ii][1] + break + tfoname = frombus_name+ '_' + tobus_name + '_' +bus3+'_' + str(id_tfo)+'__'+ 'TR3' + tfoname = tfoname.replace(" ", "_") + tfoname = tfoname.replace("-", "_") + tfoname = tfoname.replace(".", "_") + tfoname = tfoname.replace("/", "_") + tfoname = tfoname.replace("&", "and") + tfoname = tfoname.replace("%","pct") + tfoname = tfoname.replace("=","eq") + tfoname = tfoname.replace("#","_") + tfoname = tfoname.replace("$","_") + tfoname = tfoname.replace("\\","_") + tfoname = tfoname.replace("(","_") + tfoname = tfoname.replace(")","_") + try: + int(tfoname[0]) + tfoname = "_" + tfoname + except: + pass + if NoBreakersandSwitches: + TfoDico[tfoname] = {} + TfoDico[tfoname]['FROMNAME'] = frombus_name + TfoDico[tfoname]['TONAME'] = tobus_name + TfoDico[tfoname]['3NAME']= bus3 + TfoDico[tfoname]['ID'] = id_tfo + TfoDico[tfoname]['FROMEXNAME'] = frombus_name+'_'+str(frombus_KV) + TfoDico[tfoname]['TOEXNAME'] = tobus_name+'_'+str(tobus_KV) + TfoDico[tfoname]['3EXNAME']=bus3+'_'+str(bus3_KV) + TfoDico[tfoname]['FROMNUMBER'] = frombus_number # il n'y a pas de bus number dans PowerFactory + TfoDico[tfoname]['TONUMBER'] = tobus_number + TfoDico[tfoname]['3NUMBER'] = bus3_number + TfoDico[tfoname]['#WIND'] = 3 + + print ("Read data OK") + prj.Delete() + return MachineDico, LoadDico, LineDico, TfoDico, MotorDico,buses +filer=open('temp.txt','r') +_path=[] +for line in filer: + _path.append(line) +filer.close() +pfd_file=_path[0].replace('\n','') +PF_path=_path[1].replace('\n','') + +MachineDico, LoadDico, LineDico, TransfoDico, MotorDico,BusDico = PFExtractData(pfd_file,PF_path) +Data={} +Data['MachineDico']=MachineDico +Data['LoadDico']=LoadDico +Data['LineDico']=LineDico +Data['TransfoDico']=TransfoDico +Data['MotorDico']=MotorDico +Data['BusDico']=BusDico +# Data=[MachineDico, LoadDico, LineDico, TransfoDico, MotorDico] +import pickle +# print('=========='+str(pickle.HIGHEST_PROTOCOL)+'=========') +with open('Data_for_interface', 'wb') as fichier: + mon_pickler = pickle.Pickler(fichier,protocol=2) + mon_pickler.dump(Data) + diff --git a/ProcessOutputs_Eficas/dico_print.py b/ProcessOutputs_Eficas/dico_print.py deleted file mode 100644 index 12c51b66..00000000 --- a/ProcessOutputs_Eficas/dico_print.py +++ /dev/null @@ -1,30 +0,0 @@ -import sys -import os - -path1 = os.path.abspath(os.path.join(os.path.abspath(__file__),'..','TreatOutputs')) -sys.path.append(path1) -from Run import run - -# dico1 = {'CONTINGENCY_SELECTION': {'N1TransformersList': ['30.0 - 90.0', '90.0 - 30.0'], 'TripLines': True, 'csv_file': 'D:/PSEN_AVRIL_2018/Small Grid PSSE/Results2/QuatreCas.csv', 'N1LinesList': ['90.0'], 'N1BusesList': ['90.0'], 'SelectionMethod': 'CaseSelectionFromFile', 'case_name': 'QuatreCas', 'TripBuses': False, 'N1AreaList': [], 'TripTransfos': True, 'TripGenerators': True}, 'CASE_SELECTION': {'TransformersList': ['30.0 - 90.0', '90.0 - 30.0'], 'PSEN_results_csvfile': 'D:/PSEN_AVRIL_2018/Small Grid PSSE/Results2/N_20180411_07h44m15/simulationDClog_complete_07h44m15.csv', 'DecimalSeparator': '.', 'NewCsvFile': 'CleanedData.csv', 'PSSPY_path':'C:\\Program Files (x86)\\PTI\\PSSE34\\PSSPY27', 'BusesList': ['90.0'], 'PSEN_results_csvfile_cleaned': False, 'MaxDepth': 5, 'LinesList': ['90.0'], 'PSSE_path': 'C:\\Program Files (x86)\\PTI\\PSSE34\\PSSBIN', 'PSEN_results_folder': 'D:/PSEN_AVRIL_2018/Small Grid PSSE/Results2/N_20180411_07h44m15', 'OutputNewCsv': False, 'AreaList': ['1']}, 'CONTINGENCY_OPTIONS': {'SolutionMethod': '1 -FNSL', 'AdjustSwitchedShunts': '0 - Disable', 'Vmin': 0.95, 'FlowLimitTransformers': 100, 'Tolerance': 0.5, 'VarLimits': 99, 'FlowLimitLines': 100, 'FlatStart': False, 'AdjustDCtaps': '0 - Disable', 'output_file_format': 'csv', 'AdjustTaps': '1 - Stepping', 'Vmax': 1.05, 'ContingencyRate': 'a', 'DispatchMode': '1 - Reserve'}, 'N_PROCESSING_OPTIONS': {'Output_bus_values': False, 'Output_transformer_values': False, 'Output_lines_values': False}} -Dico ={'CONTINGENCY_SELECTION': {'N1TransformersList': ['30.0 - 90.0', '90.0 - 30.0'], 'TripLines': True, 'csv_file': 'D:/PSEN_AVRIL_2018/Small Grid PSSE/Results2/QuatreCas.csv', 'N1LinesList': ['30.0', '90.0'], 'N1BusesList': ['11.0', '30.0', '90.0'], 'SelectionMethod': 'CaseSelectionFromFile', 'case_name': 'TEST_QUATRE_CAS', 'TripBuses': False, 'N1AreaList': ['1'], 'TripTransfos': True, 'TripGenerators': True}, 'CASE_SELECTION': {'TransformersList': ['11.0 - 30.0', '11.0 - 90.0', '30.0 - 90.0', '90.0 - 30.0'], 'PSEN_results_csvfile': 'D:/PSEN_AVRIL_2018/Small Grid PSSE/Results2/N_20180411_08h39m58/simulationDClog_complete_08h39m58.csv', 'DecimalSeparator': '.', 'NewCsvFile': 'CleanedData.csv', 'PSSPY_path': 'C:\\Program Files (x86)\\PTI\\PSSE34\\PSSPY27', 'BusesList': ['11.0', '30.0', '90.0'], 'PSEN_results_csvfile_cleaned': False, 'MaxDepth': 5, 'LinesList': ['30.0', '90.0'], 'PSSE_path': 'C:\\Program Files (x86)\\PTI\\PSSE34\\PSSBIN', 'PSEN_results_folder': 'D:/PSEN_AVRIL_2018/Small Grid PSSE/Results2/N_20180411_08h39m58', 'OutputNewCsv': False, 'AreaList': ['1']}, 'CONTINGENCY_OPTIONS': {'SolutionMethod': '1 - FNSL', 'AdjustSwitchedShunts': '0 - Disable', 'Vmin': 0.99, 'FlowLimitTransformers': 100, 'Tolerance': 0.5, 'VarLimits': 99, 'FlowLimitLines': 100, 'FlatStart': False, 'AdjustDCtaps': '0 - Disable', 'output_file_format': 'csv', 'AdjustTaps': '1 - Stepping', 'Vmax': 1.01, 'ContingencyRate': 'a', 'DispatchMode': '1 - Reserve'}, 'N_PROCESSING_OPTIONS': {'Output_bus_values': False, 'Output_transformer_values': False, 'Output_lines_values': False}} -# try: - # run(Dico) -# except: - # pass - -# dico2 = {'CONTINGENCY_SELECTION': {'N1TransformersList': ['30.0 - 90.0', '90.0 - 30.0'], 'TripLines': True, 'csv_file': 'D:/PSEN_AVRIL_2018/Small Grid PSSE/Results2/QuatreCas.csv', 'N1LinesList': ['90.0'], 'N1BusesList': ['90.0'], 'SelectionMethod': 'CaseSelectionFromFile', 'case_name': 'TESTQuatreCas', 'TripBuses': False, 'N1AreaList': [], 'TripTransfos': True, 'TripGenerators': True}, 'CASE_SELECTION': {'TransformersList': ['30.0 - 90.0', '90.0 - 30.0'], 'PSEN_results_csvfile': 'D:/PSEN_AVRIL_2018/Small Grid PSSE/Results2/N_20180411_07h44m15/simulationDClog_complete_07h44m15.csv', 'DecimalSeparator': '.', 'NewCsvFile': 'CleanedData.csv', 'PSSPY_path':'C:\\Program Files (x86)\\PTI\\PSSE34\\PSSPY27', 'BusesList': ['90.0'], 'PSEN_results_csvfile_cleaned': False, 'MaxDepth': 5, 'LinesList': ['90.0'], 'PSSE_path': 'C:\\Program Files (x86)\\PTI\\PSSE34\\PSSBIN', 'PSEN_results_folder': 'D:/PSEN_AVRIL_2018/Small Grid PSSE/Results2/N_20180411_07h44m15', 'OutputNewCsv': False, 'AreaList': ['1', '2', '3']}, 'CONTINGENCY_OPTIONS': {'SolutionMethod': '1 - FNSL', 'AdjustSwitchedShunts': '0 - Disable', 'Vmin': 0.95, 'FlowLimitTransformers': 100, 'Tolerance': 0.5, 'VarLimits': 99, 'FlowLimitLines': 100, 'FlatStart': False, 'AdjustDCtaps': '0 - Disable', 'output_file_format': 'csv', 'AdjustTaps': '1 - Stepping', 'Vmax': 1.05, 'ContingencyRate': 'a', 'DispatchMode': '1 - Reserve'}, 'N_PROCESSING_OPTIONS': {'Output_bus_values': False, 'Output_transformer_values': False, 'Output_lines_values': False}} -# run(dico2) - -import cProfile, pstats, StringIO -pr = cProfile.Profile() -pr.enable() -run(Dico) -pr.disable() -s = StringIO.StringIO() -sortby = 'cumulative' -ps = pstats.Stats(pr, stream=s).sort_stats(sortby) -ps.print_stats() -print(dir(s)) -print(s) -print(ps.print_stats()) -# print(s.getValue()) \ No newline at end of file diff --git a/ProcessOutputs_Eficas/opsPSEN_N1_PF.py b/ProcessOutputs_Eficas/opsPSEN_N1_PF.py new file mode 100644 index 00000000..bcb43f3c --- /dev/null +++ b/ProcessOutputs_Eficas/opsPSEN_N1_PF.py @@ -0,0 +1,272 @@ + +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2013 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +from PFExtractGeneratorLoadLineandTransfoDico import * +#from ExtractGeneratorLoadLineandTransfoDico import ExtractGeneratorLoadLineandTransfoDico2 +path1 = os.path.abspath(os.path.join(os.path.abspath(__file__), '../','TreatOutputs')) +sys.path.append(path1) + +import Options + +def INCLUDE(self,PF_path,Python3_path,**args): + """ + Fonction sd_prod pour la macro INCLUDE + """ + CaseFolder = args['PSEN_results_folder'] + Options.RecursiveDepth = args['MaxDepth'] + if CaseFolder==None: + return + reevalue=0 + if hasattr(self,'fichier_ini'): + reevalue=1 + if self.fichier_ini == CaseFolder : return + if hasattr(self,'old_context_fichier_init' ): + for concept in self.old_context_fichier_init.values(): + self.jdc.delete_concept(concept) + self.jdc_aux=None + self.contexte_fichier_init={} + self.reevalue_sd_jdc() + self.jdc.reset_context() + + self.fichier_ini=CaseFolder + self.contexte_fichier_init = {} + self.fichier_unite = 999 + self.fichier_err = None + self.fichier_text="" + + unite = 999 + + CaseFile = '' + FolderList = os.listdir(CaseFolder) + for folder in FolderList: + if folder[0:7] == 'package' or folder[0:4]== 'core': + # Get BaseCase.sav inside the first package folder we find + FolderContents = os.listdir(os.path.join(CaseFolder, folder)) + for file in FolderContents: + if file == 'BaseCase.pfd': + CaseFile = os.path.join(os.path.join(CaseFolder, folder), file) + break + break + + + try: + + MachineDico, LoadDico, LineDico, TransfoDico, MotorDico = PFExtractGeneratorLoadLineandTransfoDico( + 0, 0, CaseFile, PF_path, Python3_path) + + BusList, LinesList, TransfosList,BusDico = getNominalkV(CaseFile) + + getTrueLines(CaseFile) + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exec_info() + print(e) + print(exc_type, exc_tb.tb_lineno) + #print "" + #print MachineDico,LoadDico,LineDico,TransfoDico,MotorDico,BusDico,BranchesDico,BusNominal + + for e in self.jdc.etapes: + if e.nom == 'CASE_SELECTION' : + etape=e + break + self.jdc.appli.changeIntoMC(e, 'BusesList', BusList) + self.jdc.appli.changeIntoMC(e, 'LinesList', LinesList) + self.jdc.appli.changeIntoMC(e, 'TransformersList', TransfosList) + + # self.jdc.appli.changeIntoDefMC('CONTINGENCY_SELECTION', ('Automatic_N_2_Selection', 'BusesList'), BusList) + self.jdc.appli.changeIntoDefMC('CONTINGENCY_SELECTION', ('Automatic_N_2_Selection', 'LinesList'), LinesList) + self.jdc.appli.changeIntoDefMC('CONTINGENCY_SELECTION', ('Automatic_N_2_Selection', 'TransformersList'), TransfosList) + + + try: + a = updateConts() + self.jdc.appli.changeIntoDefMC('CONTINGENCY_SELECTION', ('MultipleContingencyList', 'ComponentList'), Options.ContFullList) + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exec_info() + print(e) + print(exc_type, exc_tb.tb_lineno) + + + #self.jdc.ajoutMC(e,'TransfosList',listeTuple) + + + +def INCLUDE_context(self,d): + """ + Fonction op_init pour macro INCLUDE + """ + for k,v in self.g_context.items(): + d[k]=v + + +def PROCESS_context(self,d): + pass + +def PROCESS(self,XLS_file,**args): + + self.sauve_args=args + if XLS_file == "" or XLS_file == None: return + #Storage.csvFileName = XLS_file + # c est la premiere fois + + if not (hasattr(self,'sheets')) : + from Processor import getXLSinfo, getCSVinfo + #from Processor_Storage import * + #print getSheets + #getSheets() + #ComponentList, ContingencyList = getComponentandContingencyList(Storage.sheets[0]) + #print ComponentList + #print ContingencyList + #Storage.selectedDoubleRow[Storage.sheets[0]]=['PV MATIMBA'] + #Storage.selectedDoubleCol[Storage.sheets[0]]=['MAZENOD_MHDAM_LI1_'] + #self.jdc.appli.changeIntoMC(self,'TabList',Storage.sheets) + #self.sheets=Storage.sheets + #self.OngletsValeurs=[] + if not (XLS_file == "" or XLS_file == None): + #XLSinfo = getXLSinfo(XLS_file) + if XLS_file.endswith('.xls') or XLS_file.endswith('.xlsx'): + XLSinfo = getXLSinfo(XLS_file) + elif XLS_file.endswith('.csv'): + XLSinfo = getCSVinfo(XLS_file) + self.sheets=XLSinfo + #self.sheets={'a':(('a','b','c'),('f','g','h'))} + #v pascale + self.jdc.editor.changeIntoMC(self,'TabList',self.sheets.keys(),('b_TabList',)) + + + + +## self.jdc.appli.changeIntoMC(self,'TabList',self.sheets.keys()) +## +## for k in self.sheets.keys(): +## nom='Component_List_For_'+k +## monInto=self.sheets[k][0] +## self.jdc.appli.ajoutDefinitionMC('CONTINGENCY_PROCESSING',nom,'TXM',min=0, max='**', into=monInto, homo= 'SansOrdreNiDoublon') +## nom='Contingency_List_For_'+k +## monInto=self.sheets[k][1] +## self.jdc.appli.ajoutDefinitionMC('CONTINGENCY_PROCESSING',nom,'TXM',min=0, max='**', into=monInto, homo= 'SansOrdreNiDoublon') + + self.MCAjoutes=[] + self.OngletsSelectionnes=[] + else : + # On a selectionne un onglet + # On teste si on a modifie la liste des onglets + + + nouveauxOngletsSelectionnes = self.get_child('b_TabList').get_child('TabList').valeur +# print (self.get_child('b_TabList')) +# print (self.get_child('b_TabList').get_child('TabList')) +# print (dir(self.get_child('b_TabList').get_child('TabList'))) +# print (self.get_child('b_TabList').get_child('TabList').valeur) + #print('nouveauxOngletsSelectionnes',nouveauxOngletsSelectionnes) + if nouveauxOngletsSelectionnes == self.OngletsSelectionnes: return + #print (6) + if nouveauxOngletsSelectionnes == () or nouveauxOngletsSelectionnes ==[]: + for MC in self.MCAjoutes : self.jdc.editor.deleteMC(self,MC,('b_TabList',)) + self.MCAjoutes==[] + self.OngletsSelectionnes=[] + self.jdc.editor.fenetreCentraleAffichee.reaffiche() + return + +# TabList= self.get_child('b_TabList').get_child('TabList').valeur +# nouveauxOngletsSelectionnes = [] +# for tab in TabList: +# nouveauxOngletsSelectionnes.append(tab.replace(' ','___')) +# +# if nouveauxOngletsSelectionnes==self.OngletsSelectionnes : return +# +# if nouveauxOngletsSelectionnes==() or nouveauxOngletsSelectionnes == [] : +# for MC in self.MCAjoutes : self.jdc.editor.deleteMC(self,MC,('b_TabList',)) +# self.MCAjoutes=[] +# self.OngletsSelectionnes=[] + + + + for Onglet in nouveauxOngletsSelectionnes: + if Onglet in self.OngletsSelectionnes : continue + + MCFils='Component_List_For_'+Onglet + if MCFils in self.jdc.editor.dicoNouveauxMC.keys() : continue + + + Onglet2 = Onglet.replace('___',' ') + MCFils='Component_List_For_'+Onglet + monInto=self.sheets[Onglet2][0] + self.jdc.editor.ajoutDefinitionMC('CONTINGENCY_PROCESSING',('b_TabList',),MCFils,'TXM',min=0, max='**', into=monInto, homo= 'SansOrdreNiDoublon') + self.jdc.editor.ajoutMC(self,MCFils,[],('b_TabList',)) + self.MCAjoutes.append(MCFils) + + MCFils='Contingency_List_For_'+Onglet + monInto=self.sheets[Onglet2][1] + self.jdc.editor.ajoutDefinitionMC('CONTINGENCY_PROCESSING',('b_TabList',),MCFils,'TXM',min=0, max='**', into=monInto, homo= 'SansOrdreNiDoublon') + self.jdc.editor.ajoutMC(self,MCFils,[],('b_TabList',)) + self.MCAjoutes.append(MCFils) + + + for Onglet in self.OngletsSelectionnes: + if Onglet in nouveauxOngletsSelectionnes : continue + + MCFils='Contingency_List_For_'+Onglet + self.jdc.editor.deleteMC(self,MCFils,('b_TabList',)) + self.jdc.editor.deleteDefinitionMC('CONTINGENCY_PROCESSING',('b_TabList',),MCFils) + self.MCAjoutes.remove(MCFils) + + MCFils='Component_List_For_'+Onglet + self.jdc.editor.deleteMC(self,MCFils,('b_TabList',)) + self.jdc.editor.deleteDefinitionMC('CONTINGENCY_PROCESSING',('b_TabList',),MCFils) + self.MCAjoutes.remove(MCFils) + + self.OngletsSelectionnes=nouveauxOngletsSelectionnes + self.jdc.editor.fenetreCentraleAffichee.reaffiche() +## nouveauxOngletsSelectionnes= self.get_child('TabList').getval() +## if nouveauxOngletsSelectionnes==self.OngletsSelectionnes : return +## if nouveauxOngletsSelectionnes==() or nouveauxOngletsSelectionnes == [] : +## for MC in self.MCAjoutes : +## self.jdc.appli.deleteMC(self,MC) +## self.MCAjoutes=[] +## self.OngletsSelectionnes=[] +## return +## +## for Onglet in nouveauxOngletsSelectionnes: +## if Onglet in self.OngletsSelectionnes : continue +## +## MCFils='Contingency_List_For_'+Onglet +## self.jdc.appli.ajoutMC(self,MCFils,[]) +## self.MCAjoutes.append(MCFils) +## MCFils='Component_List_For_'+Onglet +## self.jdc.appli.ajoutMC(self,MCFils,[]) +## self.MCAjoutes.append(MCFils) +## +## +## for Onglet in self.OngletsSelectionnes: +## if Onglet in nouveauxOngletsSelectionnes : continue +## +## MCFils='Contingency_List_For_'+Onglet +## self.jdc.appli.deleteMC(self,MCFils) +## self.MCAjoutes.remove(MCFils) +## +## MCFils='Component_List_For_'+Onglet +## self.jdc.appli.deleteMC(self,MCFils) +## self.MCAjoutes.remove(MCFils) +## +## self.OngletsSelectionnes=nouveauxOngletsSelectionnes +## +## diff --git a/ProcessOutputs_Eficas/prefs_PSEN_N1.py b/ProcessOutputs_Eficas/prefs_PSEN_N1.py index cb93ccbb..3d2098c0 100644 --- a/ProcessOutputs_Eficas/prefs_PSEN_N1.py +++ b/ProcessOutputs_Eficas/prefs_PSEN_N1.py @@ -38,8 +38,9 @@ affiche='ordre' # catalogues=( - ('PSEN_N1','Process contingency calculation and analysis',os.path.join(repIni,'PSEN_Cata_Contingency.py'),'ProcessOutputs','python'), - ('PSEN_N1','Post Calculation Analysis',os.path.join(repIni,'PSEN_Cata_DataProcessing.py'),'ProcessOutputs','python'), + ('PSEN_N1','PSSE_Process contingency calculation and analysis',os.path.join(repIni,'PSEN_Cata_Contingency.py'),'ProcessOutputs','python'), + ('PSEN_N1','PSSE_Post Calculation Analysis',os.path.join(repIni,'PSEN_Cata_DataProcessing.py'),'ProcessOutputs','python'), + ('PSEN_N1','PF_Process contingency calculation and analysis AND Post Calculation Analysis',os.path.join(repIni,'PSEN_Cata_N1_PF.py'),'ProcessOutputs','python'), ) diff --git a/generator/generator_PSEN.py b/generator/generator_PSEN.py index 2761c6b3..137f4a4c 100755 --- a/generator/generator_PSEN.py +++ b/generator/generator_PSEN.py @@ -97,7 +97,7 @@ class PSENGenerator(DicoImbriqueGenerator): #---------------------------------------------------------------------------------------- def writeDefault(self,fn) : - fileDico=os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)),'..','PSEN_Eficas','PSEN','PSENconfig.py')) + fileDico=os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)),'..','PSSE_PF_Eficas','PSEN','PSENconfig.py')) f = open( str(fileDico), 'wb') f.write( self.Entete + "Dico =" + str(self.Dico) ) f.close() -- 2.39.2