예제 #1
0
class SardanaMacro(CommandObject, SardanaObject):

    macroStatusAttr = None
    INIT, STARTED, RUNNING, DONE = range(4)

    def __init__(self, name, macro, doorname=None, username=None, **kwargs):
        super(SardanaMacro, self).__init__(name, username, **kwargs)

        self._reply_arrived_event = Event()
        self.macro_format = macro
        self.doorname = doorname
        self.door = None
        self.init_device()
        self.macrostate = SardanaMacro.INIT
        self.doorstate = None
        self.t0 = 0

    def init_device(self):
        self.door = Device(self.doorname)
        self.door.set_timeout_millis(10000)

        #
        # DIRTY FIX to make compatible taurus listeners and existence of Tango channels/commands
        # as defined in Command/Tango.py
        #
        # if self.door.__class__ == taurus.core.tango.tangodevice.TangoDevice:
        #    dp = self.door.getHWObj()
        #    try:
        #        dp.subscribe_event = dp._subscribe_event
        #    except AttributeError:
        #        pass

        if self.macroStatusAttr is None:
            self.macroStatusAttr = self.door.getAttribute("State")
            self.macroStatusAttr.addListener(self.objectListener)

    def __call__(self, *args, **kwargs):

        self._reply_arrived_event.clear()
        self.result = None

        wait = kwargs.get("wait", False)

        if self.door is None:
            self.init_device()

        logging.getLogger("HWR").debug("Executing sardana macro: %s" %
                                       self.macro_format)
        logging.getLogger("HWR").debug("   args=%s / kwargs=%s" %
                                       (str(args), str(kwargs)))

        try:
            fullcmd = self.macro_format + " " + " ".join(
                [str(a) for a in args])
        except BaseException:
            import traceback

            logging.getLogger("HWR").info(traceback.format_exc())
            logging.getLogger("HWR").info(
                "  - Wrong format for macro arguments. Macro is %s / args are (%s)"
                % (self.macro_format, str(args)))
            return

        try:
            import time

            self.t0 = time.time()
            if self.doorstate in ["ON", "ALARM"]:
                self.door.runMacro(fullcmd.split())
                self.macrostate = SardanaMacro.STARTED
                self.emit("commandBeginWaitReply", (str(self.name()), ))
            else:
                logging.getLogger("HWR").error(
                    "%s. Cannot execute. Door is not READY", str(self.name()))
                self.emit("commandFailed", (-1, self.name()))
        except TypeError:
            logging.getLogger("HWR").error(
                "%s. Cannot properly format macro code. Format is: %s, args are %s",
                str(self.name()),
                self.macro_format,
                str(args),
            )
            self.emit("commandFailed", (-1, self.name()))
        except DevFailed as error_dict:
            logging.getLogger("HWR").error("%s: Cannot run macro. %s",
                                           str(self.name()), error_dict)
            self.emit("commandFailed", (-1, self.name()))
        except AttributeError as error_dict:
            logging.getLogger("HWR").error("%s: MacroServer not running?, %s",
                                           str(self.name()), error_dict)
            self.emit("commandFailed", (-1, self.name()))
        except BaseException:
            logging.getLogger("HWR").exception(
                "%s: an error occured when calling Tango command %s",
                str(self.name()),
                self.macro_format,
            )
            self.emit("commandFailed", (-1, self.name()))

        if wait:
            logging.getLogger("HWR").debug("... start waiting...")
            t = gevent.spawn(endOfMacro, self)
            t.get()
            logging.getLogger("HWR").debug("... end waiting...")

        return

    def update(self, event):
        data = event.event[2]

        try:
            if not isinstance(data, PyTango.DeviceAttribute):
                # Events different than a value changed on attribute.  Taurus sends an event with attribute info
                # logging.getLogger('HWR').debug("==========. Got an event, but it is not an attribute . it is %s" % type(data))
                # logging.getLogger('HWR').debug("doorstate event. type is %s" % str(type(data)))
                return

            # Handling macro state changed event
            doorstate = str(data.value)
            logging.getLogger("HWR").debug("doorstate changed. it is %s" %
                                           str(doorstate))

            if doorstate != self.doorstate:
                self.doorstate = doorstate

                # logging.getLogger('HWR').debug("self.doorstate is %s" % self.canExecute())
                self.emit("commandCanExecute", (self.canExecute(), ))

                if doorstate in ["ON", "ALARM"]:
                    # logging.getLogger('HWR').debug("Macroserver ready for commands")
                    self.emit("commandReady", ())
                else:
                    # logging.getLogger('HWR').debug("Macroserver busy ")
                    self.emit("commandNotReady", ())

            if self.macrostate == SardanaMacro.STARTED and doorstate == "RUNNING":
                # logging.getLogger('HWR').debug("Macro server is running")
                self.macrostate = SardanaMacro.RUNNING
            elif self.macrostate == SardanaMacro.RUNNING and (doorstate in [
                    "ON", "ALARM"
            ]):
                logging.getLogger("HWR").debug("Macro execution finished")
                self.macrostate = SardanaMacro.DONE
                self.result = self.door.result
                self.emit("commandReplyArrived",
                          (self.result, str(self.name())))
                if doorstate == "ALARM":
                    self.emit("commandAborted", (str(self.name()), ))
                self._reply_arrived_event.set()
            elif (self.macrostate == SardanaMacro.DONE
                  or self.macrostate == SardanaMacro.INIT):
                # already handled in the general case above
                pass
            else:
                logging.getLogger("HWR").debug("Macroserver state changed")
                self.emit("commandFailed", (-1, str(self.name())))
        except ConnectionFailed:
            logging.getLogger("HWR").debug("Cannot connect to door %s" %
                                           self.doorname)
            self.emit("commandFailed", (-1, str(self.name())))
        except BaseException:
            import traceback

            logging.getLogger("HWR").debug(
                "SardanaMacro / event handling problem. Uggh. %s" %
                traceback.format_exc())
            self.emit("commandFailed", (-1, str(self.name())))

    def abort(self):
        if self.door is not None:
            logging.getLogger("HWR").debug("SardanaMacro / aborting macro")
            self.door.abortMacro()
            # self.emit('commandReady', ())

    def isConnected(self):
        return self.door is not None

    def canExecute(self):
        return self.door is not None and (self.doorstate in ["ON", "ALARM"])
