def test_alarm_propagation(self): device_name = '%s/sub1/1' % self.DOMAIN_NAME members_template = ['%s/capability/sub1cap1', '%s/capability/sub1cap2'] members = [member % self.DOMAIN_NAME for member in members_template] self.add_members(device_name, 'tiles', members) dp = DeviceProxy(device_name) self.assertNotEqual(dp.state(), AttrQuality.ATTR_ALARM) member_dp = DeviceProxy(members[0]) alarm_data = json.dumps({ 'name': 'an_attr', 'min_alarm': '20', 'max_alarm': '50' }) member_dp.command_inout('set_attribute_alarm', alarm_data) member_dp.an_attr = 10 attr = AttributeProxy(members[0] + '/an_attr') self.assertEqual(attr.read().quality, AttrQuality.ATTR_ALARM) self.assertEqual(member_dp.state(), PyTango._PyTango.DevState.ALARM) i = 0 while (dp.state() != PyTango._PyTango.DevState.ALARM) and i < 3: sleep(1) i += 1 self.assertEqual(dp.state(), PyTango._PyTango.DevState.ALARM)
def make_test(self, attr=None): """ Performs a full test of the tango server device If the attribute is given - trying to read it as well :param attr: :return: """ #@TODO : test database res = True try: d = DeviceProxy(self.device) self.debug("Device ({}) ping value ({})".format( self.device, d.ping())) state = d.state() if state == DevState.FAULT or state == DevState.UNKNOWN: raise DevFailed if self.testString(attr): v = d.read_attribute(attr) except (DevFailed, AttributeError) as e: res = False return res
def read_attributes(self, attrs): """ Reads attribute value, returns none in case of na error :param attr: :return: """ res = [] try: if not self.test(self.device): raise ValueError d = DeviceProxy(self.device) d.ping() self.debug("Device ({}) is online".format(self.device)) state = d.state() values = None # read value only if the state is fine if state != DevState.FAULT and state != DevState.UNKNOWN: values = d.read_attributes(attrs) for value in values: res.append(value.value) self.debug("Attributes value ({}/{}/{})".format(state, attrs, res)) except DevFailed: self.error( "There is an error with access to the device ({})".format( self.device)) except ValueError: self.error("User has not provided a valid device name") return res
def run(self): """ Starts a process :return: """ self.debug("Starting a door command ({}, {})".format( self.door, self.args)) info, error, output = "", "", "" try: # connect to the door, run macro d = DeviceProxy(self.door) state = d.state() d.RunMacro(self.args) state = d.state() while (True): time.sleep(0.2) if state == DevState.ON or state == DevState.ALARM: break state = d.state() output = d.read_attribute("output").value info = d.read_attribute("info").value error = d.read_attribute("error").value except (DevFailed, AttributeError) as e: output = "Door connection error ({})".format(self.door) self.error(output) self.debug( "Received information from the door \nOutput: {}\nInfo: {}\nError: {}" .format(output, info, error)) if output is None: output = [] if info is None: info = [] if error is None: error = [] if self.bresponse: self.emitter.emitSignal(output, info, error)
def run(self): """ Starts a process :return: """ self.debug("Starting a pytango runner ({}/{}/{})".format( self.device, self.attr, self.value)) try: d = DeviceProxy(self.device) d.ping() state = d.state() if state == DevState.FAULT: raise DevFailed d.write_attribute(self.attr, self.value) except DevFailed: self.error("Error with the pytango runner ({}/{}/{})".format( self.device, self.attr, self.value))
class TangoResolutionComplex(BaseHardwareObjects.Equipment): # resoState = { # None: 'unknown', # 'UNKNOWN': 'unknown', # 'CLOSE': 'closed', # 'OPEN': 'opened', # 'MOVING': 'moving', # 'FAULT': 'fault', # 'DISABLE': 'disabled', # 'OFF': 'fault', # 'ON': 'unknown' # } stateDict = { "UNKNOWN": 0, "OFF": 1, "ALARM": 1, "STANDBY": 2, "RUNNING": 4, "MOVING": 4, "2": 2, "1": 1} def _init(self): self.currentResolution = None self.currentDistance = None self.currentWavelength = None self.currentEnergy = None self.connect("equipmentReady", self.equipmentReady) self.connect("equipmentNotReady", self.equipmentNotReady) #self.device = SimpleDevice(self.getProperty("tangoname"), waitMoves = False, verbose=False) self.device = DeviceProxy(self.getProperty("tangoname")) #self.device.timeout = 3000 # Setting timeout to 3 sec #self.monodevice = SimpleDevice(self.getProperty("tangoname2"), waitMoves = False, verbose=False) hobj = self.getProperty("BLEnergy") logging.getLogger("HWR").debug('TangoResolution: load specify the %s hardware object' % hobj) self.blenergyHO = None if hobj is not None: try: self.blenergyHO=HardwareRepository.HardwareRepository().getHardwareObject(hobj) except: logging.getLogger("HWR").error('TangoResolutionComplex: BLEnergy is not defined in resolution equipment %s', str(self.name())) if self.blenergyHO is not None: #self.connect(self.blenergyHO, "energyChanged",self.energyChanged) self.blenergyHO.connect("energyChanged",self.energyChanged) else: logging.info('TANGORESOLUTION : BLENERGY is not defined in TangoResolution equipment %s', str(self.name())) #self.connect(self.blenergyHO,, "energyChanged",self.energyChanged) #self.connect(self.beam_info_hwobj, # "beamPosChanged", # self.beam_position_changed) #self.blenergyHO.connectSignal('energyChanged', self.energyChanged) # creer un chanel sur l'energy: pour faire un update positChan = self.getChannelObject("position") # utile seulement si statechan n'est pas defini dans le code positChan.connectSignal("update", self.positionChanged) stateChan = self.getChannelObject("state") # utile seulement si statechan n'est pas defini dans le code stateChan.connectSignal("update", self.stateChanged) self.currentDistance = self.device.position self.currentEnergy = self.blenergyHO.getCurrentEnergy() self.currentWavelength = self.blenergyHO.getCurrentWavelength() return BaseHardwareObjects.Equipment._init(self) def init(self): #self.detm = self.getDeviceByRole("detm") #self.dtox = self.getDeviceByRole("dtox") #self.dist2res = self.getCommandObject("dist2res") #self.res2dist = self.getCommandObject("res2dist") self.__resLimitsCallback = None self.__resLimitsErrCallback = None self.__resLimits = {} #self.connect(self.device, "stateChanged", self.detmStateChanged) #self.dist2res.connectSignal("commandReplyArrived", self.newResolution) #self.res2dist.connectSignal("commandReplyArrived", self.newDistance) def positionChanged(self, value): res = self.dist2res(value) try: logging.getLogger("HWR").debug("%s: TangoResolution.positionChanged: %.3f", self.name(), res) except: logging.getLogger("HWR").error("%s: TangoResolution not responding, %s", self.name(), '') self.emit('positionChanged', (res,)) def getState(self): return TangoResolutionComplex.stateDict[str(self.device.State())] def equipmentReady(self): self.emit("deviceReady") def equipmentNotReady(self): self.emit("deviceNotReady") def get_value(self): return self.getPosition() def getPosition(self): #if self.currentResolution is None: self.recalculateResolution() return self.currentResolution def energyChanged(self, energy,wave=None): #logging.getLogger("HWR").debug(" %s energychanged : %.3f wave is %.3f", self.name(), energy,wave) if self.currentEnergy is None: self.currentEnergy = energy if type(energy) is not float: logging.getLogger("HWR").error("%s: TangoResolution Energy not a float: %s", energy, '') return if abs(self.currentEnergy - energy) > 0.0002: self.currentEnergy = energy # self.blenergyHO.getCurrentEnergy() self.wavelengthChanged(self.blenergyHO.getCurrentWavelength()) def wavelengthChanged(self, wavelength): self.currentWavelength = wavelength self.recalculateResolution() def recalculateResolution(self): self.currentDistance = self.device.position self.currentResolution = self.dist2res(self.currentDistance) if self.currentResolution is None: return self.newResolution(self.currentResolution) def newResolution(self, res): if self.currentResolution is None: self.currentResolution = self.recalculateResolution() logging.getLogger().info("new resolution = %.3f" % res) self.currentResolution = res self.emit("positionChanged", (res, )) def connectNotify(self, signal): #logging.getLogger("HWR").debug("%s: TangoResolution.connectNotify, : %s", \ # self.name(), signal) if signal == "stateChanged": self.stateChanged(self.getState()) #elif signal == 'limitsChanged': # self.motorLimitsChanged() elif signal == 'positionChanged': self.positionChanged(self.device.position) # self.setIsReady(True) def stateChanged(self, state): #logging.getLogger("HWR").debug("%s: TangoResolution.stateChanged: %s"\ # % (self.name(), state)) try: self.emit('stateChanged', (TangoResolutionComplex.stateDict[str(state)], )) except KeyError: self.emit('stateChanged', (TangoResolutionComplex.stateDict['UNKNOWN'], )) #ms 2015-03-26 trying to get rid of the fatal error with connection to detector ts motor def getLimits(self, callback=None, error_callback=None): #low, high = self.device.getLimits("position") # MS 18.09.2012 adapted for use without SimpleDevice position_info = self.device.attribute_query("position") low = float(position_info.min_value) high = float(position_info.max_value) logging.getLogger("HWR").debug("%s: DetectorDistance.getLimits: [%.2f - %.2f]"\ % (self.name(), low, high)) if callable(callback): self.__resLimitsCallback = callback self.__resLimitsErrCallback = error_callback self.__resLimits = {} rlow = self.dist2res(low, callback=self.__resLowLimitCallback, \ error_callback=self.__resLimitsErrCallback) rhigh = self.dist2res(high, callback=self.__resHighLimitCallback,\ error_callback=self.__resLimitsErrCallback) else: #rlow, rhigh = map(self.dist2res, self.device.getLimits("position")) # MS 18.09.2012 adapted for use without SimpleDevice #rhigh = self.device.attribute_query("positon").max_value rlow = self.dist2res(low) rhigh = self.dist2res(high) #position_info = self.device.attribute_query("position") #rlow = float(position_info.min_value) #rhigh = float(position_info.max_value) logging.getLogger("HWR").debug("%s: TangoResolution.getLimits: [%.3f - %.3f]"\ % (self.name(), rlow, rhigh)) return (rlow, rhigh) def isSpecConnected(self): #logging.getLogger().debug("%s: TangoResolution.isSpecConnected()" % self.name()) return True def __resLowLimitCallback(self, rlow): self.__resLimits["low"]=float(rlow) if len(self.__resLimits) == 2: if callable(self.__resLimitsCallback): self.__resLimitsCallback((self.__resLimits["low"], self.__resLimits["high"])) self.__resLimitsCallback = None self.__dist2resA1 = None self.__dist2resA2 = None def __resHighLimitCallback(self, rhigh): self.__resLimits["high"]=float(rhigh) if len(self.__resLimits) == 2: if callable(self.__resLimitsCallback): self.__resLimitsCallback((self.__resLimits["low"], self.__resLimits["high"])) self.__resLimitsCallback = None self.__dist2resA1 = None self.__dist2resA2 = None def __resLimitsErrCallback(self): if callable(self.__resLimitsErrCallback): self.__resLimitsErrCallback() self.__resLimitsErrCallback = None self.__dist2resA1 = None self.__dist2resA2 = None def move(self, res, mindist=114, maxdist=1000): self.currentWavelength = self.blenergyHO.getCurrentWavelength() distance = self.res2dist(res) if distance >= mindist and distance <= maxdist: self.device.position = distance elif distance < mindist: logging.getLogger("user_level_log").warning("TangoResolution: requested resolution is above limit for specified energy, moving to maximum allowed resolution") self.device.position = mindist elif distance > maxdist: logging.getLogger("user_level_log").warning("TangoResolution: requested resolution is below limit for specified energy, moving to minimum allowed resolution") self.device.position = maxdist def newDistance(self, dist): self.device.position = dist def motorIsMoving(self): return self.device.state().name in ['MOVING', 'RUNNING'] def stop(self): try: self.device.Stop() except: logging.getLogger("HWR").err("%s: TangoResolution.stop: error while trying to stop!", self.name()) pass def dist2res(self, Distance, callback=None, error_callback=None): #Distance = float(Distance)# MS 2015-03-26 moving statement inside try loop try: Distance = float(Distance) #Wavelength = self.monodevice._SimpleDevice__DevProxy.read_attribute("lambda").value if self.currentWavelength is None: self.currentWavelength = self.blenergyHO.getCurrentWavelength() thetaangle2 = math.atan(DETECTOR_DIAMETER/2./Distance) Resolution = 0.5*self.currentWavelength /math.sin(thetaangle2/2.) if callable(callback): callback(Resolution) return Resolution except: if callable(error_callback): error_callback() def dist2resWaveLenght(self,wavelength, Distance, callback=None, error_callback=None): #Distance = float(Distance)# MS 2015-03-26 moving statement inside try loop try: #Distance = Distance #Wavelength = self.monodevice._SimpleDevice__DevProxy.read_attribute("lambda").value thetaangle2 = math.atan(DETECTOR_DIAMETER/2./Distance) Resolution = 0.5*wavelength /math.sin(thetaangle2/2.) if callable(callback): callback(Resolution) return Resolution except: if callable(error_callback): error_callback() def res2dist(self, Resolution): #print "********* In res2dist with ", Resolution Resolution = float(Resolution) #Wavelength = self.monodevice._SimpleDevice__DevProxy.read_attribute("lambda").value if self.currentWavelength is None: self.currentWavelength = self.blenergyHO.getCurrentWavelength() thetaangle=math.asin(self.currentWavelength / 2. / Resolution) Distance=DETECTOR_DIAMETER/2./math.tan(2.*thetaangle) #print "********* Distance ", Distance return Distance
class TangoDevice(object): """ Wrapper for basic Tango device. It provides registering device, halting device and executing commands """ POLL_STATE_TIME = 0.5 TEST_MODE = False def __init__(self, devicePath=None): """ Class constructor @type devicePath: String """ self.devicePath = devicePath self.maxValue = False self.minValue = False self.name = "Generic device" self.output = {} self.profiling = False self.deviceError = False self.defaultClass = self.__class__ # state change marker self._bstate_changed = False self.old_state = None self.__thread = None try: self.__device_init() except: logging.error( str("Device %s could not be connected" % self.devicePath)) self.name = self.devicePath if config.DEVICE_ALLOW_RETRY: self._retry_device() #raise Exception(str("Device %s could not be connected" % self.devicePath)) # logging.error(str("Device %s could not be connected" % self.devicePath)) #else: #raise Exception(str("Device %s could not be connected" % self.devicePath)) def __postInit__(self): pass def __device_init(self): self.device = DeviceProxy(self.devicePath) info = self.device.import_info() self.name = info.name if (self.name in DEVICE_NAMES): self.name = DEVICE_NAMES[self.name] self.deviceError = False self.__postInit__() def _retry_device(self, callback=None): self.deviceError = True thread = Thread(target=self.__retry_routine, args=([callback])) threads.add_thread(thread) thread.start() self.__class__ = DummyDevice def __retry_routine(self, callback): retrySleep = [True] while (retrySleep[0] and threads.THREAD_KEEP_ALIVE): try: DeviceProxy(self.devicePath).state() logging.error("Device online: %s" % (self.devicePath)) retrySleep = [False] except: logging.error("Device offline, retrying: %s" % (self.devicePath)) threads.thread_sleep(config.DEVICE_RETRY_INTERVAL, sleepFlags=retrySleep) if threads.THREAD_KEEP_ALIVE == True: self.__class__ = self.defaultClass self.__device_init() if callback: callback() return True def isDeviceError(self): return self.deviceError def halt(self, callBack=None): """ Stop device """ pass def running_remove(self, *args): """ Remove device from all running devices set """ try: if (not stopDevices): runningDevices.remove(self) except: pass def running_add(self): """ Add device to all runing devices set """ global runningDevices runningDevices.add(self) def is_connected(self): """ Return true if device is connected @rtype: bool """ if self.device is None: return False else: return True def read_attributes(self, attributes): try: return self.device.read_attributes(attributes) except: logging.error("Device read attribute error: retrying device") if not config.DEVICE_ALLOW_RETRY: raise Exception( str("Device %s could not be connected" % self.devicePath)) else: self._retry_device() return self.read_attributes(attributes) def read_attribute(self, attribute): try: return self.device.read_attribute(attribute) except: if not config.DEVICE_ALLOW_RETRY: raise Exception( str("Device %s could not be connected" % self.devicePath)) else: self._retry_device() return self.read_attribute(attribute) def write_attributes(self, attributes): """ Write attribute to device @type attributes: list @rtype: String """ res = None if self.device: for attribute in attributes: logging.info("Attribute: %s wrote on device: %s", attribute[0], self.devicePath) try: self.device.state() res = self.device.write_attributes(attributes) except (DevFailed, AttributeError) as e: pass return res def write_attributes_async(self, attributes, callback=None): res = None if self.device: for attribute in attributes: logging.info("Attribute: %s wrote on device: %s", attribute[0], self.devicePath) try: self.device.state() res = self.device.write_attributes_asynch(attributes, callback) except (DevFailed, AttributeError) as e: pass return res def execute_command(self, commandName, commandParam=None): """ Execute command on device @type commandName: String @type commandParam: String @rtype: String """ try: if self.device: return self.device.command_inout(commandName, commandParam) except: if not config.DEVICE_ALLOW_RETRY: raise Exception( str("Device %s could not be connected" % self.devicePath)) else: self._retry_device() return self.execute_command(commandName, commandParam) def wait_for_state(self, state, callback=None): """ Wait for state @type state: DevState.state """ if self.device: while (self.device.state() == state): sleep(self.POLL_STATE_TIME) if not (callback is None): callback(self) def wait_seconds(self, duration=1): """ Wait for a time duration @type duration: float if not config.DEVICE_ALLOW_RETRY: raise Exception(str("Device %s could not be connected" % self.devicePath)) else: self._retry_device() return self.execute_command(commandName, commandParam) """ if self.device: sleep(duration) def poll(self, commandName, duration=0.1, commandResult=True, callback=None, commandParam=None): """ Poll device with command @type commandName: String @type duration: float @type callback: fun @type commandParam: String """ while (self.execute_command(commandName, commandParam) == commandResult and threads.THREAD_KEEP_ALIVE): self.wait_seconds(duration) if not (callback is None): callback(self) def poll_attribute(self, attrName, duration=0.1, attributeResult=True, callback=None, commandParam=None): """ Poll device with command @type attrName: String @type duration: float @type callback: fun @type commandParam: String """ while (self.read_attribute(attrName).value == attributeResult and threads.THREAD_KEEP_ALIVE): self.wait_seconds(duration) if not (callback is None): callback(self) def check_idle(self): """ Check if device id idle """ pass def is_idle(self): """ Return True if is idle, False if not and None if unknown """ return None def start_profiling(self): if self.profiling: return False self.profiling = True logging.info("Profiling of device %s started" % self.devicePath) return True def stop_profiling(self): self.profiling = False self.cleanup_thread() def current_value(self, value): return self.read_attribute(value).value def __profiling_routine(self): pass @property def thread(self): return self.__thread def start_external_profiling(self, func): """ Starts profiling with an external function """ self.profiling = True if self.__thread is None: thread = threads.threading.Thread(target=func, args=([self])) threads.add_thread(thread) thread.start() self.__thread = thread def cleanup_thread(self): if self.__thread is not None: self.profiling = False threads.join_thread(self.__thread) self.__thread = None def state(self): """ Overload of the state function to keep track of old states :return: """ state = None try: state = DeviceProxy(self.devicePath).state() self._bstate_changed = False if state != self.old_state: self.old_state = state self._bstate_changed = True except DevFailed: pass return state def is_state_changed(self): return self._bstate_changed
class TangoConnector(Connector): value_changed = pyqtSignal(str, name="valueChanged") def __init__(self, uri=None, attributes=[], policy=UpdatePolicy.POLLING, interval=1.0): #QThread.__init__(self) self.alive = False self.connected = False self.poll_attributes = {} self.thread = threading.Thread(target=self.run, name=uri) try: self.proxy = DeviceProxy(uri) self.connected = True except: self.attributes["state"]["value"] = State.UNKNOWN self.janus.utils["logger"].error("TangoConnector(" + self.uri + ").__init__() " + "connection failed") self.janus.utils["logger"].debug("", exc_info=True) Connector.__init__(self, uri, attributes, policy, interval) def add_attribute(self, attribute=None): Connector.add_attribute(self, attribute=attribute) if type(attribute) is not dict or "attr" not in attribute: return if "mode" in attribute and attribute["mode"] == "execute": return if "name" in attribute: name = attribute["name"] else: name = attribute["attr"].lower() self.poll_attributes[attribute["attr"]] = name def update_policy(self, policy=UpdatePolicy.POLLING, interval=1.0): self.interval = interval if policy != UpdatePolicy.POLLING and self.isRunning(): self.stop() elif policy != UpdatePolicy.EVENTBASED: for attr in self.attributes.keys(): if "event" not in self.attributes[attr]: continue try: self.proxy.unsubscribe_event( self.attributes[attr]["event"]) except: self.janus.utils["logger"].error( "TangoConnector(" + self.uri + ").update_policy() " + "failed to unsubscribe from tango event") self.janus.utils["logger"].debug("", exc_info=True) del self.attributes[attr]["event"] if policy == UpdatePolicy.POLLING and not self.thread.is_alive(): self.thread.start() elif policy == UpdatePolicy.EVENTBASED: for attr in self.attributes.keys: try: self.attributes[attr]["event"] = \ self.proxy.subscribe_event(EventType.CHANGE_EVENT, \ self.on_tango_event, [], False) except: self.janus.utils["logger"].error( "TangoConnector(" + self.uri + ").update_policy() " + "failed to subscribe to tango event") self.janus.utils["logger"].debug("", exc_info=True) self.policy = policy def on_tango_event(self, event): try: name = event.attr_name value = event.attr_value.value except: self.janus.utils["logger"].warning("TangoConnector(" + self.uri + ").on_tango_event() " + "invalid tango event type") self.janus.utils["logger"].debug("", exc_info=True) self.attributes[self.poll_attributes[name]]["value"] = value self.value_changed.emit(self.poll_attributes[name]) def stop_device(self): self.stop() def stop(self): self.alive = False self.thread.join() pass def run(self): print("thread started: {} ({})".format( threading.get_ident(), threading.currentThread().getName())) self.alive = True while self.alive: #remember when we started timestamp = time.time() #try to poll attributes try: attrs = self.proxy.read_attributes( list(self.poll_attributes.keys())) except: self.attributes["state"]["value"] = State.UNKNOWN self.janus.utils["logger"].error( "TangoConnector(" + self.uri + ").run() " + "reading tango attributes failed") self.janus.utils["logger"].debug("", exc_info=True) attrs = [] #assign attribute values and fire change signal if necessary for attr in attrs: name = self.poll_attributes[attr.name] changed = False if "delta" in self.attributes[name]: if self.attributes[name]["value"] is None or \ abs(self.attributes[name]["value"] - attr.value) > \ self.attributes[name]["delta"]: changed = True elif name == "state" and \ int(self.attributes[name]["value"]) != int(attr.value): changed = True elif name == "image_8": changed = True elif self.attributes[name]["value"] != attr.value: changed = True if changed: if name == "state": self.attributes[name]["value"] = State(int(attr.value)) else: self.attributes[name]["value"] = attr.value self.value_changed.emit(name) if not self.alive: break #wait for the rest of the polling interval interval = int((self.interval - (time.time() - timestamp))) while interval > 0: if interval > 0.05: time.sleep(0.05) interval -= 0.05 else: time.sleep(interval) interval = 0 if not self.alive: break print("closing thread: {} ({})".format( threading.get_ident(), threading.currentThread().getName())) def state(self, refresh=False): if refresh: try: self.attributes["state"]["value"] = State( int(self.proxy.state())) except: self.attributes["state"]["value"] = State.UNKNOWN self.janus.utils["logger"].error("TangoConnector(" + self.uri + ").state() " + "reading tango state failed") self.janus.utils["logger"].debug("", exc_info=True) return self.attributes["state"]["value"] def read(self, attribute=None, refresh=False, alt=None): if refresh or self.attributes[attribute]["value"] is None: try: self.attributes[attribute]["value"] = \ self.proxy.read_attribute(self.attributes[attribute]["attr"]).value except: self.janus.utils["logger"].error( "TangoConnector(" + self.uri + ")" + ".read(" + attribute + ") " + "reading tango attribute failed") self.janus.utils["logger"].debug("", exc_info=True) if self.attributes[attribute]["value"] is None \ and alt is not None: return alt return self.attributes[attribute]["value"] def write(self, attribute=None, value=None): try: self.proxy.write_attribute(self.attributes[attribute]["attr"], value) return True except: self.janus.utils["logger"].error("TangoConnector(" + self.uri + ")" + ".write(" + attribute + ") " + "writing tango attribute failed") self.janus.utils["logger"].debug("", exc_info=True) return False def execute(self, command=None, *values): try: if len(values) == 0: value = self.proxy.command_inout( self.attributes[command]["attr"]) else: value = self.proxy.command_inout( self.attributes[command]["attr"], values) except Exception as e: self.janus.utils["logger"].error("TangoConnector(" + self.uri + ")" + ".execute(" + command + ") " + "executing tango command failed") self.janus.utils["logger"].debug("", exc_info=True) return None return value