AlarmStates.py

Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 #
00003 #                               Copyright 2006
00004 #                                     by
00005 #                        The Board of Trustees of the
00006 #                     Leland Stanford Junior University.
00007 #                            All rights reserved.
00008 #
00009 #
00010 
00011 __facility__ = "Online"
00012 __abstract__ = "Classes for determining alarm states"
00013 __author__   = "J. Panetta <panetta@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online"
00014 __date__     = "12/29/2005" # Created
00015 __updated__  = ("$Date: 2006/04/28 01:20:18 $").split(' ')[1]
00016 __version__  = "$Revision: 1.3 $"
00017 __release__  = "$Name: HEAD $"
00018 __credits__  = "SLAC"
00019 
00020 import LICOS.copyright_SLAC
00021 
00022 from ISOC.TlmUtils.TlmInterface      import LimitState
00023 
00024 
00025 class AlarmState(LimitState):
00026   """!\brief Settable limit state class
00027   """
00028   def __init__(self, state=LimitState.NoLimit):
00029     """!\brief AlarmState constructor
00030 
00031     \param  state  Starting state.  Default: LimitState.Unknown
00032     """
00033     LimitState.__init__(self)
00034 
00035     if state is not None:
00036       self.__setState(state)
00037     else:
00038       self.__state = self.Unknown
00039 
00040   def setState(self, newState):
00041     """!\brief Set the current state
00042 
00043     \param newState   A LimitState member or an integer
00044 
00045     \return  Can throw an exception if newState isn't allowed.
00046     """
00047     self.__setState(newState)
00048 
00049   def stateEnum(self):
00050     """!\brief return the current integer state value
00051 
00052     \return  Integer state value
00053     """
00054     return self.__state
00055 
00056   def state(self):
00057     """!\brief Return a string defining the current state
00058 
00059     \return String state value
00060     """
00061     return self.stateName(self.__state)
00062 
00063   def __setState(self, newState):
00064     if isinstance(newState, AlarmState):
00065       self.__state = newState.__state
00066     elif type(newState) == type(LimitState.NoLimit) and \
00067              self.stateName(newState) is not None:
00068       self.__state = newState
00069     else:
00070       raise RuntimeError("Attempt to set an invalid state: %s" % newState)
00071 
00072   def __cmp__(self, state):
00073     """!\brief Comparison operator.  Allows state1 < state2
00074     """
00075     return cmp(self.__state, state.__state)
00076 
00077 
00078 
00079 class AlarmedItem(object):
00080   """!\brief Basic hierarchical state item
00081   """
00082 
00083   def __init__(self, parent=None, state = AlarmState.Unknown):
00084     """!\brief AlarmedItem constructor
00085 
00086     \param parent   Item's parent.  Default: None (No Parent)
00087     \param state    Item's starting state.  Default: AlarmState.Unknown
00088     """
00089 
00090     self.__parent      = parent
00091     if self.__parent is not None and type(self.__parent) == type(self):
00092       self.__parent.newChild(self)
00093 
00094     if state is not None:
00095       self.__state = AlarmState(state)
00096     else:
00097       self.__state = AlarmState()  # defaults to Unknown
00098 
00099     self.__children    = []
00100     self.__enabled     = True
00101 
00102   def parent(self):
00103     """!\brief return the parent AlarmedItem
00104 
00105     \return An AlarmedItem object, or None
00106     """
00107     if type(self.__parent) == type(self):
00108       return self.__parent
00109     else:
00110       return None
00111 
00112   def state(self):
00113     """!\brief return the state of this object
00114 
00115     \return An AlarmState object
00116     """
00117     return self.__state
00118 
00119   def children(self):
00120     """!\brief return the children of this object
00121 
00122     \return a List of AlarmedItem objects
00123     """
00124     # Note, JHP:  override this method when using QListView objects
00125     return self.__children
00126 
00127   def newChild(self, child):
00128     """!\brief Add a child to the set of this object children
00129 
00130     \param child
00131     """
00132     if child not in self.__children:
00133       self.__children.append(child)
00134 
00135   def isEnabled(self):
00136     """!\brief Is this item enabled?
00137 
00138     \return boolean
00139     """
00140     return self.__enabled
00141 
00142   def enable(self, enableChildren=True):
00143     """!\brief Enable alarms on this object and all its children
00144 
00145     \param enableChildren  Enable the children also (Default: True)
00146     """
00147     self.__enabled = True
00148     self.setState(self.__state)
00149     if enableChildren:
00150       self.iterateChildren( self.__class__.enable, enableChildren )
00151 
00152   def disable(self, disableChildren=True):
00153     """!\brief Disable alarms on this object and all its children
00154 
00155     \param disableChildren  Disable the children also (Default: True)
00156     """
00157     self.__enabled = False
00158     self.setState(self.__state)
00159     if disableChildren:
00160       self.iterateChildren( self.__class__.disable, disableChildren )
00161 
00162   def iterateChildren(self, callback, *args):
00163     """!\brief iterate over the children of this method, calling a function on each
00164 
00165     \param callback  A method
00166     \param *args     Arguments to be used for *each* callback
00167     """
00168     if self.children() is None:
00169       return None
00170     if args == ():
00171       return map( callback, self.children() )
00172     else:
00173       return map( callback, self.children(), args*len(self.children()) )
00174 
00175   def setState(self, state , forceUpdate = False):
00176     """!\brief Set the state of the current object and propogate to parent if need be
00177 
00178     \param state  Either an integer or an AlarmState object
00179     """
00180     oldState = self.__state
00181     # set the current state
00182     self.__state = AlarmState(state)
00183     # propogate to parent.  Check types because we can be in qlistview.
00184 
00185     parent = self.__parent
00186     if (parent is not None and \
00187       oldState != self.__state )\
00188       or forceUpdate:
00189       while parent is not None:
00190         try:
00191           psNow = parent.state()
00192           psRec = parent.childStateSum()
00193       # set parent's state new state is worse.
00194           if psRec != psNow:
00195             parent.setState(psRec)
00196           parent = parent.__parent
00197         except:
00198           break
00199 
00200   def childStateSum(self):
00201     """!\brief Recalculate this object's state from its children
00202 
00203     """
00204     # If I have children, calculate the worstState from them. Else use mine.
00205     worstState = min(AlarmState(AlarmState.InLimits),self.state())
00206     if self.children() == []:
00207       if self.isEnabled():
00208         worstState = self.state()
00209     else:
00210       if self.isEnabled():
00211         # Only look at child states if parent state is not disabled
00212         for state in self.iterateChildren( self.__class__.childStateSum ):
00213           if state > worstState:
00214             worstState = state
00215     return worstState
00216 
00217 
00218 if __name__ == '__main__':
00219 
00220   # regression test to make sure that inheritance works.
00221   a = AlarmedItem(state=0)
00222   print 'a:',a,dir(a)
00223 
00224   b = [ AlarmedItem(a,state=0), AlarmedItem(a,state=0) ]
00225   print 'b:', b
00226 
00227   c = [ AlarmedItem(b[0],state=0), AlarmedItem(b[1],state=0) ]
00228 
00229   print 'c:',c
00230 
00231   print 'a.state():',a.state(), dir(a.state())
00232 
00233   print a.state().state(),\
00234         map(AlarmState.state, map(AlarmedItem.state, b)), \
00235         map(AlarmState.state, map(AlarmedItem.state, c))
00236 
00237 
00238   a.setState(AlarmState.HiRed)
00239 #  c[0].setState(AlarmState.HiRed)
00240 #  b[1].setState(AlarmState.HiRed)
00241 
00242   print a.state().state(),\
00243         map(AlarmState.state, map(AlarmedItem.state, b)), \
00244         map(AlarmState.state, map(AlarmedItem.state, c))
00245 
00246 
00247   a.setState(AlarmState.InLimits)
00248 #  c[0].setState(AlarmState.InLimits)
00249 
00250   print a.state().state(),\
00251         map(AlarmState.state, map(AlarmedItem.state, b)), \
00252         map(AlarmState.state, map(AlarmedItem.state, c))
00253 

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