Main Page | Packages | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | Related Pages

rcStatusMonitor.py

00001 #!/usr/local/bin/python
00002 #
00003 #                               Copyright 2002
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__ = "Status Monitor for Run Control"
00012 __author__   = "Selim Tuvi <stuvi@slac.stanford.edu> SLAC - GLAST I&T/Online"
00013 __date__     = ("$Date: 2005/10/26 01:57:29 $").split(' ')[1]
00014 __version__  = "$Revision: 2.11 $"
00015 __release__  = "$Name: R04-12-00 $"
00016 __credits__  = "SLAC"
00017 
00018 import LATTE.copyright_SLAC
00019 
00020 
00021 from qt import *
00022 import logging as log
00023 
00024 class ListViewToolTip(QToolTip):
00025   def __init__(self, view, column, truncatedOnly=0):
00026     QToolTip.__init__(self, view.viewport())
00027     self.__view = view
00028     self.__col  = column
00029 
00030   def maybeTip(self, pos):
00031     item = self.__view.itemAt(pos)
00032     if item is not None:
00033       #if self.__view.header().sectionSize(self.__col) >= \
00034       #    item.width(self.__view.fontMetrics(), self.__view, self.__col):
00035       #  return
00036       cp = self.__view.viewportToContents(pos)
00037       tipString = item.text(self.__col)
00038       cr = self.__view.itemRect(item)
00039       headerPos = self.__view.header().sectionPos(self.__col)
00040       cr.setLeft(headerPos)
00041       cr.setRight(headerPos + self.__view.header().sectionSize(self.__col))
00042       self.tip(cr, tipString)
00043 
00044 class StatusItem(QListViewItem):
00045   def __init__(self, *args):
00046     QListViewItem.__init__(self, *args)
00047     self.alarmExpr = None
00048 
00049   def paintCell(self, p, cg, column, width, align):
00050     g = QColorGroup(cg)
00051     g.setColor( QColorGroup.Base, Qt.white)
00052     g.setColor( QColorGroup.Foreground, Qt.black)
00053     if self.alarmExpr is not None:
00054       # If alarm expr starts with '@' then treat the monitored
00055       # value as a string in the expression.
00056       if self.alarmExpr.startswith("@"):
        expr = "'"+str(self.text(1))+"'" + self.alarmExpr[1:]
