SysCAD COM Interface Class
Jump to navigation
Jump to search
Basic COM Functionality in a python class
Save the code in a file syscadif.py This needs to be either in the working directory, or somewhere on the PYTHONPATH (so that you can import the module from any script) Alteratively, add to the import module path as in the code below. Then import the module and create an instance of the SysCADCom class:
import sys
sys.path.append(r"C:\SysCAD139\BaseFilesUser\Scripts") ## syscadif.py is saved in a subdirectory of BaseFilesUser
import syscadif
sc = syscadif.SysCADCom()
After a project is loaded, you can get and set tags, and run the model or scenarios. For convenience, operators __getitem__ and __setitem__ are provided which allow using a similar syntax to PGM: Copy Tag for PGM can be used to grab the tag string with enclosing brackets.
sc.setTag("SLURRY_IN.QmReqd (t/h)", 50.0)
sc["SLURRY_IN.QmReqd (t/h)"] =50.0 ## equivalent
sc.run()
prod = sc.getTag("P_007.Qo.QM.Au(s) (oz/d)")
prod = sc["P_007.Qo.QM.Au(s) (oz/d)"] ## equivalent
## Setting a single tag for three different scenarios: Flow in P_01 and P_03 for feeds of 1, 3, and 5 tph
sc.RunScenarios([1,3,5], "Feed1.QmRqd (tph)", ["P_01.Qm (tph)", "P_03.Qm (tph)"])
# Four different scenarios, setting two tags
sc.RunScenarios([[2,4], [3,5], [4, 7], [5, 8]], ## List of value lists
["Feed1.QmRqd (tph)","Feed2.QmRqd (tph)"],
["P_01.Qm (tph)", "P_03.Qm (tph)"])
Creating an instance of the SysCADCom class will fire up SysCAD (or attach if SysCAD is already running). To see the code below click on the Expand link:
import win32com.client
import time, os
from tkinter import filedialog
PrjFolder = "C:/SysCAD139/Examples" # Where to look for SysCAD projects when opening with the file dialog
class SysCADCom:
def __init__(self):
self.ProgID = r"SysCADSimulator93.Application"
self.SysCAD = self.Prj = self.Tags = self.Solver = None
self.Probal = self.Dynamic = None
self.SysCAD = win32com.client.DispatchEx(self.ProgID)
self.build = self.SysCAD.VersionNumber(2)
def OpenProject(self, fn=None, checkFile = True):
print (self.ProgID)
if fn is None:
self.fn = filedialog.askopenfilename(filetypes=[("SysCAD Projects", "*spj")],
initialdir = PrjFolder,
defaultextension="spj")
else:
self.fn = fn
if not self.fn: return 0
if checkFile and not os.path.isfile(self.fn):
print ("Project File not found")
return 0
self.Prj = self.SysCAD.OpenProject(self.fn)
self.Tags = self.Prj.Tags
self.Solver = self.Prj.Solver
self.RunMode()
time.sleep(1)
def RunMode(self):
'''Select Run mode depending if project is SS or dynamic'''
if self.Solver.RunMode & 1:
self.Probal = self.Solver.Probal
self.Dynamic = None
else:
self.Dynamic = self.Solver.Dynamic
self.Probal = None
def CloseProject(self):
self.SysCAD.CloseProject()
def Close(self):
'''remove all references to COM objects...'''
del self.Probal
del self.Dynamic
del self.Solver
del self.Tags
del self.Prj
del self.SysCAD
def startSysCAD(self):
if self.Solver.RunMode & 1:
self.Probal.Start()
else:
self.Dynamic.Start()
def run(self, sleepTime=0.1):
'''Run a Probal project to completion. For a project that takes a longer time to solve
increase sleepTime'''
if self.Probal is not None:
self.Probal.Start()
while not self.Probal.IsStopped:
time.sleep(sleepTime)
elif self.Dynamic is not None:
self.Dynamic.Start()
else:
print ("No project")
def stop(self):
if self.Solver.RunMode & 1:
self.Probal.Stop()
else:
self.Dynamic.Stop()
def RunScenarios(self, XVals, Tag, getTagList, verbose=True):
'''Run a number of scenarios.
If Tag is a string, XVals should be a list or iterable of appropriate elements
Otherwise Tag should be a list of tags or iterable, and XVals a list of multiple values
Accumulate the results and return'''
Y = []
for x in XVals:
if verbose: print (x)
if isinstance(Tag, str):
self.setTag(Tag, x) ## Change tag value
else:
self.setTags(Tag, x)
self.run()
Y.append(self.getTags(getTagList))
return Y
def getTag(self, tag):
'''Fetch a single tag'''
return self.Tags.TagValue(tag)
def __getitem__(self, tag):
return self.Tags.TagValue(tag)
def getTags(self, tagList):
'''Fetch a list of tags'''
return [self.Tags.TagValue(tag) for tag in tagList]
def setTag(self, tag, value):
'''Set a single tag'''
self.Tags.SetTagValue(tag, value)
def __setitem__(self, tag, value):
self.Tags.SetTagValue(tag, value)
def setTags(self, tagLis, valLis):
'''Set a list of tags to corresponding values'''
for t, v in zip(tagLis, valLis):
self.Tags.SetTagValue(t, v)
def state(self, timeout = 0.0):
if timeout: time.sleep(timeout)
return self.Probal.IsStopped
|