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 decorate(self, target): if isCallable(target): self.f = target self.f_name = target.__name__ #self.call = wraps(self.f)(self.__call__) #Not for methods!! functools.update_wrapper(self, self.f) else: self.f = None
def decimation(history, method, window='0', logger_obj=None, N=1080): """ Nones and NaNs are always removed if this method is called history: array of data method: method or callable window: string for time logger_obj: ArchivedTrendLogger or similar N: max array size to return """ t0 = time.time() l0 = len(history) if not l0: return history trace = getattr(logger_obj, 'warning', fandango.printf) try: window = str2time(window or '0') except: window = 0 start_date, stop_date = float(history[0][0]), float(history[-1][0]) ## Decimation by data_has_changed is ALWAYS done if len(history): #method is not None nv = [] #sq = isSequence(history[0][1]) for i, v in enumerate(history): if (v[1] not in (None, NaN ) # is not None and (sq or not isNaN(v[1])) #and (i in (0,l0-1,l0-2) or #data_has_changed(history[i-1],v,history[i+1])) ): nv.append(v) t1 = time.time() trace('Removed %d (None,NaN, Rep) values in %fs' % (l0 - len(nv), t1 - t0)) t0, i, c, lh = t1, 0, 0, len(history) while i < len(history): if history[c] in (None, NaN): history.pop(c) else: c += 1 i += 1 t1 = time.time() trace('Removed %d (None,NaN, Rep) values in %fs' % (l0 - len(history), t1 - t0)) history = nv if (method and isCallable(method) and method != data_has_changed and len(history) and type(history[0][-1]) in (int, float, bool)): #type(None)): # Data is filtered applying an averaging at every "window" interval. # As range() only accept integers the minimum window is 1 second. # It means that filtering 3 hours will implicitly prune millis data. #DATA FROM EVAL IS ALREADY FILTERED; SHOULD NOT PASS THROUGH HERE wmin = max(1., (stop_date - start_date) / (10 * 1080.)) wauto = max(1., (stop_date - start_date) / (10 * N)) trace('WMIN,WUSER,WAUTO = %s,%s,%s' % (wmin, window, wauto)) window = wauto if not window else max((wmin, window)) if len(history) > (stop_date - start_date) / window: history = fandango.arrays.filter_array(data=history, window=window, method=method) t2 = time.time() trace('Decimated %d values to %d in %f seconds ' '(%s,%s)' % (l0, len(history), t2 - t1, method, window)) else: trace('Decimation is not callable') return history
def _log(self, msg): if isCallable(self.log): self.log(msg) elif self.log: print(msg)