Ejemplo n.º 1
0
class TServer(Object):
    '''Class used by ServerDict to manage TangoDeviceServer admin devices.'''
    def __init__(self, name='', host='', parent=None):
        if not name or '/' not in name:
            raise Exception, 'TServer_WrongServerName_%s' % name
        self.info = None
        self.name = self.get_simple_name(name)
        self.update_level(host, 0)
        self.controlled = False
        self.level = 0
        self._classes = None
        self.state = None  #PyTango.DevState.UNKNOWN
        self.log = Logger('TServer-%s' % name)
        if parent and parent.log.getLogLevel():
            self.log.setLogLevel(parent.log.getLogLevel())
        else:
            self.log.setLogLevel('ERROR')
        self.state_lock = threading.Lock()
        if parent: self.proxies = parent.proxies
        else: self.proxies = ProxiesDict()
        pass

    def set_state(self, state):
        self.state_lock.acquire()
        self.state = state
        self.state_lock.release()

    def ping(self, dname=None):
        '''Executes .ping() and .state() methods of the admin device.'''
        name = dname or self.get_admin_name()
        wait = threading.Event().wait
        if not dname: self.set_state(None)
        try:
            proxy = self.get_proxy(name)
        except:
            self.log.error('%s.ping() ... %s not in database!!!' %
                           (self.name, name))
            return None
        wait(.01)  #this wait allows parallel threads
        try:
            proxy.ping()
        except:
            #self.log.debug( '%s.ping() ... Alive'%s_name)
            return None
        if not dname:
            self.set_state(
                PyTango.DevState.FAULT
            )  #Device pings but its state is not readable (ZOMBIE)
        wait(.01)  #this wait allows parallel threads
        try:
            result = proxy.state()
            if not dname: self.set_state(result)
            return result
        except:
            if not dname: return self.state
            else: return None

    def init_from_db(self, db=None, load_devices=False):
        """ Gets name, classes, devices, host, level information from Tango Database. """
        self._db = db or (self._db
                          if hasattr(self, '_db') else PyTango.Database())
        #print ('init_from_db(%s,%s,%s)'%(self.name,get_tango_host(self._db),load_devices))
        self.info = self._db.get_server_info(self.name)
        di = get_device_info(
            'dserver/' + self.name, db=self._db
        )  #get_server_info() must be combined with get_device_info to obtain the real name of the launcher
        self.name = di.server
        self.update_level(self.info.host, self.info.level)
        if load_devices: self.get_classes()

    def update_level(self, host, level=0):
        """ It only initializes the values, does not get values from database. """
        self.controlled = True if host or level else False
        if type(level) is str: level = level.strip()
        if self.controlled:
            self.host, self.level = host.split('.')[0].strip(), trial(
                int, args=level, excepts=0)
        else:
            self.host, self.level = '', 0

    def get_classes(self, load=False):
        if not load and self._classes is not None:
            return self._classes
        devs = self._db.get_device_class_list(self.name)
        self._classes = collections.defaultdict(list)
        #print 'loading from %s server:%s'%(s,str(devs))
        for i in range(0, len(devs), 2):
            klass = devs[i + 1]
            self._classes[klass].append(devs[i].lower())
        return self._classes

    classes = property(fget=get_classes)

    def get_server_level(self):
        """ It returns initialized values, does not get values from database. """
        if self.controlled and self.host: return self.host, self.level
        else: return '', 0

    def get_simple_name(self, name=''):
        '''Returns the name of the server in the Server/Instance format.'''
        name = name or self.name
        return name if name.count('/') == 1 else name.split('/', 1)[1]

    def get_tango_host(self):
        return get_tango_host(self._db)

    def get_admin_name(self):
        '''Returns the name of the server in the dserver/Server/Instance format.'''
        n = 'dserver/' + self.name if self.name.count('/') == 1 else self.name
        return self.get_tango_host() + '/' + n

    def get_starter_name(self):
        """Returns the starter on charge of controlling this server."""
        n = 'tango/admin/%s' % self.host if self.host else None
        return self.get_tango_host() + '/' + n

    def get_device_list(self):
        '''Returns a list of devices declared for this server.'''
        result = []
        [
            result.extend(v) for c, v in self.classes.items()
            if c.lower() != 'dserver'
        ]
        return result

    def get_proxy(self, device=''):
        '''Returns a proxy to the given device; or the admin device if no device name is provided.'''
        if device and ':' not in device:
            device = self.get_tango_host() + '/' + device
        device = device or self.get_admin_name()
        return self.proxies.get(device)

    def get_admin(self):
        return self.get_proxy()

    def get_device(self, device):
        return self.get_proxy(device)

    def get_all_states(self):
        """Returns a dictionary with the individual states of the inner devices."""
        result = {}
        for klass in self.classes:
            for device in self.classes[klass]:
                try:
                    result[device] = self.proxies[device].State()
                except Exception, e:
                    self.log.warning('Unable to read %s state: %s' %
                                     (device, str(e)[:100] + '...'))
                    result[device] = None  #PyTango.DevState.UNKNOWN
        return result
