def dataReceived(self, data): db = "" e = "" if not data: return # empty line if data[0] in PREFIX: for d in data[1:]: if e: db += chr(eval("0x" + e + d)) e = "" else: e = d if e: db += chr(eval("0x" + e + "0")) self.datagramReceived(data[0], db, timestamp=self.timestamp) self.timestamp = None elif data[0] == PREFIX_TIMESTAMP: self.timestamp = float(data[1:]) elif data[0] == "+" and TESTING: from homevent.times import sleep, test_runtime try: f, c = data[1:].split(" ", 1) except ValueError: f = data[1:] c = "Timer" f = float(f) log("fs20", DEBUG, "Wait until", f, " -- now:", test_runtime(), "::", c) sleep(False, f - test_runtime()) else: simple_event(Context(), "fs20", "unknown", "prefix", data[0], data[1:])
def get_collect(name, allow_collection=False): c = None if not len(name): return None coll = collections if allow_collection and name[-1] == "*": return coll[Name(*name[:-1])] while len(name): n = len(name) while n > 0: try: coll = coll[Name(*name[:n])] except KeyError: n = n-1 else: name = name[n:] if c is None: c = coll break if n == 0: try: coll = coll[name[0]] except KeyError: from homevent.logging import DEBUG,log log(DEBUG,"Contents: "+", ".join(str(x) for x in coll.keys())) raise CKeyError(name,coll) else: name = name[1:] if c is None: c = coll if not allow_collection and not isinstance(coll,Collected): raise CCollError(name) return coll
def run(self,ctx,**k): event = self.params(ctx) try: out = self.ctx.out except AttributeError: out = sys.stderr if not len(event): for s,v in LogNames.iteritems(): print >>out,"%d = %s" % (s,v) print >>out,"." return None if len(event) > 1: log(getattr(logging,event[0].upper()), *event[1:]) else: level = getattr(logging,event[0].upper()) if level == logging.NONE: if hasattr(out,"logger"): out.logger.delete() del out.logger else: if hasattr(out,"logger"): out.logger.level = level else: try: out = self.ctx.out except AttributeError: out = sys.stderr logger = OutLogger(out=out, level=level) try: out.logger = logger except AttributeError: pass # file objects don't except: logger.delete() raise
def error(self,err): """An error occurred.""" if self.result is not None and not self.result.successful: log("onewire",DEBUG,"done error: ",self,err) self.result.set_exception(err) else: process_failure(err)
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 _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 got_entry(name): if key is None and name.startswith("bus."): buses.append(name) elif len(name)>3 and name[2] == ".": entries.append(name) else: log("onewire",TRACE,"got unrecognized name %s" % (name,))
def lineReceived(self,data): db = "" e = "" if not data: return # empty line if data[0] in PREFIX: for d in data[1:]: if e: try: db += chr(eval("0x"+e+d)) except SyntaxError: simple_event(Context(),"fs20","unknown","hex",data) return e="" else: e=d if e: log("fs20",WARN,"fs20 odd length "+data) self.datagramReceived(data[0], db, timestamp=self.timestamp) self.timestamp = None elif data[0] == PREFIX_TIMESTAMP: self.timestamp = float(data[1:]) elif data[0] == "P": pass # idle elif data[0] == "+": log("fs20",DEBUG,"fs20 trace "+data) else: simple_event(Context(),"fs20","unknown","prefix",data[0],data[1:])
def up(self): dev = devices[self.device] if self.switch is not None and self.switched is None: log(DEBUG,"switch low1",self.switch,self.to_low) dev.set(self.switch,self.to_low) self.switched = False return super(OWFSmon,self).up()
def _update_all(self): log("onewire",TRACE,"start bus update") old_ids = devices.copy() new_ids = {} seen_ids = {} for dev in self.all_devices(): if dev.id in seen_ids: continue seen_ids[dev.id] = dev if dev.id in old_ids: del old_ids[dev.id] else: new_ids[dev.id] = dev n_old = 0 n_dev = 0 for dev in old_ids.itervalues(): if dev.bus is self: n_old += 1 ## Just because something vanishes from the listing ## doesn't mean it's dead; the bus may be a bit unstable # dev.go_down() log("onewire",DEBUG,"Bus unstable?",self.name,dev.id) for dev in devices.itervalues(): if dev.bus is self: n_dev += 1 simple_event("onewire","scanned",self.name, old=n_old, new=len(new_ids), num=n_dev)
def dataReceived(self, data): self._stop_timer() data = self.dbuf+data while True: xi = len(data)+1 try: pi = data.index('\r') except ValueError: pi = xi try: ei = data.index('\n') except ValueError: ei = xi if pi==xi and ei==xi: break if pi < ei: self.lbuf = data[:pi] data = data[pi+1:] else: msg = data[:ei] data = data[ei+1:] if msg == "" and self.lbuf is not None: msg = self.lbuf self.lbuf = None try: self.lineReceived(msg) except Exception as e: log("fs20",ERROR,msg,e) fix_exception(e) process_failure(e) self.dbuf = data self._start_timer()
def exposed_write(self,s): i = s.find("\n") while i >= 0: log("TEST",DEBUG,">>>",self.buf+s[:i]) self.buf = "" s = s[i+1:] i = s.find("\n") self.buf += s
def do_post(self): self.slotter = None if self.running != "during" or self.waiter is not None: log(ERROR,"timeslot error post",self.running,*self.name) return self.running = "next" simple_event("timeslot","end",*self.name) self.next = time_delta(self.interval, now=self.next)-dt.timedelta(0,self.duration) self.waiter = callLater(False, self.next, self.do_pre)
def _init(self, bus, short_id=None, id=None, path=()): log("onewire",DEBUG,"NEW", bus,short_id,id,path) self.bus_id = id if short_id: self.id = short_id.lower() self.bus = bus assert path is not None self.path = path self.is_up = None self.ctx = Context()
def __init__(self, name, cmd, ctx=Context, timeout=3): self.name = name self.cmd = cmd self.timeout = timeout self.timer = None self.dbuf = "" self.ebuf = "" super(FS20xmit, self).__init__() # (ctx=ctx) log(DEBUG, "*** added", self.name, self) self.stopped = False
def __init__(self, parent, name=None, prio=(MIN_PRIO + MAX_PRIO) // 2 + 1): self.prio = prio self.parent = parent if name is None: name = Name("_on", self._get_id()) super(OnEventWorker, self).__init__(*name) # self.name = unicode(self.parent.arglist) # if self.parent.displayname is not None: # self.name += u" ‹"+" ".join(unicode(x) for x in self.parent.displayname)+u"›" log(TRACE, "NewHandler", self.id)
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 cont(self, _=None): while self.waiting: try: msg = self.waiting.pop(0) log("fs20",DEBUG,msg) d = self._dataReceived(msg) except Exception as e: fix_exception(e) process_failure(e) else: if d: d.addCallback(self.cont) return self.waiting = None self._start_timer()
def sendMsg(self, typ, data, rlen): """Send an OWFS message to the other end of the connection. """ flags = 0 if self.persist: flags |= OWFlag.persist # needed for sometimes-broken 1wire daemons flags |= OWFlag.busret # flags |= 1<<8 ## ? flags |= OWtempformat.celsius << OWtempformat._offset flags |= OWdevformat.fdi << OWdevformat._offset log("onewire",DEBUG,"SEND", 0, len(data), typ, flags, rlen, 0, repr(data)) self.write(struct.pack("!6i", \ 0, len(data), typ, flags, rlen, 0) +data)
def filter_data(self): """Discard outlier values and calculate average""" log("monitor",TRACE,"filter",self.data,"on", self.name) if len(self.data) < self.points: return None avg = sum(self.data)/len(self.data) if not self.range: return avg data = self.data while True: lo = min(data) hi = max(data) if hi-lo <= self.range: return avg if len(data) == self.points: break new_data = [] extr = None # stored outlier nsum = 0 # new sum dif = None # difference for extr for val in data: ndif = abs(avg-val) if dif is None or dif < ndif: dif = ndif if extr is not None: nsum += extr new_data.append(extr) extr = val else: nsum += val new_data.append(val) data = new_data avg = nsum/len(data) return None
def lineReceived(self, line): log("rrd",TRACE,"recv",repr(line)) msgid = 0 off = 0 mt = MT_OTHER if self.buf is not None: self.buf.append(line) self.lines -= 1 if self.lines == 0: buf,self.buf = self.buf,None self.msgReceived(type=MT_MULTILINE, msg=buf[0],data=buf[1:]) return elif line == "": self.msgReceived(type=MT_OTHER, msg=line) elif line[0] == "-": off=1 errno=0 while off < len(line) and line[off].isdigit(): errno = 10*errno+int(line[off]) off += 1 self.msgReceived(type=MT_ERROR, errno=errno, msg=line[off:].strip()) elif line[0].isdigit(): off=0 lines=0 while off < len(line) and line[off].isdigit(): lines = 10*lines+int(line[off]) off += 1 if lines: self.lines = lines self.buf = [line[off:]] return self.msgReceived(type=MT_ACK, msg=line[off:].strip()) return else: self.msgReceived(type=MT_OTHER, msg=line)
def dataReceived(self, data): """Convert OWFS messages into calls to msgReceived.""" self._data += data while len(self._data) >= self._len: if self._typ is None: version, payload_len, ret_value, format_flags, data_len, offset = struct.unpack('!6i', self._data[:24]) self._data = self._data[self._len:] log("onewire",DEBUG,"RECV", version, payload_len, ret_value, format_flags, data_len, "x%x"%offset) # 0 253 0 2 252 32774 if offset & 32768: offset = 0 if version != 0: self.error(RuntimeError("Wrong version: %d"%(version,))) return if payload_len == -1 and data_len == 0 and offset == 0: log("onewire",DEBUG,"RECV", u"… server busy") continue # server busy # if payload_len < 0 or payload_len > 0 and (payload_len < data_len or offset+data_len > payload_len): # self.errReceived(RuntimeError("Wrong length: %d %d %d"%(payload_len,offset,data_len,))) # return if payload_len > self.MAX_LENGTH: self.error(RuntimeError("Length exceeded: %d %d %d"%(payload_len,offset,data_len,))) return self._offset = offset if payload_len: self._data_len = data_len else: self._data_len = 0 self._len = payload_len self._typ = ret_value else: # offset seems not to mean what we all think it means #data = self._data[self._offset:self._offset+self._data_len] data = self._data[:self._offset+self._data_len] log("onewire",DEBUG,"RECV", u"…",self._data_len,repr(data)) self._data = self._data[self._len:] typ = self._typ self._typ = None self._len = 24 self.msgReceived(typ=typ,data=data)
def drop(self,_): log("parser",DEBUG,"LAST_SYM drop") conns.remove(self) self.loseConnection() return _
def done(self, _=None): log("onewire",DEBUG,"doneDIR",self) return super(DIRmsg,self).done()
def dataReceived(self, data): # child object expect this log("onewire",DEBUG,"done: ",self) if self.result is not None: self.result.set(data)
def _do_line(self,line): try: try: if line is None: raise StopIteration log("token",TRACE,"IN",line) except StopIteration: line = '' log("token",TRACE,"IN_END") self.lnum = self.lnum + 1 pos, max = 0, len(line) if self.contstr: # continued string if not line: raise TokenError, ("EOF in multi-line string", strstart) endmatch = endprog.match(line) if endmatch: pos = end = endmatch.end(0) self.output(STRING, self.contstr + line[:end], strstart, (self.lnum, end), self.contline + line) self.contstr, self.needcont = '', 0 self.contline = None elif self.needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n': self.output(ERRORTOKEN, self.contstr + line, strstart, (self.lnum, len(line)), self.contline) self.contstr = '' self.contline = None return else: self.contstr += line self.contline += line return elif self.parenlev == 0 and not self.continued: # new statement if not line: self.feed_end() self.output(ENDMARKER, '', (self.lnum, 0), (self.lnum, 0), '') return column = 0 while pos < max: # measure leading whitespace if line[pos] == ' ': column = column + 1 elif line[pos] == '\t': column = (column/tabsize + 1)*tabsize elif line[pos] == '\f': column = 0 else: break pos = pos + 1 if pos == max: self.feed_end() return if line[pos] in '#\r\n': # skip comments or blank lines self.output((NL, COMMENT)[line[pos] == '#'], line[pos:], (self.lnum, pos), (self.lnum, len(line)), line) return if column > self.indents[-1]: # count indents or dedents self.indents.append(column) self.output(INDENT, line[:pos], (self.lnum, 0), (self.lnum, pos), line) if column < self.indents[-1]: while column < self.indents[-1]: self.indents.pop() self.output(DEDENT, '', (self.lnum, pos), (self.lnum, pos), line) if column != self.indents[-1]: raise IndentationError( "unindent does not match any outer indentation level", (u"‹tokenize›", self.lnum, pos, line)) else: # continued statement if not line: raise TokenError, ("EOF in multi-line statement", (self.lnum, 0)) self.continued = 0 while pos < max: pseudomatch = pseudoprog.match(line, pos) if pseudomatch: # scan for tokens start, end = pseudomatch.span(1) spos, epos, pos = (self.lnum, start), (self.lnum, end), end token, initial = line[start:end], line[start] if num.match(token) or \ (initial == '.' and token != '.'): # ordinary number self.output(NUMBER, token, spos, epos, line) elif initial in '\r\n': self.output(NL if self.parenlev > 0 else NEWLINE, token, spos, epos, line) elif initial == '#': self.output(COMMENT, token, spos, epos, line) elif token in triple_quoted: endprog = endprogs[token] endmatch = endprog.match(line, pos) if endmatch: # all on one line pos = endmatch.end(0) token = line[start:pos] self.output(STRING, token, spos, (self.lnum, pos), line) else: strstart = (self.lnum, start) # multiple lines self.contstr = line[start:] self.contline = line break elif initial in single_quoted or \ token[:2] in single_quoted or \ token[:3] in single_quoted: if token[-1] == '\n': # continued string strstart = (self.lnum, start) endprog = (endprogs[initial] or endprogs[token[1]] or endprogs[token[2]]) self.contstr, self.needcont = line[start:], 1 self.contline = line break else: # ordinary string self.output(STRING, token, spos, epos, line) elif namestart.match(initial): # ordinary name self.output(NAME, token, spos, epos, line) elif initial == '\\': # continued stmt self.continued = 1 else: if initial in '([{': self.parenlev = self.parenlev + 1 elif initial in ')]}': self.parenlev = self.parenlev - 1 self.output(OP, token, spos, epos, line) else: self.output(ERRORTOKEN, line[pos], (self.lnum, pos), (self.lnum, pos+1), line) pos = pos + 1 except StopParsing as e: fix_exception(e) self.q = None if self.parent: self.parent.kill(e) return
def output(self,*a): log("token",TRACE,repr(a)) self._output(*a)
def logged(level, *a): log("TEST", DEBUG, "The logger says: <%d> %s" % (level, "¦".join((str(x) for x in a)))) got_something.set(a)
def called(**k): for a, b in k.iteritems(): log("TEST", DEBUG, "CB %s: %s" % (a, b))
def tester(): sleep(0.2) c = rpyc.connect("localhost", 56478) def called(**k): for a, b in k.iteritems(): log("TEST", DEBUG, "CB %s: %s" % (a, b)) cb = c.root.monitor(called, *("wait start * some time".split())) def logged(level, *a): log("TEST", DEBUG, "The logger says: <%d> %s" % (level, "¦".join((str(x) for x in a)))) got_something.set(a) cm = c.root.logger(logged, "hello", DEBUG) for x in c.root.cmd_list(): log("TEST", DEBUG, repr(x)) log("TEST", DEBUG, ".") for x in c.root.cmd_list("rpc", "server"): log("TEST", DEBUG, repr(x)) log("TEST", DEBUG, ".") for x in c.root.cmd_list("rpc", "server", "foo"): log("TEST", DEBUG, repr(x)) log("TEST", DEBUG, ".") for x in c.root.cmd_list("rpc", "connection", "foo", "n1"): log("TEST", DEBUG, repr(x)) log("TEST", DEBUG, ".") try: c.root.command("fuubar", "This is not found.") except Exception as e: log("TEST", DEBUG, "YES Got an error") else: log("TEST", DEBUG, "NO Got no error") c.root.command("log", "DEBUG", "This is logged.") c.root.command("var", "state", "get_me", "the", "tester") log("TEST", DEBUG, "The value is: " + c.root.var("get_me")) c.root.command("trigger", "send", "logger") got_something.get() c.root.command("del", "wait", "shutdown") cb.cancel() cm.cancel() c.close()