from datetime import datetime
import os
import pandapower
from .PowerFactory import PowerFactory
from .emt_simulation import SimulationEMT
[docs]
def get_power_system_objects_for_overview(
app_path: str, project_name: str, obj_classes: dict
) -> dict:
"""
Getter method for all obj_class objects of the power system to
create the overview table in the GUI.
:param app_path: path to the power factory executable files
:type app_path: str
:param project_name: name of the investigated power factory
project
:type project_name: str
:param obj_classes: dictionary defining the power system
components classes
:type obj_classes: dict
:return: - **return_dict** (dict) - dictionary containing \
the combination of obj_class and a list of the label of \
its instances
"""
# create an empty return dict to hold the loaded data
return_dict = {}
# open up powerfactory in unattended mode
pf = PowerFactory(path=app_path)
app = pf.open_app(project_name=project_name)
# iterate threw the considered object classes
for row in obj_classes:
# get objects from the active powerfactory application
objects = app.GetCalcRelevantObjects('*.{}'.format(obj_classes[row]))
# check if there are line objects in the considered power system
if not objects:
raise Exception("No {} objects found".format(obj_classes[row]))
else:
# create a dict holding a list of the power system object
# labels
return_dict.update({row: [obj.loc_name for obj in objects]})
return return_dict
[docs]
def get_power_system_objects(app, obj_class: str) -> dict:
"""
Getter method for all obj_class objects of the power system.
:param app: active instance of power factory application
:type app: powerfactory.Application
:param obj_class: str defining the power system components class
:type obj_class: str
:return: - **return_dict** (dict) - dictionary containing the \
combination of power system object label and its instance
"""
return_dict = {}
# get objects from the active power factory application
objects = app.GetCalcRelevantObjects('*.{}'.format(obj_class))
# check if there are line objects in the considered power system
if not objects:
raise Exception("No {} objects found".format(obj_class))
else:
# create a dict holding the combination of the line object
# label and its power factory object
for obj in objects:
return_dict.update({obj.loc_name: obj})
return return_dict
[docs]
def add_shc_and_run_emt(
app_path: str, project_name: str, shc_args: dict, sim_args: dict
) -> None:
"""
In this method, the preparations for an EMT simulation are first
made before an EMT simulation is carried out and the results are
then exported as a CSV.
For this purpose, an instance of the SimulationEMT class is
created. A short circuit event is then added to this and the
measured values to be recorded are transferred. Finally, the
temporal resolution of the simulation is defined and the
simulation is carried out.
:param app_path: path to the powerfactory executable files
:type app_path: str
:param project_name: name of the investigated powerfactory
project
:type project_name: str
:param shc_args: dictionary holding the parameter of the \
investigated short circuit event (e.g. the fault type)
:type shc_args: dict
:param sim_args: dictionary holding the temporal attributes of \
the EMT simulation (e.g. the step size)
:type sim_args: dict
"""
pf = PowerFactory(path=app_path)
app = pf.open_app(project_name=project_name)
# get all powersystem transmission lines
system_lines = get_power_system_objects(app=app, obj_class="ElmLne")
system_vts = get_power_system_objects(app=app, obj_class="StaVt")
system_cts = get_power_system_objects(app=app, obj_class="StaCt")
# create an emt simulation model object
emt = SimulationEMT(app)
# initialize the emt simulation model to make sure all necessary
# data structures exist
emt.init_emt()
# clear old values from emt simulation model data structures
emt.clear()
# update shc_args obj from str to its corresponding power system
# component
shc_args.update({"obj": system_lines[shc_args["obj"]]})
# update shc_args fault type from str to its corresponding integer
switch_dict_fault_type = {"1phG": 2, "2phwoG": 1, "2phG": 3, "3ph": 0}
fault_type = shc_args["fault_type"]
shc_args["fault_type"] = switch_dict_fault_type.get(shc_args["fault_type"])
# add a short circuit event to the EMT Simulation object
emt.add_shc_event(
obj=shc_args["obj"],
event_time=float(shc_args["event_time"]),
fault_location=float(shc_args["fault_location"]),
fault_type=int(shc_args["fault_type"]),
fault_impedance_r=float(shc_args["fault_impedance_r"]),
fault_impedance_x=float(shc_args["fault_impedance_x"])
)
# add the necessary voltage transformer to the EMT Simulation
# result object
for vt in system_vts:
emt.add_variables(objects=[system_vts[vt]],
attributes=["s:U2r_A", "s:U2r_B", "s:U2r_C"])
# add the necessary current transformer to the EMT Simulation
# result object
for ct in system_cts:
emt.add_variables(objects=[system_cts[ct]],
attributes=["s:I2r_A", "s:I2r_B", "s:I2r_C"])
# define the initial conditions of the emt model
emt.inc_settings(step_size=float(sim_args["step_size"]),
start_time=float(sim_args["start_time"]))
emt.sim_settings(stop_time=float(sim_args["stop_time"]))
# run the emt simulation
emt.run()
# export the results of the emt simulation
filename = (project_name + "_" + fault_type + "_"
+ datetime.now().strftime("%m_%d_%Y_%H_%M_%S") + ".csv")
res_path = (os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+ "/Results")
emt.export_to_csv(res_path + "/" + filename)
[docs]
def convert_model(app_path: str, project_name: str) -> None:
"""
Method to convert the power system data of the power factory
model file (.pfd) to a pandapower loadable JSON File.
:param app_path: path to the power factory executable files
:type app_path: str
:param project_name: name of the investigated power factory
project
:type project_name: str
"""
pf = PowerFactory(path=app_path)
app = pf.open_app(project_name=project_name)
res_path = (os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+ "/Results")
filename = (project_name + "_"
+ datetime.now().strftime("%m_%d_%Y_%H_%M_%S")
+ "_" + "network.json")
# create the powerpandas instance of the considered power factory
# model
pandapower.converter.from_pfd(
app=app,
prj_name=project_name,
path_dst=res_path + "/" + filename
)