def go_down(self, _=None): if not self.is_up: return self.is_up = False if _ is not None: process_failure(_) simple_event("onewire","down",typ=self.typ,id=self.id)
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 _loop(self): simple_event("amqp","start",*self.name) try: while True: self.conn.drain_events() finally: simple_event("amqp","stop",*self.name)
def get(self, state, ext=None, handler=None): simple_event("fs20","state", *self.name, state=state, ext=ext) ctx = Context(value=state) if ext is not None: ctx.ext = ext simple_event(ctx, "input","fs20", *self.name)
def update_all(self): try: simple_event("onewire","scanning",self.name) self._update_all() except Exception as e: fix_exception(e) process_failure(e)
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 _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 on_disconnect(self): simple_event("rpc","disconnect",*self.name) if self.workers is not None: for w in self.workers: unregister_worker(w) self.workers = None super(RPCconn,self).delete()
def datagramReceived(self, prefix, data, handler=None, timestamp=None): try: ext = PREFIX[prefix] except KeyError: simple_event(self.ctx, "fs20","unknown","prefix",prefix,"".join("%02x" % ord(x) for x in data)) else: return ext.datagramReceived(self.ctx, data, handler, timestamp)
def datagramReceived(self, prefix, data, handler=None, timestamp=None): try: ext = PREFIX[prefix] except KeyError: simple_event("fs20","unknown","prefix",prefix=prefix,data=data) else: return ext.datagramReceived(self.ctx, data, handler, timestamp)
def em_proc_thermo_hygro(ctx, data): if len(data) != 7: simple_event("fs20","em","bad_length","thermo_hygro",len=len(data),data=data) return None temp = data[1]/10 + data[2] + data[3]*10 if data[0] & 8: temp = -temp hum = data[4]/10 + data[5] + data[6]*10 return {"temperature":temp, "humidity":hum}
def datagramReceived(self, data, handler=None, timedelta=None): if len(data) < 2: raise WrongDatagram(data) if self.last_dgram is not None and timedelta is not None and self.last_dgram == data and timedelta < 0.15: return self.last_dgram = data fcode = ord(data[1]) if fcode & 0x20: if len(data) != 3: raise WrongDatagram(data) ext = ord(data[2]) else: if len(data) != 2: raise WrongDatagram(data) ext = None dc = ord(data[0]) try: dev = self.devs[dc] except KeyError: simple_event( Context(), "fs20", "unknown", "device", to_hc(self.code), to_dev(dc), "".join("%02x" % ord(x) for x in data), ) return try: fn = switch_names[fcode & 0x1F] except KeyError: simple_event( Context(), "fs20", "unknown", "function", to_hc(self.code), fcode & 0x1F, "".join("%02x" % ord(x) for x in data), ) return if fcode & 0x80: hdl = dev.getReply else: hdl = dev.get if ext is not None: hdl(fn, ext, handler=handler) else: hdl(fn, handler=handler) data = chr(dc) + chr(fcode | 0x80) + data[2:] self.send(data, handler)
def tx_proc_hygro(ctx, data): if len(data) != 7: simple_event("fs20","tx","bad_length","hygro",len=len(data),data=data) return None if data[2] != data[5] or data[3] != data[6]: simple_event("fs20","tx","bad_repeat","hygro",data=data) return None hum = data[2]*10 + data[3] + data[4]/10 return {"humidity":hum}
def tx_proc_thermo(ctx, data): if len(data) != 7: simple_event(ctx, "fs20","tx","bad_length","thermo",len(data),"".join("%x"%x for x in data[1:])) return None if data[2] != data[5] or data[3] != data[6]: simple_event(ctx, "fs20","tx","bad_repeat","thermo",len(data),"".join("%x"%x for x in data[1:])) return None temp = data[2]*10 + data[3] + data[4]/10 -50 return {"temperature":temp}
def tx_proc_thermo(ctx, data): if len(data) != 7: simple_event("fs20","tx","bad_length","thermo",len=len(data),data=data) return None if data[2] != data[5] or data[3] != data[6]: simple_event("fs20","tx","bad_repeat","thermo",data=data) return None temp = data[2]*10 + data[3] + data[4]/10 -50 return {"temperature":temp}
def on_connect(self): global conn_seq conn_seq += 1 self.name = self.dest + ("n"+str(conn_seq),) self.ctx = Context() self.ctx.words = global_words(self.ctx) self.workers = set() simple_event(self.ctx,"rpc","connect",*self.name) Collected.__init__(self)
def tx_proc_hygro(ctx, data): if len(data) != 7: simple_event(ctx, "fs20","tx","bad_length","hygro",len(data),"".join("%x"%x for x in data[1:])) return None if data[2] != data[5] or data[3] != data[6]: simple_event(ctx, "fs20","tx","bad_repeat","hygro",len(data),"".join("%x"%x for x in data[1:])) return None hum = data[2]*10 + data[3] + data[4]/10 return {"humidity":hum}
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 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 one_value(self, step): """\ Get one value from some "set monitor" command. Override this for active monitoring. """ if self.send_check_event and step==1: simple_event(self.ectx, "monitor","checking",*self.name) with log_wait("monitor","one_value",*self.name): return self.watcher.get(block=True, timeout=None)
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 on_info_msg(self,msg): if not TESTING and getattr(msg,'message_id','').startswith(base_mseq): return # dup if getattr(msg,'content_type','') == "application/json": try: data = json.loads(msg.body) except Exception: data = { "raw": msg.body } else: data = { "raw": msg.body } self.last_recv = msg.__dict__ simple_event(*(self.prefix+tuple(msg.routing_key.split('.')[self.strip:])), _direct=self._direct, **data)
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 simple_event("monitor","start",*self.name) self.start_job("job",self._run_loop) self.state_change_at = now() def tell_ended(_): simple_event("monitor","stop",*self.name) self.job.link(tell_ended)
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 go_up(self): if self.is_up: return if not hasattr(self,"typ"): self.typ = None gevent.spawn(self._get_typ) return if self.typ is None: return if self.is_up is None: simple_event("onewire","new",typ=self.typ,id=self.id) self.is_up = True simple_event("onewire","up",typ=self.typ,id=self.id)
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 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 __init__(self,name,host,port, vhost,username,password): self.name = name self.host=host self.port=port self.vhost=vhost self.username=username self.password=password self.workers = [] try: self.conn=amqp.connection.Connection(host=self.host,userid=self.username,password=self.password,login_method='AMQPLAIN', login_response=None, virtual_host=self.vhost) except Exception as e: simple_event("amqp","error",*name) else: super(AMQPclient,self).__init__() simple_event("amqp","connect",*name)
def dataReceived(self, ctx, data, handler=None, timedelta=None): if len(data) < 4: return # obviously way too short qs = 0 for d in data: qs += ord(d) qs -= ord(data[-1]) # the above loop added it, that's nonsense qs = (ord(data[-1]) - qs) & 0xFF # we want the actual difference code = ord(data[0])*256+ord(data[1]) try: g = groups[(code,qs)] except KeyError: simple_event(ctx, "fs20","unknown",to_hc(code),qs,"".join("%02x" % ord(x) for x in data)) else: return g.datagramReceived(data[2:-1], handler, timedelta=timedelta)
def do_switch(self): """Click""" if self.state: self.state = 0 tn = self.t_off else: self.state = 1 tn = self.t_on process_event(Event(self.ctx,"pcm","set",self.names[self.state],*self.name)) try: self.last = self.next if tn is not None: self.next = self.last + dt.timedelta(0,tn) self.timer = callLater(False,self.next,self.do_timed_switch) else: self.next = None except Exception as e: fix_exception(e) process_failure(e) simple_event(self.ctx,"pcm","error",*self.name)