def _build_elements(self): self._user_elements = [] self._physical_elements = {} self._physical_elements_set = set() pool = self._get_pool() for user_element_id in self._user_element_ids: # an internal element internal = isinstance(user_element_id, int) if internal: try: user_element = pool.get_element(id=user_element_id) except KeyError: self._pending = True self._user_elements = None self._physical_elements = None self._physical_elements_set = None raise internal = self._is_managed_element(user_element) if not internal: user_element_id = user_element.get_source() # a tango channel or non internal element (ex: ioregister or motor # in measurement group) if not internal: validator = TangoAttributeNameValidator() params = validator.getUriGroups(user_element_id) params['pool'] = self._get_pool() user_element = PoolExternalObject(**params) self.add_user_element(user_element) self._pending = False
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 _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
def on_message(self, json_data): """Executed when a message comes from the client through the websocket. It expected that json_data is a JSON encoded string. It should be a JSON object with *models* member. the value of *models* should be an array of strings, each representing a model name. Example: { models : [ "BO/S05/Pump5/Pressure", "BO/S05/Pump5/Pressure#unit", "sys/tg_test/1/double_scalar" ] } So far, only attributes and configuration parameters are supported. A TaurusWebXXX object will be created for each different model. This object subscribes itself to taurus events. The callback usually transforms such an event into a JSON encoded string which is sent back to the client through this same web socket. """ data = json_decode(json_data) if 'models' in data: self.clear_models() model_names = set(data['models']) for model_name in model_names: model_name = str(model_name) if TangoAttributeNameValidator().isValid(model_name): web_model = TaurusWebAttribute(self, model_name) elif TangoConfigurationNameValidator().isValid(model_name): web_model = TaurusWebConfiguration(self, model_name) else: continue self.models.add(web_model)
def on_message(self, json_data): data = json_decode(json_data) if 'models' in data: self.clear_models() model_names = set(data['models']) for model_name in model_names: model_name = str(model_name) if TangoAttributeNameValidator().isValid(model_name): web_model = TaurusWebAttribute(self, model_name) elif TangoConfigurationNameValidator().isValid(model_name): web_model = TaurusWebConfiguration(self, model_name) else: continue self.models.add(web_model)
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 create_measurement_group(self, **kwargs): name = kwargs['name'] elem_ids = kwargs["user_elements"] kwargs['pool'] = self kwargs["pool_name"] = self.name td = TYPE_MAP_OBJ[ElementType.MeasurementGroup] klass = td.klass auto_full_name = td.auto_full_name full_name = kwargs.get("full_name", auto_full_name.format(**kwargs)) kwargs.pop('pool_name') self.check_element(name, full_name) for elem_id in elem_ids: if isinstance(elem_id, int): self.pool.get_element(id=elem_id) else: tg_attr_validator = TangoAttributeNameValidator() params = tg_attr_validator.getUriGroups(elem_id) if params is None: raise Exception("Invalid channel name %s" % elem_id) eid = kwargs.get('id') if eid is None: kwargs['id'] = eid = self.get_new_id() else: self.reserve_id(eid) elem = klass(**kwargs) ret = self.add_element(elem) self.fire_event(EventType("ElementCreated"), elem) return ret
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()
NEXUS_SRC = re.compile( r'^((nxfile|nxdata):)(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*)(\[[0-9,: ]*?\]))?' ) ASCII_SRC = re.compile( r'^((file):)(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*)(\[[0-9,: ]*?\]))?') # set some named constants # columns: NUMCOLS = 4 X, Y, TITLE, VIS = range(NUMCOLS) SRC_ROLE = Qt.Qt.UserRole + 1 PROPS_ROLE = Qt.Qt.UserRole + 2 # TODO: Tango-centric (use agnostic validation) from taurus.core.tango.tangovalidator import TangoAttributeNameValidator ATTRNAMEVALIDATOR = TangoAttributeNameValidator() class Component(object): def __init__(self, src): self.src = src self.display = '' self.icon = Qt.QIcon() self.ok = True self._attrnamevalidator = ATTRNAMEVALIDATOR self._dbCache = taurus.Authority() self.setSrc(src) def update(self): self.setSrc(self.src)
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()