Ejemplo n.º 2
0
class TServer(Object):
    '''Class used by ServerDict to manage TangoDeviceServer admin devices.'''
    def __init__(self,name='', host='', parent=None):
        if not name or '/' not in name: raise Exception,'TServer_WrongServerName_%s' % name
        self.info = None
        self.name=self.get_simple_name(name)
        self.update_level(host,0)
        self.controlled = False
        self.level = 0
        self._classes = None
        self.state=None #PyTango.DevState.UNKNOWN
        self.log = Logger('TServer-%s'%name)
        if parent and parent.log.getLogLevel(): self.log.setLogLevel(parent.log.getLogLevel())
        else: self.log.setLogLevel('ERROR')
        self.state_lock = threading.Lock()
        if parent: self.proxies=parent.proxies
        else: self.proxies=ProxiesDict()
        pass
        
    def set_state(self,state):
        self.state_lock.acquire()
        self.state=state
        self.state_lock.release()
        
    def ping(self,dname=None):
        '''Executes .ping() and .state() methods of the admin device.'''
        name = dname or self.get_admin_name()
        wait = threading.Event().wait
        if not dname: self.set_state(None)
        try: proxy = self.get_proxy(name)
        except: 
            self.log.error('%s.ping() ... %s not in database!!!' % (self.name,name))
            return None
        wait(.01) #this wait allows parallel threads
        try: proxy.ping()
        except:
            #self.log.debug( '%s.ping() ... Alive'%s_name)
            return None
        if not dname: self.set_state(PyTango.DevState.FAULT) #Device pings but its state is not readable (ZOMBIE)
        wait(.01) #this wait allows parallel threads
        try: 
            result = proxy.state()
            if not dname: self.set_state(result)
            return result
        except:
            if not dname: return self.state
            else: return None
            
    def init_from_db(self,db=None,load_devices=False):
        """ Gets name, classes, devices, host, level information from Tango Database. """
        self._db = db or (self._db if hasattr(self,'_db') else PyTango.Database())
        #print ('init_from_db(%s,%s,%s)'%(self.name,get_tango_host(self._db),load_devices))
        self.info = self._db.get_server_info(self.name)
        di = get_device_info('dserver/'+self.name,db=self._db) #get_server_info() must be combined with get_device_info to obtain the real name of the launcher
        self.name = di.server
        self.update_level(self.info.host,self.info.level)
        if load_devices: self.get_classes()
    
    def update_level(self,host,level=0):
        """ It only initializes the values, does not get values from database. """
        self.controlled = True if host or level else False
        if type(level) is str: level=level.strip()
        if self.controlled: self.host,self.level = host.split('.')[0].strip(),trial(int,args=level,excepts=0)
        else: self.host,self.level = '',0
        
    def get_classes(self,load=False):
        if not load and self._classes is not None:
            return self._classes
        devs = self._db.get_device_class_list(self.name)
        self._classes = collections.defaultdict(list)
        #print 'loading from %s server:%s'%(s,str(devs))
        for i in range(0,len(devs),2):
            klass = devs[i+1]
            self._classes[klass].append(devs[i].lower())
        return self._classes
        
    classes = property(fget=get_classes)
        
    def get_server_level(self):
        """ It returns initialized values, does not get values from database. """
        if self.controlled and self.host: return self.host,self.level
        else: return '',0
    
    def get_simple_name(self,name=''): 
        '''Returns the name of the server in the Server/Instance format.'''
        name = name or self.name
        return name if name.count('/')==1 else name.split('/',1)[1]
      
    def get_tango_host(self):
        return get_tango_host(self._db)
    
    def get_admin_name(self): 
        '''Returns the name of the server in the dserver/Server/Instance format.'''
        n = 'dserver/'+self.name if self.name.count('/')==1 else self.name
        return self.get_tango_host()+'/'+n
    
    def get_starter_name(self):
        """Returns the starter on charge of controlling this server."""
        n = 'tango/admin/%s' % self.host if self.host else None
        return self.get_tango_host()+'/'+n
    
    def get_device_list(self): 
        '''Returns a list of devices declared for this server.'''
        result=[]
        [result.extend(v) for c,v in self.classes.items() if c.lower()!='dserver']
        return result
    
    def get_proxy(self,device=''): 
        '''Returns a proxy to the given device; or the admin device if no device name is provided.'''
        if device and ':' not in device:
          device = self.get_tango_host()+'/'+device
        device = device or self.get_admin_name()
        return self.proxies.get(device)
    
    def get_admin(self): return self.get_proxy()
    def get_device(self,device): return self.get_proxy(device)
    
    def get_all_states(self):
        """Returns a dictionary with the individual states of the inner devices."""
        result = {}
        for klass in self.classes:
            for device in self.classes[klass]:
                try:
                    result[device] = self.proxies[device].State()
                except Exception,e:
                    self.log.warning('Unable to read %s state: %s' % (device,str(e)[:100]+'...'))
                    result[device] = None #PyTango.DevState.UNKNOWN
        return result