CurrValTable.py

Go to the documentation of this file.
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__ = "Current Value Table"
00012 __author__  = "Jim Panetta <panetta@slac.stanford.edu> SLAC - GLAST LAT I&T/Online"
00013 __date__     = ("$Date: 2006/03/19 00:04:42 $").split(' ')[1]
00014 __version__ = "$Revision: 1.8 $"
00015 __release__  = "$Name: HEAD $"
00016 __credits__ = "SLAC"
00017 
00018 import LICOS.copyright_SLAC
00019 
00020 import time
00021 import cPickle as pickle
00022 import struct
00023 
00024 # encode into: name, raw, flags, age: 16byte, ulong, ushort, double : 16sLHd
00025 CV_STRUCT_FMT = "!16sLHd"
00026 
00027 
00028 class CurrentValueBase(object):
00029   """!\brief CurrentValue class
00030   """
00031   FLAG_STALE          = 0x0001
00032   FLAG_ALARM_RED      = 0x1000
00033   FLAG_ALARM_YEL      = 0x2000
00034   FLAG_ALARM_DISABLED = 0x8000
00035   
00036   
00037   def __init__(self, name=None, raw=None, flags=0x0, age=0):
00038     self.clear()
00039     self.name    = name
00040     self.__raw   = raw
00041     self.__flags = flags
00042     self.__age   = age
00043     
00044   def rawValue(self):
00045     """!\brief rawValue
00046     
00047     \return observable's  value in raw (machine) units
00048     """
00049     return self.__raw
00050     
00051   def age(self):
00052     """!\brief 
00053     """
00054     return self.__age
00055     
00056   def flags(self):
00057     """!\brief 
00058     """
00059     return self.__flags
00060   
00061   def setFlags(self, flags):
00062     """!\brief
00063     """
00064     self.__flags |= flags
00065   
00066   def unsetFlags(self, flags):
00067     """!\brief
00068     """
00069     self.__flags &= ~flags
00070     
00071   def update(self, raw, aTime):
00072     """!\brief 
00073     """
00074     self.__raw = raw
00075     self.__age = aTime
00076     self.__flags &= ~self.FLAG_STALE
00077     
00078   def clear(self):
00079     """!\brief 
00080     """
00081     self.__raw = 0
00082     self.__age = None
00083   
00084 class CurrentValue(CurrentValueBase):
00085   def __init__(self):
00086     super(CurrentValue,self).__init__()
00087     self.observers = []
00088     
00089   def addObserver(self, observer):
00090     """!\brief 
00091     """
00092     if observer not in self.observers:
00093       self.observers.append(observer)
00094     
00095   def delObserver(self, observer):
00096     """!\brief 
00097     """
00098     if observer in self.observers:
00099       # log.debug( "removing observer " + str(observer) + " from value " + self.name )
00100       self.observers.remove(observer)
00101   
00102   def nObservers(self):
00103     """!\brief 
00104     """
00105     return len(self.observers)
00106   
00107   def update(self, raw, aTime):
00108     super(CurrentValue,self).update(raw,aTime)
00109     self.__post()
00110 
00111   def __post(self):
00112     """!\brief 
00113     """
00114     for obs in self.observers:
00115       obs.update(self)
00116 
00117 
00118 class CurrentValueTable(object):
00119   POOL_SIZE = 1000
00120   
00121   def __init__(self):
00122     
00123     # internal dictionary
00124     self.__cvt = {}
00125   
00126     self.__cvtPool = []
00127     self.__allocatePool()
00128     self.__lastUpdate = 0
00129     
00130   def fullTable(self):
00131     return self.__cvt
00132     
00133   def getValue(self, mnemonic, age=None):
00134     """!\brief 
00135     """
00136     if mnemonic not in self.__cvt:
00137       return None
00138   
00139     if age != None:
00140       # if age == None, get most recent, 
00141       #   otherwise require (now - age) <= object.age
00142       #   otherwise block until timeout or new data is available
00143       now = time.time()
00144       if (now - self.__cvt[mnemonic].age()) <= age:
00145         return self.__cvt[mnemonic]
00146     
00147       pass
00148       
00149       
00150     return self.__cvt[mnemonic]
00151   
00152   def hasValue(self, mnemonic):
00153     """!\brief 
00154     """
00155     return (mnemonic in self.__cvt)
00156     
00157   def setValue(self, mnemonic, value, aTime):
00158     """!\brief 
00159     """
00160     #passthrough for now.  Maybe otherwise?
00161     if mnemonic not in self.__cvt:
00162       self.__cvt[mnemonic] = self.__getPoolObject()
00163       self.__cvt[mnemonic].name = mnemonic
00164     self.__cvt[mnemonic].update(value, aTime)
00165     self.__lastUpdate = aTime
00166     
00167   def lastUpdate(self):
00168     return self.__lastUpdate
00169     
00170   def clearOldValues(self, maxAge):
00171     """!\brief 
00172     """
00173     # if value.age > maxAge, return value to pool/
00174     
00175     now = time.time()
00176     
00177     for mnem in self.__cvt:
00178       if (now - self.__cvt[mnem].age()) > maxAge:
00179         # If there are active observers, don't do this.
00180         self.__cvtPool.append(self.__cvt[mnem])
00181         self.__cvt[mnem] = None
00182     
00183     pass
00184     
00185   def removeObserver(self, observer):
00186     for val in self.__cvt.values():
00187       val.delObserver(observer)
00188     
00189   def __getPoolObject(self):
00190     # return one from the pool, if there's anything in the 
00191     # pool.  Deal with empty pool
00192     
00193     if len(self.__cvtPool) == 0:
00194       self.__allocatePool()    
00195     return self.__cvtPool.pop()
00196     
00197   def __allocatePool(self):
00198     # Allocate a new block of value objects into the pool
00199     for i in range(CurrentValueTable.POOL_SIZE):
00200       self.__cvtPool.append(CurrentValue())  
00201     
00202 def encodeCurrentValue(cv):
00203   # cv is a subclass of CurrentValueBase
00204 
00205   encoded = pickle.dumps( (cv.name, cv.rawValue(), cv.flags(), cv.age()), 2)
00206   
00207   return encoded
00208 
00209 def decodeCurrentValue(decode):
00210 
00211   p = pickle.loads(decode)
00212   if p is not None:
00213     name, raw, flags, age = p
00214     cv = CurrentValueBase(name, raw, flags, age)
00215   else:
00216     print "Received null object from current value table at %s" % time.asctime()
00217     cv = None
00218   
00219   return cv
00220 
00221 
00222 if __name__ == '__main__':
00223 
00224   pass
00225 
00226 
00227 
00228 
00229 
00230 
00231 
00232 
00233 
00234 
00235 #eof

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