class ProxiesDict(CaselessDefaultDict,Object): ''' Dictionary that stores PyTango.DeviceProxies/AttributeProxies It is like a normal dictionary but creates a new proxy each time that the "get" method is called All keys translated to full tango URIs (fqdn=True by default) An earlier version is used in PyTangoArchiving.utils module Taurus3+ support is not tested ''' def __init__(self,use_tau = False, tango_host = ''): self.log = Logger('ProxiesDict') self.log.setLogLevel('INFO') self.use_tau = TAU and use_tau self.tango_host = tango_host self.call__init__(CaselessDefaultDict,self.__default_factory__) def translate(self, dev): try: attr = get_attr_name(dev,False) if self.tango_host and ':' not in dev: dev = self.tango_host + '/' + dev dev = get_dev_name(dev,full=True,fqdn=True).lower() except: dev = get_dev_name(dev,full=True,fqdn=False).lower() if attr: dev += '/'+attr return dev def __default_factory__(self,dev_name): ''' Called by defaultdict_fromkey.__missing__ method If a key doesn't exists this method is called and returns a proxy for a given device. If the proxy caused an exception (usually because device doesn't exists) a None value is returned ''' dev_name = self.translate(dev_name) if dev_name not in self.keys(): self.log.debug( 'Getting a Proxy for %s'%dev_name) try: devklass,attrklass = (TAU.Device,TAU.Attribute) \ if self.use_tau else \ (PyTango.DeviceProxy,PyTango.AttributeProxy) klass = (devklass,attrklass)[get_attr_name(dev_name,False)] dev = klass(dev_name) except Exception,e: print('ProxiesDict: %s doesnt exist!'%dev_name) dev = None return dev
class ProxiesDict(CaselessDefaultDict,Object): ''' Dictionary that stores PyTango.DeviceProxies It is like a normal dictionary but creates a new proxy each time that the "get" method is called An earlier version is used in PyTangoArchiving.utils module This class must be substituted by Tau.Core.TauManager().getFactory()() ''' def __init__(self,use_tau = False, tango_host = ''): self.log = Logger('ProxiesDict') self.log.setLogLevel('INFO') self.use_tau = TAU and use_tau self.tango_host = tango_host self.call__init__(CaselessDefaultDict,self.__default_factory__) def __default_factory__(self,dev_name): ''' Called by defaultdict_fromkey.__missing__ method If a key doesn't exists this method is called and returns a proxy for a given device. If the proxy caused an exception (usually because device doesn't exists) a None value is returned ''' if self.tango_host and ':' not in dev_name: dev_name = self.tango_host + '/' + dev_name if dev_name not in self.keys(): self.log.debug( 'Getting a Proxy for %s'%dev_name) try: devklass,attrklass = (TAU.Device,TAU.Attribute) \ if self.use_tau else \ (PyTango.DeviceProxy,PyTango.AttributeProxy) dev = (attrklass if str(dev_name).count('/')==(4 if ':' in dev_name else 3) else devklass)(dev_name) except Exception,e: print('ProxiesDict: %s doesnt exist!'%dev_name) dev = None return dev
class ServersDict(CaselessDict, Object): ''' Dictionary of TServer classes indexed by server/instance names and loaded using wildcard expressions. Provides Jive/Astor functionality to a list of servers and allows to select/start/stop them by host, class or devices Its purpose is to allow generic start/stop of lists of Tango DeviceServers. This methods of selection provide new ways of search apart of Jive-like selection. @attention Dict keys are lower case, to get the real server name each key returns a TServer object with a .name attribute @par Usage: <pre> from fandango import Astor astor = Astor() astor.load_by_name('snap*') astor.keys() ['snapmanager/1', 'snaparchiver/1', 'snapextractor/1'] server = astor['snaparchiver/1'] server.get_device_list() ['dserver/snaparchiver/1', 'archiving/snaparchiver/1'] astor.states() server.get_all_states() dserver/snaparchiver/1: ON archiving/snaparchiver/1: ON astor.get_device_host('archiving/snaparchiver/1') palantir01 astor.stop_servers('snaparchiver/1') astor.stop_all_servers() astor.start_servers('snaparchiver/1','palantir01',wait=1000) astor.set_server_level('snaparchiver/1','palantir01',4) #Setting the polling of a device: server = astor['PySignalSimulator/bl11'] for dev_name in server.get_device_list(): dev = server.get_device(dev_name) attrs = dev.get_attribute_list() [dev.poll_attribute(attr,3000) for attr in attrs] </pre> ''' def __init__(self, pattern='', klass='', devs_list='', servers_list='', hosts='', loadAll=False, log='WARNING', logger=None, tango_host=''): ''' def __init__(self,pattern='', klass='',devs_list='',servers_list=''): The ServersDict can be initialized using any of the three argument lists or a wildcard for Database.get_server_list(pattern) ServersDict('*') can be used to load all servers in database ''' self.call__init__(CaselessDict, self) if logger is None: self.log = Logger('ServersDict') self.log.setLogLevel(log) else: self.log = logger self.log.debug('ServersDict(%s)' % ','.join( map(str, (pattern, klass, devs_list, servers_list, hosts, loadAll, log, logger, tango_host)))) ## proxies will keep a list of persistent device proxies self.proxies = ProxiesDict(tango_host=tango_host) ## db will keep a persistent link to PyTango database self.db = get_database() if not tango_host else get_database( *(tango_host.split(':'))) self.server_names = self.keys self.servers = self.values if loadAll: self.load_all_servers() elif klass: self.load_by_class(klass) elif devs_list: self.load_from_devs_list(devs_list) elif servers_list: self.load_from_servers_list(servers_list) #elif pattern: self.load_from_servers_list(self.db.get_server_list(pattern)) elif hosts: hosts = type(hosts) is str and (',' in hosts and hosts.split(',') or [hosts]) or hosts for h in hosts: self.load_by_host(h) elif pattern: self.load_by_name(pattern) #dict.__init__(self) ## @name Dict methods # @{ def __arranged_key(self, key): return key if key.count('/') <= 1 else key.split('/', 1)[1] #def __getitem__(self,key): dicts.CaselessDict.__getitem__(self,self.__arranged_key(key)) #def __setitem__(self,key,value): dicts.CaselessDict.__setitem__(self,self.__arranged_key(key),value) #def __delitem__(self,key): dicts.CaselessDict.__delitem__(self,self.__arranged_key(key)) #def __contains__(self,key): dicts.CaselessDict.__contains__(self,self.__arranged_key(key)) #def has_key(self,key): dicts.CaselessDict.has_key(self,self.__arranged_key(key)) #def get(self,key,def_val=None): dicts.CaselessDict.get(self,self.__arranged_key(key),def_val) #def pop(self,key,def_val=None): dicts.CaselessDict.pop(self,self.__arranged_key(key),def_val) #def setdefault(self,key,def_val=None): dicts.CaselessDict.pop(self,self.__arranged_key(key),def_val) def __repr__(self): return self.get_report() def __str__(self): return self.get_report() ## @} ## @name Database access # @{ def load_all_servers(self): """ It loads all device servers declared in Tango database """ #classes = self.db.get_device_family('dserver/*') #for c in classes: # self.load_by_exec(c) print self.db self.load_from_servers_list(self.db.get_server_list()) def load_by_name(self, name): ''' Initializes the dict with all the servers matching a given name (usually the executable name or class). A list of names is also possible.''' if type(name) in (list, set): for pattern in name: self.load_by_name(pattern) else: if name.count('/') >= 2 and not name.startswith('dserver/'): return self.load_from_devs_list([name]) else: server_name = name.replace('dserver/', '') self.log.info('loading by %s server_name' % server_name) family = server_name.split( '/')[0] if '/' in server_name else server_name member = server_name.split( '/')[1] if '/' in server_name else '*' servers_list = self.get_devs_from_db('dserver/%s/%s' % (family, member)) #servers_list = [s for s in self.db.get_server_list() if fun.matchCl('%s/%s'%(family,member),s)] if servers_list: self.load_from_servers_list( [d.replace('dserver/', '') for d in servers_list], check=False) self.log.info('%d servers loaded' % len(servers_list)) return len(servers_list) else: self.log.warning('No server matches with %s (family=%s).' % (server_name, family)) return 0 return self def load_by_class(self, klass): """ Initializes the ServersDict using all the devices from a given class """ self.load_from_devs_list(get_class_devices(klass)) def load_by_host(self, host): """ Initializes the dict with all the servers assigned to a given host. """ servers = self.get_db_device().DbGetHostServerList(host) self.log.warning("%d servers assigned in DB to host %s: %s" % (len(servers), host, servers)) if servers: self.load_from_servers_list(servers) return self def load_from_devs_list(self, devs_list): ''' Initializes the dict using a list of devices; a query to the database is used to identify the server for each device. ''' if type(devs_list) is str: devs_list = devs_list.split(',') if type(devs_list) not in [list, set, tuple]: devs_list = [devs_list] servers_list = set() for d in devs_list: devs = self.get_devs_from_db(d) if '*' in d else [d] devs = [get_normal_name(d) for d in devs] [ servers_list.add(self.get_device_server(dev)) for dev in devs if dev ] self.log.info('Loading %d servers matching %s devices' % (len(servers_list), len(devs_list))) self.load_from_servers_list([s for s in servers_list if s]) return self def load_from_servers_list(self, servers_list, check=True): """ Initializes the dictionary using a list of server_names like ['Exec/Instance'] """ t0 = time.time() if type(servers_list) is str: servers_list = servers_list.split(',') if check: self.check_servers_names(servers_list) for s in servers_list: try: self.log.debug('loading from %s/%s server' % (get_tango_host(self.db), s)) ss = TServer(name=s, parent=self) ss.init_from_db(self.db) self[s] = ss except Exception, e: self.log.warning('exception loading %s server: %s' % (s, str(e)[:100] + '...')) print traceback.format_exc() self.log.debug('load_from_servers_list(%d) took %f seconds' % (len(servers_list), time.time() - t0)) return self
class ServersDict(CaselessDict,Object): ''' Dictionary of TServer classes indexed by server/instance names and loaded using wildcard expressions. Provides Jive/Astor functionality to a list of servers and allows to select/start/stop them by host, class or devices Its purpose is to allow generic start/stop of lists of Tango DeviceServers. This methods of selection provide new ways of search apart of Jive-like selection. @attention Dict keys are lower case, to get the real server name each key returns a TServer object with a .name attribute @par Usage: <pre> from fandango import Astor astor = Astor() astor.load_by_name('snap*') astor.keys() ['snapmanager/1', 'snaparchiver/1', 'snapextractor/1'] server = astor['snaparchiver/1'] server.get_device_list() ['dserver/snaparchiver/1', 'archiving/snaparchiver/1'] astor.states() server.get_all_states() dserver/snaparchiver/1: ON archiving/snaparchiver/1: ON astor.get_device_host('archiving/snaparchiver/1') palantir01 astor.stop_servers('snaparchiver/1') astor.stop_all_servers() astor.start_servers('snaparchiver/1','palantir01',wait=1000) astor.set_server_level('snaparchiver/1','palantir01',4) #Setting the polling of a device: server = astor['PySignalSimulator/bl11'] for dev_name in server.get_device_list(): dev = server.get_device(dev_name) attrs = dev.get_attribute_list() [dev.poll_attribute(attr,3000) for attr in attrs] </pre> ''' def __init__(self,pattern='',klass='',devs_list='',servers_list='',hosts='',loadAll=False,log='WARNING',logger=None,tango_host=''): ''' def __init__(self,pattern='', klass='',devs_list='',servers_list=''): The ServersDict can be initialized using any of the three argument lists or a wildcard for Database.get_server_list(pattern) ServersDict('*') can be used to load all servers in database ''' self.call__init__(CaselessDict,self) if logger is None: self.log = Logger('ServersDict') self.log.setLogLevel(log) else: self.log=logger self.log.debug('ServersDict(%s)'%','.join(map(str,(pattern,klass,devs_list,servers_list,hosts,loadAll,log,logger,tango_host)))) ## proxies will keep a list of persistent device proxies self.proxies = ProxiesDict() ## db will keep a persistent link to PyTango database self.db = get_database() if not tango_host else get_database(*(tango_host.split(':'))) self.server_names = self.keys self.servers = self.values if loadAll: self.load_all_servers() elif klass: self.load_by_class(klass) elif devs_list: self.load_from_devs_list(devs_list) elif servers_list: self.load_from_servers_list(servers_list) #elif pattern: self.load_from_servers_list(self.db.get_server_list(pattern)) elif hosts: hosts = type(hosts) is str and (',' in hosts and hosts.split(',') or [hosts]) or hosts for h in hosts: self.load_by_host(h) elif pattern: self.load_by_name(pattern) #dict.__init__(self) ## @name Dict methods # @{ def __arranged_key(self,key): return key if key.count('/')<=1 else key.split('/',1)[1] #def __getitem__(self,key): dicts.CaselessDict.__getitem__(self,self.__arranged_key(key)) #def __setitem__(self,key,value): dicts.CaselessDict.__setitem__(self,self.__arranged_key(key),value) #def __delitem__(self,key): dicts.CaselessDict.__delitem__(self,self.__arranged_key(key)) #def __contains__(self,key): dicts.CaselessDict.__contains__(self,self.__arranged_key(key)) #def has_key(self,key): dicts.CaselessDict.has_key(self,self.__arranged_key(key)) #def get(self,key,def_val=None): dicts.CaselessDict.get(self,self.__arranged_key(key),def_val) #def pop(self,key,def_val=None): dicts.CaselessDict.pop(self,self.__arranged_key(key),def_val) #def setdefault(self,key,def_val=None): dicts.CaselessDict.pop(self,self.__arranged_key(key),def_val) def __repr__(self): return self.get_report() def __str__(self): return self.get_report() ## @} ## @name Database access # @{ def load_all_servers(self): """ It loads all device servers declared in Tango database """ #classes = self.db.get_device_family('dserver/*') #for c in classes: # self.load_by_exec(c) print self.db self.load_from_servers_list(self.db.get_server_list()) def load_by_name(self,name): ''' Initializes the dict with all the servers matching a given name (usually the executable name or class). A list of names is also possible.''' if type(name) in (list,set): for pattern in name: self.load_by_name(pattern) else: if name.count('/')>=2 and not name.startswith('dserver/'): return self.load_from_devs_list([name]) else: server_name = name.replace('dserver/','') self.log.info('loading by %s server_name'%server_name) family = server_name.split('/')[0] if '/' in server_name else server_name member = server_name.split('/')[1] if '/' in server_name else '*' servers_list = self.get_devs_from_db('dserver/%s/%s' % (family,member)) #servers_list = [s for s in self.db.get_server_list() if fun.matchCl('%s/%s'%(family,member),s)] if servers_list: self.load_from_servers_list([d.replace('dserver/','') for d in servers_list],check=False) self.log.info('%d servers loaded'%len(servers_list)) return len(servers_list) else: self.log.warning('No server matches with %s (family=%s).'%(server_name,family)) return 0 return self def load_by_class(self,klass): """ Initializes the ServersDict using all the devices from a given class """ self.load_from_devs_list(get_class_devices(klass)) def load_by_host(self,host): """ Initializes the dict with all the servers assigned to a given host. """ servers = self.get_db_device().DbGetHostServerList(host) self.log.warning("%d servers assigned in DB to host %s: %s" % (len(servers),host,servers)) if servers: self.load_from_servers_list(servers) return self def load_from_devs_list(self,devs_list): ''' Initializes the dict using a list of devices; a query to the database is used to identify the server for each device. ''' if type(devs_list) is str: devs_list = devs_list.split(',') if type(devs_list) not in [list,set,tuple]: devs_list = [devs_list] servers_list=set() for d in devs_list: devs = self.get_devs_from_db(d) if '*' in d else [d] [servers_list.add(self.get_device_server(dev)) for dev in devs if dev] self.log.info('Loading %d servers matching %s devices'%(len(servers_list),len(devs_list))) self.load_from_servers_list([s for s in servers_list if s]) return self def load_from_servers_list(self,servers_list,check=True): """ Initializes the dictionary using a list of server_names like ['Exec/Instance'] """ t0 = time.time() if type(servers_list) is str: servers_list = servers_list.split(',') if check: self.check_servers_names(servers_list) for s in servers_list: try: self.log.debug('loading from %s/%s server'%(get_tango_host(self.db),s)) ss=TServer(name=s,parent=self) ss.init_from_db(self.db) self[s] = ss except Exception,e: self.log.warning('exception loading %s server: %s' % (s,str(e)[:100]+'...')) print traceback.format_exc() self.log.debug('load_from_servers_list(%d) took %f seconds' % (len(servers_list),time.time()-t0)) return self