def getInfo(self):
        try:
            self.attrInfo = self.device.get_attribute_config(self.name)

        except pt.DevFailed, e:
            if e[0].reason == 'API_DeviceTimeOut':
                print 'AttrInfo Timeout'
            else:
                print self.name, '  attrinfo error ', e[0].reason
            self.attrInfo = pt.AttributeInfoEx()
    def attr_read(self):
        replyReady = True
        while self.stopThread is False:
            if self.getInfoFlag is True:
                self.getInfoFlag = False
                try:
                    self.attrInfo = self.device.get_attribute_config(self.name)
                    self.attrInfoSignal.emit(self.attrInfo)

                except pt.DevFailed, e:
                    if e[0].reason == 'API_DeviceTimeOut':
                        print 'AttrInfo Timeout'
                    else:
                        print self.name, '  attrinfo error ', e[0].reason
                    self.attrInfo = pt.AttributeInfoEx()
                    self.attrInfoSignal.emit(self.attrInfo)
                except Exception, e:
                    print self.name, ' recovering from attrInfo ', str(e)
                    self.attrInfo = pt.AttributeInfoEx()
                    self.attrInfoSignal.emit(self.attrInfo)
Exemple #3
0
    def _decodeAttrInfoEx(self, pytango_attrinfoex=None):
        if pytango_attrinfoex is None:
            self._pytango_attrinfoex = PyTango.AttributeInfoEx()
        else:
            self._pytango_attrinfoex = i = pytango_attrinfoex

            self.writable = i.writable != PyTango.AttrWriteType.READ
            self._label = i.label
            self.data_format = data_format_from_tango(i.data_format)
            desc = description_from_tango(i.description)
            if desc != "":
                self._description = desc
            self.type = data_type_from_tango(i.data_type)
            ###############################################################
            # changed in taurus4: range, alarm and warning now return
            # quantities if appropriate
            units = self._unit_from_tango(i.unit)
            if PyTango.is_numerical_type(i.data_type, inc_array=True):
                Q_ = partial(quantity_from_tango_str,
                             units=units,
                             dtype=i.data_type)
                ninf, inf = float('-inf'), float('inf')
                min_value = Q_(i.min_value) or Quantity(ninf, units)
                max_value = Q_(i.max_value) or Quantity(inf, units)
                min_alarm = Q_(i.alarms.min_alarm) or Quantity(ninf, units)
                max_alarm = Q_(i.alarms.max_alarm) or Quantity(inf, units)
                min_warning = Q_(i.alarms.min_warning) or Quantity(ninf, units)
                max_warning = Q_(i.alarms.max_warning) or Quantity(inf, units)
                self._range = [min_value, max_value]
                self._warning = [min_warning, max_warning]
                self._alarm = [min_alarm, max_alarm]

            ###############################################################
            # The following members will be accessed via __getattr__
            # self.standard_unit
            # self.display_unit
            # self.disp_level
            ###############################################################
            # Tango-specific extension of TaurusConfigValue
            self.display_level = display_level_from_tango(i.disp_level)
            self.tango_writable = i.writable
            self.max_dim = i.max_dim_x, i.max_dim_y
            ###############################################################
            fmt = standard_display_format_from_tango(i.data_type, i.format)
            self.format_spec = fmt.lstrip('%')  # format specifier
            match = re.search("[^\.]*\.(?P<precision>[0-9]+)[eEfFgG%]", fmt)
            if match:
                self.precision = int(match.group(1))
            # self._units and self._display_format is to be used by
            # TangoAttrValue for performance reasons. Do not rely on it in other
            # code
            self._units = units
class AttributeEventClass(QtCore.QObject):
    '''This class encapsulates the tango events for an attribute and re-emits
    a Qt signal. The main purpose of this is that the Qt gui obejcts cannot 
    be called from other threads than the gui thread, causing problems with tango events.  
    '''
    attrSignal = QtCore.pyqtSignal(pt.device_attribute.DeviceAttribute)
    attrInfoSignal = QtCore.pyqtSignal(pt.AttributeInfoEx)

    def __init__(self,
                 name,
                 device,
                 eventType=pt.EventType.CHANGE_EVENT,
                 minInterval=0.0,
                 slot=None):
        ''' Init the attribute listener.
         
        name: Attribute tango name
        device: DeviceProxy for the tango device server
        eventType: Type of event (member of PyTango.EventType)
        minInterval: Minimum time in s between pushing QSignals for limiting 
                    the rate of gui redraw. The event rate could be higher.
        slot: Method to send the attrSignal to
        '''
        super(AttributeEventClass, self).__init__()
        self.name = name
        self.device = device
        self.eventType = eventType
        self.minInterval = minInterval
        if slot != None:
            self.attrSignal.connect(slot)

        self.eventId = None

        self.lastRead = 0

        self.subscribe_event()

    def subscribe_event(self):
        self.eventId = self.device.subscribe_event(self.name,
                                                   self.eventType,
                                                   self.attr_read,
                                                   stateless=True)

    def unsubscribe_event(self):
        if self.eventId != None:
            self.device.unsubscribe_event(self.eventId)

    def attr_read(self, event):
        if event.err == False:
            t = time.time()
            if (t - self.lastRead) > self.minInterval:
                self.attrSignal.emit(event.attr_value)
                self.lastRead = t

    def attr_write(self, wvalue):
        self.device.write_attribute(self.name, wvalue)

    def stopRead(self):
        self.unsubscribe_event()

    def startRead(self):
        self.subscribe_event()

    def getInfo(self):
        try:
            self.attrInfo = self.device.get_attribute_config(self.name)

        except pt.DevFailed, e:
            if e[0].reason == 'API_DeviceTimeOut':
                print 'AttrInfo Timeout'
            else:
                print self.name, '  attrinfo error ', e[0].reason
            self.attrInfo = pt.AttributeInfoEx()

        except Exception, e:
            print self.name, ' recovering from attrInfo ', str(e)
            self.attrInfo = pt.AttributeInfoEx()
Exemple #5
0
    def test_GetAttributeConfig(self):
        ai = self.device1.get_attribute_config('Float_spec_attr_rw')
        old_ai = PyTango.AttributeInfoEx(ai)
        assert (ai.min_value == 'Not specified')
        assert (ai.max_value == 'Not specified')
        assert (ai.alarms.min_alarm == 'Not specified')
        assert (ai.alarms.max_alarm == 'Not specified')

        ai.min_value = '3.5'
        ai.max_value = '15.5'
        ai.alarms.min_alarm = '4.2'
        ai.alarms.max_alarm = '13.5'
        self.device1.set_attribute_config(ai)
        restore_set(self, 'Float_spec_attr_rw')

        new_ai = self.device1.get_attribute_config('Float_spec_attr_rw')
        assert (new_ai.name == ai.name)
        assert (new_ai.data_type == ai.data_type)
        assert (new_ai.data_format == ai.data_format)
        assert (new_ai.max_dim_x == ai.max_dim_x)
        assert (new_ai.max_dim_y == ai.max_dim_y)
        assert (new_ai.writable == ai.writable)
        assert (new_ai.label == ai.label)
        assert (new_ai.description == ai.description)
        assert (new_ai.alarms.min_alarm == ai.alarms.min_alarm)
        assert (new_ai.alarms.max_alarm == ai.alarms.max_alarm)
        assert (new_ai.min_value == ai.min_value)
        assert (new_ai.max_value == ai.max_value)

        ai.min_value = 'NaN'
        ai.max_value = 'NaN'
        ai.alarms.min_alarm = 'NaN'
        ai.alarms.max_alarm = 'NaN'
        self.device1.set_attribute_config(ai)
        restore_unset(self, 'Float_spec_attr_rw')

        new_ai = self.device1.get_attribute_config('Float_spec_attr_rw')
        assert (new_ai.name == old_ai.name)
        assert (new_ai.data_type == old_ai.data_type)
        assert (new_ai.data_format == old_ai.data_format)
        assert (new_ai.max_dim_x == old_ai.max_dim_x)
        assert (new_ai.max_dim_y == old_ai.max_dim_y)
        assert (new_ai.writable == old_ai.writable)
        assert (new_ai.label == old_ai.label)
        assert (new_ai.description == old_ai.description)
        assert (new_ai.alarms.min_alarm == old_ai.alarms.min_alarm)
        assert (new_ai.alarms.max_alarm == old_ai.alarms.max_alarm)
        assert (new_ai.min_value == old_ai.min_value)
        assert (new_ai.max_value == old_ai.max_value)

        new_ai.min_value = '3.5'
        new_ai.max_value = '15.5'
        self.device1.set_attribute_config(new_ai)
        restore_set(self, 'Float_spec_attr_rw')

        # TODO: choose one variant
        # variant 1
        with self.assertRaises(PyTango.DevFailed) as cm:
            self.device1.write_attribute('Float_spec_attr_rw', [3.6, 3.3, 3.7])
        assert (cm.exception.args[0].reason == 'API_WAttrOutsideLimit')
        # variant 2
        self.assertRaisesRegexp(PyTango.DevFailed,
                                'reason = API_WAttrOutsideLimit',
                                self.device1.write_attribute,
                                'Float_spec_attr_rw', [3.6, 3.3, 3.7])

        self.assertRaisesRegexp(PyTango.DevFailed,
                                'reason = API_WAttrOutsideLimit',
                                self.device1.write_attribute,
                                'Float_spec_attr_rw', [17.6])

        new_ai.min_value = 'NaN'
        new_ai.max_value = 'NaN'
        new_ai.alarms.min_alarm = '6.0'
        self.device1.set_attribute_config(new_ai)

        state = self.device1.state()
        assert (state == PyTango.DevState.ALARM)
        status = self.device1.status()
        self.assertRegexpMatches(status, 'ALARM')
        self.assertRegexpMatches(status, 'Float_spec_attr_rw')

        da = self.device1.read_attribute('Float_spec_attr_rw')
        assert (da.quality == PyTango.AttrQuality.ATTR_ALARM)

        new_ai.alarms.min_alarm = 'NaN'
        self.device1.set_attribute_config(new_ai)

        state = self.device1.state()
        assert (state == PyTango.DevState.ON)

        da = self.device1.read_attribute('Float_spec_attr_rw')
        assert (da.quality == PyTango.AttrQuality.ATTR_VALID)
    def attr_read(self):
        logger.debug("Entering attr_read for \"{0}\"".format(self.name))
        reply_ready = True
        while self.stop_thread_flag is False:
            if self.pause_read_flag is True:
                time.sleep(0.1)
            else:
                if self.get_info_flag is True:
                    self.get_info_flag = False
                    try:
                        self.attr_info = self.device.get_attribute_config(
                            self.name)
                        self.attrInfoSignal.emit(self.attr_info)

                    except pt.DevFailed as e:
                        if e.args[0].reason == 'API_DeviceTimeOut':
                            logger.debug('AttrInfo Timeout')
                        else:
                            logger.debug("{0} attrinfo error: {1}".format(
                                self.name, e.args[0].reason))
                        self.attr_info = pt.AttributeInfoEx()
                        self.attrInfoSignal.emit(self.attr_info)
                    except Exception as e:
                        logger.debug(
                            "{0} recovering from attrInfo error {1}".format(
                                self.name, str(e)))
                        self.attr_info = pt.AttributeInfoEx()
                        self.attrInfoSignal.emit(self.attr_info)

                t = time.time()

                if self.interval is None:
                    dt = 0
                else:
                    dt = self.interval
                if t - self.last_read_time > dt:
                    self.last_read_time = t
                    try:
                        reply_id = self.device.read_attribute_asynch(self.name)

                        reply_ready = False
                    except pt.DevFailed as e:
                        if e.args[0].reason == 'API_DeviceTimeOut':
                            logger.debug("Timeout")
                        else:
                            logger.debug(
                                "{0} read_attribute_asynch error: {1}".format(
                                    self.name, e.args[0].reason))
                        self.attr = pt.DeviceAttribute()
                        self.attr.quality = pt.AttrQuality.ATTR_INVALID
                        self.attr.value = None
                        self.attr.w_value = None
                        self.attrSignal.emit(self.attr)

                    except Exception as e:
                        logger.error("{0} recovering from {1}".format(
                            self.name, str(e)))
                        self.attr = pt.DeviceAttribute()
                        self.attr.quality = pt.AttrQuality.ATTR_INVALID
                        self.attr.value = None
                        self.attrSignal.emit(self.attr)

                    while reply_ready is False and self.stop_thread_flag is False:
                        try:
                            self.attr = self.device.read_attribute_reply(
                                reply_id)
                            reply_ready = True
                            # logger.debug("{0} Reply: {1}".format(self.name, self.attr))
                            self.attrSignal.emit(self.attr)
                            # Read only once if interval = None:
                            if self.interval is None:
                                self.stop_thread_flag = True
                                self.interval = 0.0
                        except pt.DevFailed as e:
                            logger.info("Exception e: {0}".format(e))
                            if isinstance(e, pt.AsynReplyNotArrived):
                                time.sleep(0.1)
                            else:
                                reply_ready = True
                                logger.debug("Error reply {0}: {1}".format(
                                    self.name, str(e)))
                                self.attr = pt.DeviceAttribute()
                                self.attr.quality = pt.AttrQuality.ATTR_INVALID
                                self.attr.value = None
                                self.attr.w_value = None
                                self.attrSignal.emit(self.attr)

                if self.interval is not None:
                    time.sleep(self.interval)
                else:
                    time.sleep(0.2)
        logger.debug("{0} waiting for final reply".format(self.name))
        final_timeout = 1.0  # Wait max 1 s
        final_start_time = time.time()
        final_timeout_flag = False
        while reply_ready is False and final_timeout_flag is False:
            try:
                self.attr = self.device.read_attribute_reply(reply_id)
                reply_ready = True
                self.attrSignal.emit(self.attr)
            except Exception as e:
                if e.args[0].reason == 'API_AsynReplyNotArrived':
                    time.sleep(0.1)
                else:
                    reply_ready = True
                    logger.debug("Error reply {0}: {1}".format(
                        self.name, str(e)))
                    self.attr = pt.DeviceAttribute()
                    self.attr.quality = pt.AttrQuality.ATTR_INVALID
                    self.attr.value = None
                    self.attr.w_value = None
                    self.attrSignal.emit(self.attr)
            if time.time() - final_start_time > final_timeout:
                final_timeout_flag = True
        if final_timeout_flag is False:
            logger.debug("{0}... Thread stopped".format(self.name))
        else:
            logger.debug("{0}... Thread timed out".format(self.name))