コード例 #1
0
    def test_ValueRefEnabled(self, elements=["_test_2d_1_1", "_test_2d_1_2",
                                             "_test_ct_1_3",
                                             "_test_mt_1_3/position"]):
        mg_name = str(uuid.uuid1())
        argin = [mg_name] + elements
        self.pool.CreateMeasurementGroup(argin)
        try:
            mg = Device(mg_name)

            # Check initial state of all kind of channels, nonexistent
            # channels for the feature return None as result.
            enabled = mg.getValueRefEnabled(*elements)
            expected = [False, False, None, None]
            self._assertMultipleResults(enabled, elements, expected)

            # Check if the nonexistent channels raise error if trying to set
            with self.assertRaises(Exception):
                mg.setValueRefEnabled(True, *elements[-2])
            with self.assertRaises(Exception):
                mg.setValueRefEnabled(True, *elements[-1])

            # Redefine elements to ony use existing values
            elements = ["_test_2d_1_1", "_test_2d_1_2"]

            # Test every possible combination of setting values
            # Check that changing one channel doesn't affect the other
            mg.setValueRefEnabled(True, *elements)
            enabled = mg.getValueRefEnabled(*elements)
            self._assertResult(enabled, elements, True)
            mg.setValueRefEnabled(False, elements[0])
            result = mg.getValueRefEnabled(*elements)
            expected = [True] * len(elements)
            expected[0] = False
            self._assertMultipleResults(result, elements, expected)
            mg.setValueRefEnabled(True, *elements)
            enabled = mg.getValueRefEnabled(*elements)
            self._assertResult(enabled, elements, True)

            # Set values using the controller instead of channels
            mg.setValueRefEnabled(True, "_test_2d_ctrl_1")
            enabled = mg.getValueRefEnabled(*elements)
            self._assertResult(enabled, elements, True)

            # Get values by controller
            mg.setValueRefEnabled(False, *elements)
            enabled = mg.getValueRefEnabled("_test_2d_ctrl_1")
            self._assertResult(enabled, elements, False)

            # Check ret_full_name
            v = TangoDeviceNameValidator()
            full_names = [v.getNames(element)[0] for element in elements]
            enabled = mg.getValueRefEnabled(*full_names)
            self._assertResult(enabled, elements, False)
            mg.setValueRefEnabled(True, *full_names)
            enabled = mg.getValueRefEnabled(*elements, ret_full_name=True)
            self._assertResult(enabled, full_names, True)
        finally:
            mg.cleanUp()
            if os.name != "nt":
                self.pool.DeleteElement(mg_name)
コード例 #2
0
ファイル: test_measgrpconf.py プロジェクト: catunlock/sardana
    def test_ValueRefPattern(self,
                             elements=[
                                 "_test_2d_1_1", "_test_2d_1_2",
                                 "_test_ct_1_3", "_test_mt_1_3/position"
                             ]):
        mg_name = str(uuid.uuid1())
        argin = [mg_name] + elements
        self.pool.CreateMeasurementGroup(argin)
        try:
            mg = Device(mg_name)

            # Check initial state of all kind of channels, nonexistent
            # channels for the feature return None as result.
            pattern = mg.getValueRefPattern(*elements)
            expected = ['', '', None, None]
            self._assertMultipleResults(pattern, elements, expected)

            # Check if the nonexistent channels raise error if trying to set
            with self.assertRaises(Exception):
                mg.setValueRefPattern('/tmp/test_foo.txt', *elements[-2])
            with self.assertRaises(Exception):
                mg.setValueRefPattern('/tmp/test_foo.txt', *elements[-1])

            # Redefine elements to ony use existing values
            elements = ["_test_2d_1_1", "_test_2d_1_2"]

            # Test every possible combination of setting values
            # Check that changing one channel doesn't affect the other
            mg.setValueRefPattern('/tmp/test_foo.txt', *elements)
            pattern = mg.getValueRefPattern(*elements)
            self._assertResult(pattern, elements, '/tmp/test_foo.txt')

            # Set values using the controller instead of channels
            mg.setValueRefPattern('/tmp/test_foo2.txt', "_test_2d_ctrl_1")
            pattern = mg.getValueRefPattern(*elements)
            self._assertResult(pattern, elements, '/tmp/test_foo2.txt')

            # Get values by controller
            mg.setValueRefPattern('/tmp/test_foo.txt', *elements)
            pattern = mg.getValueRefPattern("_test_2d_ctrl_1")
            self._assertResult(pattern, elements, '/tmp/test_foo.txt')

            # Check ret_full_name
            v = TangoDeviceNameValidator()
            full_names = [v.getNames(element)[0] for element in elements]
            pattern = mg.getValueRefPattern(*full_names)
            self._assertResult(pattern, elements, '/tmp/test_foo.txt')
            mg.setValueRefPattern('/tmp/test_foo2.txt', *full_names)
            pattern = mg.getValueRefPattern(*elements, ret_full_name=True)
            self._assertResult(pattern, full_names, '/tmp/test_foo2.txt')

        finally:
            mg.cleanUp()
            self.pool.DeleteElement(mg_name)
