def info(self): if self.running not in ("off","error"): tm = unixdelta(self.next-now()) elif self.last is not None: tm = unixdelta(now()-self.last) else: tm = "never" return "%s %s" % (self.running,tm)
def exposed_cmd_list(self,*args): # don't call this 'exposed_list'! c = get_collect(args, allow_collection=True) try: if c is None: for m in all_collect(skip=False): yield m.name, elif isinstance(c,Collection): if args[-1] == "*": for n,m in c.iteritems(): yield n,m return for n,m in c.iteritems(): try: m = m.info except AttributeError: m = m.name else: if callable(m): m = m() if isinstance(m,basestring): m = m.split("\n")[0].strip() if m is not None: yield (n,m) else: yield n, else: q = Queue(3) job = spawn(flatten,q,(c,)) job.link(lambda _:q.put(None)) while True: res = q.get() if res is None: return p,t = res if isinstance(t,datetime): if TESTING: if t.year != 2003: t = "%s" % (humandelta(t-now(t.year != 2003)),) else: t = "%s (%s)" % (humandelta(t-now(t.year != 2003)),t) ti = t.rfind('.') if ti>0 and len(t)-ti > 3 and len(t)-ti<9: # limit to msec t= t[:ti+3]+")" # otherwise transmit the datetime as-is elif not isinstance(t,(date,time,timedelta)): t = unicode(t) yield p,t except Exception as e: fix_exception(e) yield "* ERROR *",repr(e) process_failure(e)
def time_name(self): if self.started_at is None: return "never" if not self.running.is_set(): delta = now() - self.started_at elif self.job: delta = self.started_at - now() else: delta = now() - self.started_at delta = unixdelta(delta) res = humandelta(delta) return u"‹"+res+"›"
def run(self,ctx,**k): event = self.params(ctx) if len(event): self.displayname = SName(event) if self.timespec is None: raise SyntaxError(u'Usage: wait [name…]: for|until|next ‹timespec›') if self.is_update: return Waiters[self.displayname].retime(self.timespec()) w = Waiter(self, self.displayname, self.force) w.init(self.timespec()) process_event(Event(self.ctx(loglevel=TRACE),"wait","start",ixtime(w.end,self.force),*w.name)) try: if w.job: r = w.job.get() else: r = True except Exception as ex: fix_exception(ex) log_exc(msg=u"Wait %s died:"%(self.name,), err=ex, level=TRACE) raise else: tm = ixtime(now(self.force),self.force) if r: # don't log 'done' if canceled process_event(Event(self.ctx(loglevel=TRACE),"wait","done",tm, *w.name)) ctx.wait = tm if not r: raise DelayCancelled(w)
def list(self): yield super(Waiter,self) yield("start",self.start) if self._plinger: end=now()+dt.timedelta(0,self.value) yield("end",end) yield("total", humandelta(end-self.start)) w = self while True: w = getattr(w,"parent",None) if w is None: break n = getattr(w,"displayname",None) if n is not None: if not isinstance(n,basestring): n = " ".join(unicode(x) for x in n) else: try: if w.args: n = unicode(w.args) except AttributeError: pass if n is None: try: if isinstance(w.name,basestring): n = w.name else: n = " ".join(unicode(x) for x in w.name) except AttributeError: n = w.__class__.__name__ if n is not None: yield("in",n)
def _set_pling(self): timeout = unixtime(self.end) - unixtime(now(self.force)) if timeout <= 0.1: timeout = 0.1 if self._plinger: self._plinger.cancel() self._plinger = callLater(self.force, timeout, self._pling)
def _job(self): try: self._set_pling() self._running = True while True: cmd = self.q.get() q = cmd[0] a = cmd[2] if len(cmd)>2 else None cmd = cmd[1] if cmd == "timeout": assert self._plinger is None q.put(None) return True elif cmd == "cancel": if self._plinger: self._plinger.cancel() self._plinger = None q.put(None) return False elif cmd == "update": q.put(None) self.end = a self._set_pling() elif cmd == "remain": q.put(unixtime(self.end)-unixtime(now(self.force))) else: q.put(RuntimeError('Unknown command: '+cmd)) finally: q,self.q = self.q,None super(Waiter,self).delete() if q is not None: while not q.empty(): q.get()[0].put(StopIteration())
def _do_measure(self): log("monitor",TRACE,"Start run",self.name) try: self.running.clear() self.started_at = now() self._monitor() if self.send_check_event: process_event(Event(self.ctx, "monitor","checked",*self.name)) if self.new_value is not None: if hasattr(self,"delta"): if self.value is not None: val = self.new_value-self.value if val >= 0 or self.delta == 0: process_event(Event(Context(),"monitor","value",self.new_value-self.value,*self.name)) else: process_event(Event(Context(),"monitor","value",self.new_value,*self.name)) if self.new_value is not None: self.value = self.new_value except Exception as e: fix_exception(e) process_failure(e) finally: log("monitor",TRACE,"Stop run",self.name) self.running.set() self._schedule()
def __init__(self,parent,name, names=("off","on"), **k): self.ctx = parent.ctx self.start = now() self.names = names for a,b in k.iteritems(): self.arg(a,b) self.validate() super(CommonPM,self).__init__(*name)
def run(self,ctx,**k): event = self.params(ctx) if len(event): self.displayname = SName(event) if self.timespec is None: raise SyntaxError(u'Usage: wait [name…]: for|until|next ‹timespec›') if self.is_update: return Waiters[self.displayname].retime(self.timespec()) w = Waiter(self, self.displayname, self.force) w.init(self.timespec()) simple_event("wait","start",*w.name, end_time=ixtime(w.end,self.force), loglevel=TRACE) try: if w.job: r = w.job.get() else: r = True except Exception as ex: simple_event("wait","error", *w.name, time=tm,loglevel=TRACE) fix_exception(ex) log_exc(msg=u"Wait %s died:"%(self.name,), err=ex, level=TRACE) raise else: tm = ixtime(now(self.force),self.force) if r: simple_event("wait","done", *w.name, loglevel=TRACE) else: simple_event("wait","cancel", *w.name, loglevel=TRACE) ctx.wait = tm if not r: raise DelayCancelled(w) finally: w.delete()
def _do_measure(self): log("monitor",TRACE,"Start run",self.name) try: self.running.clear() self.started_at = now() self._monitor() if self.send_check_event: simple_event(self.ectx, "monitor","checked",*self.name) if self.new_value is not None: self.last_value = self.value self.value = self.new_value if hasattr(self,"delta"): if self.last_value is not None: val = self.value-self.last_value self._ectx.value_delta = val if val >= 0 or self.delta == 0: simple_event(self.ectx,"monitor","update",*self.name) else: simple_event(self.ectx,"monitor","update",*self.name) except Exception as e: fix_exception(e) process_failure(e) finally: log("monitor",TRACE,"Stop run",self.name) self.running.set() self._schedule()
def list(self): n = now() for r in super(OutTimer,self).list(): yield r yield ("output",self.parent.name) yield ("start", self.started) yield ("end", self.end) yield ("next value",self.val)
def read(self): """Read an output, check range.""" res = self._read() res = self.repr(res) self.check(res) self.last_time = now() self.last_value = res return res
def weigth(self, mod=False): if self.value_tm is None: return None t = now()-self.value_tm nt = unixdelta(t) if nt == 0: ## called right after init'ing return 0 else: return 1-(1-self.p)**(nt/self.p_base)
def __init__(self,parent,name,force): self.ctx = parent.ctx self.start = now() self.force = force try: self.parent = parent.parent except AttributeError: pass super(Waiter,self).__init__(name)
def feed(self, value): self.prev_value = self.value if value is None: value = self.value if value is None: return self.value = value self.value_tm = now() self.total_samples += 1 self.avg = self._calc(True)
def event(self,ctx,data): for m,n in data.iteritems(): try: n = n * self.faktor[m] except KeyError: pass try: n = n + self.offset[m] except KeyError: pass simple_event(ctx, "fs20","tx", m,n, *self.name) self.last = now() self.last_data = data
def getter(out,q): while True: res = q.get() if res is None: return p,t = res if isinstance(t,datetime): if TESTING and t.year != 2003: t = "%s" % (humandelta(t-now(t.year != 2003)),) else: t = "%s (%s)" % (humandelta(t-now(t.year != 2003)),t) if TESTING: lim = 3 else: lim = 4 ti = t.rfind('.') if ti>0 and len(t)-ti>lim and len(t)-ti<lim+6: # limit to msec t = t[:ti+lim]+")" print >>out,p+u": "+unicode(t)
def report(self, verbose=False): if self.name: yield "WORK: "+self.name if self.id: yield "id: "+str(self.id) yield "call count: "+str(self.call_count) if self.last_call: yield "last call: %s (%s)" % (humandelta(now()-self.last_call),self.last_call) if self.last_args: for a,b in self.last_args.iteritems(): yield "last %s: %s" % (a,b)
def sleepUntil(force,delta): from homevent.times import unixdelta,now,sleep if isinstance(delta,dt.datetime): delta = delta - now() if isinstance(delta,dt.timedelta): delta = unixdelta(delta) if delta < 0: # we're late delta = 0 # but let's hope not too late sleep(force,delta)
def list(self): yield ("name"," ".join(unicode(x) for x in self.name)) yield ("run",self.running) if self.interval is not None: yield ("interval"," ".join(str(x) for x in self.interval)) yield ("duration",self.duration) if self.last is not None: yield ("last",self.last) if self.next is not None: yield ("next",self.next) if self.slotter is not None: yield ("slot",(unixdelta(self.next-now()))/self.duration)
def event(self,ctx,data): d={} for m,n in data.iteritems(): try: n = n * self.faktor[m] except KeyError: pass try: n = n + self.offset[m] except KeyError: pass d[m]=n simple_event("fs20","em", *self.name, **d) self.last = now() self.last_data = data
def weigth(self, mod=False): if self.value_tm is None: return None n = now() t = n-self.value_tm nt = self.total_tm+t nts = unixdelta(nt) if mod: self.total_tm = nt if nts == 0: ## called right after init'ing return 0 else: return unixdelta(t) / nts
def do_pre(self): self.waiter = None if self.running != "next" or self.slotter is not None: log(ERROR,"timeslot error pre",self.running,*self.name) return if self.next is None: self.next = now() self.last = self.next self.running = "during" simple_event("timeslot","begin",*self.name) self.next += dt.timedelta(0,self.duration) self.slotter = callLater(False,self.next, self.do_post)
def up(self): with log_wait("monitor up "+repr(self)): while self.job and self.job.dead: gevent.sleep(0.1) # link will clear if not self.job: self.value = None process_event(Event(Context(),"monitor","start",*self.name)) self.start_job("job",self._run_loop) self.state_change_at = now() def tell_ended(_): simple_event(Context(),"monitor","stop",*self.name) self.job.link(tell_ended)
def event(self,ctx,data): for m,n in data.iteritems(): try: n = n * self.faktor[m] except KeyError: pass else: data[m] = n if self.delta is not None: if self.last_data: val = n-self.last_data[m] if val < 0: val = val + 0x10000 # 16-bit rollover if val >= 0 or self.delta == 0: simple_event(ctx, "fs20","en", m,val, *self.name) else: simple_event(ctx, "fs20","en", m,n, *self.name) self.last = now() self.last_data = data
def run(self,ctx,**k): event = self.params(ctx) if len(event) < 2: raise SyntaxError(u'Usage: set rrd ‹value› ‹name…›') s = RRDs[Name(*event[1:])] # Using "N:" may run into a RRD bug # if we're really close to the next minute try: rrdtool.update(s.upath, "-t",s.udataset, now().strftime("%s")+":"+unicode(event[0]).encode("utf-8")) except Exception as e: fix_exception(e) if "minimum one second step" in str(e): pass else: raise
def feed(self, value): """Store the new value but calculate over the previous ones.""" self.prev_value = self.value self.total_samples += 1 if value is None: value = self.value if value is None: return if self.avg is None: self.avg = value self.total_tm = timedelta(0) else: self._calc(True) self.value = value self.value_tm = now()
def set_value(self,val=None): if val is None: val = self._value assert 0<=val<=1, u"Value is '%s', not in 0…1" % (val,) do = self.t_on if self.state else self.t_off self.t_off,self.t_on = self.new_value(val) dn = self.t_on if self.state else self.t_off self._value = val if do != dn: if self.timer is not None: self.timer.cancel() if dn is not None: self.next = (self.last if self.last is not None else now()) + dt.timedelta(0,dn) self.timer = callLater(False,self.next,self.do_timed_switch)
def list(self): n=now() yield ("type",self.type) yield ("name"," ".join(unicode(x) for x in self.name)) if self.state is not None: yield ("state",self.names[self.state]) if self._value is not None: yield ("current",self._value) if self.last is not None: yield ("last",self.last) if self.next is not None: yield ("next",self.next) if self.t_off is not None: yield ("t_off",humandelta(self.t_off)) if self.t_on is not None: yield ("t_on",humandelta(self.t_on))