00001 #!/usr/local/bin/python 00002 # 00003 # Copyright 2004 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__ = "Housekeeping trending tester module" 00012 __author__ = "J. Panetta <panetta@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online" 00013 __date__ = "7/20/2004" 00014 __version__ = "$Revision: 1.3 $" 00015 __credits__ = "SLAC" 00016 00017 00018 import LATTE.copyright_SLAC 00019 00020 from LATTE.monitoring.Receiver import * 00021 import logging 00022 import qt 00023 00024 00025 class QtReceiver(qt.QObject,UDPReceiver): 00026 class TrendUpdateEvent(qt.QCustomEvent): 00027 def __init__(self,trendables): 00028 qt.QCustomEvent.__init__(self,qt.QEvent.MaxUser-20) 00029 self.trendables=trendables 00030 def __init__(self,*args): 00031 qt.QObject.__init__(self,*args) 00032 Receiver.__init__(self) 00033 def process(self,trendables): 00034 qt.QApplication.postEvent(self,QtReceiver.TrendUpdateEvent(trendables)) 00035 def customEvent(self,event): 00036 self.emit(qt.PYSIGNAL('TrendUpdate(trendables)'),(event.trendables,)) 00037 00038 class TrendTestGUI(qt.QTextEdit): 00039 def __init__(self,*args): 00040 qt.QTextEdit.__init__(self,*args) 00041 self.setTextFormat(qt.Qt.LogText) 00042 self.setMaxLogLines(1000) 00043 def update(self,trendables): 00044 for t in trendables: 00045 self.append(str(t)) 00046 00047 class TrendTree(qt.QListView): 00048 def __init__(self,*args): 00049 qt.QListView.__init__(self,*args) 00050 self.columns=['Name','Time'] 00051 self.addColumn('Name') 00052 self.addColumn('Time') 00053 self.setRootIsDecorated(1) 00054 self.setResizeMode(qt.QListView.AllColumns) 00055 self.setAllColumnsShowFocus(1) 00056 self.setShowSortIndicator(1) 00057 self.setSelectionMode(qt.QListView.Extended) 00058 self.__dynamic=1 00059 00060 def isDynamic(self): 00061 return self.__dynamic 00062 00063 def setDynamic(self,bool): 00064 self.__dynamic=bool 00065 00066 def addLeaf(self,name): 00067 if not self.findItem(name,0): 00068 bname=self.getBranchName(name) 00069 branch=self.findItem(bname,0) 00070 if not branch: 00071 branch=qt.QListViewItem(self,bname) 00072 leaf=qt.QListViewItem(branch,name) 00073 return leaf 00074 00075 def update(self,trendables): 00076 for t in trendables: 00077 leaf=self.findItem(t.name,0) 00078 if not leaf and self.__dynamic: 00079 leaf=self.addLeaf(t.name) 00080 if leaf: 00081 from time import ctime 00082 leaf.setText(1,ctime(t.time)) 00083 for k in t.content.keys(): 00084 try: 00085 c=self.columns.index(k) 00086 except ValueError, e: 00087 self.addColumn(k) 00088 self.columns.append(k) 00089 c=self.columns.index(k) 00090 leaf.setText(c,str(t.content[k])) 00091 00092 def getBranchName(self,name): 00093 return name.split('_')[0] 00094 00095 00096 class TrendPlotter(qt.QWidget): 00097 def __init__(self,*args): 00098 qt.QWidget.__init__(self,*args) 00099 00100 self.__ntuples={} 00101 self.__plots={} 00102 self.__views={} 00103 self.__defaultDepth=150 00104 self.__defaultLabels=['Time','Counts'] 00105 00106 self.__dynamic=1 00107 00108 self.grid=qt.QGridLayout(self,1,4) 00109 self.grid.setAutoAdd(1) 00110 00111 def isDynamic(self): 00112 return self.__dynamic 00113 def setDynamic(self,bool): 00114 self.__dynamic=bool 00115 00116 def addPlot(self,trendable): 00117 name=trendable.name 00118 labels=self.__defaultLabels 00119 depth=self.__defaultDepth 00120 import sihippo 00121 # Create the Circular buffer to store the data 00122 ntc=sihippo.NTupleController.instance() 00123 nt=ntc.createCircularBuffer(labels) 00124 nt.reserve(depth) 00125 nt.setTitle(name) 00126 nt.setName(name) 00127 # Create the Plot 00128 dc=sihippo.DisplayController.instance() 00129 # plot=dc.createDisplay('XY Plot',nt,labels) 00130 plot=dc.createDisplay('Strip Chart',nt,labels) 00131 view=sihippo.QtViewWidget(self) 00132 view.setPlotter(plot) 00133 view.setDoubleBuffering(1) 00134 view.resize(200,100) 00135 view.setMinimumSize(qt.QSize(100,50)) 00136 #self.grid.addWidget(view) 00137 view.show() 00138 00139 self.__ntuples[name]=nt 00140 self.__plots[name]=plot 00141 self.__views[name]=view 00142 00143 def update(self,trendables): 00144 for t in trendables: 00145 if t.name not in self.__views.keys() and self.__dynamic: 00146 self.addPlot(t) 00147 if t.name not in self.__views.keys(): 00148 return 00149 x=t.time 00150 y=t.content['Raw Value'] 00151 self.__ntuples[t.name].addRow([x,y]) 00152 00153 00154 # This is just a dumb way to control the TrendTree 00155 class FancyTrendTree(qt.QVBox): 00156 def __init__(self,*args): 00157 qt.QVBox.__init__(self,*args) 00158 00159 self.tree=TrendTree(self) 00160 00161 self.menu=qt.QPopupMenu(self) 00162 self.menu.insertItem('Remove Selected',self.removeSelected) 00163 self.menu.insertItem('New Leaf',self.newTrend) 00164 self.menu.insertItem('Toggle Dynamic',self.toggleDynamic) 00165 00166 self.connect(self.tree, 00167 qt.SIGNAL('contextMenuRequested'\ 00168 +'(QListViewItem*,const QPoint&,int)') 00169 ,self.contextMenu) 00170 00171 def toggleDynamic(self): 00172 self.tree.setDynamic(not self.tree.isDynamic()) 00173 00174 def update(self,trendables): 00175 self.tree.update(trendables) 00176 00177 def newTrend(self): 00178 name,ok=qt.QInputDialog.getText('New Leaf', 00179 'Name of new leaf', 00180 qt.QLineEdit.Normal, 00181 '',self) 00182 if ok: 00183 self.tree.addLeaf(str(name)) 00184 00185 00186 def removeSelected(self): 00187 it=qt.QListViewItemIterator(self.tree, 00188 qt.QListViewItemIterator.Selected) 00189 while it.current(): 00190 item=it.current() 00191 if item.parent(): 00192 item.parent().takeItem(item) 00193 else: 00194 self.tree.takeItem(item) 00195 it+=1 00196 00197 def contextMenu(self,item,point,pos): 00198 self.menu.popup(point) 00199 00200 ############################################################### 00201 def testQtReceiver(args): 00202 app=qt.QApplication(args) 00203 00204 logging.basicConfig() 00205 logging.root.setLevel(logging.DEBUG) 00206 00207 r=QtReceiver() 00208 udpServerName='testTrendingServer' 00209 udpServerAddr='54320@239.255.1.14' 00210 r.setUDPClient(udpServerName,udpServerAddr) 00211 00212 # gui=TrendTestGUI() 00213 # gui=TrendTree() 00214 # gui=FancyTrendTree() 00215 gui=TrendPlotter() 00216 gui.connect(r,qt.PYSIGNAL('TrendUpdate(trendables)'),gui.update) 00217 00218 app.connect(app,qt.SIGNAL("lastWindowClosed()"), 00219 app,qt.SLOT("quit()")) 00220 00221 app.setMainWidget(gui) 00222 gui.show() 00223 00224 r.setReceiving(1) 00225 app.exec_loop() 00226 r.shutdown() 00227 00228 def testReceiver(): 00229 logging.basicConfig() 00230 logging.root.setLevel(logging.DEBUG) 00231 00232 udpServerName='testTrendingServer' 00233 udpServerAddr='54320@239.255.1.14' 00234 00235 r=UDPReceiver() 00236 r.setUDPClient(udpServerName,udpServerAddr) 00237 r.setReceiving(1) 00238 from time import sleep 00239 try: 00240 while 1: 00241 sleep(.1) 00242 except Exception, e: 00243 r.shutdown() 00244 00245 if __name__ == '__main__': 00246 import sys 00247 testQtReceiver(sys.argv) 00248 #testReceiver()