コード例 #3
0
ファイル: test_measgrpconf.py プロジェクト: catunlock/sardana
    def test_Synchronizer(self,
                          elements=[
                              "_test_ct_1_1", "_test_ct_1_2", "_test_ct_1_3",
                              "_test_2d_1_1", "_test_mt_1_3/position"
                          ]):
        mg_name = str(uuid.uuid1())
        argin = [mg_name] + elements
        self.pool.CreateMeasurementGroup(argin)
        try:
            mg = Device(mg_name)
            result = mg.getSynchronizer()
            expected = ['software', 'software', 'software', 'software', None]
            self._assertMultipleResults(result, elements, expected)
            with self.assertRaises(Exception):
                mg.setSynchronizer('_test_tg_1_2', "_test_mt_1_3/position")

            mg.setSynchronizer('_test_tg_1_2', "_test_ct_ctrl_1",
                               "_test_2d_ctrl_1")

            expected = [
                '_test_tg_1_2', '_test_tg_1_2', '_test_tg_1_2', '_test_tg_1_2',
                None
            ]
            result = mg.getSynchronizer()
            self._assertMultipleResults(result, elements, expected)

            mg.setSynchronizer('software', "_test_ct_ctrl_1",
                               "_test_2d_ctrl_1")
            result = mg.getSynchronizer()
            expected = ['software', 'software', 'software', 'software', None]
            self._assertMultipleResults(result, elements, expected)

            with self.assertRaises(Exception):
                mg.setSynchronizer('asdf', "_test_ct_ctrl_1",
                                   "_test_2d_ctrl_1")

            # Check ret_full_name
            v = TangoDeviceNameValidator()
            counters = [
                "_test_ct_1_1", "_test_ct_1_2", "_test_ct_1_3", '_test_2d_1_1'
            ]
            full_names = [v.getNames(counter)[0] for counter in counters]
            mg.setSynchronizer('_test_tg_1_2', "_test_ct_ctrl_1",
                               "_test_2d_ctrl_1")

            result = mg.getSynchronizer(*counters, ret_full_name=True)

            self._assertResult(result, full_names, '_test_tg_1_2')

        finally:
            mg.cleanUp()
            self.pool.DeleteElement(mg_name)