예제 #2
0
class SardanaMacro(CommandObject, SardanaObject):

    macroStatusAttr = None
    INIT, STARTED, RUNNING, DONE = list(range(4))

    def __init__(self, name, macro, doorname = None, username = None, **kwargs):
        super(SardanaMacro,self).__init__(name,username,**kwargs)

        self._reply_arrived_event = Event()
        self.macro_format = macro   
        self.doorname = doorname  
        self.door = None
        self.init_device()
        self.macrostate = SardanaMacro.INIT
        self.doorstate = None
        self.t0 = 0
      
    def init_device(self): 
        self.door = Device(self.doorname)
        self.door.set_timeout_millis(10000)

        # 
        # DIRTY FIX to make compatible taurus listeners and existence of Tango channels/commands
        # as defined in Command/Tango.py
        # 
        #if self.door.__class__ == taurus.core.tango.tangodevice.TangoDevice:
        #    dp = self.door.getHWObj()
        #    try:
        #        dp.subscribe_event = dp._subscribe_event
        #    except AttributeError:
        #        pass

        if self.macroStatusAttr == None:
            self.macroStatusAttr = self.door.getAttribute("State")
            self.macroStatusAttr.addListener(self.objectListener)

    def __call__(self, *args, **kwargs):

        self._reply_arrived_event.clear()
        self.result = None

        wait = kwargs.get('wait', False)

        if self.door is None:
            self.init_device()

        logging.getLogger('HWR').debug("Executing sardana macro: %s" % self.macro_format)
        
        try:
            fullcmd = self.macro_format % args 
        except:
            logging.getLogger('HWR').info("  - Wrong format for macro arguments. Macro is %s / args are (%s)" % (self.macro_format, str(args)))
            return
   
        try:
            import time
            self.t0 = time.time()
            if (self.doorstate in ["ON","ALARM"]):
                self.door.runMacro( (fullcmd).split()  )
                self.macrostate = SardanaMacro.STARTED
                self.emit('commandBeginWaitReply', (str(self.name()), ))
            else:
                logging.getLogger('HWR').error("%s. Cannot execute. Door is not READY", str(self.name()) )
                self.emit('commandFailed', (-1, self.name()))
        except TypeError:
            logging.getLogger('HWR').error("%s. Cannot properly format macro code. Format is: %s, args are %s", str(self.name()), self.macro_format, str(args)) 
            self.emit('commandFailed', (-1, self.name()))
        except DevFailed as error_dict:
            logging.getLogger('HWR').error("%s: Cannot run macro. %s", str(self.name()), error_dict) 
            self.emit('commandFailed', (-1, self.name()))
        except AttributeError as error_dict:
            logging.getLogger('HWR').error("%s: MacroServer not running?, %s", str(self.name()), error_dict) 
            self.emit('commandFailed', (-1, self.name()))
        except:
            logging.getLogger('HWR').exception("%s: an error occured when calling Tango command %s", str(self.name()), self.macro_format)
            self.emit('commandFailed', (-1, self.name()))

        if wait:
            logging.getLogger('HWR').debug("... start waiting...")
            t=gevent.spawn(endOfMacro, self)
            t.get()
            logging.getLogger('HWR').debug("... end waiting...")

        return 

    def update(self, event):
        data = event.event[2]

        try:
            if type(data) != PyTango.DeviceAttribute:
                  # Events different than a value changed on attribute.  Taurus sends an event with attribute info
                  # logging.getLogger('HWR').debug("==========. Got an event, but it is not an attribute . it is %s" % type(data))
                  logging.getLogger('HWR').debug("doorstate event. type is %s" % str(type(data)))
                  return

            # Handling macro state changed event
            doorstate = str(data.value)
            logging.getLogger('HWR').debug("doorstate changed. it is %s" % str(doorstate))

            if doorstate != self.doorstate:
                self.doorstate = doorstate

                # logging.getLogger('HWR').debug("self.doorstate is %s" % self.canExecute())
                self.emit('commandCanExecute', (self.canExecute(),))

                if (doorstate in ["ON","ALARM"]):
                    # logging.getLogger('HWR').debug("Macroserver ready for commands")
                    self.emit('commandReady', ())
                else:
                    # logging.getLogger('HWR').debug("Macroserver busy ")
                    self.emit('commandNotReady', ())
            
            if self.macrostate == SardanaMacro.STARTED and doorstate == "RUNNING":
                # logging.getLogger('HWR').debug("Macro server is running")
                self.macrostate = SardanaMacro.RUNNING
            elif self.macrostate == SardanaMacro.RUNNING and (doorstate in ["ON", "ALARM"]):
                logging.getLogger('HWR').debug("Macro execution finished")
                self.macrostate = SardanaMacro.DONE
                self.result = self.door.result
                self.emit('commandReplyArrived', (self.result, str(self.name())))
                if doorstate == "ALARM":
                    self.emit('commandAborted', (str(self.name()), ))
                self._reply_arrived_event.set()
            elif self.macrostate == SardanaMacro.DONE or self.macrostate == SardanaMacro.INIT:
                # already handled in the general case above
                pass
            else:
                logging.getLogger('HWR').debug("Macroserver state changed")
                self.emit('commandFailed', (-1, str(self.name())))
        except ConnectionFailed:
            logging.getLogger('HWR').debug("Cannot connect to door %s" % self.doorname)
            self.emit('commandFailed', (-1, str(self.name())))
        except:
            import traceback
            logging.getLogger('HWR').debug("SardanaMacro / event handling problem. Uggh. %s" % traceback.format_exc())
            self.emit('commandFailed', (-1, str(self.name())))

    def abort(self):
        if self.door is not None:
            logging.getLogger('HWR').debug("SardanaMacro / aborting macro")
            self.door.abortMacro()
            #self.emit('commandReady', ())
        
    def isConnected(self):
        return self.door is not None

    def canExecute(self):
        return self.door is not None and ( self.doorstate in ["ON", "ALARM"] )