def delete_element(self, name): try: elem = self.get_element(name=name) except: try: elem = self.get_element(full_name=name) except: raise Exception("There is no element with name '%s'" % name) elem_type = elem.get_type() if elem_type == ElementType.Controller: if len(elem.get_elements()) > 0: raise Exception("Cannot delete controller with elements. " "Delete elements first") elif elem_type == ElementType.Instrument: if elem.has_instruments(): raise Exception("Cannot delete instrument with instruments. " "Delete instruments first") if elem.has_elements(): raise Exception("Cannot delete instrument with elements") parent_instrument = elem.parent_instrument if parent_instrument is not None: parent_instrument.remove_instrument(elem) elif hasattr(elem, "get_controller"): ctrl = elem.get_controller() ctrl.remove_element(elem) instrument = elem.instrument if instrument is not None: instrument.remove_element(elem) self.remove_element(elem) self.fire_event(EventType("ElementDeleted"), elem)
def create_instrument(self, full_name, klass_name, id=None): is_root = full_name.count('/') == 1 if is_root: parent_full_name, _ = '', full_name[1:] parent = None else: parent_full_name, _ = full_name.rsplit('/', 1) try: parent = self.get_element_by_full_name(parent_full_name) except: raise Exception("No parent instrument named '%s' found" % parent_full_name) if parent.get_type() != ElementType.Instrument: raise Exception("%s is not an instrument as expected" % parent_full_name) self.check_element(full_name, full_name) td = TYPE_MAP_OBJ[ElementType.Instrument] klass = td.klass if id is None: id = self.get_new_id() else: self.reserve_id(id) elem = klass(id=id, name=full_name, full_name=full_name, parent=parent, klass=klass_name, pool=self) if parent: parent.add_instrument(elem) ret = self.add_element(elem) self.fire_event(EventType("ElementCreated"), elem) return ret
def _set_value_ref_pattern(self, value_ref_pattern, propagate=1): self._value_ref_pattern = value_ref_pattern if not propagate: return self.fire_event( EventType("value_ref_pattern", priority=propagate), value_ref_pattern)
def _set_step_per_unit(self, step_per_unit, propagate=1): self._step_per_unit = step_per_unit if propagate: self.fire_event(EventType("step_per_unit", priority=propagate), step_per_unit) # force ask controller for new position to send priority event self.get_position(cache=False, propagate=2)
def set_moveable(self, moveable, propagate=1, to_fqdn=True): self._moveable = moveable if self._moveable != 'None' and self._moveable is not None: if to_fqdn: moveable = _to_fqdn(moveable, logger=self) self._moveable_obj = self.pool.get_element_by_full_name(moveable) self.fire_event(EventType("moveable", priority=propagate), moveable)
def set_acquisition_mode(self, acquisition_mode, propagate=1): self._acquisition_mode = acquisition_mode self._config_dirty = True # acquisition mode goes to configuration if not propagate: return self.fire_event(EventType("acquisition_mode", priority=propagate), acquisition_mode)
def set_synchronization(self, synchronization, propagate=1): self._synchronization = synchronization self._config_dirty = True # acquisition mode goes to configuration if not propagate: return self.fire_event(EventType("synchronization", priority=propagate), synchronization)
def set_configuration_from_user(self, cfg, propagate=1, to_fqdn=True): self._config.set_configuration_from_user(cfg, to_fqdn) self._config_dirty = True if not propagate: return self.fire_event(EventType("configuration", priority=propagate), self._config.get_configuration_for_user())
def _set_value_ref_enabled(self, value_ref_enabled, propagate=1): self._value_ref_enabled = value_ref_enabled if not propagate: return self.fire_event( EventType("value_ref_enabled", priority=propagate), value_ref_enabled)
def set_configuration(self, config=None, propagate=1, to_fqdn=True): self._config._use_fqdn = to_fqdn self._config.configuration = config self._config_dirty = True if not propagate: return self.fire_event(EventType("configuration", priority=propagate), config)
def set_configuration(self, config=None, propagate=1): if config is None: config = self._build_configuration() else: # create a configuration based on a new configuration user_elem_ids = {} pool = self.pool for c, c_data in config['controllers'].items(): external = isinstance(c, (str, unicode)) # attention: following line only prepared for 1 unit per controller for channel_data in c_data['units']['0']['channels'].values(): if external: element = id = channel_data['full_name'] channel_data['source'] = id else: element = pool.get_element_by_full_name( channel_data['full_name']) id = element.id channel_data = self._build_channel_defaults( channel_data, element) if channel_data["enabled"]: user_elem_ids[channel_data['index']] = id # sorted ids may not be consecutive (if a channel is disabled) indexes = sorted(user_elem_ids.keys()) self.set_user_element_ids([user_elem_ids[idx] for idx in indexes]) # checks g_timer, g_monitor = config['timer'], config['monitor'] # attention: following line only prepared for 1 unit per controller timer_ctrl_data = config['controllers'][ g_timer.controller]['units']['0'] if timer_ctrl_data['timer'] != g_timer: self.warning('unit timer and global timer mismatch. ' 'Using global timer') self.debug( 'For controller %s, timer is defined as channel %s. ' 'The global timer is set to channel %s which belongs ' 'to the same controller', g_timer.controller.name, timer_ctrl_data['timer'].name, g_timer.name) timer_ctrl_data['timer'] = g_timer # attention: following line only prepared for 1 unit per controller monitor_ctrl_data = config['controllers'][ g_monitor.controller]['units']['0'] if monitor_ctrl_data['monitor'] != g_monitor: self.warning('unit monitor and global monitor mismatch. ' 'Using global monitor') self.debug( 'For controller %s, monitor is defined as channel %s. ' 'The global timer is set to channel %s which belongs ' 'to the same controller', g_monitor.controller.name, monitor_ctrl_data['monitor'].name, g_monitor.name) monitor_ctrl_data['monitor'] != g_monitor self._config = config self._config_dirty = True if not propagate: return self.fire_event(EventType("configuration", priority=propagate), config)
def create_motor_group(self, **kwargs): name = kwargs['name'] elem_ids = kwargs["user_elements"] kwargs['pool'] = self kwargs["pool_name"] = self.name td = TYPE_MAP_OBJ[ElementType.MotorGroup] 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: elem = self.pool.get_element(id=elem_id) if elem.get_type() not in (ElementType.Motor, ElementType.PseudoMotor): raise Exception("%s is not a motor" % elem.name) 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
def append_value(self, value, timestamp=None, propagate=1): cumulation = self.cumulation cumulation.append_value(value, timestamp) if not propagate: return self.fire_event(EventType("value", priority=propagate), cumulation.value)
def start(self): self._start_time = time.time() self._stopped = False self._started = True self._position = None self._position_event.clear() self._id = 0 self.fire_event(EventType("state"), State.Moving)
def set_simulation_mode(self, simulation_mode, propagate=1): self._simulation_mode = simulation_mode if not propagate: return if simulation_mode == self._simulation_mode: # current state is equal to last state_event. Skip event return self.fire_event(EventType("simulation_mode", priority=propagate), simulation_mode)
def rename_element(self, old_name, new_name): elem = self.get_element_by_name(old_name) if type(elem) == PoolMeasurementGroup: elem.rename_element(old_name, new_name) else: elem.controller.rename_element(old_name, new_name) PoolContainer.rename_element(self, old_name, new_name) elem = self.get_element_by_name(new_name) self.fire_event(EventType("ElementChanged"), elem)
def _set_state(self, state, propagate=1): self._state = state if not propagate: return if state == self._state_event: # current state is equal to last state_event. Skip event return self._state_event = state self.fire_event(EventType("state", priority=propagate), state)
def unset_env(self, key): """Unsets the environment for the given key. :param key: the key for the environment to be unset""" ret = self.environment_manager.unsetEnv(key) # list is unhashable - convert to a tuple if isinstance(key, list): key = tuple(key) evt = {'del': {key: None}} self.fire_event(EventType("EnvironmentChanged"), evt) return ret
def _set_status(self, status, propagate=1): self._status = status if not propagate: return s_evt = self._status_event if s_evt is not None and len(status) == len(s_evt) and status == s_evt: # current status is equal to last status_event. Skip event return self._status_event = status self.fire_event(EventType("status", priority=propagate), status)
def create_controller(self, **kwargs): ctrl_type = kwargs['type'] lib = kwargs['library'] class_name = kwargs['klass'] name = kwargs['name'] elem_type = ElementType[ctrl_type] mod_name, _ = os.path.splitext(lib) kwargs['module'] = mod_name td = TYPE_MAP_OBJ[ElementType.Controller] klass_map = td.klass auto_full_name = td.auto_full_name kwargs['full_name'] = full_name = \ kwargs.get("full_name", auto_full_name.format(**kwargs)) self.check_element(name, full_name) ctrl_class_info = None ctrl_lib_info = self.ctrl_manager.getControllerLib(mod_name) if ctrl_lib_info is not None: ctrl_class_info = ctrl_lib_info.get_controller(class_name) kwargs['pool'] = self kwargs['class_info'] = ctrl_class_info kwargs['lib_info'] = ctrl_lib_info eid = kwargs.get('id') if eid is None: kwargs['id'] = eid = self.get_new_id() else: self.reserve_id(eid) # For pseudo controllers make sure 'role_ids' is given klass = klass_map.get(elem_type, PoolController) if elem_type in TYPE_PSEUDO_ELEMENTS: motor_roles = kwargs['role_ids'] # make sure the properties (that may have come from a case insensitive # environment like tango) are made case sensitive props = {} if ctrl_class_info is None: ctrl_prop_info = {} else: ctrl_prop_info = ctrl_class_info.ctrl_properties for k, v in kwargs['properties'].items(): info = ctrl_prop_info.get(k) if info is None: props[k] = v else: props[info.name] = v kwargs['properties'] = props ctrl = klass(**kwargs) ret = self.add_element(ctrl) self.fire_event(EventType("ElementCreated"), ctrl) return ret
def run(self): self._running = True try: while len(self.active_events) > 0 and not self.is_stopped(): self.wait_active() self.fire_active() self.wait_passive() self.fire_passive() self._id += 1 finally: self._started = False self._running = False self._stopped = False self.fire_event(EventType("state"), State.On)
def _set_instrument(self, instrument, propagate=1): if self._instrument is not None: self._instrument().remove_element(self) new_instrument_name = "" if instrument is None: self._instrument = None else: self._instrument = weakref.ref(instrument) new_instrument_name = instrument.full_name instrument.add_element(self) if not propagate: return self.fire_event(EventType("instrument", priority=propagate), new_instrument_name)
def create_element(self, **kwargs): etype = kwargs['type'] ctrl_id = kwargs['ctrl_id'] axis = kwargs['axis'] elem_type = ElementType[etype] name = kwargs['name'] try: ctrl = self.get_element(id=ctrl_id) except: raise Exception("No controller with id '%d' found" % ctrl_id) elem_axis = ctrl.get_element(axis=axis) if elem_axis is not None: raise Exception("Controller already contains axis %d (%s)" % (axis, elem_axis.get_name())) kwargs['pool'] = self kwargs['ctrl'] = ctrl kwargs['ctrl_name'] = ctrl.get_name() td = TYPE_MAP_OBJ[elem_type] klass = td.klass auto_full_name = td.auto_full_name full_name = kwargs.get("full_name", auto_full_name.format(**kwargs)) self.check_element(name, full_name) if ctrl.is_online(): ctrl_types, ctrl_id = ctrl.get_ctrl_types(), ctrl.get_id() if elem_type not in ctrl_types: ctrl_type_str = ElementType.whatis(ctrl_types[0]) raise Exception("Cannot create %s in %s controller" % (etype, ctrl_type_str)) # check if controller is online # check if axis is allowed # create the element in the controller eid = kwargs.get('id') if eid is None: kwargs['id'] = eid = self.get_new_id() else: self.reserve_id(eid) elem = klass(**kwargs) ctrl.add_element(elem) ret = self.add_element(elem) self.fire_event(EventType("ElementCreated"), elem) return ret
def set_integration_time(self, integration_time, propagate=1): """Set the integration time for this object. :param integration_time: integration time in seconds to set :type integration_time: :obj:`float` :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: :obj:`int` """ if integration_time == self._integration_time: # integration time is not changed. Do nothing return self._integration_time = integration_time if not propagate: return self.fire_event(EventType("integration_time", priority=propagate), integration_time)
def reload_controller_lib(self, lib_name): manager = self.ctrl_manager old_lib = manager.getControllerLib(lib_name) new_elements, changed_elements, deleted_elements = [], [], [] old_ctrl_classes = () if old_lib is not None: ctrl_infos = old_lib.get_controllers() pool_ctrls = self.get_elements_by_type(ElementType.Controller) init_pool_ctrls = [] for pool_ctrl in pool_ctrls: if pool_ctrl.get_ctrl_info() in ctrl_infos: init_pool_ctrls.append(pool_ctrl) old_ctrl_classes = ctrl_infos changed_elements.append(old_lib) new_lib = manager.reloadControllerLib(lib_name) if old_lib is None: new_elements.extend(new_lib.get_controllers()) new_elements.append(new_lib) else: new_names = set([ctrl.name for ctrl in new_lib.get_controllers()]) old_names = set([ctrl.name for ctrl in old_lib.get_controllers()]) changed_names = set.intersection(new_names, old_names) deleted_names = old_names.difference(new_names) new_names = new_names.difference(old_names) for new_name in new_names: new_elements.append(new_lib.get_controller(new_name)) for changed_name in changed_names: changed_elements.append(new_lib.get_controller(changed_name)) for deleted_name in deleted_names: deleted_elements.append(old_lib.get_controller(deleted_name)) evt = { "new": new_elements, "change": changed_elements, "del": deleted_elements } self.fire_event(EventType("ElementsChanged"), evt) if old_lib is not None: for pool_ctrl in init_pool_ctrls: pool_ctrl.re_init()
def set_env(self, key, value): """Sets the environment key to the new value and stores it persistently. :param key: the key for the environment :param value: the value for the environment :return: a tuple with the key and value objects stored""" env_man = self.environment_manager if env_man.hasEnv(key): evt_type = "change" else: evt_type = "new" k, v = self.environment_manager.setEnv(key, value) evt = {evt_type: {k: v}} self.fire_event(EventType("EnvironmentChanged"), evt) return k, v
def fire_active(self): # check if some events needs to be skipped i = 0 while i < len(self.active_events) - 1: candidate = self.active_events[i + 1] if self.initial_domain_in_use is SynchDomain.Time: candidate += self._start_time now = time.time() elif self.initial_domain_in_use is SynchDomain.Position: now = self._position if self._condition(now, candidate): i += 1 else: break self._id += i self.fire_event(EventType("active"), self._id) self.active_events = self.active_events[i + 1:] self.passive_events = self.passive_events[i:]
def change_env(self, data): env_man = self.environment_manager new_change_env = data.get('new', {}) new_change_env.update(data.get('change', {})) del_env = data.get('del', []) new, change = {}, {} for key, value in new_change_env.items(): d = new if env_man.hasEnv(key): d = change d[key] = value del_keys = env_man.unsetEnv(del_env) env_man.setEnvObj(new_change_env) evt = dict(new=new, change=change) evt['del'] = del_keys self.fire_event(EventType("EnvironmentChanged"), evt)
def set_integration_time(self, integration_time, propagate=1): total_time = integration_time + self.latency_time synch = [{ SynchParam.Delay: { SynchDomain.Time: 0 }, SynchParam.Active: { SynchDomain.Time: integration_time }, SynchParam.Total: { SynchDomain.Time: total_time }, SynchParam.Repeats: 1 }] self.set_synchronization(synch) if not propagate: return self.fire_event(EventType("integration_time", priority=propagate), integration_time)
def rename_element(self, old_name, new_name, propagate=1): """Rename element in the controller. :param old_name: old name of the element :type old_name: :obj:`str` :param new_name: new name of the element :type new_name: :obj:`str` :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: :obj:`int` """ element = self._element_names.pop(old_name, None) if element is None: raise KeyError('There is no element with name %s' % old_name) self._element_names[new_name] = element if propagate: elements = self.get_elements() elements = [elements[_id].name for _id in sorted(elements)] self.fire_event(EventType("elementlist", priority=propagate), elements)