00001
00002
00003
00004
00005
00006
00007
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"
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()
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
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
00182 self.__state = AlarmState(state)
00183
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
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
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
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
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
00240
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
00249
00250 print a.state().state(),\
00251 map(AlarmState.state, map(AlarmedItem.state, b)), \
00252 map(AlarmState.state, map(AlarmedItem.state, c))
00253