00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 __facility__ = "Online"
00011 __abstract__ = "GLAST LAT run control common class"
00012 __author__ = "R. Claus <Claus@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online"
00013 __date__ = "2005/07/23 00:08:27"
00014 __updated__ = "$Date: 2006/04/26 21:46:21 $"
00015 __version__ = "$Revision: 1.53 $"
00016 __release__ = "$Name: HEAD $"
00017 __credits__ = "SLAC"
00018
00019 import LICOS.copyright_SLAC
00020
00021
00022 import sys
00023 import os
00024 import time
00025 import types
00026 import atexit
00027 import socket
00028 import logging as log
00029 import logging.handlers
00030 from ConfigParser import ConfigParser, NoOptionError
00031 import threading
00032
00033 from rcLoginImpl import rcLoginImpl
00034 from rcSecurityMan import rcSecurityMan
00035 from rcPreferencesManager import rcPreferencesManager
00036 from rcPreferencesGUIImpl import rcPreferencesGUIImpl
00037
00038 from LICOS.scriptEngine.ScriptEngineConnector import ScriptEngineConnector
00039 from LICOS.lib.currValTable.ScriptClient import ScriptClient
00040 from LICOS.lib.cmdTlmDb.LCATtlmDb import LCATtlmDb
00041 from LICOS.lib.cmdTlmDb.LCATcmdDb import LCATcmdDb
00042 from LICOS.util.gOptions import Options
00043 from LICOS.tools.logger.MSGLogGUIImpl import MSGLogGUIImpl
00044 from LICOS.util.gVersions import Gversions
00045 from LICOS.scriptEngine.HwCfgSelectorImpl import HwCfgSelectorImpl
00046 from LICOS.lib.LATconstants import *
00047
00048 from ISOC.TlmUtils.TlmRdbInterface import TlmRdbDb
00049 import VSC
00050
00051
00052 class GDBN(dict):
00053 """!\brief Database node record.
00054
00055 The database node contains session level variables in addition
00056 to preferences and entries used for diagnostics purposes.
00057 """
00058 def __init__(self):
00059 """!\brief GDBN constructor.
00060
00061 Initialize the dictionary.
00062
00063 """
00064 dict.__init__(self)
00065
00066
00067 class ScriptEngineSocketHandler(logging.handlers.SocketHandler):
00068 """!\brief Socket handler for logging.
00069
00070 """
00071 def __init__(self, *args):
00072 """!\brief ScriptEngineSocketHandler constructor.
00073
00074 \param args Positional arguments
00075 """
00076 apply(logging.handlers.SocketHandler.__init__, (self,) + args)
00077
00078 def handleError(self, record):
00079 """!\brief Handle error.
00080
00081 \param record Log record
00082 """
00083 if self.closeOnError and self.sock:
00084 self.sock.shutdown(2)
00085 self.sock.close()
00086 self.sock = None
00087 else:
00088 raise IOError, sys.exc_info()[1]
00089
00090 class ErrorLogCounterHandler(logging.Handler):
00091 """!\brief Log handler to check if any ERROR logs are produced during the run.
00092
00093 """
00094 def __init__(self, common):
00095 """!\brief ErrorLogCounterHandler constructor.
00096
00097 """
00098 logging.Handler.__init__(self)
00099 self.__common = common
00100
00101 def emit(self, record):
00102 """!\brief Log handler callback.
00103
00104 Increment the error log count.
00105
00106 \param record Log record
00107 """
00108 self.__common.incrementErrorLogCount()
00109
00110 class ScriptEngineFileHandler(log.FileHandler):
00111 """!\brief FileHandler class for handling multiple line log entries
00112
00113 If a log entry contains multiple lines, such as the case for
00114 tracebacks or exceptions a begin and end delimiter is added
00115 to the log entry so that it can be parsed by the MessageLogger
00116 """
00117 def __init__(self, filename, mode):
00118 """!\brief ScriptEngineFileHandler constructor.
00119
00120 """
00121 log.FileHandler.__init__(self, filename, mode)
00122
00123 def emit(self, record):
00124 """!\brief Log handler callback.
00125
00126 Format the log message. If it is a multiline message
00127 (like in exceptions), delimit the beginning and ending
00128 of the message.
00129
00130 \param record Log record
00131 """
00132 try:
00133 msg = self.format(record)
00134 (msg1, msg2) = msg.split(' - ',1)
00135 if msg2.find('\n') > 0:
00136 msg = msg1 + " - <//" + msg2+"//>"
00137 if not hasattr(types, "UnicodeType"):
00138 self.stream.write("%s\n" % msg)
00139 else:
00140 try:
00141 self.stream.write("%s\n" % msg)
00142 except UnicodeError:
00143 self.stream.write("%s\n" % msg.encode("UTF-8"))
00144 self.flush()
00145 except:
00146 self.handleError(record)
00147
00148 class ScriptEngineCommon(object):
00149 """!\brief Common class for providing a run control helper functions.
00150
00151 """
00152 def __init__(self):
00153 """!\brief ScriptEngineCommon constructor.
00154
00155 """
00156 self.MSGLogger = None
00157 self.__startGMT = time.gmtime()
00158 self.__options = Options(['config', 'server', 'vscConfig'],
00159 ['noreload', 'securedir',
00160 'app', 'appdir',
00161 'cvtHost', 'cvtPort', 'scriptOpts',
00162 'diagHost', 'telemHost'],
00163 ['cmdDebug', 'endRunDlg', 'norcoverride',
00164 'paramverify'])
00165 if len(sys.argv) > 1 and sys.argv[1] == '--help':
00166 self.__options.usage()
00167 print self.__usage()
00168 sys.exit(0)
00169 self.__dds = None
00170 self.__server = None
00171 try:
00172 self.__options.parse()
00173 except Exception, msg:
00174 self.__options.usage(self.__usage())
00175 raise Exception, msg
00176
00177 self.__evtCli = None
00178 self.__securityMan = None
00179 self.__dbn = GDBN()
00180 self.__dbn['_common'] = self
00181 self.__prefMan = None
00182 self.__prefGUI = None
00183 self.__errLogCnt = 0
00184 self.__hwVersions = None
00185 self.__gui = None
00186 self.__diagHandler = None
00187 self.__tlmDb = None
00188 self.__lcat = None
00189 self.__lcatTlm = None
00190
00191 try:
00192 import qt
00193 self.__qApp = qt.QApplication([])
00194 self.__qApp.addLibraryPath(os.path.join(ONLINE_ROOT, 'LICOS/ext/plugins'))
00195 except ImportError:
00196 self.__qApp = None
00197
00198
00199 atexit.register(log.shutdown)
00200
00201 def connectVSC(self):
00202 """!\brief Connect to the Script Engine Proxy.
00203
00204 """
00205 configFile = os.path.abspath(self.__options.vscConfig)
00206 config = ConfigParser()
00207 config.readfp(file(configFile))
00208
00209 try:
00210 archive_path = config.get('paths','archive_path')
00211 granularity = config.getint('ccsds_archivers',
00212 'granularity')
00213 if len(archive_path) != 0:
00214 from LICOS.tools.proxy.VscArchivers import VscArchiver
00215 archiver = VscArchiver("CMD", archive_path, granularity)
00216 else:
00217 print "Archiving disabled due to null archive_path or ingest_path"
00218 archiver = None
00219 except NoOptionError, e:
00220 print "Archiving disabled: ", e
00221 archiver = None
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 diagHost = self.__options.diagHost
00243 if diagHost is None: diagHost = 'localhost'
00244 telemHost = self.__options.telemHost
00245 if telemHost is None: telemHost = 'localhost'
00246 portBase = config.getint('vsc', 'proxyPortBase')
00247 vsc = ScriptEngineConnector( vscHost=self.__options.server,
00248 diagHost=diagHost,
00249 telemHost=telemHost,
00250 archiver=archiver,
00251 cmdDebug=self.__options.cmdDebug,
00252 portBase = portBase)
00253 self.__lcatTlm = LCATtlmDb()
00254 vsc.setTlmDb(self.__lcatTlm)
00255 vsc.initCmdCountMon()
00256 vsc.start()
00257 vsc.m7default()
00258
00259 self.__vsc = vsc
00260 self.__dbn['_vsc'] = vsc
00261 self.__lcat = LCATcmdDb(vsc)
00262 self.__lcat.LIM.startStateMonitor()
00263
00264
00265 self.addLatWatchItems()
00266
00267 def getLCATcmd(self):
00268 """!\brief Retrieve the LCAT command database wrapper instance.
00269
00270 \return LCATcmdDb instance
00271 """
00272 return self.__lcat
00273
00274 def getLCATtlm(self):
00275 """!\brief Retrieve the LCAT telemetry database wrapper instance.
00276
00277 \return LCATtlmDb instance
00278 """
00279 return self.__lcatTlm
00280
00281 def addLatWatchItems(self):
00282 """!\brief Add LAT related watch items to the status panel.
00283
00284 """
00285 statMon = self.__gui.statusMonitor()
00286 statMon.addWatchItem('LAT Configuration', self.getLatConfigId)
00287 lim = self.getLCATcmd().LIM
00288 statMon.addWatchItem('LIM Operating Mode', lim.getOperatingModeStr,
00289 isStale=lim.isLimStateStale)
00290 statMon.addWatchItem('LIM Action', lim.getActionStr,
00291 isStale=lim.isLimStateStale)
00292 statMon.addWatchItem('LIM Status', lim.getStatusStr,
00293 isStale=lim.isLimStateStale)
00294 self.__gui.statusMonitor().saveWatch()
00295
00296
00297 def connectCVT(self):
00298 """!\brief Connect to the current value table.
00299
00300 """
00301 try:
00302 self.cvt = ScriptClient(self.__options.cvtHost, int(self.__options.cvtPort))
00303 except:
00304 log.info("Connection to CVT failed. User scripts that call the CVT may fail")
00305 self.cvt = None
00306 pass
00307
00308 def populateTlmDb(self):
00309 try:
00310 import psycopg
00311 except ImportError:
00312 log.warn("Unable to import the Postgres Python package, EGU conversions will not be available")
00313 return
00314 try:
00315
00316 configFile = self.__options.vscConfig
00317 config = ConfigParser()
00318 config.read(configFile)
00319 DSN = config.get('postgres', 'dsn')
00320 db = psycopg.connect( DSN )
00321 dbc = db.cursor()
00322 self.__tlmDb = TlmRdbDb(dbc)
00323 src = config.get('tlmdb', 'source')
00324 bld = config.get('tlmdb', 'build')
00325 self.__tlmDb.populate(source=src, build=bld)
00326 except Exception, e:
00327 log.exception("Unable to populate the telemetry database")
00328 self.__tlmDb = None
00329
00330 def initialize(self, startup=False):
00331 """!\brief Initialization.
00332
00333 \param startup Are we initializing for the first time?
00334 """
00335 self.__prefMan = rcPreferencesManager(self.__options.config)
00336 if (self.__prefMan.loadConfig()):
00337
00338 self.startLogger(startup)
00339
00340
00341
00342
00343
00344
00345
00346
00347 if self.__options.securedir is not None:
00348 self.__securityMan = rcSecurityMan(os.path.abspath(self.__options.securedir),
00349 self.preferences()["users"])
00350 self.__securityMan.readPermissions()
00351 self.__dbn['_securityMan'] = self.__securityMan
00352 if self.__options.noreload is not None:
00353 import string
00354 self.__dbn["_dontReload"] = map(string.strip, file(self.__options.noreload).readlines())
00355 if self.__options.scriptOpts is not None:
00356 scrOptsFile = os.path.abspath(self.__options.scriptOpts)
00357 self.__scriptOpts = self.readScriptOpts(scrOptsFile)
00358 else:
00359 self.__scriptOpts = {}
00360
00361 else:
00362 raise RuntimeError, "Can not find configuration file: %s" % self.__options.config
00363
00364 def readScriptOpts(self, scrOptsFile):
00365 """!\brief Read the script options file.
00366
00367 The script options file is used to debug a script without
00368 issuing a LICOS release. It should not be used in 'for credit'
00369 runs since it may change the behavior of the script.
00370
00371 The script options file is a configuration file parsable by
00372 ConfigParser. Each section contains the script name. Under
00373 each section the options for that script and their values
00374 are listed.
00375
00376 The options used for a given script are recorded in the run
00377 report.
00378
00379 \param scrOptsFile File containing the script options
00380
00381 \return Dictionary containing the script options
00382 """
00383 config = ConfigParser()
00384 config.readfp(file(scrOptsFile))
00385 scriptOpts = {}
00386 for section in config.sections():
00387 scriptOpts[section] = {}
00388 for option in config.options(section):
00389 scriptOpts[section][option] = config.get(section, option)
00390 return scriptOpts
00391
00392 def getScriptOpts(self, scriptName):
00393 """!\brief Retrieve the options for script \a scriptName.
00394
00395 \param scriptName Name of the script
00396
00397 \return Dictionary of options for the script or None.
00398 """
00399 if scriptName in self.__scriptOpts:
00400 return self.__scriptOpts[scriptName]
00401 else:
00402 return {}
00403
00404 def __usage(self):
00405 """!\brief Usage.
00406
00407 """
00408 return """
00409
00410 Detailed explanation:
00411
00412 Mandatory options:
00413 --config to specify the run control configuration file to use
00414 --server to specify the hostname or the IP address of the teststand crate
00415 to connect to.
00416 --vscConfig to specify the configuration of the VSC and related quantities
00417
00418 Optional options:
00419 --app Specify the standalone application or suite to run.
00420 Typically used by test or suite runners.
00421 --appdir Specify the application directory
00422 --cmdDebug Specify command debugging.
00423 --cvtHost Current value table host.
00424 --cvtPort Current value table port.
00425 --diagHost Diagnostic proxy host. If omitted, defaults to localhost.
00426 --endRunDlg Force the end run dialog to come up even in non-secure mode.
00427 --norcoverride Prevents the run conditions to be overridden with NOT-DEFINED.
00428 --noreload Specify a file that contains prefixes of modules
00429 which should not be reloaded when a user script is selected.
00430 This list gets appended to the default list which currently contains
00431 the following prefixes 'scipy', 'weave', 'qwt', 'xml', 'pyexpat', 'win32'.
00432 The file should contain one prefix per line.
00433 --paramverify Force the parameter verifier to come up even if running in non-secure mode
00434 --scriptOpts Specify a configuration file containing script specific options.
00435 The script name is specified as a section and all options can be specified
00436 under that section.
00437 --securedir The full path to the secure directory where the password file
00438 ("passwords") and the user permissions file ("security.cfg") is stored.
00439 If this switch is specified then ScriptEngine is started in secure mode.
00440 --telemHost Telemetry proxy host. If omitted, defaults to localhost.
00441 """
00442
00443
00444 def connect(self):
00445 """!\brief Connect to the servers.
00446
00447 """
00448
00449
00450
00451 self.connectCVT()
00452 self.populateTlmDb()
00453 self.connectVSC()
00454
00455 def disconnect(self):
00456 """!\brief Disconnect from the servers.
00457
00458 """
00459
00460 pass
00461
00462 def elogWebsite(self):
00463 """!\brief Launch the web browser and point it to the E-Logbook site.
00464
00465 """
00466 import webbrowser
00467 webbrowser.open(url=self.preferences()["elogurl"], new=1)
00468
00469 def EBFdistribution(self):
00470 """!\brief Initialize the data distribution server.
00471
00472 """
00473 if int(self.preferences()["servernbl"]) == 0:
00474 if self.__dds is not None:
00475 self.__dds.disconnect()
00476 log.info("Disconnected from the data distribution server since it was disabled in preferences.")
00477 self.__dds = None
00478 return
00479 dataType = 'LAT_EBFdata'
00480 server = self.preferences()["server"].strip()
00481 if server != '':
00482 try:
00483 import LICOS.core.distributor.DataDistributor as DD
00484 except:
00485 log.error("Can't find DataDistributor module, is it in PYTHONPATH?")
00486 else:
00487 if self.__server is None:
00488 self.__dds = DD.DataDistributorServer(dataType)
00489 try:
00490 self.__dds.connect(server)
00491 log.info("Connected to the data distribution server at %s." % server)
00492
00493 except:
00494 log.warn("Unable to connect to data distribution server %s: serving of %s disabled" % (self.preferences()["server"], dataType))
00495 self.__dds = None
00496 elif server != self.__server:
00497 if self.__dds is not None:
00498 self.__dds.disconnect()
00499 log.info("Disconnected from the data distribution server.")
00500 self.__dds = DD.DataDistributorServer(dataType)
00501 try:
00502 self.__dds.connect(server)
00503 log.info("Reconnected to the data distribution server since the server changed in preferences.")
00504
00505 except:
00506 log.warn("Unable to connect to data distribution server %s: serving of %s disabled" % (self.preferences()["server"], dataType))
00507 self.__dds = None
00508 self.__server = self.preferences()["server"].strip()
00509
00510 def setLoggingLevel(self, logLevel=None):
00511 """!\brief Set the logging level.
00512
00513 \param logLevel Log level.
00514 Can be one of "DEBUG","INFO","WARN","ERROR","CRITICAL"
00515 """
00516 if logLevel is None: logLevel = self.preferences()["loglevel"]
00517
00518
00519 log.getLogger("").setLevel(0)
00520
00521 log.getLogger("").handlers[0].setLevel(eval("log."+logLevel))
00522 for hdlr in log.getLogger("").handlers[1:]:
00523 if hdlr.__class__.__name__ == 'ScriptEngineSocketHandler':
00524 hdlr.setLevel(eval("log."+logLevel))
00525 elif hdlr.__class__.__name__ == 'ErrorLogCounterHandler':
00526 hdlr.setLevel(eval("log.ERROR"))
00527
00528 def startLogger(self, startup=True):
00529 """!\brief Start the logger.
00530
00531 \param startup Are we calling startLogger from startup?
00532 """
00533
00534 log.basicConfig()
00535 loghost = self.preferences()["loghost"]
00536 logport = self.preferences()["logport"]
00537 local = socket.gethostname().lower() == loghost.lower() or socket.gethostbyname(loghost) == '127.0.0.1'
00538 if int(self.preferences()["lognbl"]) == 1:
00539 if local and startup:
00540 if self.MSGLogger is not None:
00541 return
00542 self.MSGLogger = MSGLogGUIImpl(logport)
00543 self.MSGLogger.startListenerThread()
00544 msgPath = self.preferences()["logdir"]
00545
00546 ts = time.strftime('%y%m%d%H%M%S', self.__startGMT)
00547 fileName = "msg" + ts + ".log"
00548
00549 self.preferences()["logfilename"] = fileName
00550 fmt = log.Formatter("%(asctime)s %(filename)s:%(lineno)d %(levelname)-5s - %(message)s")
00551 self.fileHdlr = ScriptEngineFileHandler(os.path.join(msgPath, fileName), "a")
00552 self.fileHdlr.setFormatter(fmt)
00553 log.getLogger("").addHandler(self.fileHdlr)
00554 self.sockHdlr = ScriptEngineSocketHandler(loghost, logport)
00555 self.sockHdlr.setFormatter(fmt)
00556 log.getLogger("").addHandler(self.sockHdlr)
00557 self.errLogCounter = ErrorLogCounterHandler(self)
00558 log.getLogger("").addHandler(self.errLogCounter)
00559 self.setLoggingLevel()
00560 try:
00561 log.info('Trying to connect to the message logger')
00562 except:
00563 log.getLogger("").removeHandler(self.sockHdlr)
00564 log.exception("Can't connect to the message logger, disabling logging to socket")
00565 else:
00566 log.info('Successfully connected to the message logger')
00567 elif self.MSGLogger is not None:
00568 log.info('Disconnecting from the message logger')
00569 if local:
00570 self.MSGLogger.close()
00571 self.MSGLogger = None
00572 log.getLogger("").removeHandler(self.errLogCounter)
00573 log.getLogger("").removeHandler(self.sockHdlr)
00574 log.getLogger("").removeHandler(self.fileHdlr)
00575 log.shutdown()
00576 else:
00577
00578
00579 self.errLogCounter = ErrorLogCounterHandler(self)
00580 log.getLogger("").addHandler(self.errLogCounter)
00581 self.setLoggingLevel()
00582
00583
00584 def stopRunLog(self, fileHdlr):
00585 """!\brief Stop the file log.
00586
00587 \brief fileHdlr Log file handler.
00588 """
00589
00590
00591 fileHdlr.acquire()
00592 log.getLogger("").removeHandler(fileHdlr)
00593 fileHdlr.release()
00594 fileHdlr.close()
00595
00596 def startRunLog(self, fileName):
00597 """!\brief Start the file log.
00598
00599 \brief fileName File name for the log file.
00600 """
00601 fileHdlr = ScriptEngineFileHandler(fileName, "w")
00602 fmt = log.Formatter("%(asctime)s %(filename)s:%(lineno)d %(levelname)-5s - %(message)s")
00603 fileHdlr.setFormatter(fmt)
00604 log.getLogger("").addHandler(fileHdlr)
00605 return fileHdlr
00606
00607 def startLcmLog(self, filename):
00608 self.__lcmFile = file(filename, "w")
00609 self.__vsc.getDiagHandler().register(self.__lcatTlm.getApidsFromNames(['LCMMSGOUTC']), self.__processMsgOut)
00610
00611
00612
00613 self.__lcmLock = threading.Lock()
00614
00615 def stopLcmLog(self):
00616 self.__vsc.getDiagHandler().unregister(self.__lcatTlm.getApidsFromNames(['LCMMSGOUTC']),
00617 self.__processMsgOut)
00618 self.__lcmLock.acquire()
00619 self.__lcmFile.close()
00620 self.__lcmLock.release()
00621
00622 def __processMsgOut(self, telem):
00623 self.__lcmLock.acquire()
00624 if not self.__lcmFile.closed:
00625 pkt = self.__lcatTlm.decodeTelemetry(telem)
00626 msg = self.__lcatTlm.msgOutToText(pkt)
00627 log.debug(msg)
00628 self.__lcmFile.write(msg + '\n')
00629 self.__lcmFile.flush()
00630 self.__lcmLock.release()
00631
00632 def options(self):
00633 """!\brief Retrieve the command line options.
00634
00635 \return Command line options.
00636 """
00637 return self.__options
00638
00639 def prefMan(self):
00640 """!\brief Retrieve the preferences manager.
00641
00642 \return rcPreferencesManager instance
00643 """
00644 return self.__prefMan
00645
00646 def preferences(self):
00647 """!\brief Retrieve the preferences.
00648
00649 \return Preferences instance
00650 """
00651 return self.__prefMan.preferences()
00652
00653 def prefGUI(self):
00654 """!\brief Retrieve the preferences GUI.
00655
00656 \return rcPreferencesGUIImpl instance
00657 """
00658 if self.__prefGUI is None:
00659 self.__prefGUI = rcPreferencesGUIImpl(self)
00660 return self.__prefGUI
00661
00662 def getMSGLogger(self):
00663 """!\brief Retrieve the message logger GUI.
00664
00665 \return MSGLogGUIImpl instance
00666 """
00667 return self.MSGLogger
00668
00669 def getDDS(self):
00670 """!\brief Retrieve the data distributor.
00671
00672 \return DataDistributorServer instance
00673 """
00674 return self.__dds
00675
00676 def getCmdCli(self):
00677 """!\brief Retrieve the Script Engine proxy.
00678
00679 \return seProxy instance
00680 """
00681
00682
00683 return self.__vsc
00684
00685 def getTlmDb(self):
00686 """!\brief Retrieve the telemetry database object.
00687
00688 This object contains EGU conversions for LAT housekeeping telemetry.
00689
00690 \return An ISOC.TlmUtils.TlmRdbInterface.TlmRdbDb instance
00691 """
00692 return self.__tlmDb
00693
00694 def getDBN(self):
00695 """!\brief Retrieve the DBN node.
00696
00697 \return GDBN instance.
00698 """
00699 return self.__dbn
00700
00701 def getSecurityMan(self):
00702 """!\brief Retrieve the security manager.
00703
00704 \return rcSecurityMan instance
00705 """
00706 return self.__securityMan
00707
00708 def getQtApp(self):
00709 """!\brief Retrieve the Qt app.
00710
00711 \return QApplication instance
00712 """
00713 return self.__qApp
00714
00715 def setGUI(self, gui):
00716 """!\brief Set the GUI.
00717
00718 \param gui The GUI widget
00719 """
00720 self.__gui = gui
00721
00722 def getGUI(self):
00723 """!\brief Retrieve the GUI.
00724
00725 \return The GUI widget
00726 """
00727 return self.__gui
00728
00729 def getLoginId(self):
00730 """!\brief Returns the login id for the last successful login
00731
00732 \return User's login id
00733 """
00734 return self.__loginId
00735
00736 def getErrorLogCount(self):
00737 """!\brief Retrueve the error log count for the current run.
00738
00739 \return Error log count
00740 """
00741 return self.__errLogCnt
00742
00743 def incrementErrorLogCount(self):
00744 """!\brief Increment the error log count.
00745
00746 """
00747 self.__errLogCnt += 1
00748
00749 def resetErrorLogCount(self):
00750 """!\brief Reset the error log count.
00751
00752 """
00753 self.__errLogCnt = 0
00754
00755 def showLogin(self, parent):
00756 """!\brief Handle login.
00757
00758 \param parent Parent GUI
00759
00760 \return Authentication result, 0=Successful login,
00761 -1=Authentication failed,
00762 else password database is not accessible.
00763 """
00764 login = rcLoginImpl(parent=parent)
00765 status = login.exec_loop()
00766 if status == login.Accepted:
00767 loginId = str(login.txtLoginId.text()).strip()
00768 password = str(login.txtPassword.text()).strip()
00769 authResult = self.__securityMan.authenticateUser(loginId, password)
00770 if authResult == 0:
00771 self.__loginId = loginId
00772 log.info("User %s successfully logged in" % loginId)
00773 return 1
00774 elif authResult == -1:
00775 log.error("User authentication failed, loginId=%s" % loginId)
00776 return authResult
00777 else:
00778 log.error("Password database is not accessible.")
00779 return authResult
00780 else:
00781 return None
00782
00783 def configureHardware(self):
00784 """!\brief Configure the hardware based on the user selection.
00785
00786 \return Whether the user cancelled or confirmed the selection
00787 """
00788 hwCfgGUI = HwCfgSelectorImpl(self, self.getGUI())
00789 hwCfgGUI.setCaption("Hardware Configuration Selector")
00790 result = hwCfgGUI.exec_loop()
00791 if result:
00792 hwConfig = self.preferences()["hwConfig"]
00793 self.__vsc.siuSelect(getattr(self.__vsc, hwConfig['siuSelect']))
00794 self.__vsc.daqSelect(getattr(self.__vsc, hwConfig['daqSelect']))
00795 if hwConfig['primaryFeed'] == 1:
00796 self.__vsc.monitor(VSC.VscProxy.Primary)
00797 else:
00798 self.__vsc.monitor(VSC.VscProxy.Redundant)
00799 return result
00800
00801 def getLatConfigId(self):
00802 if "hwConfig" in self.preferences():
00803 preset = self.preferences()["hwConfig"]["preset"]
00804 if preset == -1:
00805 return "NON STANDARD"
00806 else:
00807 return preset
00808
00809 def getDiagHandler(self):
00810 """!\brief Retrieve the LAT/VSC diagnostic telemetry handler.
00811
00812 \return seTelemetryHandler instance
00813 """
00814 return self.__vsc.getDiagHandler()
00815
00816 def getTelemHandler(self):
00817 """!\brief Retrieve the LAT/VSC telemetry handler.
00818
00819 \return seTelemetryHandler instance
00820 """
00821 return self.__vsc.getTelemHandler()
00822
00823 def getPidsHandler(self):
00824 """!\brief Retrieve the pids telemetry handler.
00825
00826 \return sePidsHandler instance
00827 """
00828 return self.__vsc.getPidsHandler()