def trigger_callbacks(self, regs=None): """ regs = list of addresses that changed """ if not self.callbacks: return for key, cb in self.callbacks.items(): try: push = False if fun.isSequence(cb): if not regs or any(r in cb for r in regs): #print('%s: %s.trigger(%s): callback(%s):%s' % #(fun.time2str(),self,key,cb,regs)) cb, push = cb[-1], True else: continue if fun.isCallable(cb): cb(key, push=push) else: cb = getattr(cb, 'push_event', getattr(cb, 'event_received', None)) cb and cb(key) fandango.wait(1.e-4) except Exception as e: print(fandango.except2str()) print('%s.callback(%s): %s' % (self, cb, e))
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. """ if att == self.ChannelName.split('[')[0].lower(): if '[' in self.ChannelName and fun.isSequence(attr_value.value): attr_value.value = attr_value.value[self.getOrdinal( self.ChannelName)] self.Cache[self.ChannelName] = attr_value self.ChannelValue = attr_value.value if attr_value.quality in (PyTango.AttrQuality.ATTR_ALARM, PyTango.AttrQuality.ATTR_WARNING): new_state = PyTango.DevState.ALARM elif attr_value.value <= self.LowRange: new_state = PyTango.DevState.STANDBY else: new_state = PyTango.DevState.ON date = attr_value.time if not hasattr( attr_value.time, 'totime') else attr_value.time.totime() self.plog( 'info', 'Updated Pressure Value: %s at %s' % (attr_value.value, date)) elif att == 'state': self.Cache[att] = attr_value else: self.plog('warning', 'UNKNOWN ATTRIBUTE %s!!!!!' % attr_name) self.plog('debug', 'self.Channel=%s' % str(self.Channel)) self.plog('debug', 'attr_name.split=%s' % str(attr_name.split('/'))) return new_state
def get_attributes_as_event_list(attributes,start_date=None,stop_date=None,formula=None): """ This method returns attribute changes ordered by time (event_list format) Attributes can be passed as a list or as a formula (TangoEval) or both. If a formula is available the evaluated value will be added at each row of the list. """ from PyTangoArchiving import Reader from fandango import isSequence,isString,TangoEval rd = Reader() te = fandango.TangoEval() if isString(attributes) and formula is None: try: formula = attributes attributes = sorted(set('%s/%s'%t[:2] for t in te.parse_variables(formula))) if len(attributes)==1: formula = None except: formula,attributes = None,[] if isSequence(attributes): assert start_date, 'start_date argument is missing!' attributes = rd.get_attributes_values(attributes,start_date,stop_date) avals = dict((k,decimate_array(v)) for k,v in attributes.items()) buffer = sorted((v[0],k,v[1]) for k,l in avals.items() for i,v in enumerate(l) if not i or v[1]!=l[i-1][1]) if formula is not None: cache,parsed = {},te.parse_formula(formula) for i,event in enumerate(buffer): cache[event[1]] = event[2] f = te.eval(parsed,cache) if all(k in cache for k in attributes) else None buffer[i] = (event[0],event[1],event[2],f) return buffer
def __init__(self, parent=None, model=None, filters=[], connect=False): #,palette=None, bound=True,filters=[]): """ In Init, the class VaccaPanel check if exist any shareDataManager to subscribe in it. :param parent: :param model: Model to start the Panel. :param filters: dictionary with 'attrs' and 'comms' filters as regexp or tuples lists :return: """ self.call__init__(taurus.qt.qtgui.panel.TaurusDevicePanel, parent, model) self._status.setFixedHeight(2000) self._status.setFixedWidth(7000) #self.setLogLevel(self.Info) self.info('init(%s,%s): connecting ...' % (model, filters)) self._connected = [] if connect: self.connectSharedSignals() if self.checkDropSupport(): self.setSupportedMimeTypes([ self.TAURUS_DEV_MIME_TYPE, self.TEXT_MIME_TYPE, self.TAURUS_MODEL_MIME_TYPE ]) self.setDropEventCallback(self.setModelHook) self.info('init(...): layout ...') self._header.layout().removeWidget(self._label) self._label = fandango.qt.Dropable(fandango.qt.Draggable(Qt.QLabel))() self._label.font().setBold(True) self._label.setText('SELECT A DEVICE FROM THE TREE') self._header.layout().addWidget(self._label, 0, 1, Qt.Qt.AlignLeft) self._label.setDragEventCallback(self._label.text) self._label.checkDropSupport() self._label.setSupportedMimeTypes([ self.TAURUS_DEV_MIME_TYPE, self.TEXT_MIME_TYPE, self.TAURUS_MODEL_MIME_TYPE ]) self._label.setDropEventCallback(self.setModelHook) #self.setToolTip(getattr(self,'__help__',self.__doc__)) if filters: self.info('VaccaPanel(filters=%s)' % filters) if 'attrs' in filters: type(self)._attribute_filter = {'.*': filters['attrs']} if 'comms' in filters: type(self)._command_filter = { '.*': [ c if fun.isSequence(c) else (c, ()) for c in filters['comms'] ] }
def get_alias_file(schema=''): from fandango.tango import get_free_property, get_class_property if not schema or schema in ('*', ''): alias_file = get_free_property('PyTangoArchiving', 'AliasFile') else: alias_file = get_class_property('%sextractor' % schema, 'AliasFile') if isSequence(alias_file) and len(alias_file): alias_file = alias_file[0] if not alias_file: alias_file = get_alias_file() return alias_file
def reader_hook(self, attribute, values): """This method will be executed by the ReaderProcess to process the queried data.""" try: print('>' * 80) print(time.ctime() + ' In reader_hook(%s,[%d])' % (attribute, len(values))) MAXDIM = 1024 * 1024 * 1024 #First create the attributes epoch, data, aname = [], [], attribute.replace('/', '__') values = decimate_values(values) [(epoch.append(v[0]), data.append(v[1])) for v in values] writable = PyTango.AttrWriteType.READ #Adding time attribute m, atformat, dims = None, PyTango.SpectrumAttr, [MAXDIM] for d in data: if d is not None: if fn.isSequence(d): atformat, dims = PyTango.ImageAttr, [MAXDIM, MAXDIM] m = d[0] else: m = d break attype = PyTango.DevDouble if ( fn.isNumber(m) or fn.isBool(m)) else PyTango.DevString self.add_attribute( PyTango.ImageAttr(aname, attype, writable, MAXDIM, MAXDIM), self.read_dyn_attr, None, self.is_dyn_attr_allowed) self.add_attribute( PyTango.SpectrumAttr(aname + '_t', PyTango.DevDouble, writable, MAXDIM), self.read_dyn_attr, None, self.is_dyn_attr_allowed) self.add_attribute( PyTango.SpectrumAttr(aname + '_d', PyTango.DevString, writable, MAXDIM), self.read_dyn_attr, None, self.is_dyn_attr_allowed) self.add_attribute(atformat(aname + '_r', attype, writable, *dims), self.read_dyn_attr, None, self.is_dyn_attr_allowed) #Then add the data to Cache values, so IsDataReady will return True t = fn.now() self.RemoveCachedAttribute(attribute) self.AttrData[attribute] = (t, atformat, attype, values) print('Done: %s,%s,%s,%s,%d' % (attribute, t, atformat, attype, len(values))) except: print(traceback.format_exc())
def get_alias_file(schema = ''): from fandango.tango import get_free_property,get_class_property if not schema or schema in ('*',''): alias_file = get_free_property('PyTangoArchiving','AliasFile') else: alias_file = get_class_property('%sextractor'%schema,'AliasFile') if isSequence(alias_file) and len(alias_file): alias_file = alias_file[0] if not alias_file: alias_file = get_alias_file() return alias_file
def get_attribute_pytype(attribute=None,value=None): assert attribute or value v = value or check_attribute(attribute,readable=True) if not v: return None v = getattr(v,'value',v) if fun.isString(v): return str if fun.isSequence(v): return list if fun.isBool(v): return bool if any(s in str(type(v).__name__.lower()) for s in ('int','short','long')): return int return float
def get_only_scalar_attributes(model,exclude_strings=True): """ This method will filter out all attributes that are either Arrays or Strings. Model can be a device name, a regexp expression or a list of attributes. """ if fun.isSequence(model): attrs = model elif fun.isRegexp(model): attrs = fandango.get_matching_attributes(model) else: attrs = fandango.get_matching_attributes(model+'/*') exclude = [list] + ([str] if exclude_strings else []) return [a for a in attrs if get_attribute_pytype(a) not in exclude]
def get_only_scalar_attributes(model, exclude_strings=True): """ This method will filter out all attributes that are either Arrays or Strings. Model can be a device name, a regexp expression or a list of attributes. """ if fun.isSequence(model): attrs = model elif fun.isRegexp(model): attrs = fandango.get_matching_attributes(model) else: attrs = fandango.get_matching_attributes(model + '/*') exclude = [list] + ([str] if exclude_strings else []) return [a for a in attrs if get_attribute_pytype(a) not in exclude]
def get_density(values): """ returns the number of values/second (expanding arrays) """ if not len(values): return 0 t0 = values[0][0] t1 = values[-1][0] if t0==t1: return 1 v = fun.first((v[1] for v in values if v[1] is not None),default=None) if fun.isSequence(v): return len(values)*len(v)/(t1-t0) return len(values)/(t1-t0)
def applyModes(self): self.logger().show() #Qt.QApplication.instance().setOverrideCursor(Qt.QCursor(Qt.Qt.WaitCursor)) try: attr = self.getModel() v = F.check_attribute(attr, brief=True) if isinstance(v, (type(None), Exception)): Qt.QMessageBox.warning( self, "Warning", "%s is not readable nor archivable" % attr) self.logger().hide() return if fun.isSequence(v) or fun.isString(v): Qt.QMessageBox.warning(self, "Warning", "%s array type is not supported" % attr) self.logger().hide() return modes = self.getModes() or {'MODE_P': [60000]} schema = self.getSchema() print('%s: applyModes(%s)' % (fun.time2str(), modes)) msg = 'Modes to be applied:\n' for m, v in modes.items(): msg += '\t%s.%s: %s\n' % (schema, m, v) qm = Qt.QMessageBox(Qt.QMessageBox.Warning, 'Confirmation', msg, Qt.QMessageBox.Ok | Qt.QMessageBox.Cancel) r = qm.exec_() if r == Qt.QMessageBox.Ok: if not self.api: self.api = pta.api(self.getSchema().lower(), logger=self.logger()) self.api.log = self.logger() #self.emit(Qt.SIGNAL('archive'),attr,modes) Qt.QApplication.instance().setOverrideCursor( Qt.QCursor(Qt.Qt.WaitCursor)) thr = threading.Thread(target=self.startArchiving, args=(attr, modes)) QLoggerDialog._threads = filter(Thread.is_alive, self.threads()) + [thr] thr.start() else: self.logger().hide() except: self.logger().error(traceback.print_exc()) print('%s: applyModes(...): running!' % (fun.time2str()))
def summarize(seq,seq2=[],NMAX=5): #Max number of attrs to display in a single line #seq = [seq for seq in seq if seq] #return str(seq) if len(seq)<NMAX else '[%d]'%len(seq) if not fun.isSequence(seq): if type(seq) is float: if seq>1e-2 or not seq: if 0<=seq<=.9: return color(web.bold('%1.2f'%seq),'red') else: return '%1.2f'%seq else: return '%1.2e'%seq else: return seq res = fandango.device.reduce_distinct(seq,seq2) if seq2 else (seq,1.0) if seq and len(res[0])<NMAX and res[1]>.5: return '%d, like:<br>%s' % (len(seq),'<br>'.join(res[0])) else: return '%d'%len(seq)
def applyModes(self): self.logger().show() #Qt.QApplication.instance().setOverrideCursor(Qt.QCursor(Qt.Qt.WaitCursor)) try: attr = self.getModel() v = F.check_attribute(attr,brief=True) if isinstance(v,(type(None),Exception)): Qt.QMessageBox.warning(self,"Warning","%s is not readable nor archivable"%attr) self.logger().hide() return if fun.isSequence(v) or fun.isString(v): Qt.QMessageBox.warning(self,"Warning","%s array type is not supported"%attr) self.logger().hide() return modes = self.getModes() or {'MODE_P':[60000]} schema = self.getSchema() print('%s: applyModes(%s)'%(fun.time2str(),modes)) msg = 'Modes to be applied:\n' for m,v in modes.items(): msg += '\t%s.%s: %s\n'%(schema,m,v) qm = Qt.QMessageBox(Qt.QMessageBox.Warning,'Confirmation',msg,Qt.QMessageBox.Ok|Qt.QMessageBox.Cancel) r = qm.exec_() if r == Qt.QMessageBox.Ok: if not self.api: self.api = pta.api(self.getSchema().lower(),logger=self.logger()) self.api.log = self.logger() #self.emit(Qt.SIGNAL('archive'),attr,modes) Qt.QApplication.instance().setOverrideCursor(Qt.QCursor(Qt.Qt.WaitCursor)) thr = threading.Thread(target=self.startArchiving,args=(attr,modes)) QLoggerDialog._threads = filter(Thread.is_alive,self.threads())+[thr] thr.start() else: self.logger().hide() except: self.logger().error(traceback.print_exc()) print('%s: applyModes(...): running!'%(fun.time2str()))
try: f = open(chkfile,'w') f.write('\t'.join(CHECK_KEYS)+'\n') f.write('\t'.join([str(vals[k]) for k in CHECK_KEYS]) + '\n') f.close() except: print 'Unable to write %s: %s' % (chkfile,traceback.format_exc()) #Adding Summaries for each Schema for schema,vals in sorted(results.items()): add2lines(web.title('Checking %s configurations' % schema.upper(),2)) add2lines(web.paragraph('Filters are:'+web.ulist(web.item('include %s'%argfilters)+web.item('exclude %s'%argexclude)))) add2lines(web.dict2dict2table(dict((web.link(k,web.iurl(schema+':'+k)),v) for k,v in vals.items()),keys=['']+CHECK_KEYS,formatter=fun.partial(summarize,seq2=(vals['ok'] if 'ok' in vals else[]),NMAX=0))) totals.update([(k,sum([(len(v[k]) if fun.isSequence(v[k]) else v[k]) for v in vals.values() if k in v])) for k in CHECK_KEYS]) conf2file(filename.rsplit('.',1)[0]+'.%s'%schema,totals) if polizons.get(schema): add2lines(web.paragraph(web.link('%d attributes in archiving does not appear in listed files'%len(polizons[schema]),web.iurl(schema+':polizons')))) add2lines(web.separator) try: add2lines(web.title('Tables legend:',3)) add2lines(web.ulist('<br>\n'.join([web.item(s) for s in ['%s: \t%s'%(k,v) for k,v in files.REPORT_LEGEND.items()]]))) except: pass if failed: try: add2lines(web.title('Failed config files',2)) for conf,error in failed.items():
def reader_hook(self,attribute,values): """This method will be executed by the ReaderProcess to process the queried data.""" try: print('>'*80) print(time.ctime()+' In reader_hook(%s,[%d])' %(attribute,len(values))) self.counter-=1 print(self.counter) MAXDIM = 1024*1024*1024 #First create the attributes epoch,data,aname = [],[],attribute.replace('/','__') values = decimate_values(values) [(epoch.append(v[0]),data.append(v[1])) for v in values] writable = PyTango.AttrWriteType.READ #Adding time attribute m,atformat,dims = None,PyTango.SpectrumAttr,[MAXDIM] for d in data: if d is not None: if fn.isSequence(d): atformat,dims = PyTango.ImageAttr,[MAXDIM,MAXDIM] m = d[0] else: m = d break attype = PyTango.DevDouble if (fn.isNumber(m) or fn.isBool(m)) else PyTango.DevString self.add_attribute( PyTango.ImageAttr(aname,attype,writable,MAXDIM,MAXDIM), self.read_dyn_attr,None,self.is_dyn_attr_allowed) self.add_attribute( PyTango.SpectrumAttr(aname+'_t',PyTango.DevDouble, writable,MAXDIM), self.read_dyn_attr,None,self.is_dyn_attr_allowed) self.add_attribute( PyTango.SpectrumAttr(aname+'_d',PyTango.DevString, writable,MAXDIM), self.read_dyn_attr,None,self.is_dyn_attr_allowed) #ARRAY self.add_attribute(atformat(aname+'_r',attype, writable,*dims), self.read_dyn_attr,None,self.is_dyn_attr_allowed) #LAST VALUE self.add_attribute(PyTango.Attr(aname+'_l',attype,PyTango.AttrWriteType.READ), self.read_dyn_attr,None,self.is_dyn_attr_allowed) #LAST DATE self.add_attribute( PyTango.Attr(aname+'_ld',PyTango.DevString,PyTango.AttrWriteType.READ), self.read_dyn_attr,None,self.is_dyn_attr_allowed) self.add_attribute( PyTango.Attr(aname+'_rg',PyTango.DevString,PyTango.AttrWriteType.READ), self.read_dyn_attr,None,self.is_dyn_attr_allowed) #Then add the data to Cache values, so IsDataReady will return True t = fn.now() self.RemoveCachedAttribute(attribute) self.AttrData[attribute] = (t,atformat,attype,values) print('Done: %s,%s,%s,%s,%d'%(attribute,t,atformat,attype,len(values))) except: print(traceback.format_exc())