def load_all_devices(self, filters='*'): import fandango self.tango = fandango.get_database() self.alias_devs = fandango.defaultdict_fromkey( lambda k, s=self: str(s.tango.get_device_alias(k))) self.archattrs = [] self.archdevs = [] #print('In load_all_devices(%s)...'%str(filters)) devs = fandango.tango.get_all_devices() if filters != '*': devs = [ d for d in devs if fandango.matchCl(filters.replace(' ', '*'), d, extend=True) ] self.all_devices = devs self.all_domains = sorted(set(a.split('/')[0] for a in devs)) self.all_families = sorted(set(a.split('/')[1] for a in devs)) members = [] for a in devs: try: members.append(a.split('/')[2]) except: # Wrong names in DB? yes, they are pass #print '%s is an invalid name!'%a members = sorted(set(members)) self.all_members = sorted( set(e for m in members for e in re.split('[-_0-9]', m) if not fandango.matchCl('^[0-9]+([ABCDE][0-9]+)?$', e))) #print 'Loading alias list ...' self.all_alias = self.tango.get_device_alias_list('*') #self.alias_devs = dict((str(self.tango.get_device_alias(a)).lower(),a) for a in self.all_alias) tracer('Loading (%s) finished.' % (filters))
def load_all_devices(self,filters='*'): import fandango as fn #needed by subprocess self.tango = fn.get_database() self.alias_devs = fn.defaultdict_fromkey( lambda k,s=self: str(s.tango.get_device_alias(k))) self.archattrs = [] self.archdevs = [] #print('In load_all_devices(%s)...'%str(filters)) devs = fn.tango.get_all_devices() if filters!='*': devs = [d for d in devs if fn.matchCl( filters.replace(' ','*'),d,extend=True)] self.all_devices = devs self.all_domains = sorted(set(a.split('/')[0] for a in devs)) self.all_families = sorted(set(a.split('/')[1] for a in devs)) members = [] for a in devs: try: members.append(a.split('/')[2]) except: # Wrong names in DB? yes, they are pass #print '%s is an invalid name!'%a members = sorted(set(members)) self.all_members = sorted(set(e for m in members for e in re.split('[-_0-9]',m) if not fn.matchCl('^[0-9]+([ABCDE][0-9]+)?$',e))) #print 'Loading alias list ...' self.all_alias = self.tango.get_device_alias_list('*') #self.alias_devs = dict((str(self.tango.get_device_alias(a)).lower(),a) for a in self.all_alias) tracer('Loading (%s) finished.'%(filters))
def main(self,class_override=False): import fandango #needed to avoid startup exceptions when loading dynamically #fandango.tango.get_device_property failed! desc = BAD_INV_ORDER CORBA system exception: BAD_INV_ORDER_ORBHasShutdown #doppels = dict((d,(db.get_device_property(d,['TargetDevice'])['TargetDevice'] or [''])[0]) for d in self.classes['CopyCatDS']) ks = [k for k in self.classes if fandango.matchCl('CopyCatDS|(^*Copy$)',k)] print 'classes: %s'%ks doppels = sorted(set(t for k in ks for t in self.classes[k])) print 'copycat devices: %s'%doppels targets = dict((d,fandango.tango.get_device_property(d,'TargetDevice')) for d in doppels) classes = {} print 'targets: %s'%targets for t in set(targets.values()): if t: classes[t] = choose_db(t,self.db).get_class_for_device(t if ':' not in t else t.split('/',1)[-1]) print 'Devices: \n%s'%"\n".join(sorted('%s = %s(%s)'%(d,t,classes.get(t,None)) for d,t in targets.items())) if class_override and classes: for c in set(classes.values()): print('Adding %s_Copy ...'%c) import fandango.interface setattr(fandango.interface,'%s_Copy',CopyCatDS),setattr(fandango.interface,'%s_CopyClass',CopyCatDSClass) self.util.add_TgClass(CopyCatDSClass,CopyCatDS,c+'_Copy') for d in targets: fandango.tango.add_new_device(self.name,classes[targets[d]]+'_Copy',d) self.instance.server_init() self.instance.server_run()
def init_device(self): self.setLogLevel('DEBUG') self.info("In %s::init_device()"%self.get_name()) self.get_device_properties(self.get_device_class()) #Needed to do it twice to generate StaticAttributes properly fandango.tango.put_device_property(self.get_name(),dict((k,getattr(self,k)) for k in CopyCatDSClass.device_property_list),db=self.db) self.StaticAttributes = [] try: for a,t in sorted(copy_attr_list(self.TargetDevice).items()): if any(fandango.matchCl(e,a) for e in self.CopyAttributes): ttype,format,writable = t[0][:3] if not isTypeSupported(ttype): self.warning('%s attribute of type %s is not supported by DynamicDS'%(a,ttype.name)) else: dims = len(t[0][3:]) if dims==2: self.warning('%s attribute of type IMAGE is not supported by DynamicDS'%(a)) else: ttype = ttype.name if not dims else ttype.name.replace('Dev','DevVar')+'Array' if self.ReadOnly or writable==PyTango.AttrWriteType.READ: formula = "%s=%s(XATTR('%s'))"%(a,ttype,self.TargetDevice+'/'+a) else: formula = "%s=%s(XATTR('%s') if not WRITE else WATTR('%s',VALUE))"%(a,ttype,self.TargetDevice+'/'+a,self.TargetDevice+'/'+a) self.StaticAttributes.append(formula) self.info('Added %s'%formula) except: traceback.print_exc() self.set_status('Copied attributes:\n\t'+'\n\t'.join(self.StaticAttributes)) self.get_DynDS_properties() if self.DynamicStates: self.set_state(PyTango.DevState.UNKNOWN) self.info("Out of %s::init_device()"%self.get_name())
def main(self,class_override=False): import fandango #needed to avoid startup exceptions when loading dynamically #fandango.tango.get_device_property failed! desc = BAD_INV_ORDER CORBA system exception: BAD_INV_ORDER_ORBHasShutdown #doppels = dict((d,(db.get_device_property(d,['TargetDevice'])['TargetDevice'] or [''])[0]) for d in self.classes['CopyCatDS']) ks = [k for k in self.classes if fandango.matchCl('CopyCatDS|(^*Copy$)',k)] print 'classes: %s'%ks doppels = sorted(set(t for k in ks for t in self.classes[k])) print 'copycat devices: %s'%doppels targets = dict((d,fandango.tango.get_device_property(d,'TargetDevice')) for d in doppels) classes = {} print 'targets: %s'%targets if class_override: for t in set(targets.values()): if t: classes[t] = choose_db(t,self.db).get_class_for_device(t if ':' not in t else t.split('/',1)[-1]) print 'Devices: \n%s'%"\n".join(sorted('%s = %s(%s)'%(d,t,classes.get(t,None)) for d,t in targets.items())) if class_override and classes: for c in set(classes.values()): print('Adding %s_Copy ...'%c) import fandango.interface setattr(fandango.interface,'%s_Copy',CopyCatDS) setattr(fandango.interface,'%s_CopyClass',CopyCatDSClass) self.util.add_TgClass(CopyCatDSClass,CopyCatDS,c+'_Copy') for d in targets: fandango.tango.add_new_device(self.name,classes[targets[d]]+'_Copy',d) self.instance.server_init() self.instance.server_run()
def StateMachine(self, att, attr_value, new_state): """ This method will be called from common.PseudoDev.event_received when a valid attribute value is received. It updates the self.Cache dictionary and returns the new_state value. """ #READING CHANNEL STATUS if att == 'channelstate': channels = attr_value.value #It is a list of "Channel: Status" strings self.info('ChannelState received : %s' % str(channels)) #Channels is a tuple instead of a list!?! c_state = '' FLOAT = '[0-9](\.[0-9]{1,2})?[eE][+-][0-9]{2,2}$' if channels: for i, chann in enumerate(channels): if (chann.split(':')[0].lower() == self. ChannelName #Check attribute name == channel name or fandango.matchCl('p[0-9]', self.ChannelName) and i + 1 == int( self.ChannelName[1:] ) #Check value index == channel number ): self.info('%s => %s' % (self.ChannelName, chann)) c_state = chann.split(':')[-1].lower().strip() new_state = fun.matchMap([ ('.*off', PyTango.DevState.OFF), ('misconn|negativ', PyTango.DevState.FAULT), ('nogauge', PyTango.DevState.DISABLE), ('lo.*', PyTango.DevState.STANDBY), ('hi.*|protect', PyTango.DevState.ALARM), (FLOAT, PyTango.DevState.ON), ('.*', PyTango.DevState.UNKNOWN), ], c_state) break self.Cache[att].time = attr_value.time self.Cache[att].value = c_state.upper( ) #It will be 'OK' if the channel is enabled self.plog( 'info', 'Updated ChannelState: %s; new state is %s' % (self.Cache[att].value, new_state)) else: self.plog('warning', 'ChannelState received has no value!: %s' % channels) #READING CHANNEL VALUE elif att == self.ChannelName: self.Cache[att] = attr_value self.plog( 'info', 'Updated Pressure Value: %s at %s' % (attr_value.value, attr_value.time)) elif att == 'state': self.Cache[att] = attr_value else: self.plog('warning', 'UNKNOWN ATTRIBUTE %s!!!!!' % attr_name) self.plog('debug', 'self.ChannelName=%s' % str(self.ChannelName)) self.plog('debug', 'attr_name.split=%s' % str(attr_name.split('/'))) return new_state
def filterMatching(a,dct=AttributeFilters,p=printf): match = False if a.lower().endswith('/state'): return True elif a.lower().endswith('/status'): return False for k,l in dct.items(): if fn.searchCl(k,a.rsplit('/',1)[0]): for t in l: #T is every declared Tab for panel (TabName,[attrlist]); or just attrname when not using tabs p((k,t)) f = t[-1] if all(map(fn.isSequence,(t,t[-1]))) else [t] if any(fn.matchCl(v,a.rsplit('/',1)[-1]) for v in f): match =True return match
def get_servers_status(regexp='*', exclude=['bpms', 'test', 'sr_vc_']): servers = fandango.Astor() servers.load_by_name('PyAlarm/*%s*' % regexp) servers.load_by_name('Panic*/*%s*' % regexp) print('%d servers loaded' % len(servers)) states = servers.states() [states.pop(k) for k in states.keys() if any(e in k for e in exclude)] exported = fandango.get_all_devices(exported=True) exported = [s for s in states if 'dserver/' + s in exported] zombies = sorted(d for d, s in states.items() if d in exported and s is None) off = sorted(d for d, s in states.items() if d not in zombies and s is None) on = sorted(s for s in states if states[s] is not None) print('\n') for s in off: print('%s : %s : OFF' % (servers[s].host, s)) for s in zombies: print('%s : %s : ZOMBIE!' % (servers[s].host, s)) print('\n') failed = [] for s in on: for d in sorted(servers[s].get_device_list()): if not fandango.matchCl('(sys|dserver)/*', d): ss = fandango.check_device(d) p = fandango.tango.get_device_property(d, 'pollingperiod') if not p: print('%s has no polling defined' % d) elif float(p) > 1000: print('%s has a wrong polling! %s' % (d, p)) if str(ss) not in ('ALARM', 'ON'): failed.append(s) print('%s : %s : %s : %s' % (servers[s].host, s, d, str(ss))) print('\n%d servers have failed devices' % len(failed)) restart = sorted(set(d for l in (off, zombies, failed) for d in l)) print('%d servers should be restarted' % len(restart)) print('') return { 'off': off, 'on': on, 'zombies': zombies, 'failed': failed, 'restart': restart }
def pack_window_message(comm, value=None, trace=False): ncomm = Commands.get(comm, comm) if TRACE or trace: print('pack_window_message(%s => %s)' % (comm, ncomm)) if isinstance(ncomm, int): ncomm = '%03d' % ncomm data = [RS232] + str2bytes(ncomm) #list(ncomm) if TRACE or trace: print('pack_window_message(%s,%s)' % (['%x' % d for d in data], value)) if value is not None: data.append(WRITE) try: if str(value) not in '01': if fandango.matchCl('^[\-0-9]+$', str(value)): value = '%06d' % int(value) else: value = '%10s' % ('%4.1e' % float(value)) except Exception, e: print('pack_window_message(%s) failed!: %s' % (value, e)) data.extend(str2bytes(value))
from fandango import SingletonMap, str2time, time2str from fandango.qt import Qt, Qwt5, QTextBuffer, setDialogCloser, QWidgetWithLayout import taurus from taurus.qt.qtgui.plot import TaurusTrend from taurus.qt.qtgui.base import TaurusBaseWidget from taurus.qt.qtgui.container import TaurusWidget, TaurusGroupBox USE_MULTIPROCESS = False try: prop = PyTango.Database().get_class_property( 'HdbExtractor', ['Multiprocess'])['Multiprocess'] if any(a in str(prop).lower() for a in ('true', '1')): USE_MULTIPROCESS = True elif any(fn.matchCl(p, platform.node()) for p in prop): USE_MULTIPROCESS = True except: print traceback.format_exc() print 'Multiprocess:%s' % USE_MULTIPROCESS DECIMATION_MODES = [ #('Hide Nones',fn.arrays.notnone), ('Pick One', fn.arrays.pickfirst), ('Minimize Noise', fn.arrays.mindiff), ('Maximize Peaks', fn.arrays.maxdiff), ('Average Values', fn.arrays.average), ('In Client', False), ('RAW', None), ]
def load_attributes(self,servfilter,devfilter,attrfilter,warn=True, exclude = ('dserver','tango*admin','sys*database','tmp','archiving')): servfilter = servfilter.replace(' ','*').strip() attrfilter = (attrfilter or 'state').replace(' ','*') devfilter = (devfilter or attrfilter).replace(' ','*') #Solve fqdn issues devfilter = devfilter.replace('tango://','') if ':' in devfilter: tracer('ArchivingBrowser ignores tango host filters') devfilter = fn.clsub(fn.tango.rehost,'',devfilter) tracer('In load_attributes(%s,%s,%s)'%(servfilter,devfilter,attrfilter)) archive = self.dbcheck.isChecked() all_devs = self.all_devices if not archive else self.archdevs all_devs = [d for d in all_devs if not any(d.startswith(e) for e in exclude) or any(d.startswith(e) and fn.matchCl(e,devfilter) for e in exclude)] if servfilter.strip('.*'): sdevs = map(str.lower,fn.Astor(servfilter).get_all_devices()) all_devs = [d for d in all_devs if d in sdevs] #print('In load_attributes(%s,%s,%s): Searching through %d %s names' #%(servfilter,devfilter,attrfilter,len(all_devs), #'server' if servfilter else 'device')) if devfilter.strip().strip('.*'): devs = [d for d in all_devs if (fn.searchCl(devfilter,d,extend=True))] print('\tFound %d devs, Checking alias ...'%(len(devs))) alias,alias_devs = [],[] if '&' in devfilter: alias = self.all_alias else: for df in devfilter.split('|'): alias.extend(self.tango.get_device_alias_list('*%s*'%df.strip())) if alias: print('\t%d alias found'%len(alias)) alias_devs.extend(self.alias_devs[a] for a in alias if fn.searchCl(devfilter,a,extend=True)) print('\t%d alias_devs found'%len(alias_devs)) #if not self.alias_devs: #self.alias_devs = dict((str(self.tango.get_device_alias(a)).lower(),a) for a in self.all_alias) #devs.extend(d for d,a in self.alias_devs.items() if fn.searchCl(devfilter,a) and (not servfilter or d in all_devs)) devs.extend(d for d in alias_devs if not servfilter.strip('.*') or d in all_devs) else: devs = all_devs devs = sorted(set(devs)) self.matching_devs = devs print('In load_attributes(%s,%s,%s): %d devices found'%(servfilter,devfilter,attrfilter,len(devs))) if False and not len(devs) and not archive: #Devices do not actually exist, but may exist in archiving ... #Option disabled, was mostly useless self.dbcheck.setChecked(True) return self.load_attributes(servfilter,devfilter,attrfilter,warn=False) if len(devs)>self.MAX_DEVICES and warn: Qt.QMessageBox.warning(self, "Warning" , "Your search (%s,%s) matches too many devices!!! (%d); please refine your search\n\n%s\n..."%(devfilter,attrfilter,len(devs),'\n'.join(devs[:30]))) return {} elif warn and len(devs)>15: r = Qt.QMessageBox.warning(self, "Message" , "Your search (%s,%s) matches %d devices."%(devfilter,attrfilter,len(devs)),Qt.QMessageBox.Ok|Qt.QMessageBox.Cancel) if r==Qt.QMessageBox.Cancel: return {} self.matching_attributes = {} #{attribute: (device,alias,attribute,label)} failed_devs = [] for d in sorted(devs): try: dp = taurus.Device(d) if not archive: dp.ping() tcs = [t for t in dp.get_attribute_list()] else: tcs = [a.split('/')[-1] for a in self.archattrs if a.startswith(d+'/')] matches = [t for t in tcs if fn.searchCl(attrfilter,t,extend=True)] for t in sorted(tcs): if not self.dbcheck.isChecked() or not matches: label = dp.get_attribute_config(t).label else: label = t if t in matches or fn.searchCl(attrfilter,label,extend=True): if self.archivecheck.isChecked() \ and not self.reader.is_attribute_archived(d+'/'+t): continue if d in self.alias_devs: alias = self.alias_devs[d] else: try: alias = str(self.tango.get_alias(d)) except: alias = '' self.matching_attributes['%s/%s'%(d,t)] = (d,alias,t,label) if warn and len(self.matching_attributes)>self.MAX_ATTRIBUTES: Qt.QMessageBox.warning(self, "Warning" , "Your search (%s,%s) matches too many attributes!!! (%d); please refine your search\n\n%s\n..."%( devfilter,attrfilter,len(self.matching_attributes),'\n'.join(sorted(self.matching_attributes.keys())[:30]))) return {} except: print('load_attributes(%s,%s,%s => %s) failed!'%(servfilter,devfilter,attrfilter,d)) failed_devs.append(d) if attrfilter in ('state','','*','**'): self.matching_attributes[d+'/state'] = (d,d,'state',None) #A None label means device-not-readable if warn and len(self.matching_attributes)>30: r = Qt.QMessageBox.warning(self, "Message" , "(%s) matches %d attributes."%(attrfilter,len(self.matching_attributes)),Qt.QMessageBox.Ok|Qt.QMessageBox.Cancel) if r==Qt.QMessageBox.Cancel: return {} if not len(self.matching_attributes): Qt.QMessageBox.warning(self, "Warning", "No matching attribute has been found in %s." % ('Archiving DB' if archive else 'Tango DB (try Archiving option)')) if failed_devs: print('\t%d failed devs!!!: %s'%(len(failed_devs),failed_devs)) if warn: Qt.QMessageBox.warning(self, "Warning" , "%d devices were not running:\n"%len(failed_devs) +'\n'.join(failed_devs[:10]+(['...'] if len(failed_devs)>10 else []) )) tracer('\t%d attributes found'%len(self.matching_attributes)) return self.matching_attributes
JDRAW_HOOK = None #lambda s: apply_transform(get_coordinates(s)) # Enable multiple selection of objects in Synoptic #from taurus.qt.qtgui.graphic import TaurusGraphicsScene #TaurusGraphicsScene.ANY_ATTRIBUTE_SELECTS_DEVICE = True ############################################################################### # Setup of the tree #Domain/Target used to generate grids/trees ; domain may be regexp, target should not DOMAIN = '*test*' TARGET = DOMAIN USE_DEVICE_TREE = True #Devices not in JDraw or regular expression to be added to the tree DEVICES = [ d for d in get_all_devices() if not matchCl('^(tango|dserver)/*', d) ] #map(bool,set(['%s/VC/ALL'%TARGET,'%s/CT/ALARMS'%TARGET,DEVICE,COMPOSER])) EXTRA_DEVICES = [] #Custom tree branches are built using nested dictionaries and regular expressions (if empty a jive-like tree is built). CUSTOM_TREE = {} # {'CT':'BL*(CT|ALARMS|PLC)$', # 'FE':'FE*/VC/*', # 'Valves': {'.OH':'*OH/PNV*', # 'EH01':'*EH01/PNV*',}, # 'BAKEOUTS':'BL*(BAKE|BK)*',} ############################################################################### # Device Panel setup
def create_simulators(filein, instance='', path='', domains={}, server='', tango_host='', filters='', override=True): #domains = {'wr/rf':'test/rf'} path = path or os.path.abspath(os.path.dirname(filein)) + '/' print('create_simulators:' + str( (filein, instance, path, domains, tango_host))) files = fd.listdir(path) if not any(f.endswith('_attributes.txt') for f in files): q = raw_input('Property files do not exist yet,\n' 'Do you want to generate them? (y/n)') if q.lower().startswith('y'): cur = os.path.abspath(os.curdir) os.chdir(path) generate_class_properties(filein) os.chdir(cur) ## CHECK IS MANDATORY, YOU SHOULD EXPORT AND SIMULATE IN DIFFERENT HOSTS assert tango_host and tango_host in str(fd.tango.get_tango_host()),\ 'Tango Host (%s!=%s) does not match!'%(tango_host,fd.tango.get_tango_host()) devs, org = {}, pickle.load( open(filein if '/' in filein else path + filein)) done = [] all_devs = fd.get_all_devices() print('>' * 80) if not filters: print('%d devices in %s: %s' % (len(org), filein, sorted(org.keys()))) filters = raw_input('Enter a filter for device names: [*/*/*]').lower() for d, t in org.items(): k = ('/'.join( d.split('/')[-3:])).lower() #Removing tango host from the name for a, b in domains.items(): if k.startswith(a): k = k.replace(a, b) if not filters or fd.matchCl(filters, d) or fd.matchCl( filters, org[d].dev_class): devs[k] = t if override is not False: dds = [ d for d in devs if ('/'.join(d.split('/')[-3:])).lower() in all_devs ] if dds: print('%d devices already exist: %s' % (len(dds), sorted(dds))) override = raw_input( 'Do you want to override existing properties? (y/n)').lower( ).startswith('y') else: override = False if not instance: instance = raw_input( 'Enter your instance name for the simulated server (use "instance-" to use multiple instances):' ) elif '/' in instance: server, instance = instance.split('/') keepclass = 'y' in raw_input('Keep original Class names?').lower() if keepclass: server = 'SimulatorDS' elif not server: server = raw_input( 'Enter your server name (SimulatorDS/DynamicDS): [SimulatorDS]') \ or 'SimulatorDS' print('>' * 80) for d, t in sorted(devs.items()): t.dev_class = t.dev_class or d.split('/')[-1] if t.dev_class == 'PyStateComposer': klass = t.dev_class elif keepclass: klass = t.dev_class + '_sim' else: klass = 'SimulatorDS' instance_temp = '%s%s' % (instance, t.dev_class) if '-' in instance else instance print('%s/%s:%s , "%s" => %s ' % (server, instance_temp, d, t.dev_class, klass)) its_new = ('/'.join(('dserver', server, instance_temp)) ).lower() not in all_devs or d.lower() not in all_devs if its_new or override: print('writing ... %s(%s)' % (type(t), d)) fd.tango.add_new_device('%s/%s' % (server, instance_temp), klass, d) for p, v in t.props.items(): if not p.startswith( '__' ): #p not in ('DynamicCommands','DynamicStates','LoadFromFile','DevicesList') and fd.tango.put_device_property(d, p, v) #Overriding Dynamic* properties try: fd.tango.put_device_property( d, 'LoadFromFile', path + '%s_attributes.txt' % t.dev_class) fd.tango.put_device_property( d, 'DynamicAttributes', filter( bool, map( str.strip, open(path + '%s_attributes.txt' % t.dev_class).readlines()))) fd.tango.put_device_property( d, 'DynamicCommands', filter( bool, map( str.strip, open(path + '%s_commands.txt' % t.dev_class).readlines()))) fd.tango.put_device_property( d, 'DynamicStates', filter( bool, map( str.strip, open(path + '%s_states.txt' % t.dev_class).readlines()))) except: print('Unable to configure %s(%s) properties ' % (d, t.dev_class)) #traceback.print_exc() fd.tango.put_device_property(d, 'OFFSET', random.randint(0, len(devs))) done.append(d) exported = fd.get_all_devices(exported=True) update = [d for d in done if d in exported] print('Updating %d Devices ...' % len(update)) for d in update: if fd.check_device(d): print('Updating %s ...' % d) try: fd.get_device(d).updateDynamicAttributes() except Exception, e: print(e) else: print('%s failed!' % d) time.sleep(.2)
#A method that does transformation on signals sent to other widgets. JDRAW_HOOK = None #lambda s: apply_transform(get_coordinates(s)) # Enable multiple selection of objects in Synoptic #from taurus.qt.qtgui.graphic import TaurusGraphicsScene #TaurusGraphicsScene.ANY_ATTRIBUTE_SELECTS_DEVICE = True ############################################################################### # Setup of the tree #Domain/Target used to generate grids/trees ; domain may be regexp, target should not DOMAIN = '*test*' TARGET = DOMAIN USE_DEVICE_TREE = True #Devices not in JDraw or regular expression to be added to the tree DEVICES = [d for d in get_all_devices() if not matchCl('^(tango|dserver)/*',d)]#map(bool,set(['%s/VC/ALL'%TARGET,'%s/CT/ALARMS'%TARGET,DEVICE,COMPOSER])) EXTRA_DEVICES = [] #Custom tree branches are built using nested dictionaries and regular expressions (if empty a jive-like tree is built). CUSTOM_TREE = {} # {'CT':'BL*(CT|ALARMS|PLC)$', # 'FE':'FE*/VC/*', # 'Valves': {'.OH':'*OH/PNV*', # 'EH01':'*EH01/PNV*',}, # 'BAKEOUTS':'BL*(BAKE|BK)*',} ############################################################################### # Device Panel setup #PyStateComposer to get Vacuum Profile curves
class AttributesPanel(PARENT_KLASS): _domains = ['ALL EPS'] + ['LI', 'LT'] + [ 'LT%02d' % i for i in range(1, 3) ] + ['SR%02d' % i for i in range(1, 17)] _fes = [ f for f in get_distinct_domains(fn.get_database().get_device_exported( 'fe*')) if fn.matchCl('fe[0-9]', f) ] LABELS = 'Label/Value Device Attribute Alias Archiving Check'.split() SIZES = [500, 150, 90, 90, 120, 40] STRETCH = [8, 4, 4, 4, 2, 1] def __init__(self, parent=None, devices=None): #print '~'*80 tracer('In AttributesPanel()') PARENT_KLASS.__init__(self, parent) self.setSizePolicy( Qt.QSizePolicy(Qt.QSizePolicy.Ignored, Qt.QSizePolicy.Ignored)) self.worker = SingletonWorker(parent=self, cursor=True, sleep=50., start=True) #self.worker.log.setLogLevel(self.worker.log.Debug) self.filters = ('', '', '') #server/device/attribute self.devices = devices or [] self.setValues(None) self.models = [] self.current_item = None #self.connect(self, Qt.SIGNAL('customContextMenuRequested(const QPoint&)'), self.onContextMenu) self.popMenu = Qt.QMenu(self) self.actions = { 'TestDevice': self.popMenu.addAction(Qt.QIcon(), "Test Device", self.onTestDevice), 'ShowDeviceInfo': self.popMenu.addAction(Qt.QIcon(), "Show Device Info", self.onShowInfo), #'ShowDevicePanel': self.popMenu.addAction(Qt.QIcon(),"Show Info",self.onShowPanel), 'ShowArchivingInfo': self.popMenu.addAction(Qt.QIcon(), "Show Archiving Info", self.onShowArchivingModes), 'AddToTrend': self.popMenu.addAction(Qt.QIcon(), "Add attribute to Trend", self.addAttributeToTrend), 'AddSelected': self.popMenu.addAction(Qt.QIcon(), "Add selected attributes to Trend", self.addSelectedToTrend), 'CheckAll': self.popMenu.addAction(Qt.QIcon(), "Select all attributes", self.checkAll), 'UncheckAll': self.popMenu.addAction(Qt.QIcon(), "Deselect all attributes", self.uncheckAll), #'Test Device': self.popMenu.addAction(Qt.QIcon(),"Test Device",self.onTestDevice) } #if hasattr(self,'setFrameStyle'): #self.setFrameStyle(self.Box) try: import PyTangoArchiving self.reader = PyTangoArchiving.Reader('*') #self.hreader = self.reader.configs['hdb'] #self.treader = self.reader.configs.get('tdb',self.hreader) except: traceback.print_exc() def __del__(self): print 'AttributesPanel.__del__' QGridTable.__del__(self) def setItem(self, x, y, item, spanx=1, spany=1, align=None, model=None): align = align or Qt.Qt.AlignLeft try: if model: item._model = model except: pass self.layout().addWidget(item, x, y, spany, spanx, Qt.Qt.AlignCenter) if item not in self._widgets: self._widgets.append(item) def mousePressEvent(self, event): point = event.pos() widget = Qt.QApplication.instance().widgetAt(self.mapToGlobal(point)) if hasattr(widget, '_model'): print('onMouseEvent(%s)' % (getattr(widget, 'text', lambda: widget)())) self.current_item = widget if event.button() == Qt.Qt.RightButton: self.onContextMenu(point) getattr(super(type(self), self), 'mousePressEvent', lambda e: None)(event) def onContextMenu(self, point): print('onContextMenu()') try: self.actions['TestDevice'].setEnabled( '/' in self.current_item._model) self.actions['ShowDeviceInfo'].setEnabled( '/' in self.current_item._model) self.actions['ShowArchivingInfo'].setEnabled( '/' in self.current_item._model) self.actions['AddToTrend'].setEnabled(hasattr(self, 'trend')) self.actions['AddSelected'].setEnabled(hasattr(self, 'trend')) self.popMenu.exec_(self.mapToGlobal(point)) except: traceback.print_exc() def getCurrentModel(self): return '/'.join(str(self.current_item._model).split('/')[-4:]) def getCurrentDevice(self): return str(self.current_item._model.rsplit('/', 1)[0]) def onTestDevice(self, device=None): from PyTangoArchiving.widget.panel import showTestDevice showTestDevice(device or self.getCurrentDevice()) def onShowInfo(self, device=None): from PyTangoArchiving.widget.panel import showDeviceInfo showDeviceInfo(device=device or self.getCurrentDevice(), parent=self) def onShowArchivingModes(self, model=None): try: from PyTangoArchiving.widget.panel import showArchivingModes model = model or self.getCurrentModel() showArchivingModes(model, parent=self) except: Qt.QMessageBox.warning(self, "ups!", traceback.format_exc()) def addAttributeToTrend(self, model=None): try: model = model or self.getCurrentModel() self.trend.addModels([model]) except: Qt.QMessageBox.warning(self, "ups!", traceback.format_exc()) def addSelectedToTrend(self): try: y = self.columnCount() - 1 models = [] for x in range(self.rowCount()): item = self.itemAt(x, y).widget() m = getattr(item, '_model', '') if m and item.isChecked(): models.append(m) if len(models) > 20: Qt.QMessageBox.warning( self, "warning", "To avoid performance issues, dynamic scale will be disabled" ) self.trend.setXDynScale(False) self.trend.addModels(models) except: Qt.QMessageBox.warning(self, "ups!", traceback.format_exc()) def checkAll(self): y = self.columnCount() - 1 for x in range(self.rowCount()): self.itemAt(x, y).widget().setChecked(True) def uncheckAll(self): y = self.columnCount() - 1 for x in range(self.rowCount()): self.itemAt(x, y).widget().setChecked(False) def setValues(self, values, filters=None): """ filters will be a tuple containing several regular expressions to match """ #print('In AttributesPanel.setValues([%s])'%len(values or [])) if values is None: self.generateTable([]) elif True: #filters is None: self.generateTable(values) #print 'In AttributesPanel.setValues(...): done' return def generateTable(self, values): #thermocouples = thermocouples if thermocouples is not None else self.thermocouples self.setRowCount(len(values)) self.setColumnCount(5) #self.vheaders = [] self.offset = 0 self.widgetbuffer = [] for i, tc in enumerate(sorted(values)): #print 'setTableRow(%s,%s)'%(i,tc) model, device, attribute, alias, archived, ok = tc model, device, attribute, alias = map( str.upper, (model, device, attribute, alias)) #self.vheaders.append(model) def ITEM(m, model='', size=0): q = fn.qt.Draggable(Qt.QLabel)(m) if size is not 0: q.setMinimumWidth(size) #(.7*950/5.) q._model = model q._archived = archived q.setDragEventCallback(lambda s=q: s._model) return q ################################################################### qf = Qt.QFrame() qf.setLayout(Qt.QGridLayout()) qf.setMinimumWidth(self.SIZES[0]) qf.setSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Fixed) #Order changed, it is not clear if it has to be done before or after adding TaurusValue selfect self.setCellWidget(i + self.offset, 0, qf) #print('Adding item: %s, %s, %s, %s, %s' % (model,device,attribute,alias,archived)) if ok: tv = TaurusValue() #TaurusValueLabel() qf.layout().addWidget(tv, 0, 0) tv.setParent(qf) else: self.setItem(i + self.offset, 0, ITEM(model, model)) devlabel = ITEM(device, model, self.SIZES[1]) self.setItem(i + self.offset, 1, devlabel) self.setItem(i + self.offset, 2, ITEM(attribute, model, self.SIZES[2])) self.setItem(i + self.offset, 3, ITEM(alias, model, self.SIZES[3])) from PyTangoArchiving.widget.panel import showArchivingModes, show_history if archived: active = self.reader.is_attribute_archived(model, active=True) txt = '/'.join(a.upper() if a in active else a for a in archived) else: txt = '...' q = Qt.QPushButton(txt) q.setFixedWidth(self.SIZES[-2]) q.setToolTip("""%s<br><br><pre> 'HDB' : Archived and updated, push to export values 'hdb' : Archiving stopped, push to export values '...' : Not archived </pre>""" % txt) self.connect(q, Qt.SIGNAL("pressed ()"), lambda a=self.reader.get_attribute_alias( model), o=q: setattr(q, 'w', show_history(a)) ) #showArchivingModes(a,parent=self))) self.setItem(i + self.offset, 4, q) qc = Qt.QCheckBox() qc.setFixedWidth(self.SIZES[-1]) self.setItem(i + self.offset, 5, qc, 1, 1, Qt.Qt.AlignCenter, model) if ok: #print('Setting Model %s'%model) #ADDING WIDGETS IN BACKGROUND DIDN'T WORKED, I JUST CAN SET MODELS FROM THE WORKER try: if self.worker: self.worker.put([(lambda w=tv, m=model: w.setModel(m)) ]) #print 'worker,put,%s'%str(model) else: tv.setModel(model) except: print traceback.format_exc() self.models.append(tv) #self.widgetbuffer.extend([qf,self.itemAt(i+self.offset,1),self.itemAt(i+self.offset,2),self.itemAt(i+self.offset,3),self.itemAt(i+self.offset,4)]) fn.threads.Event().wait(.02) if len(values): def setup(o=self): [o.setRowHeight(i, 20) for i in range(o.rowCount())] #o.setColumnWidth(0,350) o.update() o.repaint() #print o.rowCount() o.show() setup(self) if self.worker: print('%s.next()' % (self.worker)) self.worker.next() #threading.Event().wait(10.) tracer('Out of generateTable()') def clear(self): try: #print('In AttributesPanel.clear()') for m in self.models: m.setModel(None) self.models = [] self.setValues(None) #QGridTable.clear(self) def deleteItems(layout): if layout is not None: while layout.count(): item = layout.takeAt(0) widget = item.widget() if widget is not None: widget.deleteLater() else: deleteItems(item.layout()) deleteItems(self.layout()) #l = self.layout() #l.deleteLater() #self.setLayout(Qt.QGridLayout()) except: traceback.print_exc()
from fandango import SingletonMap, str2time, time2str from fandango.qt import Qt,Qwt5,QTextBuffer,setDialogCloser,QWidgetWithLayout import taurus from taurus.qt.qtgui.plot import TaurusTrend from taurus.qt.qtgui.base import TaurusBaseWidget from taurus.qt.qtgui.container import TaurusWidget,TaurusGroupBox USE_MULTIPROCESS=False try: prop = PyTango.Database().get_class_property('HdbExtractor', ['Multiprocess'])['Multiprocess'] if any(a in str(prop).lower() for a in ('true','1')): USE_MULTIPROCESS=True elif any(fn.matchCl(p,platform.node()) for p in prop): USE_MULTIPROCESS=True except: print traceback.format_exc() print 'Multiprocess:%s'%USE_MULTIPROCESS DECIMATION_MODES = [ #('Hide Nones',fn.arrays.notnone), ('Pick One',fn.arrays.pickfirst), ('Minimize Noise',fn.arrays.mindiff), ('Maximize Peaks',fn.arrays.maxdiff), ('Average Values',fn.arrays.average), ('In Client', False), ('RAW',None), ]
def load_attributes(self, servfilter, devfilter, attrfilter, warn=True, exclude=('dserver', 'tango*admin', 'sys*database', 'tmp', 'archiving')): servfilter = servfilter.replace(' ', '*').strip() attrfilter = (attrfilter or 'state').replace(' ', '*') devfilter = (devfilter or attrfilter).replace(' ', '*') #Solve fqdn issues devfilter = devfilter.replace('tango://', '') if ':' in devfilter: tracer('ArchivingBrowser ignores tango host filters') devfilter = fn.clsub(fn.tango.rehost, '', devfilter) tracer('In load_attributes(%s,%s,%s)' % (servfilter, devfilter, attrfilter)) archive = self.dbcheck.isChecked() all_devs = self.all_devices if not archive else self.archdevs all_devs = [ d for d in all_devs if not any(d.startswith(e) for e in exclude) or any( d.startswith(e) and fn.matchCl(e, devfilter) for e in exclude) ] if servfilter.strip('.*'): sdevs = map(str.lower, fn.Astor(servfilter).get_all_devices()) all_devs = [d for d in all_devs if d in sdevs] #print('In load_attributes(%s,%s,%s): Searching through %d %s names' #%(servfilter,devfilter,attrfilter,len(all_devs), #'server' if servfilter else 'device')) if devfilter.strip().strip('.*'): devs = [ d for d in all_devs if (fn.searchCl(devfilter, d, extend=True)) ] print('\tFound %d devs, Checking alias ...' % (len(devs))) alias, alias_devs = [], [] if '&' in devfilter: alias = self.all_alias else: for df in devfilter.split('|'): alias.extend( self.tango.get_device_alias_list('*%s*' % df.strip())) if alias: print('\t%d alias found' % len(alias)) alias_devs.extend(self.alias_devs[a] for a in alias if fn.searchCl(devfilter, a, extend=True)) print('\t%d alias_devs found' % len(alias_devs)) #if not self.alias_devs: #self.alias_devs = dict((str(self.tango.get_device_alias(a)).lower(),a) for a in self.all_alias) #devs.extend(d for d,a in self.alias_devs.items() if fn.searchCl(devfilter,a) and (not servfilter or d in all_devs)) devs.extend(d for d in alias_devs if not servfilter.strip('.*') or d in all_devs) else: devs = all_devs devs = sorted(set(devs)) self.matching_devs = devs print('In load_attributes(%s,%s,%s): %d devices found' % (servfilter, devfilter, attrfilter, len(devs))) if False and not len(devs) and not archive: #Devices do not actually exist, but may exist in archiving ... #Option disabled, was mostly useless self.dbcheck.setChecked(True) return self.load_attributes(servfilter, devfilter, attrfilter, warn=False) if len(devs) > self.MAX_DEVICES and warn: Qt.QMessageBox.warning( self, "Warning", "Your search (%s,%s) matches too many devices!!! (%d); please refine your search\n\n%s\n..." % (devfilter, attrfilter, len(devs), '\n'.join(devs[:30]))) return {} elif warn and len(devs) > 15: r = Qt.QMessageBox.warning( self, "Message", "Your search (%s,%s) matches %d devices." % (devfilter, attrfilter, len(devs)), Qt.QMessageBox.Ok | Qt.QMessageBox.Cancel) if r == Qt.QMessageBox.Cancel: return {} self.matching_attributes = { } #{attribute: (device,alias,attribute,label)} failed_devs = [] for d in sorted(devs): try: dp = taurus.Device(d) if not archive: dp.ping() tcs = [t for t in dp.get_attribute_list()] else: tcs = [ a.split('/')[-1] for a in self.archattrs if a.startswith(d + '/') ] matches = [ t for t in tcs if fn.searchCl(attrfilter, t, extend=True) ] for t in sorted(tcs): if not self.dbcheck.isChecked() or not matches: label = dp.get_attribute_config(t).label else: label = t if t in matches or fn.searchCl( attrfilter, label, extend=True): if self.archivecheck.isChecked() \ and not self.reader.is_attribute_archived(d+'/'+t): continue if d in self.alias_devs: alias = self.alias_devs[d] else: try: alias = str(self.tango.get_alias(d)) except: alias = '' self.matching_attributes['%s/%s' % (d, t)] = (d, alias, t, label) if warn and len(self.matching_attributes ) > self.MAX_ATTRIBUTES: Qt.QMessageBox.warning( self, "Warning", "Your search (%s,%s) matches too many attributes!!! (%d); please refine your search\n\n%s\n..." % (devfilter, attrfilter, len(self.matching_attributes), '\n'.join( sorted(self.matching_attributes.keys()) [:30]))) return {} except: print('load_attributes(%s,%s,%s => %s) failed!' % (servfilter, devfilter, attrfilter, d)) failed_devs.append(d) if attrfilter in ('state', '', '*', '**'): self.matching_attributes[d + '/state'] = ( d, d, 'state', None ) #A None label means device-not-readable if warn and len(self.matching_attributes) > 30: r = Qt.QMessageBox.warning( self, "Message", "(%s) matches %d attributes." % (attrfilter, len(self.matching_attributes)), Qt.QMessageBox.Ok | Qt.QMessageBox.Cancel) if r == Qt.QMessageBox.Cancel: return {} if not len(self.matching_attributes): Qt.QMessageBox.warning( self, "Warning", "No matching attribute has been found in %s." % ('Archiving DB' if archive else 'Tango DB (try Archiving option)')) if failed_devs: print('\t%d failed devs!!!: %s' % (len(failed_devs), failed_devs)) if warn: Qt.QMessageBox.warning( self, "Warning", "%d devices were not running:\n" % len(failed_devs) + '\n'.join(failed_devs[:10] + (['...'] if len(failed_devs) > 10 else []))) tracer('\t%d attributes found' % len(self.matching_attributes)) return self.matching_attributes
def create_simulators(filein, instance='', path='', domains={}, tango_host='controls02', filters='', override=True): #domains = {'wr/rf':'test/rf'} path = path or os.path.abspath(os.path.dirname(filein)) + '/' print('create_simulators:' + str( (filein, instance, path, domains, tango_host))) ## THIS CHECK IS MANDATORY, YOU SHOULD EXPORT AND THEN LAUNCH IN DIFFERENT CALLS assert tango_host in str( fandango.tango.get_tango_host()), 'Use Controls02 for tests!!!' devs, org = {}, pickle.load( open(filein if '/' in filein else path + filein)) done = [] all_devs = fandango.get_all_devices() print('>' * 80) if not filters: print('%d devices in %s: %s' % (len(org), filein, sorted(org.keys()))) filters = raw_input('Do you want to filter devices? [*/*/*]').lower() for d, t in org.items(): k = ('/'.join( d.split('/')[-3:])).lower() #Removing tango host from the name for a, b in domains.items(): if k.startswith(a): k = k.replace(a, b) if not filters or fandango.matchCl(filters, d) or fandango.matchCl( filters, org[d].dev_class): devs[k] = t if override is not False: dds = [ d for d in devs if ('/'.join(d.split('/')[-3:])).lower() in all_devs ] if dds: print('%d devices already exist: %s' % (len(dds), sorted(dds))) override = raw_input('Do you want to override existing properties?' ).lower().startswith('y') else: override = False if not instance: instance = raw_input( 'Enter your instance name for the simulated DynamicServer (use "instance-" to use multiple instances):' ) print('>' * 80) for d, t in sorted(devs.items()): t.dev_class = t.dev_class or d.split('/')[-1] klass = 'PyStateComposer' if t.dev_class == 'PyStateComposer' else 'SimulatorDS' server = 'DynamicDS' instance_temp = '%s%s' % (instance, t.dev_class) if '-' in instance else instance print('%s/%s:%s , "%s" => %s ' % (server, instance_temp, d, t.dev_class, klass)) its_new = ('/'.join(('dserver', server, instance_temp)) ).lower() not in all_devs or d.lower() not in all_devs if its_new or override: print('writing ... %s(%s)' % (type(t), d)) fandango.tango.add_new_device('%s/%s' % (server, instance_temp), klass, d) for p, v in t.props.items(): if not p.startswith( '__' ): #p not in ('DynamicCommands','DynamicStates','LoadFromFile','DevicesList') and fandango.tango.put_device_property(d, p, v) #Overriding Dynamic* properties try: fandango.tango.put_device_property( d, 'LoadFromFile', path + '%s_attributes.txt' % t.dev_class) fandango.tango.put_device_property( d, 'DynamicAttributes', filter( bool, map( str.strip, open(path + '%s_attributes.txt' % t.dev_class).readlines()))) fandango.tango.put_device_property( d, 'DynamicCommands', filter( bool, map( str.strip, open(path + '%s_commands.txt' % t.dev_class).readlines()))) fandango.tango.put_device_property( d, 'DynamicStates', filter( bool, map( str.strip, open(path + '%s_states.txt' % t.dev_class).readlines()))) except: print('Unable to configure %s(%s) properties ' % (d, t.dev_class)) #traceback.print_exc() fandango.tango.put_device_property(d, 'OFFSET', random.randint(0, len(devs))) done.append(d) exported = fandango.get_all_devices(exported=True) update = [d for d in done if d in exported] print('Updating %d Devices ...' % len(update)) for d in update: if fandango.check_device(d): print('Updating %s ...' % d) try: fandango.get_device(d).updateDynamicAttributes() except Exception, e: print(e) else: print('%s failed!' % d) time.sleep(.2)