TelemMonitorImpl.py

Go to the documentation of this file.
00001 #!/usr/local/bin/python
00002 #
00003 #                               Copyright 2005
00004 #                                     by
00005 #                        The Board of Trustees of the
00006 #                     Leland Stanford Junior University.
00007 #                            All rights reserved.
00008 #
00009 
00010 __facility__ = "Online"
00011 __abstract__ = "Telemetry Monitor"
00012 __author__   = "S. Tuvi <STuvi@SLAC.Stanford.edu>"
00013 __date__     = "2005/09/15 23:45:02"
00014 __updated__  = "$Date: 2006/04/28 01:41:36 $"
00015 __version__  = "$Revision: 1.19 $"
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 from Queue import Queue
00027 import time
00028 import atexit
00029 import threading
00030 from ConfigParser import ConfigParser
00031 
00032 import VSC
00033 
00034 from LICOS.tools.monitor.TelemMonitor         import TelemMonitor
00035 from LICOS.util.gOptions                      import Options
00036 from LICOS.core.thread.taskEngine             import TaskEngine
00037 from LICOS.lib.cmdTlmDb.LCATtlmDb             import LCATtlmDb
00038 from LICOS.core.thread.guiBridges             import GUIbridge
00039 
00040 from LICOS.scriptEngine.ScriptEngineConnector import LicosTelemetryRouter
00041 
00042 from LICOS.tools.proxy.VscProxyTools        import getip
00043 from LICOS.tools.proxy.VscProxyPorts        import VscProxyPorts
00044 from LICOS.scriptEngine.seTelemetryHandler  import seTelemetryHandler
00045 
00046 
00047 
00048 
00049 class TelemMonitorImpl(TelemMonitor):
00050   """!\brief Telemetry monitoring GUI.
00051 
00052   """
00053   def __init__(self, telemHandler=None, parent = None, name = None, fl = 0):
00054     """!\brief TelemMonitorImpl constructor.
00055 
00056     \param parent The parent GUI (typically the Run Control GUI)
00057     \param name   Name of the GUI
00058     \param fl     Qt flags
00059     """
00060     TelemMonitor.__init__(self, None, name, fl | Qt.WGroupLeader)
00061     atexit.register(self.shutdown)
00062     self.__parent = parent
00063     self.textTelem.setMaxLogLines(9999)
00064     self.__telemConsumer = None
00065     self.__telemHandler  = None
00066     self.__guiBridge     = None
00067     self.__verbose       = False
00068     self.__telemHandler = telemHandler
00069     self.initialize()
00070     self.connect(self.buttonClear, SIGNAL("clicked()"), self.clearAction)
00071     self.connect(self.buttonPause, SIGNAL("clicked()"), self.pauseAction)
00072     self.connect(self.buttonVerbose,SIGNAL("toggled(bool)"),self.verboseAction)
00073     self.comboTelemFilter.insertItem(" ")
00074     #self.connect(self.comboTelemFilter, SIGNAL("activated(const QString&)"), self.filterTelemetry)
00075 
00076   def initialize(self):
00077     self.__quit = False
00078     self.__pause = False
00079     self.__lcatTlm = LCATtlmDb()
00080     self.__telemQueue = Queue()
00081     self.__telemConsumer = TaskEngine("TelemMonitorConsumer")
00082     self.__telemConsumer.start()
00083     self.__telemConsumer.spawn(self.consumeTelemPackets)
00084     self.__guiThread = threading.currentThread()
00085     self.__guiBridge = GUIbridge(self.__guiThread)
00086     self.__telemHandler.register(self.__lcatTlm.getApids(), self.process)
00087 
00088 
00089   def process(self, telemetry):
00090     """!\brief Store the incoming telemetry in a queue.
00091 
00092     \param telemetry Raw packet
00093     """
00094     if self.isVisible():
00095       self.__telemQueue.put(telemetry)
00096 
00097   def consumeTelemPackets(self):
00098     """!\brief Main thread loop which consumes packets from the queue.
00099 
00100     """
00101     while not self.__quit:
00102       if self.__telemQueue.empty() or self.__pause:
00103         time.sleep(.1)
00104         continue
00105       self.execGUImethod(self.__updateGUI)
00106 
00107   def __updateGUI(self):
00108     """!\brief Retrieve a packet from the queue and display it on the GUI.
00109 
00110     """
00111     while not self.__telemQueue.empty():
00112       if self.__quit or self.__pause: break
00113       telem = self.__telemQueue.get()
00114       time.sleep(.005)
00115       #msg = "TelemetryHandler called, apid 0x%x " \
00116       #      "at seconds 0x%x useconds 0x%x length %d" % \
00117       #      (telem.apid(), telem.secs(), telem.usecs(), telem.length())
00118       #log.debug(msg)
00119       #self.textTelem.append(msg)
00120       pkt = self.__lcatTlm.decodeTelemetry(telem)
00121       if pkt.name == 'LCMMSGOUTC':
00122         self.textTelem.append(self.__lcatTlm.msgOutToText(pkt))
00123       elif pkt.name == 'CmdConfirm':
00124         statusTuple = self.__lcatTlm.msgByValue(pkt.get_payload("ITC_EXESTATUS"))
00125         if statusTuple is not None:
00126           telemDump = "CVT - %s: %s" % (statusTuple[0], statusTuple[1])
00127         else:
00128           telemDump = "CVT - Unparsable MSG: 0x%08x" % pkt.get_payload("ITC_EXESTATUS")
00129         if self.__verbose:
00130           for (name, value) in self.__lcatTlm.getPayloadData(pkt):
00131             telemDump += "\n  %20s: 0x%x" % (name, value)
00132         self.textTelem.append(telemDump)
00133       else:
00134         if str(self.comboTelemFilter.currentText()) == " " or \
00135            str(self.comboTelemFilter.currentText()) == pkt.name:
00136           telemDump = "Telemetry Name: %s Apid: 0x%04x" % (pkt.name, pkt.apid)
00137           if self.__verbose:
00138             for (name, value) in self.__lcatTlm.getPayloadData(pkt):
00139               telemDump += "\n  %20s: 0x%x" % (name, value)
00140           self.textTelem.append(telemDump)
00141         found = False
00142         for i in range(self.comboTelemFilter.count()):
00143           if pkt.name == str(self.comboTelemFilter.text(i)):
00144             found = True
00145             break
00146         if not found:
00147           self.comboTelemFilter.insertItem(pkt.name)
00148           self.comboTelemFilter.listBox().sort()
00149 
00150   def clearAction(self):
00151     """!\brief Handle Clear button clicked action.
00152 
00153     """
00154     self.textTelem.clear()
00155 
00156   def pauseAction(self):
00157     """!\brief Handle the Pause/Unpause button clicked action.
00158 
00159     """
00160     if self.buttonPause.text() == "Pause":
00161       self.__pause = True
00162       self.buttonPause.setText("Unpause")
00163       if self.__telemHandler is not None:
00164         self.__telemHandler.unregister(self.__lcatTlm.getApids(), self.process)
00165     else:
00166       self.__pause = False
00167       self.buttonPause.setText("Pause")
00168       if self.__telemHandler is not None:
00169         self.__telemHandler.register(self.__lcatTlm.getApids(), self.process)
00170 
00171   def verboseAction(self, on):
00172     """!\brief Handle the Verbose button toggle action.
00173 
00174     \param on Toggle is on
00175 
00176     """
00177     if on:
00178       self.__verbose = True
00179     else:
00180       self.__verbose = False
00181 
00182   def shutdown(self):
00183     """!\brief Shutdown the monitor.
00184 
00185     """
00186     self.__quit = True
00187     if self.__telemConsumer is not None:
00188       self.__telemConsumer.shutdown()
00189     apids = self.__lcatTlm.getApids()
00190     if self.__telemHandler is not None and self.__telemHandler.isregistered(apids, self.process):
00191       self.__telemHandler.unregister(apids, self.process)
00192     if self.__guiBridge is not None:
00193       self.__guiBridge.shutdown()
00194 
00195   def customEvent(self, e):
00196     """This method overrides the QObject base class's.  There is generally
00197     no reason to call this method directly.  It is called by the Qt
00198     infrastructure whenever the custom event is posted, e.g. by the following
00199     three methods of this class: createGUI, execGUImethodNR and execGUImethod.
00200     """
00201     self.__guiBridge.handleCustomEvent(e)
00202 
00203   def execGUImethodNR(self, func, *args, **kwargs):
00204     """Method used for executing a GUI function from a non-GUI thread.
00205     Use this method when no (useful) response is expected or
00206     when waiting for one could cause a deadlock.  Any response from the
00207     function is lost."""
00208     if self.__quit: return # Don't try to update the GUI during shutdown
00209 
00210     return self.__guiBridge.execGUImethodNR(self, func, *args, **kwargs)
00211 
00212   def execGUImethod(self, func, *args, **kwargs):
00213     """Method used for executing a GUI function from a non-GUI thread.
00214     Use this method when a response is expected from the function and
00215     when it is appropriate to wait for it (no deadlock arises)"""
00216     if self.__quit: return # Don't try to update the GUI during shutdown
00217 
00218     return self.__guiBridge.execGUImethod(self, func, *args, **kwargs)
00219 
00220 def usage():
00221   """!\brief Output command line usage.
00222 
00223   """
00224   return """
00225 
00226 TelemMonitorImpl Usage:
00227 
00228 Mandatory options:
00229 --proxyHost Specify the proxy host
00230 --type Specify the telemetry type ("telemetry" or "diagnostic")
00231 --vscConfig Specify the VSC configuration file path
00232 
00233 Example:
00234 $ TelemMonitorImpl --proxyHost localhost --type telemetry --vscConfig vsc.cfg
00235 
00236 """
00237 
00238 if __name__ == "__main__":
00239   log.getLogger().setLevel(log.INFO)
00240   options = Options(['proxyHost','type','vscConfig'])
00241   try:
00242     options.parse()
00243   except Exception, msg:
00244     options.usage(usage())
00245     raise Exception, msg
00246 
00247   a = QApplication(sys.argv)
00248   vscConfig = ConfigParser()
00249   vscConfig.read(options.vscConfig)
00250   ports = VscProxyPorts(vscConfig.getint('vsc', 'proxyPortBase'))
00251   if options.type == "telemetry":
00252     port = ports.telemMon()
00253   else:
00254     port = ports.diagMon()
00255   #handler = createHandler(options.host, port)
00256   apidRangeList = ([0x000, 0xfff],)
00257   ip_tel = getip(options.proxyHost)
00258   tele = VSC.VscProxy.Proxy(ip_tel, port)
00259   telemHandler = seTelemetryHandler(apidRangeList)
00260   vscRouter   = LicosTelemetryRouter(telemHandler)
00261   latRouter   = LicosTelemetryRouter(telemHandler)
00262   if options.type == "telemetry":
00263     tele.vscTelemetry(vscRouter)
00264     tele.latTelemetry(latRouter)
00265   else:
00266     tele.vscDiagnostic(vscRouter)
00267     tele.latDiagnostic(latRouter)
00268   dm = TelemMonitorImpl(telemHandler)
00269   if options.type == "telemetry":
00270     dm.setCaption("Telemetry Monitor (standalone)")
00271   else:
00272     dm.setCaption("Diagnostic Telemetry Monitor (standalone)")
00273   a.setMainWidget(dm)
00274   dm.show()
00275   a.exec_loop()
00276 

Generated on Thu Apr 27 20:52:44 2006 for LICOS L02-01-00 by doxygen 1.4.6-NO