Skip to content

Commit

Permalink
updates to protsetopt installs; adding modified lehigh4mgs test files…
Browse files Browse the repository at this point in the history
… for PowerModelsONM
  • Loading branch information
lilycatolson committed Jul 12, 2024
1 parent 85aa7c0 commit 1adb785
Show file tree
Hide file tree
Showing 3 changed files with 249 additions and 115 deletions.
167 changes: 52 additions & 115 deletions omf/solvers/protsetopt/__init__.py
Original file line number Diff line number Diff line change
@@ -1,135 +1,72 @@
import os, sys, json, platform
import os, sys
import platform
#import json
import shutil
from urllib.request import urlretrieve as wget
from subprocess import check_output
from dss import DSS as dssObj

thisDir = os.path.abspath(os.path.dirname(__file__))

def install_pso(system : list = platform.system()):
def pull_from_upstream():
''' pull down the upstream package'''
source_url = 'https://github.com/lilycatolson/Protection-settings-optimizer/archive/refs/heads/main.zip'
wget(source_url, f'{thisDir}/pso_source.zip') #was: pso.zip

def install_pso_env(clean=False, system : list = platform.system()):
''' create a venv for Protection Settings Optimizer and install there '''
if not os.path.isfile(os.path.join(thisDir,"pso_source.zip")):
pull_from_upstream()
if clean:
shutil.rmtree(f'{thisDir}/pso_env', ignore_errors=True)
os.system(f'{sys.executable} -m venv "{thisDir}/pso_env"')
os.system(f'unzip -o "{thisDir}/pso_source.zip" -d "{thisDir}/pso_env/"')
os.system(f'source "{thisDir}/pso_env/bin/activate"; python -m pip install -r "{thisDir}/pso_env/Protection-settings-optimizer-main/requirements.txt"')

def install_pso_env_without_download(system : list = platform.system()):
os.system(f'{sys.executable} -m venv "{thisDir}/pso_env"')
os.system(f'source "{thisDir}/pso_env/bin/activate"; {sys.executable} -m pip install -e git+https://github.com/lilycatolson/Protection-settings-optimizer.git#egg=RSO_pack')

def install_pso(clean=False, system : list = platform.system()):
''' installs dependency for protsetopt'''
instantiated_path = os.path.normpath(os.path.join(thisDir,"instantiated.txt"))
if not os.path.isfile(instantiated_path):
os.system(f"{sys.executable} -m pip install -e git+https://github.com/lilycatolson/Protection-settings-optimizer.git#egg=RSO_pack")
if system == "Windows":
os.system(f'copy nul {instantiated_path}')
else:
os.system(f'touch "{instantiated_path}"')
print(f'protsetopt dependency installed - to reinstall remove file: {thisDir}/instantiated.txt')

try:
import RSO_pack
except ImportError:
print("protsetopt is not installed - installing now")
try:
install_pso_env_without_download()
#install_pso_env(clean=clean, system=system) #put back in once other version tested
#os.system(f"{sys.executable} -m pip install -e git+https://github.com/lilycatolson/Protection-settings-optimizer.git#egg=RSO_pack")
if system == "Windows":
os.system(f'copy nul {instantiated_path}')
else:
os.system(f'touch "{instantiated_path}"')
print(f'protsetopt installed - to reinstall remove file: {thisDir}/instantiated.txt')
except Exception as e:
print(e)
print("error - unable to install protsetopt")

def run_venv_cmd(cmd=''):
''' Run a command against the venv. '''
out = check_output([f'''source "{thisDir}/pso_env/bin/activate"; cd "{thisDir}"; pwd; python -c 'import RSO_pack; {cmd}' '''], shell=True)
return out.decode('utf-8')

def run_pso(testPath, testFile):
install_pso()
try:
import RSO_pack
except ImportError:
from . import RSO_pack

# helper functions: modified from ProtectionSettingsOptimizer OpenDSS example

def runDSS( file ):
''' compiles and solves the given opendss file '''
dssText = dssObj.Text
dssCircuit = dssObj.ActiveCircuit
dssText.Command = 'clear'
dssText.Command = 'compile '+ file
dssText.Command = 'set maxcontroliter = 500'
dssText.Command = 'solve'
return dssText, dssCircuit

def parseSysInfo(SysInfo):
''' returns the Lines, Names, and Buses of the Relays and Reclosers in the circuit '''
Buses = SysInfo['Buses']
devLines = [x['MonitoredObj'].split('Line.')[1] for x in SysInfo['Relays']]
devLines += [x['MonitoredObj'].split('Line.')[1] for x in SysInfo['Recs']]
devNames = [x['Name'] for x in SysInfo['Relays']]
devNames += [x['Name'] for x in SysInfo['Recs']]
dev_BusV = [Buses[RSO_pack.index_dict(Buses,'Name',x['Bus1'])]['kV']*1e3 for x in SysInfo['Relays'] ]
dev_BusV += [Buses[RSO_pack.index_dict(Buses,'Name',x['Bus1'])]['kV']*1e3 for x in SysInfo['Recs'] ]
return Buses, devLines, devNames, dev_BusV

