

import sys
import os

path_PF = r"C:\Program Files\DIgSILENT\PowerFactory 2021 SP2\Python\3.10"
os.environ['PATH'] = path_PF + ";" + os.environ['PATH']
os.add_dll_directory(path_PF)
sys.path.append(path_PF)

import powerfactory as pf

app = pf.GetApplication()

print(app)

user = app.GetCurrentuser()
project = app.ActivateProject('Nine-bus System') # Nombre del proyecto
prj = app.GetActiveProject()




import sys
import os

path = r'C:\Program Files\DIgSILENT\PowerFactory 2021 SP2\Python\3.10'
os.environ['PATH'] += (";" + path)
sys.path.append(path)

import powerfactory as pf

app = pf.GetApplication()
if app is None:
    raise Exception('getting Powerfactory application failed')

# app.Show()

user = app.GetCurrentUser()
projects = user.GetContents('*.IntPrj', 0)
names = [pro.GetAttribute("loc_name") for pro in projects]

res = app.ActivateProject("ProyectoPrueba")
if res == 1:  # no existe y hay crearlo
    proj = app.CreateProject("ProyectoPrueba", "GridNueva")
else:
    proj = app.GetActiveProject()

#########
# MODEL #
#########
# Network model
netmod = app.GetProjectFolder('netmod')
# Network data
netdata = app.GetProjectFolder('netdat')
# Diagrams
diag_fold = app.GetProjectFolder('dia')
# Variations
var_fold = app.GetProjectFolder('scheme')

###########
# LIBRARY #
###########
# Equipment library
equip = app.GetProjectFolder('equip')
# lines_fold = equip.GetContents('Lines')[0][0]
# User defined models
main_lib = equip.GetParent()
# udm = main_lib.GetContents('User Defined Models*')[0][0]
# Script library
script_lib = app.GetProjectFolder('script')
# Template library
templ_lib = app.GetProjectFolder('templ')
# Operational library
oplib = app.GetProjectFolder('oplib')
# Characteristics
# opchar = oplib.GetContents('Characteristics')[0][0]
# Thermal ratings
therm_fold = app.GetProjectFolder('therm')
# MVAr limit curves
mvar_fold = app.GetProjectFolder('mvar')

##############
# STUDY CASE #
##############
# Study cases
op_scen = app.GetProjectFolder('scen')
# Operational scenarios
sc_fold = app.GetProjectFolder('study')

# Diagramas:
schemas = diag_fold.GetContents('*.IntGrfnet', 0)
sch = None
for obj in schemas:
    if obj.loc_name == "miEsquema":
        sch = obj
        break

if sch is None:
    sch = diag_fold.CreateObject("IntGrfnet", "miEsquema")

# redes:
print(netdata)
grids = netdata.GetContents('*.ElmNet', 0)
grid = grids[0]
ln = grid.GetContents('*.ElmLne', 0)[0]
print(ln)
# print(ln.type_id)
print(f"Terminal 1 de la línea {ln.loc_name}: {ln.bus1}")
print(f"Terminal 2 de la línea {ln.loc_name}: {ln.bus2}")


def createCable(name):
    ''''''
    cable = equip.CreateObject("TypCab", name)
    cable.uline
    cable.typCon = "cmp"  # Forma (cmp: Macizo, hol: orificio, seg: sermento)
    cable.diaCon = 5.0  # diámetro externo (double) (mm)

    # Capas condutoras: conductor, funda, blindaje
    cable.cHasEl = [1, 1, 1]  # Existe
    cable.materialCond = []  # Material ()
    cable.crho = []  # Resistividad 20ºC (double) (uOhm*cm)
    cable.my = []  # Premeabilidad relativa (double)
    cable.cThEl = []  # Espesor (dobule) (mm)
    cable.Cf = []  # Factor de Relleno (double) (%)
    cable.rpha = []  # Resistenca DC 20ºC Ohm/km

    # Capas de aislamiento: Aislamiento, Funda Exterior, Cubierta
    cable.cHasIns = [0, 0, 0]  # Existe
    cable.materialIns = []  # Material
    cable.ctand = []  # Factor de Pérdidas Dieléctricas
    cable.cepsr = []  # Permeavilidad relativa
    cable.thlns = []  # Espesor (mm)

    # Capas semicoductoras: Nucleo, Aislamiento
    cable.cHasSc = []  # Existe
    cable.thSc = []  # Espesor (mm)
    cable.cAdvSc = []  # Avanzado
    cable.rhoSc = []  # Resistividad uOhm*cm
    cable.mySc = []  # Permeabilidad relativa
    cable.epsrSC = []  # Premitividad relativa

    cable.manuf = ""  # fabricante

    # 1 Flujo de carga
    cable.tmax = 90.0  # Máx. temperatura (ºC)

    # 2. Cortocircuito VDE/IEC
    cable.rtemp = 80.0  # temperatura final máxima (ºC)
    cable.Ithr = 0.0  # Corriente de corta duración 1s (kA)

    # 3. Análisis de Cables
    cable.tmax_screen = 70.0  # max. temparatura operación (ºC)
    cable.eps_emiss = 0.9  # coeficiente de emisión en la superficie
    cable.iopt_treated = True  # Secado e impregnado
    cable.tshc = 1.0  # Cálculo de cortocircuito adiabático - Duración de la falla (s)

    return cable