コード例 #4
0
    def test_Synchronization(self, elements=["_test_ct_1_1", "_test_ct_1_2",
                                             "_test_ct_1_3", "_test_2d_1_1",
                                             "_test_mt_1_3/position"]):
        mg_name = str(uuid.uuid1())
        argin = [mg_name] + elements
        self.pool.CreateMeasurementGroup(argin)
        try:
            mg = Device(mg_name)
            result = mg.getSynchronization()
            expected = [AcqSynchType.Trigger, AcqSynchType.Trigger,
                        AcqSynchType.Trigger, AcqSynchType.Trigger, None]
            self._assertMultipleResults(result, elements, expected)
            # TODO: maybe we should raise an exception here?
            # with self.assertRaises(Exception):
            #     mg.setSynchronization(AcqSynchType.Trigger,
            #                           "_test_mt_1_3/position")

            mg.setSynchronization(AcqSynchType.Gate, "_test_ct_ctrl_1",
                                  "_test_2d_ctrl_1")

            expected = [AcqSynchType.Gate, AcqSynchType.Gate,
                        AcqSynchType.Gate, AcqSynchType.Gate, None]
            result = mg.getSynchronization()
            self._assertMultipleResults(result, elements, expected)

            mg.setSynchronization(AcqSynchType.Start, "_test_ct_ctrl_1",
                                  "_test_2d_ctrl_1")
            result = mg.getSynchronization()
            expected = [AcqSynchType.Start, AcqSynchType.Start,
                        AcqSynchType.Start, AcqSynchType.Start, None]
            self._assertMultipleResults(result, elements, expected)

            with self.assertRaises(Exception):
                mg.setSynchronization('asdf', "_test_ct_ctrl_1",
                                      "_test_2d_ctrl_1")

            # Check ret_full_name
            v = TangoDeviceNameValidator()
            counters = ["_test_ct_1_1", "_test_ct_1_2", "_test_ct_1_3",
                        '_test_2d_1_1']
            full_names = [v.getNames(counter)[0] for counter in counters]
            mg.setSynchronization(AcqSynchType.Trigger, "_test_ct_ctrl_1",
                                  "_test_2d_ctrl_1")

            result = mg.getSynchronization(*counters, ret_full_name=True)

            self._assertResult(result, full_names, AcqSynchType.Trigger)

        finally:
            mg.cleanUp()
            if os.name != "nt":
                self.pool.DeleteElement(mg_name)
コード例 #5
0
ファイル: test_measgrpconf.py プロジェクト: catunlock/sardana
    def test_PlotType(self,
                      elements=[
                          "_test_ct_1_1", "_test_ct_1_2", "_test_ct_1_3",
                          "_test_2d_1_3", "_test_mt_1_3/position"
                      ]):
        mg_name = str(uuid.uuid1())
        argin = [mg_name] + elements
        self.pool.CreateMeasurementGroup(argin)

        try:
            mg = Device(mg_name)
            plottype = mg.getPlotType()
            self._assertResult(plottype, elements, 0)
            mg.setPlotType("Image", elements[0])
            mg.setPlotType("Spectrum", elements[1])
            mg.setPlotType("No", elements[2])
            mg.setPlotType("Image", elements[3])
            mg.setPlotType("Image", elements[4])
            plottype = mg.getPlotType()
            expected_values = [2, 1, 0, 2, 2]
            self._assertMultipleResults(plottype, elements, expected_values)
            with self.assertRaises(ValueError):
                mg.setPlotType("asdf", elements[2])

            # Redefine elements
            elements = ["_test_ct_1_1", "_test_ct_1_2", "_test_ct_1_3"]

            # Set values using the controller instead of channels
            mg.setPlotType("Image", "_test_ct_ctrl_1")
            plottype = mg.getPlotType(*elements)
            self._assertResult(plottype, elements, 2)

            # Get values by controller
            mg.setPlotType("Spectrum", *elements)
            plottype = mg.getPlotType("_test_ct_ctrl_1")
            self._assertResult(plottype, elements, 1)

            # Check ret_full_name
            v = TangoDeviceNameValidator()
            full_names = [v.getNames(element)[0] for element in elements]
            plottype = mg.getPlotType(*full_names)
            self._assertResult(plottype, elements, 1)
            mg.setPlotType("Image", *full_names)
            plottype = mg.getPlotType(*elements, ret_full_name=True)
            self._assertResult(plottype, full_names, 2)

        finally:
            mg.cleanUp()
            self.pool.DeleteElement(mg_name)
コード例 #6
0
 def __init__(self, event_callback, unsubscribe_callback, period=0.5):
     QtCore.QThread.__init__(self)
     self.listeners = CaselessDict()
     self.inverse_listeners = {}
     self.event_callback = event_callback
     self.unsubscribe_callback = unsubscribe_callback
     self.period = period
     self._attributes = None
     self._config = CaselessDict()
     self._last_event = TTLDict(default_ttl=10)
     self.attribute_validator = TangoAttributeNameValidator()
     self.device_validator = TangoDeviceNameValidator()
     self.eval_validator = EvaluationAttributeNameValidator()
     self.lock = Lock()
     self.stopped = Event()