def parseFaultInfo(Buses):
''' returns the Names and Nodes of the Buses in the circuit '''
faultBuses = [x['Name'] for x in Buses]
faultBusPhases = [None]*len(faultBuses)
for ii in range(len(faultBuses)):
faultBusPhases[ii] = Buses[RSO_pack.index_dict(Buses,'Name',faultBuses[ii])]['nodes']
return faultBuses, faultBusPhases

def loadFaultCSV(FData, testPath):
''' copies the Fault data in FData to <testPath>/FData.csv'''
Fault_File_loc = os.path.normpath(os.path.join(testPath,'FData.csv'))
FData.to_csv(Fault_File_loc,index=False,header=False)
Fault_Data_CSV = RSO_pack.read_Fault_CSV_Data(Fault_File_loc)
return Fault_Data_CSV

def parseSwitchInfo(SysInfo):
''' returns the Lines and States of the switches in the circuit '''
#lines where switch = True
switchLines = [x['Name'] for x in SysInfo['Lines'] if x['isSwitch']]
#lines that are enabled
switchStates = [1 if x['Enabled'] else 0 for x in SysInfo['Lines'] if x['isSwitch']]
return switchLines, switchStates
except (ImportError, ModuleNotFoundError):
from . import RSO_pack

def writeSettingsAndInfo(testPath, settings, old_info):
''' copies the settings and previous info to <testPath>/settings_rso_out.json and <testPath>old_info_rso_out.json '''
settingsFile = os.path.normpath(os.path.join(testPath, 'settings_rso_out.json'))
with open(settingsFile, "w") as f:
j = json.dumps(settings, default=str)
f.write(j)
infoFile = os.path.normpath(os.path.join(testPath, 'old_info_rso_out.json'))
with open(infoFile, "w") as f:
j = json.dumps(old_info, default=str)
f.write(j)
RSO_pack.run(testPath, testFile)

def run(testPath, testFile, Fres=['0.001','1'], Fts=['3ph','SLG','LL'], Force_NOIBR = 1, enableIT = 0, CTI = 0.25, OTmax = 10,
type_select = False, Fault_Res = ['R0_001','R1'], Min_Ip = [0.1,0.1], Substation_bus = 'sourcebus'):
''' runs setting optimization on the given opendss file, given constant program setting inputs '''
def run_pso_venv(testPath, testFile):
install_pso()

# program settings
#DOC = 0
Sho_Plots=1
initpop = None
SetDir=False

dssText, dssCircuit = runDSS(os.path.normpath(os.path.join(testPath, testFile)))
# collect system info from OpenDSS
SysInfo = RSO_pack.getSysInfo(dssCircuit)

Buses, devLines, devNames, dev_BusV = parseSysInfo(SysInfo)
Device_Data_CSV = RSO_pack.getDeviceData(dssCircuit,devNames,devLines,dev_BusV)

# collect fault data
faultBuses, faultBusPhases = parseFaultInfo(Buses)

FData = RSO_pack.getFaultInfo(dssCircuit,dssText,faultBuses,faultBusPhases,Fres,Fts,devLines,devNames,dev_BusV)
Fault_Data_CSV = loadFaultCSV(FData, testPath)

switchLines, switchStates = parseSwitchInfo(SysInfo)
settings,old_info = RSO_pack.runSettingsOptimizer(testPath,
switchStates,
switchLines,
Device_Data_CSV,
Fault_Data_CSV,
Fault_Res,
SysInfo,
Substation_bus,
Min_Ip,
enableIT,
Force_NOIBR,
CTI,
OTmax,
type_select,
SetDir,
Sho_Plots,
GA_initial_seed=initpop)

writeSettingsAndInfo(testPath, settings, old_info)
run_venv_cmd(cmd=f'RSO_pack.run("{testPath}", "{testFile}")')

def _test():
testPath = os.path.normpath(os.path.join(thisDir, 'testFiles'))
testFile = 'IEEE34Test.dss'
run(testPath, testFile)
#run_pso(testPath, testFile)
run_pso_venv(testPath, testFile)

if __name__ == "__main__":
_test()
196 changes: 196 additions & 0 deletions omf/static/testFiles/lehigh4mgs/circuit_plus_mgAll_relays.dss

Large diffs are not rendered by default.

Loading

0 comments on commit 1adb785

Please sign in to comment.