def createLine(name):
    elmlne = p.CreateObject("ElmPvsys", name)
    elmlne.type_id = ""  # Tipo
    elmlne.bus1 = ""  # terminal i
    elmlne.bus2 = ""  # terminal j
    elmlne.nlnum = 1  # líneas en paralelo
    elmlne.dline = 0.8  # longitud de la línea (double) (km)
    elmlne.fline = 1.0  # factor de reduccion (double)
    elmlne.inAir = 0  # Medio (0: Tierra, 1: Aérea)
    elmlne.i_dist = 0  # Modelo de la línea (0: Parámetros Concentrados, 1: Parámetros Distribuidos)

    return elmlne


def createPVPanel(name):
    typpvpanel = equip.CreateObject("TypPvPanel", name)
    typpvpanel.Ppk = 500.0  # Potencia Pico MPP (double) (W)
    typpvpanel.Umpp = 80.0  # Tensión nominal MPP (double) (V)
    typpvpanel.Impp = 6.0  # Corriente nominal MPP (double) (A)
    typpvpanel.Uoc = 90.0  # Tensión de Circuito Abierto (double) (V)
    typpvpanel.Isc = 7.0  # Corriente de cortocircuito (double) (A)
    typpvpanel.material = 0  # Material: 0:mono-SI, 1:poli-Si, 2:samor-SI, 3: CIS, 4:CdTe, 5: otro
    typpvpanel.usetval = 1  # Usar valores típicos
    typpvpanel.cT = -0.4  # Coeficiente de tenperatura P (double) (%/Cº)
    typpvpanel.noct = 45.0  # SINTC (double) (Cº)

    typpvpanel.manuf = ""  # Fabricante
    typpypanel.chr_name = ""  # Nombre característico
    typpypanel.appr_status = 1  # Estado: 0: No aprobado, 1: aprobado

    return typpvpanel


def createPV(name):
    elmpvsys = grid.CreateObject("ElmPvsys", name)
    elmpvsys.typ_id = None
    elmpvsys.bus1 = None  # terminal ()
    elmpvsys.mode_pgi = 0  # modelo (0:Entrada de potencia Activa, 1: Cálculo solar)
    elmpvsys.phtech = 0  # tecnología (0: 3F, 1: 3F-T, 2:1F F-T, 3:1F F-N)
    elmpvsys.ngnum = 1  # Inversores en paralelo (int)
    elmpvsys.npnum = 1  # Paneles por incersro (int)
    elmpvsys.sgn = 1.0  # Potencia aparente (double) (kVA)
    elmpvsys.cosn = 0.8  # Factor de Potencia nominal (double)
    # elmpvsys.
    return elmpvsys


def createBarra(name, uknom=33.0):
    typbar = equip.CreateObject("TypBar", name)
    typbar.uknow = uknom

    # 1. Cortocircuito VDE/IEC
    typbar.Ithlim = 0  # Corriente Nominal de Corto tiempo (kA)
    typbar.Tkr = 1  # tiempo Corriente Nominal de Corto tiempo (s)
    typbar.Iplim = 0  # Corriente Pico de cortocircuito (kA)

    return typbar


def createTerminal(name):
    elmterm = grid.CreateObject("ElmTerm", name)
    elmterm.systype = 0  # Tipo de sistema (0: AC, 1: DC, 2: AC/BI)
    elmterm.iUsage = 0  # Uso (0:Busbar, 1:Junction, Node 2: Internal node)
    elmterm.phtech = "ABC"  # Tecnología de Fases: ABC, ABC-N, BI, BI-N, 2F, 2F-N, 1F, 1F-N, N
    elmterm.uknom = 33.0  # Tensión Nominal Línea-Línea (double)
    elmterm.iEarth = False  # Aterrizado (bool)
    # Load Flow:
    # 1. Control de tensión:
    elmterm.vtarget = 1.0  # Tensión destino (double) (p.u.)
    elmterm.Vtarget = 0.0  # Tensión destino (double) (kV)
    elmterm.dvmax = 0.0  # Max delta V (double) (%)
    elmterm.dvmin = 0.0  # Min delta V (double) (%)
    elmterm.ivpriority = -1  # prioriddad
    # 2. Límite de tensión del estado estable
    elmterm.vmax = 1.05  # Límite superior de tensión (p.u.)
    elmterm.vmin = 0.0  # Límite inferior de tensión (p.u.)
    # 3. Límites del cambio del paso de tensión
    elmterm.vstep_change = True  # Límites del cambio del paso de tensión (bool)
    elmterm.vstep_n1 = 6.0  # n-1 (%)
    elmterm.vstep_n2 = 12.0  # n-2 (%)
    elmterm.vstep_bus = 12.0  # falla de barra (%)
    # Análisis de Arco Eléctrico:
    elmterm.iAccessLoc = False  # Ubicación Accesible (bool)
    elmterm.isSoftConstr = False  # Restrinción blanda (bool)

    crearCelda()

    return elmterm