コード例 #7
0
ファイル: test_measgrpconf.py プロジェクト: catunlock/sardana
    def test_Monitor(self,
                     elements=[
                         "_test_ct_1_1", "_test_ct_1_2", "_test_ct_1_3",
                         "_test_2d_1_1", '_test_2d_1_2',
                         "_test_mt_1_3/position"
                     ]):
        mg_name = str(uuid.uuid1())
        argin = [mg_name] + elements
        self.pool.CreateMeasurementGroup(argin)
        try:
            mg = Device(mg_name)

            with self.assertRaises(Exception):
                mg.setMonitor("_test_mt_1_3/position")

            mg.setMonitor('_test_2d_1_2')
            mg.setMonitor("_test_ct_1_3")
            expected = [
                "_test_ct_1_3", "_test_ct_1_3", "_test_ct_1_3", "_test_2d_1_2",
                '_test_2d_1_2', None
            ]
            result = mg.getMonitor()
            self._assertMultipleResults(result, elements, expected)

            expected = ["_test_ct_1_3", '_test_2d_1_2', None]
            result = mg.getMonitor(ret_by_ctrl=True)
            ctrls = ['_test_ct_ctrl_1', '_test_2d_ctrl_1', '__tango__']
            self._assertMultipleResults(result, ctrls, expected)

            # Check ret_full_name
            v = TangoDeviceNameValidator()
            counters = [
                "_test_ct_1_1", "_test_ct_1_2", "_test_ct_1_3", '_test_2d_1_1',
                '_test_2d_1_2'
            ]
            full_names = [v.getNames(counter)[0] for counter in counters]
            mg.setMonitor(v.getNames('_test_ct_1_1')[0])
            mg.setMonitor(v.getNames('_test_2d_1_2')[0])

            result = mg.getMonitor(*counters, ret_full_name=True)
            expected = [
                "_test_ct_1_1", "_test_ct_1_1", "_test_ct_1_1", "_test_2d_1_2",
                '_test_2d_1_2'
            ]
            self._assertMultipleResults(result, full_names, expected)
        finally:
            mg.cleanUp()
            self.pool.DeleteElement(mg_name)
コード例 #8
0
ファイル: expdescription.py プロジェクト: sardana-org/sardana
def _to_fqdn(name, logger=None):
    """Helper to convert name into a FQDN URI reference. Works for devices
    and attributes.
    Prior to sardana 2.4.0 Pool element references were using not unique full
    names e.g. pc255:10000/motor/motctrl20/1. This helper converts them into
    FQDN URI references e.g. tango://pc255.cells.es:10000/motor/motctrl20/1.
    It is similarly solved for attribute names.
    """
    full_name = name
    # try to use Taurus 4 to retrieve FQDN URI name
    try:
        from taurus.core.tango.tangovalidator import TangoDeviceNameValidator
        try:
            full_name, _, _ = TangoDeviceNameValidator().getNames(name)
        # it is not a device try as an attribute
        except Exception:
            from taurus.core.tango.tangovalidator import \
                TangoAttributeNameValidator
            full_name, _, _ = TangoAttributeNameValidator().getNames(name)
    # if Taurus3 in use just continue
    except ImportError:
        pass
    if full_name != name and logger:
        msg = ("PQDN full name is deprecated in favor of FQDN full name. "
               "Re-apply pre-scan snapshot configuration in order to "
               "upgrade.")
        logger.warning(msg)
    return full_name
