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_device(self): try: PseudoDev.init_device(self) if not self.check_Properties(['GaugeController', 'Channel']): self.init_error += "GaugeController,Channel properties are mandatory, edit them and launch Init()" self.error(self.init_error) self.set_state(PyTango.DevState.FAULT) return else: self.ChannelName = (self.Channel.split()[0] if fun.isString( self.Channel) else fun.first( c for c in self.Channel if c.lower() not in ('State', 'ChannelState'))).lower() targets = ['State', self.ChannelName, 'ChannelState'] self.debug('Creating cache values for %s:%s' % (self.GaugeController, targets)) for attribute in targets: da = PyTango.DeviceAttribute() da.name, da.time, da.value = ( self.GaugeController + '/' + attribute), PyTango.TimeVal.fromtimestamp(0), None self.Cache[attribute] = da self.Errors[attribute] = 0 self.subscribe_external_attributes(self.GaugeController, targets) self.info('Ready to accept request ...') self.info('-' * 80) except Exception, e: print 'Exception in %s.init_device():' % self.get_name() print traceback.format_exc() raise e
def get_next_month(date): if not fun.isString(date): date = time2str(date) year,month,day = map(int,date.split()[0].split('-')) if month<12: return '%04d-%02d-%02d' % (year,month+1,1) else: return '%04d-%02d-%02d' % (year+1,1,1)
def get_days_in_interval(*args): """ args may be a list of timestamps or just start,stop dates """ if len(args)==2: if fun.isString(args[0]): start,stop = str2time(args[0]),str2time(args[1]) else: start,stop = args[0],args[1] times = range(int(start),int(stop+86400),86400) else: times = args[0] days = sorted(set(list(d.split()[0] for d in map(time2str,times)))) return days
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 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 getApi(k, schema): schema = k.getSchema(schema) api = schema.get('api', 'PyTangoArchiving.ArchivingAPI') if fun.isString(api): api = k._load_object(api, schema) return api(schema['schema']) if isinstance(api, type) else api
def event_received(self,source,type_,attr_value): """ This function manages the States of the device Initializes ChannelValue and ChannelStatus to keep the values of attributes """ self.last_event_received = time.time() #self.info,debug,error,warning should not be used here to avoid conflicts with tau.core logging log = self.plog if type_ not in fakeEventType and fn.isString(type_): type_ = fn.matchMap(fakeEventType.lookup,'change',default=0) log('info','*'*80) log('info','In .event_received(%s(%s),%s,%s)'%(type(source).__name__,source,type_,type(attr_value).__name__)) if fakeEventType[type_] == 'Config': return source = fandango.tango.get_model_name(source) params = fandango.tango.parse_tango_model(source) tango_host,dev_name,att,attr_name = '%s:%s'%(params['host'],params['port']),\ params['devicename'],params['attributename'],'%s/%s'%(params['devicename'],params['attributename']) error = ('Error'==fakeEventType[type_]) try: #Get actual State state = new_state = self.get_state() if att == 'state' and not error: dState = attr_value.value else: dState = self.Cache['state'].value log('info','In .event_received(%s): parent state is %s'%(source,dState)) if dState not in (None,PyTango.DevState.INIT,PyTango.DevState.UNKNOWN): if not error: if isinstance(attr_value,PyTango.DeviceAttribute) or isinstance(attr_value,fakeAttributeValue): new_state = self.StateMachine(att,attr_value,new_state) if new_state == PyTango.DevState.UNKNOWN and state != PyTango.DevState.UNKNOWN: #StateMachine == UNKNOWN mean that an unparsable value is received, so it is considered as an error and Errors count is checked before switching state self.Errors[att]+=1 if self.Errors[att]<self.MAX_ERRORS: new_state = state else: self.Errors[att] = 0 else: log('warning','event_received(%s,%s): no further actions for this value type ... %s' % (source,fakeEventType[type_],type(attr_value))) elif error: self.Errors[att] += 1 try: reasons = [e.reason for e in attr_value.args] except: reasons = [] error_value = {'state':None,self.Channel:None,'channelstate':'UNKNOWN'}.get(att,None) #if any([r in err_reason for r in #Discarding well-known common Exceptions #['MKS','VarianDUAL','API_AttributeFailed','AttrNotAllowed','TimeOut','Timeout']]): #print 'In IonPump(%s).push_event(%s): Attribute Reading not allowed (%s)'%(self.get_name(),att_name,err_reason) log('warning','In event_received(%s) ... received an error! %d/%d: \n%s '%(source,self.Errors[att],self.MAX_ERRORS,reasons)) if self.Errors[att]>=self.MAX_ERRORS: self.state_reason ='MAX_ERRORS limit (%d) reached for attribute %s, resetting the value to %s' % (self.MAX_ERRORS,attr_name,error_value) if self.Cache[att].value!=error_value: log('warning',self.state_reason) self.Cache[att].value = error_value new_state = PyTango.DevState.UNKNOWN #Update State, If dState=ON and state=INIT then state will not change until HVStatus is read #new_state = dState if dState is not PyTango.DevState.ON else new_state #If not able to read Controller's State else: #In UNKNOWN State is assumed that is useless to communicate with the Parent device log('debug','In .event_received(%s): %s.State is %s, events are ignored.'%(source,dev_name,dState)) new_state=PyTango.DevState.UNKNOWN # Use of states other than UNKNOWN is confussing and unpredictable! self.state_reason = '%s state is %s'%(dev_name,dState if dState is not None else 'NotRunning') self.ChannelValue = None for k in self.Cache: if k.lower()=='state': continue elif 'state' in k.lower(): #ChannelState self.Cache[k].value = 'UNKNOWN' else: self.Cache[k].value = None except Exception,e: horreur = traceback.format_exc() message = 'exception in event_received(%s): %s\n%s'% (source,e,horreur) if self.get_state()!=PyTango.DevState.UNKNOWN: self.state_error=str(e).replace('\n','')[:80]+'...' log('error',(message)) self.Errors[att] += 1 error_value = {'state':None,self.Channel:None,'channelstate':'UNKNOWN'}.get(att,None) if self.Errors[att]>=self.MAX_ERRORS and self.Cache[att].value!=error_value: log('warning','MAX_ERRORS limit (%d) reached for attribute %s, resetting the value to %s' % (self.MAX_ERRORS,attr_name,error_value)) self.Cache[att].value = error_value if att=='state': new_state = PyTango.DevState.UNKNOWN