def createCubic(parent, name):
    stacubic = parent.CreateObject("StaCubic", name)
    stacubic.cterm = parent
    # stacubic.obj_id =
    # stacubic.plntObjs =
    return stacubic


def createSwitch(name):
    staswitch = ""


def createTransformer(name):


#

def createTransformerType(name):
    typTr3 = equip.CreateObject("TypTr3", name)
    typTr3.nt3ph = 3  # Tecnología (2: Monofásico, 3: trifásico)

    # Potencia Nominal:
    typTr3.strn3_h = 1.0  # Lado AT (double) (MVA)
    typTr3.strn3_m = 1.0  # Lado MT (double) (MVA)
    typTr3.strn3_l = 1.0  # Lado BT (double) (MVA)

    # Tensión nominal:
    typTr3.utrn3_h = 0.0  # Lado AT (double) (kV)
    typTr3.utrn3_m = 0.0  # Lado MT (double) (kV)
    typTr3.utrn3_l = 0.0  # Lado BT (double) (kV)

    # Grupo Vectorial:
    typTr3.tr3cn_h = "YN"  # Lado AT (Y, YN, Z, ZN, D)
    typTr3.nt3ag_h = 0.0  # Lado AT - Ángulo de desfase (double) (*30deg)
    typTr3.tr3cn_m = "YN"  # Lado MT (Y, YN, Z, ZN, D)
    typTr3.nt3ag_m = 0.0  # Lado MT - Ángulo de desfase (double) (*30deg)
    typTr3.tr3cn_l = "YN"  # Lado BT (Y, YN, Z, ZN, D)
    typTr3.nt3ag_l = 0.0  # Lado BT - Ángulo de desfase (double) (*30deg)

    # Impedancia de secuencia positiva
    # Tensión de Cortocircuito uk:
    typTr3.uktr3_h = 3.0  # AT-MT (double) (%)
    typTr3.uktr3_m = 3.0  # MT-BT (double) (%)
    typTr3.uktr3_l = 3.0  # BT-AT (double) (%)

    # Pérdidas en el Cobre
    typTr3.pcut3_h = 0.0  # AT-MT (double) (kW)
    typTr3.pcut3_m = 0.0  # MT-BT (double) (kW)
    typTr3.pcut3_l = 0.0  # BT-AT (double) (kW)

    # Impedancia de secuencia cero
    # Tensión de Cortocircuito uk0:
    typTr3.uk0hm = 3.0  # AT-MT (double) (%)
    typTr3.uk0ml = 3.0  # MT-BT (double) (%)
    typTr3.uk0hl = 3.0  # BT-AT (double) (%)

    # Pérdidas en el Cobre
    typTr3.ur0hm = 0.0  # AT-MT (double) (kW)
    typTr3.ur0ml = 0.0  # MT-BT (double) (kW)
    typTr3.ur0hl = 0.0  # BT-AT (double) (kW)


# print(dir(app))
# print(dir(app.CreateProject))


cable = equip.GetContents('*.TypCab', 0)[0]
print(dir(cable))
print(cable.cHasEl)
print(cable.materialCond)
print(cable.tab_con)

'''
Run a load flow

#define project name and study case    
projName = '_TSI_Nine-bus System'
study_case = '01_Study_Case.IntCase'

#activate project
project = app.ActivateProject(projName)
proj = app.GetActiveProject()

#get the study case folder and activate project
oFolder_studycase = app.GetProjectFolder('study')
oCase = oFolder_studycase.GetContents(study_case)[0]
oCase.Activate()

#get load flow object and execute
oLoadflow=app.GetFromStudyCase('ComLdf') #get load flow object
oLoadflow.Execute() #execute load flow
'''