コード例 #9
0
ファイル: test_measgrpconf.py プロジェクト: catunlock/sardana
    def test_Timer(self,
                   elements=[
                       "_test_ct_1_1", "_test_ct_1_2", "_test_ct_1_3",
                       "_test_mt_1_3/position"
                   ]):
        mg_name = str(uuid.uuid1())
        argin = [mg_name] + elements
        self.pool.CreateMeasurementGroup(argin)
        try:
            mg = Device(mg_name)

            result = mg.getTimer("_test_mt_1_3/position")
            with self.assertRaises(Exception):
                mg.setTimer("_test_mt_1_3/position")
            self._assertResult(result, ["_test_mt_1_3/position"], None)
            mg.setTimer('_test_ct_1_3')
            result = mg.getTimer(*elements)
            expected = ['_test_ct_1_3', '_test_ct_1_3', '_test_ct_1_3', None]
            self._assertMultipleResults(result, elements, expected)

            mg.setTimer('_test_ct_1_2')
            result = mg.getTimer(*elements)
            expected = ['_test_ct_1_2', '_test_ct_1_2', '_test_ct_1_2', None]
            self._assertMultipleResults(result, elements, expected)

            result = mg.getTimer(*elements, ret_by_ctrl=True)
            self._assertMultipleResults(result,
                                        ['_test_ct_ctrl_1', '__tango__'],
                                        ['_test_ct_1_2', None])

            # Check ret_full_name
            v = TangoDeviceNameValidator()
            counters = ["_test_ct_1_1", "_test_ct_1_2", "_test_ct_1_3"]
            full_names = [v.getNames(counter)[0] for counter in counters]
            mg.setTimer(v.getNames('_test_ct_1_1')[0])
            result = mg.getTimer()
            expected = ['_test_ct_1_1', '_test_ct_1_1', '_test_ct_1_1', None]
            self._assertMultipleResults(result, elements, expected)
            # TODO ret_full_name gives controler name
            mg.setTimer("_test_ct_1_2")
            result = mg.getTimer(*counters, ret_full_name=True)
            self._assertResult(result, full_names, "_test_ct_1_2")
        finally:
            mg.cleanUp()
            self.pool.DeleteElement(mg_name)
コード例 #10
0
def _get_full_name(device_proxy, logger=None):
    """Obtain Sardana full name as it is used by the server."""
    db = PyTango.Database()
    if db.get_from_env_var():
        db_name = PyTango.ApiUtil.get_env_var("TANGO_HOST")
    else:
        host = device_proxy.get_db_host()  # this is FQDN
        port = device_proxy.get_db_port()
        db_name = host + ":" + port
    full_name = "//" + db_name + "/" + device_proxy.name()
    full_name, _, _ = TangoDeviceNameValidator().getNames(full_name)
    return full_name
コード例 #11
0
def _to_fqdn(name, logger=None):
    full_name = name
    # try to use Taurus 4 to retrieve FQDN
    try:
        from taurus.core.tango.tangovalidator import TangoDeviceNameValidator
        full_name, _, _ = TangoDeviceNameValidator().getNames(name)
    # if Taurus3 in use just continue
    except ImportError:
        pass
    if full_name != name and logger:
        msg = ("PQDN full name is deprecated in favor of FQDN full name."
               " Re-apply configuration in order to upgrade.")
        logger.warning(msg)
    return full_name
コード例 #12
0
 def __init__(self, event_callback, unsubscribe_callback, period=0.5):
     QtCore.QThread.__init__(self)
     self.listeners = CaselessDict()
     self.inverse_listeners = {}
     self.event_callback = event_callback
     self.unsubscribe_callback = unsubscribe_callback
     self.period = period
     self._attributes = CaselessList()
     self._config = CaselessDict()
     self._last_event = TTLDict(default_ttl=10)
     self.attribute_validator = TangoAttributeNameValidator()
     self.device_validator = TangoDeviceNameValidator()
     self.eval_validator = EvaluationAttributeNameValidator()
     self.lock = Lock()
     self.stopped = Event()
コード例 #13
0
def _get_full_name(device_proxy, logger=None):
    """Obtain Sardana full name as it is used by the server."""
    db = PyTango.Database()
    if db.get_from_env_var():
        db_name = PyTango.ApiUtil.get_env_var("TANGO_HOST")
    else:
        host = device_proxy.get_db_host()  # this is FQDN
        port = device_proxy.get_db_port()
        db_name = host + ":" + port
    full_name = db_name + "/" + device_proxy.name()
    # try to use Taurus 4 to retrieve FQDN
    try:
        from taurus.core.tango.tangovalidator import TangoDeviceNameValidator
        full_name, _, _ = TangoDeviceNameValidator().getNames(full_name)
    # if Taurus3 in use just continue
    except ImportError:
        pass
    return full_name
コード例 #14
0
    def run(self, var):
        pars = var.split(".")
        door_name = None
        macro_name = None
        if len(pars) == 1:
            key = pars[0]
        elif len(pars) > 1:
            _, door_name, _ = TangoDeviceNameValidator().getNames(pars[0])
            if door_name is None:  # first string is a Macro name
                macro_name = pars[0]
            if len(pars) == 3:
                macro_name = pars[1]
                key = pars[2]
            else:
                key = pars[1]

        env = self.getEnv(key=key, macro_name=macro_name, door_name=door_name)

        self.output("{:s} = {:s}".format(str(key), str(env)))
コード例 #15
0
class Registry(QtCore.QThread):
    """
    A thread that handles attribute subscriptions.

    The main purpose of this thread is to offload the setting up and
    tearing down of subscriptions from the main UI thread, to make the
    operation "asynchronous". We don't want the UI to lock up briefly
    every time we do this (which may be very often in the case of a
    large, zoomable synoptic).
    """
    def __init__(self, event_callback, unsubscribe_callback, period=0.5):
        QtCore.QThread.__init__(self)
        self.listeners = CaselessDict()
        self.inverse_listeners = {}
        self.event_callback = event_callback
        self.unsubscribe_callback = unsubscribe_callback
        self.period = period
        self._attributes = None
        self._config = CaselessDict()
        self._last_event = TTLDict(default_ttl=10)
        self.attribute_validator = TangoAttributeNameValidator()
        self.device_validator = TangoDeviceNameValidator()
        self.eval_validator = EvaluationAttributeNameValidator()
        self.lock = Lock()
        self.stopped = Event()

    def run(self):
        "A simple loop checking for changes to the attribute list"
        # "batching" the updates should be more efficient than
        # reacting immediately, especially when listeners can come and
        # go quite frequently.
        while not self.stopped.is_set():
            sleep(self.period)
            if self._attributes is not None:
                attributes, self._attributes = self._attributes, None
                with self.lock:
                    self._update(attributes)

    def subscribe(self, models=[]):
        """Set the currently subscribed list of models."""
        attrs = CaselessDict()
        for model in models:
            if self.device_validator.isValid(model):
                # for convenience, we subscribe to State for any devices
                attrs[model + "/State"] = True
            elif (self.attribute_validator.isValid(model)
                  or self.eval_validator.isValid(model)):
                attrs[model] = True
            else:
                print "Invalid Taurus model %s!?" % model
        self._attributes = attrs

    def get_value(self, model):
        evt = self._last_event.get(model)
        if evt:
            return evt.attr_value

    def get_config(self, model):
        return self._config.get(model)

    def handle_event(self, evt_src, *args):
        # lookup the model(s) for this listener and notify them
        models = self.inverse_listeners.get(evt_src, [])
        for model in models:
            self.event_callback(model, evt_src, *args)

    def _update(self, attributes=CaselessDict()):

        "Update the subscriptions; add new ones, remove old ones"

        listeners = set(k.lower() for k in self.listeners.keys())
        new_attrs = set(attributes) - set(listeners)
        old_attrs = set(listeners) - set(attributes)

        for attr in old_attrs:
            if self._attributes:
                # meaning we got a new list of subscriptions, so
                # no point in continuing with this one.
                return
            self._remove_listener(attr)
            self._last_event.pop(attr, None)

        for attr in new_attrs:
            if self._attributes:
                return
            try:
                self._add_listener(attr)
            except (TypeError, PyTango.DevFailed) as e:
                print "Failed to setup listener for", attr, e

        self.unsubscribe_callback(old_attrs)

    def _add_listener(self, model):
        try:
            listener = self.listeners[model] = Attribute(model)
            # to make loopkups more efficient, we also keep an "inverted"
            # mapping of listeners->models. But since some models may map
            # to the *same* listener (e.g. eval expressions), this must
            # be a one-to-many map.
            if listener in self.inverse_listeners:
                self.inverse_listeners[listener][model] = True
            else:
                self.inverse_listeners[listener] = CaselessDict([(model, True)
                                                                 ])
            listener.addListener(self.handle_event)
            return listener
        except (TaurusException, AttributeError) as e:
            print "Failed to subscribe to model %s! %s" % (model, e)

    def _remove_listener(self, model):
        listener = self.listeners.pop(model)
        models = self.inverse_listeners[listener]
        models.pop(model)
        if not models:
            self.inverse_listeners.pop(listener)
        listener.removeListener(self.handle_event)

    def get_listener(self, model):
        "return the listener for a given model"
        if model in self.listeners:
            return self.listeners[model]
        for attr in self.listeners.values():
            if attr.getNormalName().lower() == model.lower():
                return attr

    def stop(self):
        self.stopped.set()

    def clear(self):
        self._attributes.clear()
        self._last_event.clear()
        self._update()
コード例 #16
0
class Registry(QtCore.QThread):

    """
    A thread that handles attribute subscriptions.

    The main purpose of this thread is to offload the setting up and
    tearing down of subscriptions from the main UI thread, to make the
    operation "asynchronous". We don't want the UI to lock up briefly
    every time we do this (which may be very often in the case of a
    large, zoomable synoptic).
    """

    def __init__(self, event_callback, unsubscribe_callback, period=0.5):
        QtCore.QThread.__init__(self)
        self.listeners = CaselessDict()
        self.inverse_listeners = {}
        self.event_callback = event_callback
        self.unsubscribe_callback = unsubscribe_callback
        self.period = period
        self._attributes = CaselessList()
        self._config = CaselessDict()
        self._last_event = TTLDict(default_ttl=10)
        self.attribute_validator = TangoAttributeNameValidator()
        self.device_validator = TangoDeviceNameValidator()
        self.eval_validator = EvaluationAttributeNameValidator()
        self.lock = Lock()
        self.stopped = Event()

    def run(self):
        "A simple loop checking for changes to the attribute list"
        # "batching" the updates should be more efficient than
        # reacting immediately, especially when listeners can come and
        # go quite frequently.
        while not self.stopped.is_set():
            sleep(self.period)
            if self._attributes:
                attributes, self._attributes = self._attributes, CaselessList()
                with self.lock:
                    self._update(attributes)

    def subscribe(self, models=[]):
        """Set the currently subscribed list of models."""
        attrs = CaselessDict()
        for model in models:
            if self.device_validator.isValid(model):
                # for convenience, we subscribe to State for any devices
                attrs[model + "/State"] = True
            elif self.attribute_validator.isValid(model) or self.eval_validator.isValid(model):
                attrs[model] = True
            else:
                print "Invalid Taurus model %s!?" % model
        self._attributes = attrs

    def get_value(self, model):
        evt = self._last_event.get(model)
        if evt:
            return evt.attr_value

    def get_config(self, model):
        return self._config.get(model)

    def handle_event(self, evt_src, *args):
        # lookup the model(s) for this listener and notify them
        models = self.inverse_listeners.get(evt_src, [])
        for model in models:
            self.event_callback(model, evt_src, *args)

    def _update(self, attributes=CaselessDict()):

        "Update the subscriptions; add new ones, remove old ones"

        listeners = set(k.lower() for k in self.listeners.keys())
        new_attrs = set(attributes) - set(listeners)
        old_attrs = set(listeners) - set(attributes)

        for attr in old_attrs:
            if self._attributes:
                # meaning we got a new list of subscriptions, so
                # no point in continuing with this one.
                return
            self._remove_listener(attr)
            self._last_event.pop(attr, None)

        for attr in new_attrs:
            if self._attributes:
                return
            try:
                self._add_listener(attr)
            except PyTango.DevFailed as e:
                print "Failed to setup listener for", attr, e

        self.unsubscribe_callback(old_attrs)

    def _add_listener(self, model):
        try:
            listener = self.listeners[model] = Attribute(model)
            # to make loopkups more efficient, we also keep an "inverted"
            # mapping of listeners->models. But since some models may map
            # to the *same* listener (e.g. eval expressions), this must
            # be a one-to-many map.
            if listener in self.inverse_listeners:
                self.inverse_listeners[listener][model] = True
            else:
                self.inverse_listeners[listener] = CaselessDict([(model, True)])
            listener.addListener(self.handle_event)
            return listener
        except AttributeError:
            print "Failed to subscribe to model %s!" % model

    def _remove_listener(self, model):
        listener = self.listeners.pop(model)
        models = self.inverse_listeners[listener]
        print models, model
        models.pop(model)
        if not models:
            self.inverse_listeners.pop(listener)
        listener.removeListener(self.handle_event)

    def get_listener(self, model):
        "return the listener for a given model"
        if model in self.listeners:
            return self.listeners[model]
        for attr in self.listeners.values():
            if attr.getNormalName().lower() == model.lower():
                return attr

    def stop(self):
        self.stopped.set()

    def clear(self):
        self._attributes.clear()
        self._last_event.clear()
        self._update()
コード例 #17
0
ファイル: test_measgrpconf.py プロジェクト: catunlock/sardana
    def test_PlotAxes(self,
                      elements=[
                          "_test_ct_1_1", "_test_ct_1_2", "_test_ct_1_3",
                          "_test_2d_1_3", "_test_mt_1_3/position"
                      ]):
        mg_name = str(uuid.uuid1())
        argin = [mg_name] + elements
        self.pool.CreateMeasurementGroup(argin)

        try:
            mg = Device(mg_name)
            mg.setPlotType("Image", elements[0])
            mg.setPlotType("Spectrum", elements[1])
            mg.setPlotType("No", elements[2])
            mg.setPlotType("Image", elements[3])
            mg.setPlotType("Image", elements[4])
            result = mg.getPlotAxes()
            self._assertResult(result, elements, [])

            mg.setPlotAxes(["<idx>", "<idx>"], elements[0])
            mg.setPlotAxes(["<mov>"], elements[1])
            with self.assertRaises(Exception):
                mg.setPlotAxes(['<mov>'], elements[2])
            mg.setPlotAxes(["<idx>", "<idx>"], elements[3])
            mg.setPlotAxes(["<idx>", "<idx>"], elements[4])

            result = mg.getPlotAxes()
            expected_result = [['<idx>', '<idx>'], ['<mov>'], [],
                               ['<idx>', '<idx>'], ['<idx>', '<idx>']]
            self._assertMultipleResults(result, elements, expected_result)

            mg.setPlotAxes(["<mov>", "<idx>"], elements[0])
            mg.setPlotAxes(["<idx>"], elements[1])
            result = mg.getPlotAxes()
            expected_result = [['<mov>', '<idx>'], ['<idx>'], [],
                               ['<idx>', '<idx>'], ['<idx>', '<idx>']]
            self._assertMultipleResults(result, elements, expected_result)

            mg.setPlotAxes(["<mov>", "<mov>"], elements[0])
            result = mg.getPlotAxes()
            expected_result = [['<mov>', '<mov>'], ['<idx>'], [],
                               ['<idx>', '<idx>'], ['<idx>', '<idx>']]
            self._assertMultipleResults(result, elements, expected_result)

            with self.assertRaises(RuntimeError):
                mg.setPlotAxes(["<mov>"], elements[2])
            with self.assertRaises(ValueError):
                mg.setPlotAxes(["<mov>", "<idx>"], elements[1])
            with self.assertRaises(ValueError):
                mg.setPlotAxes(["<mov>"], elements[0])

            elements = ["_test_ct_1_1", "_test_ct_1_2", "_test_ct_1_3"]
            # Set values using the controller instead of channels
            with self.assertRaises(Exception):
                mg.setPlotAxes(["<mov>"], "_test_ct_ctrl_1")
            # TODO get method by controller doesn't give the order
            # Get values by controller
            result = mg.getPlotAxes("_test_ct_ctrl_1")
            expected_result = [['<mov>', '<mov>'], ['<idx>'], []]
            self._assertMultipleResults(result, elements, expected_result)

            # Check ret_full_name
            v = TangoDeviceNameValidator()
            full_names = [v.getNames(element)[0] for element in elements]
            result = mg.getPlotAxes(*full_names)
            expected_result = [['<mov>', '<mov>'], ['<idx>'], []]
            self._assertMultipleResults(result, elements, expected_result)
            mg.setPlotAxes(["<idx>", "<idx>"], full_names[0])
            mg.setPlotAxes(["<mov>"], full_names[1])
            result = mg.getPlotAxes(*elements, ret_full_name=True)
            expected_result = [['<idx>', '<idx>'], ['<mov>'], []]
            self._assertMultipleResults(result, full_names, expected_result)
        finally:
            mg.cleanUp()
            self.pool.DeleteElement(mg_name)
コード例 #18
0
def from_name_to_tango(name):
    try:
        from taurus.core.tango.tangovalidator import TangoDeviceNameValidator
        return TangoDeviceNameValidator().getNames(name)
    except ImportError:
        return _from_name_to_tango(name)