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

gRule.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__ = "Classes for defining rules"
00012 __author__   = "R. Claus <Claus@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online"
00013 __date__     = ("$Date: 2005/02/04 18:27:04 $").split(' ')[1]
00014 __version__  = "$Revision: 2.4 $"
00015 __credits__  = "SLAC"
00016 
00017 import LATTE.copyright_SLAC
00018 
00019 
00020 import               gGroup
00021 import logging as    log
00022 import LATTE.dispatch.dispatcher as dispatcher
00023 
00024 class GruleBase(object):
00025   """\brief Base rule class for use when no rule is appropriate.
00026 
00027   """
00028   def __init__(self):
00029     pass
00030   def evaluate(self, value, attr, node=None):
00031     pass
00032 
00033 
00034 class Grule(GruleBase):
00035   """\brief Base class for describing rules.
00036 
00037   """
00038   def __init__(self, name, subsystem, category, enabled, continuous = False):
00039     """Constructor.
00040       \param name       Rule name
00041       \param subsystem  Subsystem gGroup to which the rule belongs
00042       \param category   Category gGroup to which the rule belongs
00043       \param enabled    Flag indicating whether rule is enabled
00044       \param continuous Flag indicating whether rule can fire repeatedly
00045 
00046     """
00047     self.__name       = name
00048     self.__subsystem  = subsystem
00049     self.__category   = category
00050     self.__enabled    = enabled
00051     self.__continuous = continuous
00052     self.__fired      = {}  # A dict of node:bool pairs indicating if a partic node has fired.
00053     self.__actions    = {}
00054     # init self.__fired
00055     self.__fired[None]= False
00056 
00057   def _eval_(self, value, attr, node):
00058     """Base method called from derived classes.  
00059     determine whether or not this rule can fire or not.
00060 
00061     \return a tuple containing the value of the test and whether the rule can fire or not.
00062     """
00063     key = (node, attr)
00064     # print "baseEval: ", self.__continuous, self.__fired.has_key(key)
00065     
00066     if ( (self.__continuous) or\
00067          (not self.__fired.has_key(key)) or\
00068          (not self.__continuous and not self.__fired[key]) ):
00069       return (value, True)
00070     else:
00071       return (value, False)
00072 
00073   def evaluate(self, value, attr, node=None):
00074     """This method is called to evaluate the rule on 'value'
00075 
00076     \param value Value to be evaluated.
00077     \param attr  Attribute object whose \a value is being evaluated.
00078 
00079     \return Result of the evaluation, if any.
00080 
00081     """
00082     if self.__subsystem.enabled() and \
00083        self.__category.enabled()  and \
00084        self.__enabled:
00085       return self._eval_(value, attr, node)
00086     else:
00087       return (value, False)
00088 
00089   def name(self):
00090     """Method to retrieve the rule's name
00091 
00092     \return Rule's name.
00093 
00094     """
00095     return self.__name
00096 
00097   def subsystem(self):
00098     """Method for discovering this rule's subsystem
00099 
00100     \return Rule's subsystem.
00101 
00102     """
00103     return self.__subsystem
00104 
00105   def category(self):
00106     """Method for discovering this rule's category
00107 
00108     \return Rule's category.
00109 
00110     """
00111     return self.__category
00112 
00113   def enabled(self):
00114     """Method for discovering whether this rule is enabled
00115 
00116     \return Whether this rule is enabled or not.
00117 
00118     """
00119     return self.__enabled
00120 
00121   def enable(self):
00122     """Method used to enable evaluation of this rule
00123 
00124     """
00125     self.__enabled = True
00126 
00127   def disable(self):
00128     """Method used to disable evaluation of this rule
00129 
00130     """
00131     self.__enabled = False
00132 
00133   def reset(self, node=None):
00134     """Method used to reenable evaluation of this rule in the case of
00135     noncontinuous mode after it has been violated
00136 
00137     """
00138     self.__fired[node] = False
00139   
00140   def fire(self, node=None):
00141     """Method used to tell the rule it has fired
00142     """
00143     self.__fired[node] = True
00144   
00145   def fired(self, node=None):
00146     """Method for discovering whether this rule has fired
00147     
00148     \return Whether this rule has fired or not
00149     """
00150     if node not in self.__fired:
00151       return False
00152     else:
00153       return self.__fired[node]
00154 
00155   def registerAction(self, action, method, sender=dispatcher.Any):
00156     """Associate and action with a user \a method, optionally specifying a \a sender.
00157     If a \a sender is not specified, the rule \a action may be fired for all registers
00158     which declare its rule to be the rule of this \a action. If an attribute is
00159     specified as the \a sender then only if the evaluation of that specific attribute
00160     causes the \a action to be fired the \a method will be called.
00161 
00162     \param action A string that represents the action to be taken.
00163                   This is specified under the <actions> tag in the schema/configuration.
00164     \param method A user method visible to the current context.
00165     \param sender Optional parameter that specifies the sender of the action registration.
00166                   If specifed, only the sendAction requests which specify the same sender
00167                   will be honored. Defaults to dispatcher.Any.
00168 
00169     """
00170     if action not in self.__actions:
00171       log.error("Unable to register action %s, not specified in the configuration." % action)
00172     else:
00173       dispatcher.connect(method, signal=action, sender=sender)
00174 
00175   def setActions(self, actions):
00176     """Convenience method that gets called from the rule constructor
00177     that defines the action names (which is read from the schema/configuration).
00178 
00179     \param actions A list containing the action names.
00180 
00181     """
00182     self.__actions = actions
00183 
00184   def sendAction(self, action, sender, *arguments, **named):
00185     """Called from the rule evaluation method to fire the appropriate alarm action.
00186 
00187     \param action     A string that represents the action to be taken.
00188                       This is specified under the <actions> tag in the schema/configuration.
00189     \param sender     The sender that made the rule firing request. This is usually the
00190                       attribute which is being evaluated.
00191     \param *arguments An optional list of arguments which gets passed to the action method.
00192 
00193     \return A list of tuple pairs [(receiver, response), ... ]
00194     """
00195     return dispatcher.send(action, sender, *arguments, **named)
00196 
00197   def clearAllActions(self):
00198     """
00199     Forces all registered actions to be cleared.
00200     If this is not done and the scripts re-register their
00201     actions there may be extraneous rule action firings.
00202     """
00203     dispatcher.connections = {}
00204 
00205   def unregisterAction(self, action, method, sender=dispatcher.Any):
00206     """Reverse of registerAction, disassociates the action from the method.
00207 
00208    \param action A string that represents the action to be taken.
00209                   This is specified under the <actions> tag in the schema/configuration.
00210     \param method A user method visible to the current context.
00211     \param sender Optional parameter that specifies the sender of the action registration.
00212                   If specifed, only the sendAction requests which specify the same sender
00213                   will be honored. Defaults to dispatcher.Any.
00214     """
00215     dispatcher.disconnect(method, action, sender)
00216 
00217 class GruleLimit(Grule):
00218   """\brief Rule class that limits a passed in value to given limits.
00219 
00220   """
00221   def __init__(self, name, subsystem, category, enabled, continuous,
00222                low, high):
00223     """Limit rule constructor.
00224 
00225       \param name             Rule name
00226       \param subsystem        Subsystem gGroup to which the rule belongs
00227       \param category         Category gGroup to which the rule belongs
00228       \param enabled          Flag indicating whether rule is enabled
00229       \param continuous       Flag indicating whether rule can fire repeatedly
00230       \param low              Low limit
00231       \param high             High limit
00232 
00233     """
00234     Grule.__init__(self, name, subsystem, category, enabled, continuous)
00235     self.__low  = low
00236     self.__high = high
00237 
00238   def _eval_(self, value, attr, node):
00239     """Evaluate the rule.
00240     """
00241     if   value < self.__low:
00242       log.warning("%s rule: value is below low limit"  % self.name())
00243     elif value > self.__high:
00244       log.warning("%s rule: value is above high limit" % self.name())
00245 
00246 class GruleAlarms(Grule):
00247   """\brief Alarm rule
00248 
00249   If the value falls below the yellow or red lower limit or it exceeds
00250   the yellow or red upped limit the appropriate registered action is
00251   fired.
00252   """
00253   def __init__(self, name, subsystem, category, enabled, continuous,
00254                yellowUpperLimit, yellowLowerLimit,
00255                redUpperLimit, redLowerLimit, actions=[]):
00256     """Alarm rule constructor.
00257 
00258       \param name             Rule name
00259       \param subsystem        Subsystem gGroup to which the rule belongs
00260       \param category         Category gGroup to which the rule belongs
00261       \param enabled          Flag indicating whether rule is enabled
00262       \param continuous       Flag indicating whether rule can fire repeatedly
00263       \param yellowUpperLimit Yellow alarm upper limit
00264       \param yellowLowerLimit Yellow alarm lower limit
00265       \param redUpperLimit    Red alarm upper limit
00266       \param redLowerLimit    Red alarm lower limit
00267     """
00268 
00269     Grule.__init__(self, name, subsystem, category, enabled, continuous)
00270     self.__yellowLowerLimit = yellowLowerLimit
00271     self.__yellowUpperLimit = yellowUpperLimit
00272     self.__redLowerLimit = redLowerLimit
00273     self.__redUpperLimit = redUpperLimit
00274     self.setActions(actions)
00275 
00276   def _eval_(self, value, attr, node):
00277     """Alarm rule evaluation method.
00278 
00279     If the red alarm is fired then the yellow alarm does not get fired.
00280     """
00281     action = None
00282     key = (node, attr)
00283     if value < self.__redLowerLimit or value > self.__redUpperLimit:
00284       action = "redAction"
00285     elif value < self.__yellowLowerLimit or value > self.__yellowUpperLimit:
00286       action = "yellowAction"
00287     else:
00288       self.reset(key)
00289     temp, canFire = Grule._eval_(self, value, attr, node)
00290     if action is not None and canFire:
00291       self.fire(key)
00292       self.sendAction(action, attr, value, node=node)
00293 
00294 

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