'''
Print the results for generators, lines, and buses


#get the generators and their active/reactive power and loading
Generators = app.GetCalcRelevantObjects('*.ElmSym')
for gen in Generators: #loop through list
    name = getattr(gen, 'loc_name') # get name of the generator
    actPower = getattr(gen,'c:p') #get active power
    reacPower = getattr(gen,'c:q') #get reactive power
    genloading = getattr(gen,'c:loading') #get loading
    #print results
    print('%s: P = %.2f MW, Q = %.2f MVAr, loading = %.0f percent' %(name,actPower,reacPower,genloading))

print('-----------------------------------------')

#get the lines and print their loading
Lines=app.GetCalcRelevantObjects('*.ElmLne')
for line in Lines: #loop through list
    name = getattr(line, 'loc_name') # get name of the line
    value = getattr(line, 'c:loading') #get value for the loading
    #print results
    print('Loading of the line: %s = %.2f percent' %(name,value))

print('-----------------------------------------')

#get the buses and print their voltage
Buses=app.GetCalcRelevantObjects('*.ElmTerm')
for bus in Buses: #loop through list
    name = getattr(bus, 'loc_name') # get name of the bus
    amp = getattr(bus, 'm:u1') #get voltage magnitude
    phase = getattr(bus, 'm:phiu') #get voltage angle
    #print results
    print('Voltage at %s = %.2f pu %.2f deg' %(name,amp,phase))
'''

'''
Run an RMS simulation

#define project name and study case    
projName = '_TSI_nine_bus_system'
study_case = '01_Study_Case.IntCase'

#activate project
project = app.ActivateProject(projName)
proj = app.GetActiveProject()

#get the study case folder and activate project
oFolder_studycase = app.GetProjectFolder('study')
oCase = oFolder_studycase.GetContents(study_case)[0]
oCase.Activate()

# calculate initial conditions
oInit = app.GetFromStudyCase('ComInc') #get initial condition calculation object
oInit.Execute()

#run RMS-simulation
oRms = app.GetFromStudyCase('ComSim') #get RMS-simulation object
oRms.Execute()
'''

'''
Retrieve RMS results from PowerFactory in Python

import numpy as np
import pandas as pd

def getResults():    
    #get result file
    elmRes = app.GetFromStudyCase('*.ElmRes')    
    app.ResLoadData(elmRes)

    #Get number of rows and columns
    NrRow = app.ResGetValueCount(elmRes,0)

    #get objects of interest
    oSG1 = app.GetCalcRelevantObjects('G1.ElmSym')[0]
    oBus1 = app.GetCalcRelevantObjects('Bus 1.ElmTerm')[0]
    oLine4_5 = app.GetCalcRelevantObjects('Line 4-5.ElmLne')[0]

    #Get index of variable of interest
    ColIndex_time = app.ResGetIndex(elmRes,elmRes,'b:tnow')
    ColIndex_ut = app.ResGetIndex(elmRes,oSG1,'s:ut')
    ColIndex_P = app.ResGetIndex(elmRes,oSG1,'s:P1')
    ColIndex_Q = app.ResGetIndex(elmRes,oSG1,'s:Q1')
    ColIndex_speed = app.ResGetIndex(elmRes,oSG1,'s:xspeed')
    ColIndex_u_bus1 = app.ResGetIndex(elmRes,oBus1,'m:u')
    ColIndex_loading_line_4_5 = app.ResGetIndex(elmRes,oLine4_5,'c:loading')

    #pre-allocate result variables
    result_time = np.zeros((NrRow,))
    result_ut = np.zeros((NrRow))
    result_P = np.zeros((NrRow))
    result_Q = np.zeros((NrRow))    
    result_speed = np.zeros((NrRow))    
    result_u_bus1 = np.zeros((NrRow))    
    result_loading_line_4_5 = np.zeros((NrRow))    

    #get results for each time step
    for i in range(NrRow):    
        result_time[i] = app.ResGetData(elmRes,i,ColIndex_time)[1]
        result_ut[i] = app.ResGetData(elmRes,i,ColIndex_ut)[1]
        result_P[i] = app.ResGetData(elmRes,i,ColIndex_P)[1]
        result_Q[i] = app.ResGetData(elmRes,i,ColIndex_Q)[1]       
        result_speed[i] = app.ResGetData(elmRes,i,ColIndex_speed)[1]       
        result_u_bus1[i] = app.ResGetData(elmRes,i,ColIndex_u_bus1)[1]       
        result_loading_line_4_5[i] = app.ResGetData(elmRes,i,ColIndex_loading_line_4_5)[1]       

    results = pd.DataFrame()
    results['time'] = result_time
    results['P'] = result_P
    results['Q'] = result_Q
    results['ut'] = result_ut
    results['speed'] = result_speed
    results['u_bus1'] = result_u_bus1
    results['loading_line_4_5'] = result_loading_line_4_5
    return results

#query results
RES = getResults()
'''

## Graphical objects:



