示例#1
0
    def _pushAttrEvent(self, event):
        """Handler of (non-configuration) events from the PyTango layer.
        It handles the subscription and the (de)activation of polling

        :param event: (A PyTango event)

        :return: (evt_type, evt_value)  Tuple containing the event type and the
                 event value. evt_type is a `TaurusEventType` (or None to
                 indicate that there should not be notification to listeners).
                 evt_value is a TaurusValue, an Exception, or None.
        """
        if not event.err:
            self.__attr_value, self.__attr_err = self.decode(
                event.attr_value), None
            self.__subscription_state = SubscriptionState.Subscribed
            self.__subscription_event.set()
            if not self.isPollingForced():
                self._deactivatePolling()
            return TaurusEventType.Change, self.__attr_value

        elif event.errors[0].reason in EVENT_TO_POLLING_EXCEPTIONS:
            if not self.isPollingActive():
                self.info("Activating polling. Reason: %s",
                          event.errors[0].reason)
                self.__subscription_state = SubscriptionState.PendingSubscribe
                self._activatePolling()
            return None, None

        else:
            self.__attr_value, self.__attr_err = None, PyTango.DevFailed(
                *event.errors)
            self.__subscription_state = SubscriptionState.Subscribed
            self.__subscription_event.set()
            self._deactivatePolling()
            return TaurusEventType.Error, self.__attr_err
    def push_event(self, event):
        """Method invoked by the PyTango layer when a change event occurs.
           Default implementation propagates the event to all listeners."""

        curr_time = time.time()
        manager = Manager()
        sm = self.getSerializationMode()
        if not event.err:
            # if it is a configuration event
            if isinstance(event, PyTango.AttrConfEventData):
                event_type = TaurusEventType.Config
                self._decodeAttrInfoEx(event.attr_conf)
                # make sure that there is a self.__attr_value
                if self.__attr_value is None:
                    # TODO: maybe we can avoid this read?
                    self.__attr_value = self.getValueObj(cache=False)
            # if it is an attribute event
            else:
                event_type = TaurusEventType.Change
                self.__attr_value, self.__attr_err = self.decode(
                    event.attr_value), None
                self.__subscription_state = SubscriptionState.Subscribed
                self.__subscription_event.set()
                if not self.isPollingForced():
                    self._deactivatePolling()
            # notify the listeners
            listeners = tuple(self._listeners)
            if sm == TaurusSerializationMode.Concurrent:
                manager.addJob(self.fireEvent,
                               None,
                               event_type,
                               self.__attr_value,
                               listeners=listeners)
            else:
                self.fireEvent(event_type,
                               self.__attr_value,
                               listeners=listeners)
        elif event.errors[0].reason in EVENT_TO_POLLING_EXCEPTIONS:
            if self.isPollingActive():
                return
            self.info("Activating polling. Reason: %s", event.errors[0].reason)
            self.__subscription_state = SubscriptionState.PendingSubscribe
            self._activatePolling()
        else:
            self.__attr_value, self.__attr_err = None, PyTango.DevFailed(
                *event.errors)
            self.__subscription_state = SubscriptionState.Subscribed
            self.__subscription_event.set()
            self._deactivatePolling()
            listeners = tuple(self._listeners)
            if sm == TaurusSerializationMode.Concurrent:
                manager.addJob(self.fireEvent,
                               None,
                               TaurusEventType.Error,
                               self.__attr_err,
                               listeners=listeners)
            else:
                self.fireEvent(TaurusEventType.Error,
                               self.__attr_err,
                               listeners=listeners)
 def power_on(self):
     motors = []
     motors = motors + self.get_pool_motors('hfm_y')
     motors = motors + self.get_pool_motors('vfm_x1')
     motors = motors + self.get_pool_motors('vfm_x2')
     attrs = []
     all_on = True
     for mot in motors:
         try:
             power_attr = AttributeProxy(mot.name + '/PowerOn')
             attrs.append(power_attr)
             if power_attr.read().value == False:
                 power_attr.write(True)
                 all_on = False
         except PyTango.DevFailed as e:
             self._log.warning(
                 "Motor {} doesn't have a PowerOn attribute".format(
                     mot.name))
     starttime = time.time()
     while all_on == False:
         if time.time() - starttime > 2:
             raise PyTango.DevFailed(
                 "Timeout while waiting for motors to power on")
         all_on = True
         time.sleep(0.1)
         for attr in attrs:
             if attr.read().value == False:
                 all_on = False
示例#4
0
    def __init__(self, attr=None, pytango_dev_attr=None, config=None):
        # config parameter is kept for backwards compatibility only
        TaurusAttrValue.__init__(self)
        if config is not None:
            from taurus.core.util.log import deprecated
            deprecated(dep='"config" kwarg', alt='"attr"', rel='4.0')
            attr = config
        if attr is None:
            self._attrRef = None
        else:
            self._attrRef = weakref.proxy(attr)
        self.config = self._attrRef  # bck-compat

        self._pytango_dev_attr = p = pytango_dev_attr
        if p is None:
            self._pytango_dev_attr = p = PyTango.DeviceAttribute()
            return

        if self._attrRef is None:
            return

        numerical = (PyTango.is_numerical_type(self._attrRef._tango_data_type,
                                               inc_array=True)
                     or p.type == PyTango.CmdArgType.DevUChar)

        if p.has_failed:
            self.error = PyTango.DevFailed(*p.get_err_stack())
        else:
            # spectra and images can be empty without failing
            if p.is_empty and self._attrRef.data_format != DataFormat._0D:
                dtype = FROM_TANGO_TO_NUMPY_TYPE.get(
                    self._attrRef._tango_data_type)
                if self._attrRef.data_format == DataFormat._1D:
                    shape = (0, )
                elif self._attrRef.data_format == DataFormat._2D:
                    shape = (0, 0)
                p.value = numpy.empty(shape, dtype=dtype)
                if not (numerical or self._attrRef.type == DataType.Boolean):
                    # generate a nested empty list of given shape
                    p.value = []
                    for _ in xrange(len(shape) - 1):
                        p.value = [p.value]

        rvalue = p.value
        wvalue = p.w_value
        if numerical:
            units = self._attrRef._units
            if rvalue is not None:
                rvalue = Quantity(rvalue, units=units)
            if wvalue is not None:
                wvalue = Quantity(wvalue, units=units)
        elif isinstance(rvalue, PyTango._PyTango.DevState):
            rvalue = DevState[str(rvalue)]

        self.rvalue = rvalue
        self.wvalue = wvalue
        self.time = p.time  # TODO: decode this into a TaurusTimeVal
        self.quality = quality_from_tango(p.quality)
示例#5
0
 def _fromTangoMotor(motor):
     import PyTango
     attrs = "base_rate", "velocity", "acceleration", "deceleration"
     attr_values = motor.read_attributes(attrs)
     v = []
     for attr_value in attr_values:
         if attr_value.has_failed:
             raise PyTango.DevFailed(*attr_value.get_err_stack())
         v.append(attr_value.value)
     return Motor(min_vel=v[0], max_vel=v[1], accel_time=v[2], decel_time=v[3])
示例#6
0
    def check_attribute(self,
                        attr_name,
                        dev_name,
                        target_value,
                        period=0.3,
                        timeout=1.0,
                        tolerance=None,
                        write=True):
        """
        Check an attribute to see if it reaches a target value. Returns a deferred for the result of the
        check.
        Upon calling the function the target is written to the attribute if the "write" parameter is True.
        Then reading the attribute is polled with the period "period" for a maximum number of retries.
        If the read value is within tolerance, the callback deferred is fired.
        If the read value is outside tolerance after retires attempts, the errback is fired.
        The maximum time to check is then period x retries

        :param attr_name: Tango name of the attribute to check, e.g. "position"
        :param dev_name: Tango device name to use, e.g. "gunlaser/motors/zaber01"
        :param target_value: Attribute value to wait for
        :param period: Polling period when checking the value
        :param timeout: Time to wait for the attribute to reach target value
        :param tolerance: Absolute tolerance for the value to be accepted
        :param write: Set to True if the target value should be written initially
        :return: Deferred that will fire depending on the result of the check
        """
        self.logger.info("Check attribute \"{0}\" on \"{1}\"".format(
            attr_name, dev_name))
        if dev_name in self.device_names:
            factory = self.device_factory_dict[self.device_names[dev_name]]
            d = factory.buildProtocol("check",
                                      attr_name,
                                      None,
                                      write=write,
                                      target_value=target_value,
                                      tolerance=tolerance,
                                      period=period,
                                      timeout=timeout)
            d.addCallback(self.update_attribute)
        else:
            self.logger.error("Device name {0} not found among {1}".format(
                dev_name, self.device_factory_dict))
            err = tango.DevError(
                reason="Device {0} not used".format(dev_name),
                severety=tango.ErrSeverity.ERR,
                desc=
                "The device is not in the list of devices used by this controller",
                origin="check_attribute")
            d = Failure(tango.DevFailed(err))
        return d
示例#7
0
    def get_device(self, device_name):
        self.logger.debug("{0} Returning device {1}".format(self, device_name))
        try:
            dev = self.devices[device_name]
        except KeyError:
            # Maybe this should just raise an exception instead of auto-adding:
            task = self.add_device(device_name)
            try:
                dev = task.get_result(wait=True, timeout=self.timeout)
                if task.is_cancelled():
                    raise pt.DevFailed(dev)
            except AttributeError:
                pass

        return dev
示例#8
0
 def write_attribute(self, name, device_name, data):
     self.logger.info("Write attribute \"{0}\" on \"{1}\"".format(
         name, device_name))
     if device_name in self.device_names:
         factory = self.device_factory_dict[self.device_names[device_name]]
         d = factory.buildProtocol("write", name, data)
     else:
         self.logger.error("Device name {0} not found among {1}".format(
             device_name, self.device_factory_dict))
         err = tango.DevError(
             reason="Device {0} not used".format(device_name),
             severety=tango.ErrSeverity.ERR,
             desc=
             "The device is not in the list of devices used by this controller",
             origin="write_attribute")
         d = Failure(tango.DevFailed(err))
     return d
    def test_read_failure(self, monkeypatch):
        device_name = "sys/tg_test/1"
        attribute_name = "float_scalar"
        maxdelta = datetime.timedelta(seconds=5)
        s = TangoDeviceAttributeSource(device_name, attribute_name,
                                       metadata={"attribute": attribute_name})
        ex = tango.DevFailed()

        # TODO: How to test handling of tango exceptions?
        def mockreturn(attribute_name):
            raise ex
        monkeypatch.setattr(s.device, 'read_attribute', mockreturn)

        data = s.read()
        now = datetime.datetime.now(timezone("Europe/Berlin"))
        assert data.timestamp - now < maxdelta
        assert data.failure is ex
        assert data.value is None
        assert data.metadata is not s.metadata
        assert data.metadata["attribute"] == attribute_name
示例#10
0
    def _pushConfEvent(self, event):
        """Handler of AttrConfEventData events from the PyTango layer.

        :param event: (PyTango.AttrConfEventData)

        :return: (evt_type, evt_value)  Tuple containing the event type and the
                 event value. evt_type is a `TaurusEventType` (or None to
                 indicate that there should not be notification to listeners).
                 evt_value is a TaurusValue, an Exception, or None.
        """
        if not event.err:
            # update conf-related attributes
            self._decodeAttrInfoEx(event.attr_conf)
            # make sure that there is a self.__attr_value
            if self.__attr_value is None:
                # TODO: maybe we can avoid this read?
                self.__attr_value = self.getValueObj(cache=False)
            return TaurusEventType.Config, self.__attr_value

        else:
            self.__attr_value, self.__attr_err = None, PyTango.DevFailed(
                *event.errors)
            return TaurusEventType.Error, self.__attr_err
示例#11
0
def mon(self, parameter_s=''):
    """Monitor a given attribute.
    
    %mon -a <attribute name>           - activates monitoring of given attribute
    %mon -d <attribute name>           - deactivates monitoring of given attribute
    %mon -r                            - deactivates monitoring of all attributes
    %mon -i <id>                       - displays detailed information for the event with given id
    %mon -l <dev filter> <attr filter> - shows event table filtered with the regular expression for attribute name
    %mon                               - shows event table (= %mon -i .* .*)"""

    db = __get_db()
    if db is None:
        print("You are not connected to any Tango Database.")
        return

    # make sure parameter_s is a str and not a unicode
    parameter_s = str(parameter_s)
    opts, args = self.parse_options(parameter_s, 'adril', mode='list')
    if len(args) > 3:
        raise UsageError("%mon: too many arguments")
    if 'd' in opts:
        try:
            todel = args[0]
        except IndexError:
            raise UsageError("%mon -d: must provide an attribute to unmonitor")
        else:
            try:
                dev, _, attr = todel.rpartition("/")
                subscriptions = __get_device_subscriptions(dev)
                attr_id = subscriptions[attr.lower()]
                del subscriptions[attr.lower()]
                d = __get_device_proxy(dev)
                d.unsubscribe_event(attr_id)
                print("Stopped monitoring '%s'" % todel)
            except KeyError:
                raise UsageError("%%mon -d: Not monitoring '%s'" % todel)

    elif 'a' in opts:
        try:
            toadd = args[0]
        except IndexError:
            raise UsageError("%mon -a: must provide an attribute to monitor")
        dev, _, attr = toadd.rpartition("/")
        subscriptions = __get_device_subscriptions(dev)
        attr_id = subscriptions.get(attr.lower())
        if attr_id is not None:
            raise UsageError("%%mon -a: Already monitoring '%s'" % toadd)
        d = __get_device_proxy(dev)
        w = __get_event_log()
        model = w.model()
        attr_id = d.subscribe_event(attr, PyTango.EventType.CHANGE_EVENT,
                                    model, [])
        subscriptions[attr.lower()] = attr_id
        print("'%s' is now being monitored. Type 'mon' to see all events" %
              toadd)
    elif 'r' in opts:
        for d, v in db._db_cache.devices.items():
            d, subs = v[3], v[4]
            for _id in subs.values():
                d.unsubscribe_event(_id)
            v[4] = {}
    elif 'i' in opts:
        try:
            evtid = int(args[0])
        except IndexError:
            raise UsageError("%mon -i: must provide an event ID")
        except ValueError:
            raise UsageError("%mon -i: must provide a valid event ID")
        try:
            w = __get_event_log()
            e = w.getEvents()[evtid]
            if e.err:
                print(str(PyTango.DevFailed(*e.errors)))
            else:
                print(str(e))
        except IndexError:
            raise UsageError("%mon -i: must provide a valid event ID")
    elif 'l' in opts:
        try:
            dexpr = args[0]
            aexpr = args[1]
        except IndexError:
            raise UsageError("%mon -l: must provide valid device and " \
                             "attribute filters")
        w = __get_event_log()
        w.show(dexpr, aexpr)
    else:
        w = __get_event_log()
        w.show()
示例#12
0
 def data(self, index, role=Qt.Qt.DisplayRole):
     if not index.isValid() or not (0 <= index.row() < len(self._records)):
         return Qt.QVariant()
     column, row = index.column(), index.row()
     record = self._records[row]
     if record.err:
         err = PyTango.DevFailed(*record.errors)
     else:
         err = None
     name = record.s_attr_name.lower()
     if role == Qt.Qt.DisplayRole:
         if column == ID:
             return Qt.QVariant(row)
         if column == HOST:
             return Qt.QVariant(record.host)
         elif column == DEVICE:
             return Qt.QVariant(record.dev_name)
         elif column == ATTRIBUTE:
             return Qt.QVariant(record.s_attr_name)
         elif column == VALUE:
             if err is None:
                 return Qt.QVariant(
                     deviceAttributeValueStr(record.attr_value))
             else:
                 return Qt.QVariant(err[0].reason)
         elif column == TIME:
             if err is None:
                 return Qt.QVariant(
                     record.attr_value.time.strftime("%H:%M:%S.%f"))
             else:
                 return Qt.QVariant(
                     record.reception_date.strftime("%H:%M:%S.%f"))
     elif role == Qt.Qt.TextAlignmentRole:
         if column in (HOST, DEVICE, ATTRIBUTE):
             return Qt.QVariant(Qt.Qt.AlignLeft | Qt.Qt.AlignVCenter)
         return Qt.QVariant(Qt.Qt.AlignRight | Qt.Qt.AlignVCenter)
     elif role == Qt.Qt.BackgroundRole:
         if column == VALUE:
             if err is None:
                 if name == "state":
                     bg = getBrushForState(record.attr_value.value)[0]
                 else:
                     bg = getBrushForQuality(record.attr_value.quality)[0]
             else:
                 bg = Qt.QBrush(Qt.Qt.red)
         else:
             if index.row() % 2:
                 bg = self.DftOddRowBrush[0]
             else:
                 bg = self.DftEvenRowBrush[0]
         return Qt.QVariant(bg)
     elif role == Qt.Qt.ForegroundRole:
         if column == VALUE:
             if err is None:
                 if name == "state":
                     fg = getBrushForState(record.attr_value.value)[1]
                 else:
                     fg = getBrushForQuality(record.attr_value.quality)[1]
             else:
                 fg = Qt.QBrush(Qt.Qt.white)
         else:
             if index.row() % 2:
                 fg = self.DftOddRowBrush[1]
             else:
                 fg = self.DftEvenRowBrush[1]
         return Qt.QVariant(fg)
     elif role == Qt.Qt.ToolTipRole:
         if err is None:
             return Qt.QVariant(str(record.attr_value))
         else:
             return Qt.QVariant(str(record))
     elif role == Qt.Qt.SizeHintRole:
         return self._getSizeHint(column)
     #elif role == Qt.Qt.StatusTipRole:
     #elif role == Qt.Qt.CheckStateRole:
     elif role == Qt.Qt.FontRole:
         return Qt.QVariant(Qt.QFont("Mono", 8))
     return Qt.QVariant()