00057       else:
00058         expr = str(self.text(1)) + self.alarmExpr
00059       try:
00060         if eval(expr):
00061           g.setColor( QColorGroup.Text, Qt.red)
00062         else:
00063           g.setColor( QColorGroup.Text, Qt.black)
00064       except:
00065         log.exception("Error evaluating expression \"%s\"" % expr)
00066 
00067 
00068     # Do the standard painting
00069     QListViewItem.paintCell(self,p,g,column,width,align)
00070 
00071     p.setPen( QPen( cg.dark(), 1 ) )
00072     p.drawLine( 0, self.height() - 1, width, self.height() - 1 )
00073     p.drawLine( width - 1, 0, width - 1, self.height() )
00074 
00075   def setText(self, column, value):
00076     QListViewItem.setText(self, column, value)
00077 
00078   def setAlarmExpr(self, alarmExpr):
00079     self.alarmExpr = alarmExpr
00080 
00081 
00082 class WatchItem(object):
00083   def __init__(self, accessor, key, label, alarmExpr, offBoard):
00084     self.__accessor = accessor
00085     self.__statusItem = None
00086     self.__key = key
00087     self.__label = label
00088     self.__alarmExpr = alarmExpr
00089     self.__inView = 0
00090     self.__offBoard = offBoard
00091 
00092   def evaluate(self):
00093     if self.__key is not None:
00094       if self.__accessor.has_key(self.__key):
00095         return self.__accessor[self.__key]
00096       else:
00097         return 'N/A'
00098     else:
00099       val = self.__accessor()
00100       if val is None:
00101         return 'N/A'
00102       else:
00103         return val
00104 
00105   def getLabel(self):
00106     return self.__label
00107 
00108   def getAlarmExpr(self):
00109     return self.__alarmExpr
00110 
00111   def getStatusItem(self):
00112     return self.__statusItem
00113 
00114   def setStatusItem(self, si):
00115     self.__statusItem = si
00116 
00117   def isInView(self):
00118     return self.__inView
00119 
00120   def setInView(self):
00121     self.__inView = 1
00122 
00123   def setAccessor(self, accessor, key):
00124     self.__accessor = accessor
00125     self.__key      = key
00126 
00127   def isOffBoard(self):
00128     return self.__offBoard
00129 
00130 class rcStatusPanel(QWidget):
00131   def __init__(self,parent = None,name = None,fl = 0):
00132     QWidget.__init__(self,parent,name,fl)
00133 
00134     self.contextMenu = QPopupMenu( self )
00135     self.contextMenu.insertItem( "&Copy", self.copyToClipboard, Qt.CTRL+Qt.Key_C)
00136 
00137     self.clip = QApplication.clipboard()
00138 
00139     if not name:
00140       self.setName("rcStatusPanel")
00141 
00142 
00143     rcStatusPanelLayout = QGridLayout(self,1,1,0,6,"rcStatusPanelLayout")
00144 
00145     self.statusView = QListView(self,"statusView")
00146     self.statusView.addColumn(self.tr("Data"))
00147     self.statusView.addColumn(self.tr("Value"))
00148     self.statusView.setAllColumnsShowFocus(1)
00149     self.statusViewTip = ListViewToolTip(view=self.statusView, column=1,
00150                                          truncatedOnly=1)
00151 
00152     rcStatusPanelLayout.addWidget(self.statusView,0,0)
00153 
00154     QObject.connect(self.statusView,
00155                     SIGNAL("contextMenuRequested(QListViewItem*,const QPoint&,int)"),
00156                     self.contextMenuShow
00157                    )
00158 
00159   def contextMenuShow(self, item, point, column):
00160     self.selectedItem = item
00161     self.contextMenu.exec_loop(point)
00162 
00163   def copyToClipboard(self):
00164     if self.statusView.selectedItem() is not None:
00165       self.clip.setText(self.statusView.selectedItem().text(1))
00166 
00167 
00168 class rcStatusMonitor(object):
00169   def __init__(self, interval, gui=None):
00170     self.__interval = interval
00171     self.__gui = gui
00172     self.__watchList = {}
00173     self.__labelSeq = []
00174     self.__timer = QTimer(gui)
00175     self.__lastItem = None
00176     QObject.connect(self.__timer, SIGNAL("timeout()"), self.updateWatchItems)
00177 
00178   def startWatch(self):
00179     if not self.__timer.isActive():
00180       self.__timer.start(self.__interval)
00181 
00182   def stopWatch(self):
00183     if self.__timer.isActive():
00184       self.__timer.stop()
00185 
00186   def addWatchItem(self, label, accessor, key=None, alarmExpr=None, offBoard=False):
00187     if not self.__watchList.has_key(label):
00188       self.__watchList[label] = WatchItem(accessor, key, label, alarmExpr, offBoard)
00189       self.__labelSeq.append(label)
00190     else:
00191       self.__watchList[label].setAccessor(accessor, key)
00192 
00193   def updateWatchItems(self):
00194     for label in self.__labelSeq:
00195       wi = self.__watchList[label]
00196       if self.__gui is None:
00197         print label, wi.evaluate()
00198       else:
00199         if not wi.isInView():
00200           if self.__lastItem is None:
00201             si = StatusItem(self.__gui.statusView, label)
00202           else:
00203             si = StatusItem(self.__gui.statusView, self.__lastItem, label)
00204           si.setAlarmExpr(wi.getAlarmExpr())
00205           self.__lastItem = si
00206           wi.setStatusItem(si)
00207           wi.setInView()
00208         else:
00209           si = wi.getStatusItem()
00210         app = self.__gui.getApp()
00211         fsm = self.__gui.getFSM()
00212         evaluateOffBoard = True
00213         if app is not None and fsm is not None:
00214           if fsm.current_state == 'RESET':
00215             evaluateOffBoard = False
00216         if evaluateOffBoard or not wi.isOffBoard():
00217           si.setText(1, str(wi.evaluate()))
00218         else:
00219           si.setAlarmExpr(None)
00220 
00221 
00222 
00223 #~ if __name__ == '__main__':
00224 
00225   #~ from random import random
00226   #~ import sys
00227   #~ from RunControlMainGUIImpl import *
00228   #~ from RunControlCommon import *
00229 
00230   #~ class Dummy(object):
00231     #~ def __init__(self):
00232       #~ pass
00233 
00234     #~ def getValue(self):
00235       #~ return random()
00236 
00237   #~ app = QApplication(sys.argv)
00238 
00239   #~ rcCommon = RunControlCommon()
00240 
00241   #~ gui = RunControlMainGUIImpl(rcCommon)
00242 
00243   #~ #statMon = rcStatusMonitor(1000)
00244   #~ statMon = rcStatusMonitor(1000, gui)
00245   #~ dummy = Dummy()
00246   #~ statMon.addWatchItem('TestValue', dummy.getValue)
00247   #~ statMon.startWatch()
00248   #~ app.setMainWidget(gui)
00249   #~ gui.show()
00250   #~ app.exec_loop()
00251 
00252 
00253 

Generated on Fri Jul 21 13:26:31 2006 for LATTE R04-12-00 by doxygen 1.4.3