00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 __facility__ = "Online"
00011 __abstract__ = "Telecommand tester GUI"
00012 __author__ = "S. Tuvi <STuvi@SLAC.Stanford.edu>"
00013 __date__ = "2005/07/15 23:45:02"
00014 __updated__ = "$Date: 2006/02/10 21:51:14 $"
00015 __version__ = "$Revision: 1.13 $"
00016 __release__ = "$Name: HEAD $"
00017 __credits__ = "SLAC"
00018
00019 import LICOS.copyright_SLAC
00020
00021 from qt import *
00022 from qttable import *
00023 import sys
00024 import types
00025 import logging as log
00026
00027 from LICOS.tools.teleCmdGUI.TeleCmdTester import TeleCmdTester
00028 from LICOS.util.gOptions import Options
00029 from LICOS.scriptEngine.ScriptEngineConnector import ScriptEngineConnector
00030
00031 class TeleCmdTesterImpl(TeleCmdTester):
00032 """!\brief Real time tele-commanding facility
00033
00034 This tool provides the ability to send tele-commands to the VSC in
00035 real time. The user can enter a tele-command database based on which
00036 the command mnemonics and their payloads will be populated.
00037
00038 The GUI provides the means to construct a tele-command as it is allowed
00039 in LICOS test scripts. The command can be pasted in to the command window
00040 and queued to the VSC.
00041
00042 Currently only one command execution at a time is supported.
00043
00044 """
00045
00046 PAYLOAD_COL_MNEM = 0
00047 PAYLOAD_COL_VAL = 1
00048 PAYLOAD_COL_DESC = 2
00049
00050 def __init__(self, server, parent = None, name = None, fl = 0):
00051 """!\brief TeleCmdTesterImpl constructor.
00052
00053 \param parent The parent GUI (typically the Run Control GUI)
00054 \param name Name of the GUI
00055 \param fl Qt flags
00056 """
00057 TeleCmdTester.__init__(self, parent, name, fl | Qt.WGroupLeader)
00058
00059 self.connect(self.buttonPasteCmd,SIGNAL("clicked()"),self.pasteCommand)
00060 self.connect(self.buttonClearCmd,SIGNAL("clicked()"),self.clearCommand)
00061 self.connect(self.buttonQueue,SIGNAL("clicked()"),self.queueCommand)
00062 self.connect(self.buttonChangeDb,SIGNAL("clicked()"),self.changeDb)
00063 self.connect(self.comboPackage,SIGNAL("activated(const QString &)"),self.populateTeleCommands)
00064 self.connect(self.comboTeleCmd,SIGNAL("activated(const QString &)"),self.populatePayloads)
00065 self.connect(self.buttonZeroOutPayload,SIGNAL("clicked()"),self.zeroOutPayloads)
00066
00067
00068 self.setupPayloadTable()
00069 if type(server) is types.StringType:
00070
00071 self.__server = server
00072 self.__vsc = self.connectVSC()
00073 else:
00074 self.__vsc = server
00075
00076 self.changeDb()
00077
00078 def setupPayloadTable(self):
00079 """!\brief Initialize the payload table properties
00080
00081 Set the selection mode to single row.
00082 Set the Description column stretchable.
00083 """
00084 self.tablePayloads.setSelectionMode(QTable.SingleRow)
00085 self.tablePayloads.setColumnStretchable(TeleCmdTesterImpl.PAYLOAD_COL_DESC,1)
00086
00087 def populatePackages(self):
00088 """!\brief Populate the package list
00089
00090 """
00091 packages = self.__db.getPackages()
00092 packages.sort()
00093 for pkg in packages:
00094 self.comboPackage.insertItem(pkg)
00095 self.populateTeleCommands()
00096
00097 def populateTeleCommands(self):
00098 """!\brief Populate the telecommand list
00099
00100 """
00101 curPkg = str(self.comboPackage.currentText())
00102 pkg = None
00103 if curPkg in self.__teleCmds:
00104 pkg = self.__teleCmds[curPkg]
00105 elif hasattr(self.__db, curPkg):
00106 pkg = getattr(self.__db, curPkg)
00107 self.__teleCmds[curPkg] = pkg
00108 self.comboTeleCmd.clear()
00109 if pkg is not None:
00110 cmds = pkg.getCmds()
00111 cmds.sort()
00112 for cmd in pkg.getCmds():
00113 self.comboTeleCmd.insertItem(cmd)
00114 self.populatePayloads()
00115
00116 def populatePayloads(self):
00117 """!\brief Populate the payload table
00118
00119 """
00120 curPkg = str(self.comboPackage.currentText())
00121 curCmd = str(self.comboTeleCmd.currentText())
00122 if curPkg in self.__teleCmds:
00123 pkg = self.__teleCmds[curPkg]
00124 self.textCmdDescription.setText(pkg.getCmdObj(curCmd).descr)
00125 payloadList = pkg.getPayloadList(curCmd)
00126 self.tablePayloads.setNumRows(len(payloadList))
00127 row = 0
00128 for payloadMnemonic in payloadList:
00129 self.tablePayloads.setItem(row, TeleCmdTesterImpl.PAYLOAD_COL_MNEM,
00130 QTableItem(self.tablePayloads,
00131 QTableItem.Never,
00132 payloadMnemonic))
00133 payloadBrief = pkg.getPayloadDef(curCmd, payloadMnemonic)[2]
00134 self.tablePayloads.setText(row, TeleCmdTesterImpl.PAYLOAD_COL_VAL, "")
00135 self.tablePayloads.setItem(row, TeleCmdTesterImpl.PAYLOAD_COL_DESC,
00136 QTableItem(self.tablePayloads,
00137 QTableItem.Never,
00138 payloadBrief))
00139 row += 1
00140 else:
00141 self.tablePayloads.setNumRows(0)
00142
00143 def zeroOutPayloads(self):
00144 for row in range(self.tablePayloads.numRows()):
00145 self.tablePayloads.setText(row, TeleCmdTesterImpl.PAYLOAD_COL_VAL, "0")
00146
00147 def pasteCommand(self):
00148 """!\brief Paste the telecommand into the command window
00149
00150 """
00151
00152 self.tablePayloads.setReadOnly(1)
00153 self.tablePayloads.setReadOnly(0)
00154
00155 curPkg = str(self.comboPackage.currentText())
00156 curCmd = str(self.comboTeleCmd.currentText())
00157 keywords = ""
00158 for row in range(self.tablePayloads.numRows()):
00159 keywords += str(self.tablePayloads.text(row, TeleCmdTesterImpl.PAYLOAD_COL_MNEM)) + \
00160 "=" + str(self.tablePayloads.text(row, TeleCmdTesterImpl.PAYLOAD_COL_VAL))
00161 if row != self.tablePayloads.numRows() - 1:
00162 keywords += ", "
00163 cmdText = curPkg + "." + curCmd + "(" + keywords + ")"
00164 self.textSandbox.insert(cmdText)
00165
00166 def clearCommand(self):
00167 """!\brief Clear the command window
00168
00169 """
00170 self.textSandbox.setText("")
00171
00172 def queueCommand(self):
00173 """!\brief Queue the command to the VSC
00174
00175 """
00176 cmdText = str(self.textSandbox.text())
00177 cmdText = 'self.getDB().' + cmdText
00178 exec(cmdText)
00179
00180 def changeDb(self):
00181 """!\brief Change the database module
00182
00183 """
00184 self.__db = self.initDb()
00185 if self.__db is not None:
00186 self.__teleCmds = {}
00187 self.populatePackages()
00188 else:
00189 self.clearGUI()
00190
00191 def clearGUI(self):
00192 """!\brief Clear the GUI
00193
00194 """
00195 self.comboPackage.clear()
00196 self.comboTeleCmd.clear()
00197 self.tablePayloads.setNumRows(0)
00198 self.textCmdDescription.setText("")
00199
00200 def initDb(self):
00201 """!\brief Import and initialize the database module
00202
00203 """
00204 db = str(self.textDatabase.text())
00205 try:
00206 exec("from LICOS.lib.cmdTlmDb.%s import %s" % (db, db))
00207 return getattr(sys.modules['LICOS.lib.cmdTlmDb.%s' % db], db)(self.__vsc)
00208 except ImportError:
00209 log.exception("Unable to import database %s" % db)
00210 except Exception, e:
00211 log.exception(e)
00212 return None
00213
00214 def getDB(self):
00215 """!\brief Retrieve the current database instance
00216
00217 \return Current database instance
00218 """
00219 return self.__db
00220
00221 def connectVSC(self):
00222 """!\brief Connect to the Script Engine Proxy.
00223
00224 """
00225 vsc = ScriptEngineConnector( vscHost=self.__server,
00226 diagHost=None,
00227 telemHost=None)
00228 vsc.start()
00229 self.__vsc = vsc
00230 return vsc
00231
00232
00233 def usage():
00234 return """
00235
00236 TeleCmdTesterImpl Usage:
00237
00238 Mandatory options:
00239 --server specify the VSC server
00240
00241 Example:
00242 $ TeleCmdTesterImpl --server lat-elf9
00243
00244 """
00245
00246 if __name__ == "__main__":
00247 options = Options(['server'])
00248 try:
00249 options.parse()
00250 except Exception, msg:
00251 options.usage(usage())
00252 raise Exception, msg
00253
00254 a = QApplication(sys.argv)
00255 tct = TeleCmdTesterImpl(options.server)
00256 QObject.connect(a,SIGNAL("lastWindowClosed()"), a, SLOT("quit()"))
00257 a.setMainWidget(tct)
00258 tct.show()
00259 a.exec_loop()
00260