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"])
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"] )