コード例 #1
0
    def dataReceived(self, data):
        self._stop_timer()
        data = self.dbuf + data
        while True:
            xi = len(data) + 1
            try:
                pi = data.index(b'\r')
            except ValueError:
                pi = xi
            try:
                ei = data.index(b'\n')
            except ValueError:
                ei = xi
            if pi == xi and ei == xi:
                break
            if pi < ei:
                self.lbuf = data[:pi].decode('utf-8')
                data = data[pi + 1:]
            else:
                msg = data[:ei].decode('utf-8')
                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()
コード例 #2
0
ファイル: logging.py プロジェクト: ZigmundRat/moat
	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.items():
				print("%d = %s" % (s,v), file=out)
			print(".", file=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
コード例 #3
0
ファイル: collect.py プロジェクト: M-o-a-T/moat
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 moat.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
コード例 #4
0
ファイル: onewire.py プロジェクト: smurfix/MoaT
	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()
コード例 #5
0
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 moat.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
コード例 #6
0
ファイル: logging.py プロジェクト: smurfix/MoaT
	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.items():
				print("%d = %s" % (s,v), file=out)
			print(".", file=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
コード例 #7
0
ファイル: monitor.py プロジェクト: smurfix/MoaT
	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()
コード例 #8
0
ファイル: onewire.py プロジェクト: smurfix/MoaT
			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,))
コード例 #9
0
ファイル: onewire.py プロジェクト: ZigmundRat/moat
 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()
コード例 #10
0
    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("fs20", "unknown", "hex", data=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("fs20",
                         "unknown",
                         "prefix",
                         prefix=data[0],
                         data=data[1:])
コード例 #11
0
ファイル: onewire.py プロジェクト: ZigmundRat/moat
 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)
コード例 #12
0
ファイル: onewire.py プロジェクト: ZigmundRat/moat
 def start_up(self):
     f = connect(name=self.dest,
                 host=self.host,
                 port=self.port,
                 scan=self.scan)
     buses[self.dest] = f
     log(TRACE, "New OWFS bus", self.dest, f)
コード例 #13
0
ファイル: fs20avr.py プロジェクト: M-o-a-T/moat
	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("fs20","unknown","hex", data=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("fs20","unknown","prefix", prefix=data[0],data=data[1:])
コード例 #14
0
ファイル: onewire.py プロジェクト: smurfix/MoaT
	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)
コード例 #15
0
ファイル: fs20avr.py プロジェクト: M-o-a-T/moat
	def dataReceived(self, data):
		self._stop_timer()
		data = self.dbuf+data
		while True:
			xi = len(data)+1
			try: pi = data.index(b'\r')
			except ValueError: pi = xi
			try: ei = data.index(b'\n')
			except ValueError: ei = xi
			if pi==xi and ei==xi:
				break
			if pi < ei:
				self.lbuf = data[:pi].decode('utf-8')
				data = data[pi+1:]
			else:
				msg = data[:ei].decode('utf-8')
				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()
コード例 #16
0
ファイル: onewire.py プロジェクト: ZigmundRat/moat
 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, ))
コード例 #17
0
ファイル: mod_rpc.py プロジェクト: ZigmundRat/moat
	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
コード例 #18
0
ファイル: onewire.py プロジェクト: smurfix/MoaT
	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()
コード例 #19
0
ファイル: wago.py プロジェクト: ZigmundRat/moat
 def error(self, err):
     log("wago", DEBUG, "Got error", self, err)
     simple_event("output",
                  "error",
                  *self.queue.name,
                  value=self.val,
                  error=err)
     if not self.result.ready():
         self.result.set(err)
     super(WAGOtimedOutputRun, self).error(err)
コード例 #20
0
ファイル: onewire.py プロジェクト: ZigmundRat/moat
 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()
コード例 #21
0
ファイル: timeslot.py プロジェクト: ZigmundRat/moat
	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, deprecated=True)
		simple_event("timeslot","state",*self.name, state="end")
		self.next = time_delta(self.interval, now=self.next)-dt.timedelta(0,self.duration)
		self.waiter = callLater(False, self.next, self.do_pre)
コード例 #22
0
ファイル: onewire.py プロジェクト: smurfix/MoaT
	def _update_all(self):
		log("onewire",TRACE,"start bus update")
		old_ids = devices.copy()
		new_ids = {}
		seen_ids = {}
		old_bus = set(self.bus_paths.keys())
		new_bus = set()

		def bus_cb(path):
			if path in old_bus:
				old_bus.remove(path)
			else:
				new_bus.add(path)

		for dev in self.all_devices(bus_cb):
			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.values():
			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.values():
			if dev.bus is self:
				n_dev += 1
		
		for dev in old_bus:
			bp = self.bus_paths.pop(dev)
			bp.stop()
			simple_event("onewire","bus","down", bus=self.name,path=dev)
			simple_event("onewire","bus","state",self.name,"/".join(dev), bus=self.name,path=dev, state="down")
		for dev in new_bus:
			self.bus_paths[dev] = OWFSbuspath(self,dev)
			simple_event("onewire","bus","up", bus=self.name,path=dev)
			simple_event("onewire","bus","state",self.name,"/".join(dev), bus=self.name,path=dev, state="up")

		# success only, error above
		simple_event("onewire","scanned",*self.name, old=n_old, new=len(new_ids), num=n_dev, deprecated=True)
		simple_event("onewire","scan",*self.name, run="done", old=n_old, new=len(new_ids), num=n_dev)
コード例 #23
0
ファイル: wago.py プロジェクト: ZigmundRat/moat
    def lineReceived(self, line):
        log("wago", TRACE, "recv", repr(line))
        msgid = 0
        off = 0
        mt = MT_OTHER

        if self.buf is not None:
            if line == ".":
                buf, self.buf = self.buf, None
                self.msgReceived(type=MT_MULTILINE, msg=buf)
            else:
                if line.startswith("."):
                    line = line[1:]
                self.buf.append(line)
            return
        elif line == "":
            self.msgReceived(type=MT_OTHER, msg=line)
        elif line[0] == "=":
            self.buf = [line[1:]]
            return
        elif line[0] == "?":
            self.msgReceived(type=MT_ERROR, msg=line[1:].strip())
            return
        elif line[0] == "*":
            self.msgReceived(type=MT_INFO, msg=line[1:].strip())
            return
        elif line[0] == "+":
            self.msgReceived(type=MT_ACK, msg=line[1:].strip())
            return
        elif line[0] == "-":
            self.msgReceived(type=MT_NAK, msg=line[1:].strip())
            return
        elif line[0] == "!":
            if line[1] == "+":
                mt = MT_IND_ACK
                off = 2
            elif line[1] == "-":
                mt = MT_IND_NAK
                off = 2
            else:
                mt = MT_IND
                off = 1
        while off < len(line) and line[off].isdigit():
            msgid = 10 * msgid + int(line[off])
            off += 1
        if msgid > 0:
            self.msgReceived(type=mt, msgid=msgid, msg=line[off:].strip())
        else:
            self.msgReceived(type=mt, msg=line.strip())
コード例 #24
0
ファイル: wago.py プロジェクト: smurfix/MoaT
	def lineReceived(self, line):
		log("wago",TRACE,"recv",repr(line))
		msgid = 0
		off = 0
		mt = MT_OTHER

		if self.buf is not None:
			if line == ".":
				buf,self.buf = self.buf,None
				self.msgReceived(type=MT_MULTILINE, msg=buf)
			else:
				if line.startswith("."):
					line = line[1:]
				self.buf.append(line)
			return
		elif line == "":
			self.msgReceived(type=MT_OTHER, msg=line)
		elif line[0] == "=":
			self.buf = [line[1:]]
			return
		elif line[0] == "?":
			self.msgReceived(type=MT_ERROR, msg=line[1:].strip())
			return
		elif line[0] == "*":
			self.msgReceived(type=MT_INFO, msg=line[1:].strip())
			return
		elif line[0] == "+":
			self.msgReceived(type=MT_ACK, msg=line[1:].strip())
			return
		elif line[0] == "-":
			self.msgReceived(type=MT_NAK, msg=line[1:].strip())
			return
		elif line[0] == "!":
			if line[1] == "+":
				mt = MT_IND_ACK
				off = 2
			elif line[1] == "-":
				mt = MT_IND_NAK
				off = 2
			else:
				mt = MT_IND
				off = 1
		while off < len(line) and line[off].isdigit():
			msgid = 10*msgid+int(line[off])
			off += 1
		if msgid > 0:
			self.msgReceived(type=mt, msgid=msgid, msg=line[off:].strip())
		else:
			self.msgReceived(type=mt, msg=line.strip())
コード例 #25
0
 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()
コード例 #26
0
ファイル: fs20avr.py プロジェクト: M-o-a-T/moat
	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()
コード例 #27
0
ファイル: timeslot.py プロジェクト: ZigmundRat/moat
	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, deprecated=True)
		simple_event("timeslot","state",*self.name, state="begin")
		self.next += dt.timedelta(0,self.duration)
		self.slotter = callLater(False,self.next, self.do_post)
コード例 #28
0
ファイル: onewire.py プロジェクト: smurfix/MoaT
	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)
コード例 #29
0
ファイル: exec.py プロジェクト: smurfix/MoaT
def called(env,*a,**k):
    log(TRACE,"PY Proc called",env,a,k)
    env.on("test","me", doc="Test me harder",name="foo test bar")(running)
    env.on("test","me","not", doc="dummy")(not_running)
    if env.test.true():
        env.do.log.DEBUG("true")
    if env.test('false'):
        env.do.log.ERROR("false")
    env.trigger("test","it", what="ever")
    env.do.wait("some delay",_for="0.2 min")
    env.do.wait("more","delay",_for=(0.3,"min"))
    for k in env.data['on']:
        env.do.log.DEBUG("Handler",k)
    env.do("log DEBUG 'do' works")
    env.do.log('DEBUG', "'do.log' works")
    log(TRACE,"PY Proc done")
コード例 #30
0
ファイル: exec.py プロジェクト: ZigmundRat/moat
def called(env, *a, **k):
    log(TRACE, "PY Proc called", env, a, k)
    env.on("test", "me", doc="Test me harder", name="foo test bar")(running)
    env.on("test", "me", "not", doc="dummy")(not_running)
    if env.test.true():
        env.do.log.DEBUG("true")
    if env.test('false'):
        env.do.log.ERROR("false")
    env.trigger("test", "it", what="ever")
    env.do.wait("some delay", _for="0.2 min")
    env.do.wait("more", "delay", _for=(0.3, "min"))
    for k in env.data['on']:
        env.do.log.DEBUG("Handler", k)
    env.do("log DEBUG 'do' works")
    env.do.log('DEBUG', "'do.log' works")
    log(TRACE, "PY Proc done")
コード例 #31
0
ファイル: onewire.py プロジェクト: ZigmundRat/moat
    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)
コード例 #32
0
ファイル: event_hook.py プロジェクト: M-o-a-T/moat
	def __init__(self, parent, args, name=None, prio=(MIN_PRIO+MAX_PRIO)//2+1):
		self.prio = prio
		self.displayname = name
		self.args = args
		self.parent = parent

		if name is None:
			name = Name("_on",self._get_id())
		super(OnEventBase,self).__init__(*name)
		for k in self.args:
			if hasattr(k,'startswith') and k.startswith('*'):
				self._simple = False

#		self.name = six.text_type(self.args)
#		if self.displayname is not None:
#			self.name += u" ‹"+" ".join(six.text_type(x) for x in self.displayname)+u"›"

		
		log(TRACE,"NewHandler",self.id)
コード例 #33
0
ファイル: wago.py プロジェクト: ZigmundRat/moat
    def recv(self, msg):
        if msg.type is MT_MULTILINE:
            for x in msg.msg:
                if x == "":
                    continue
                m = _num.match(x)
                if m is None:
                    continue
                mon = int(m.group(0))
                self.data[mon] = x[m.end():]
                recvs, self.queue.receivers = self.queue.receivers, []
                for r in recvs:
                    mid = getattr(r, "msgid", None)
                    if mid is None or mid in self.data:
                        log("wago", TRACE, "found monitor", r)
                        self.queue.receivers.append(r)
                    else:
                        try:
                            raise DroppedMonitor(mid)
                        except DroppedMonitor as ex:
                            fix_exception(ex)
                            res = r.error(ex)
                            if res is SEND_AGAIN:
                                log("wago", TRACE, "retry monitor", r)
                                self.queue.enqueue(r)
                            else:
                                log("wago", TRACE, "drop monitor", r)
                                assert res is None or res is False, "%s.error returned %s" % (
                                    repr(r), repr(res))

            return MINE
        if msg.type is MT_NAK or msg.type is MT_ERROR:
            simple_event("wago", "monitor", "error", msg=msg.msg)
            return MINE
        return NOT_MINE
コード例 #34
0
ファイル: wago.py プロジェクト: smurfix/MoaT
	def recv(self,msg):
		if msg.type is MT_MULTILINE:
			for x in msg.msg:
				if x == "":
					continue
				m = _num.match(x)
				if m is None:
					continue
				mon = int(m.group(0))
				self.data[mon]=x[m.end():]
				recvs,self.queue.receivers = self.queue.receivers,[]
				for r in recvs:
					mid = getattr(r,"msgid",None)
					if mid is None or mid in self.data:
						log("wago",TRACE,"found monitor",r)
						self.queue.receivers.append(r)
					else:
						try:
							raise DroppedMonitor(mid)
						except DroppedMonitor as ex:
							fix_exception(ex)
							res = r.error(ex)
							if res is SEND_AGAIN:
								log("wago",TRACE,"retry monitor",r)
								self.queue.enqueue(r)
							else:
								log("wago",TRACE,"drop monitor",r)
								assert res is None or res is False, "%s.error returned %s"%(repr(r),repr(res))

			return MINE
		if msg.type is MT_NAK or msg.type is MT_ERROR:
			simple_event("wago","monitor","error", msg=msg.msg)
			return MINE
		return NOT_MINE
コード例 #35
0
ファイル: event_hook.py プロジェクト: ZigmundRat/moat
    def __init__(self,
                 parent,
                 args,
                 name=None,
                 prio=(MIN_PRIO + MAX_PRIO) // 2 + 1):
        self.prio = prio
        self.displayname = name
        self.args = args
        self.parent = parent

        if name is None:
            name = Name("_on", self._get_id())
        super(OnEventBase, self).__init__(*name)
        for k in self.args:
            if hasattr(k, 'startswith') and k.startswith('*'):
                self._simple = False

#		self.name = six.text_type(self.args)
#		if self.displayname is not None:
#			self.name += u" ‹"+" ".join(six.text_type(x) for x in self.displayname)+u"›"

        log(TRACE, "NewHandler", self.id)
コード例 #36
0
ファイル: monitor.py プロジェクト: smurfix/MoaT
	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(float(x) for x in 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
コード例 #37
0
	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)
コード例 #38
0
ファイル: onewire.py プロジェクト: ZigmundRat/moat
    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)
コード例 #39
0
ファイル: onewire.py プロジェクト: smurfix/MoaT
	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)
コード例 #40
0
ファイル: msg.py プロジェクト: M-o-a-T/moat
	def _incoming(self,msg):
		"""Process an incoming message."""
		self.n_rcvd_now += 1
		log("conn",TRACE,"incoming", self.__class__.__name__,self.name,msg)
		self.last_recv = msg
		self.last_recv_at = now()

		# i is an optimization for receiver lists that don't change in mid-action
		handled = False
		log("msg",TRACE,"recv",self.name,str(msg))
		for mq in self.receivers:
			i = 0
			for m in mq:
				try:
					r = m.recv(msg)
					log("msg",TRACE,"recv=",r,repr(m))
					if r is ABORT:
						self.channel.close(False)
						self.channel = None
						break
					elif r is NOT_MINE:
						continue
					elif r is MINE or r is SEND_AGAIN:
						handled = True
						if len(mq) > i and mq[i] is m:
							mq.pop(i)
						else:
							mq.remove(m)
						i -= 1

						if r is SEND_AGAIN:
							if m.blocking:
								self.senders[0].insert(0,m)
							else:
								self.senders[m.prio].append(m)
						else:
							m.done()
							self.n_processed_now += 1
						break
					elif r is RECV_AGAIN:
						handled = True
						break
					elif r is SEND_AGAIN:
						handled = True
						break
					elif isinstance(r,MSG_ERROR):
						raise r
					else:
						raise BadResult(m)
				except Exception as ex:
					if len(mq) < i and mq[i] is m:
						mq.pop(i)
					elif m in self.receivers:
						mq.remove(m)
					fix_exception(ex)
					process_failure(ex)

					self.channel.close(False)
					self.channel = None
					simple_event("msg","error",*self.name, msg=msg)
					handled = True
					break
			i += 1
		if not handled:
			simple_event("msg","unhandled",*self.name, msg=msg)
コード例 #41
0
ファイル: onewire.py プロジェクト: ZigmundRat/moat
 def done(self, _=None):
     log("onewire", DEBUG, "doneDIR", self)
     return super(DIRmsg, self).done()
コード例 #42
0
ファイル: msg.py プロジェクト: M-o-a-T/moat
	def _error(self,msg):
		log("conn",ERROR,self.state,self.__class__.__name__,self.name,str(msg))
		self._teardown()
		process_failure(msg)
コード例 #43
0
ファイル: onewire.py プロジェクト: ZigmundRat/moat
 def dataReceived(self, data):
     # child object expect this
     log("onewire", DEBUG, "done: ", self)
     if self.result is not None:
         self.result.set(data)
コード例 #44
0
ファイル: msg.py プロジェクト: M-o-a-T/moat
	def _set_state(self,state):
		log("conn",TRACE,state,self.__class__.__name__,self.name)
		self.state = state
		self.last_change = now()
コード例 #45
0
ファイル: msg.py プロジェクト: M-o-a-T/moat
	def _handler(self):
		"""\
			This is the receiver's main loop.

			Processing of incoming and outgoing data is serialized so that
			there will be no problems with concurrency.
			"""
		def doReOpen():
			m = MsgReOpen()
			if self.q is not None:
				self.q.put(m, block=False)

		state = "open" if self.state == "connected" else "closed" if self.channel is None else "connecting"
		log("conn",TRACE,"setstate init %s" % (state,))
		self.connect_timeout = self.initial_connect_timeout
		self.attempts = 0

		if not self.ondemand and state != "open":
			doReOpen()

		while True:
			msg = self.q.get()

			if isinstance(msg,MsgSender):
				self.senders[msg.prio].append(msg)
			elif isinstance(msg,MsgReceiver):
				if msg.blocking:
					self.receivers[msg.prio].insert(0,msg)
				else:
					self.receivers[msg.prio].append(msg)
			elif isinstance(msg,MsgIncoming):
				self._incoming(msg)
			elif isinstance(msg,MsgOpenMarker):
				log("conn",TRACE,"setstate %s %s" % (state,"connected"))
				state = "connected"

				self.connect_timeout = self.initial_connect_timeout
				self.attempts = 0

			elif isinstance(msg,MsgReOpen):
				if self.channel is None:
					log("conn",TRACE,"setstate %s %s" % (state,"want"))
					state = "want"

			elif isinstance(msg,MsgClosed):
				if self.channel is not None:
					if state != "waiting" and state != "connecting":
						log("conn",TRACE,"setstate2 %s %s" % (state,"closed"))
						state = "closed"
					self._teardown("ReOpen",external=False)
				if state == "closed" or state == "connecting":
					log("conn",TRACE,"setstate %s %s: wait %.3f" % (state,"waiting",self.connect_timeout))
					state = "waiting"
					callLater(True,self.connect_timeout,doReOpen)
					self._up_timeout()

			elif isinstance(msg,MsgError):
				self._error(msg.error)
			else:
				raise UnknownMessageType(msg)

			if self.ondemand and not self.n_outq:
				continue
			if state == "want"  or  state == "closed" and self.ondemand and self.n_outq:
				log("conn",TRACE,"setstate %s %s" % (state,"connecting"))
				state = "connecting"
				self._setup()
			if self.state != "connected":
				continue

			log("msg",TRACE,"states at run",self.state,state)
			done = False # marker for "don't send any more stuff"

			for mq in self.receivers:
				if done: break
				for m in mq:
					if m.blocking:
						log("msg",TRACE,"blocked by",str(m))
						done = True
			if done: continue

			for mq in self.senders:
				if done: break
				while len(mq):
					if done:
						break
					if self.channel is None:
						break

					msg = mq.pop(0)
					log("msg",TRACE,"send",str(msg))
					try:
						r = msg.send(self.channel)
					except Exception as ex:
						fix_exception(ex)
						r = ex
					else:
						self.last_sent = msg
						self.last_sent_at = now()
						self.n_sent_now += 1
					log("msg",TRACE,"send result",r)
					if r is RECV_AGAIN:
						if msg.blocking:
							self.receivers[msg.prio].insert(0,msg)
						else:
							self.receivers[msg.prio].append(msg)
					elif r is SEND_AGAIN:
						if msg.blocking:
							self.senders[msg.prio].insert(0,msg)
						else:
							self.senders[msg.prio].append(msg)
					elif isinstance(r,SEND_LATER):
						raise NotImplementedError("Queueing doesn't work yet")
					elif isinstance(r,MSG_ERROR):
						try:
							raise r
						except Exception as r:
							fix_exception(r)
							process_failure(r)
					elif isinstance(r,Exception):
						reraise(r)
					else:
						msg.done()

					if msg.blocking:
						done = True
						break

				# while setting up, only process PRIO_CONNECT messages
				if state != "connected":
					log(TRACE,"NotConn",self.senders)
					break
コード例 #46
0
ファイル: msg.py プロジェクト: M-o-a-T/moat
			def down_event(self,external=False,*a,**k):
				log(TRACE,"!got DOWN_EVENT",*self.name)
				msg = MsgClosed()
				self._msg_queue.put(msg)
				super(xself.cls,self).down_event()
コード例 #47
0
ファイル: context.py プロジェクト: ZigmundRat/moat
 def _dump_tree(self, pre):
     from moat.logging import log, DEBUG
     log(DEBUG, "CTX " + pre, six.text_type(self._store))
     for p in self._parent:
         p._dump_tree(pre + "  ")
コード例 #48
0
 def loseConnection(self):
     self.lost = True
     log("parser", DEBUG, "LAST_SYM _drop")
コード例 #49
0
ファイル: onewire.py プロジェクト: ZigmundRat/moat
    def _update_all(self):
        log("onewire", TRACE, "start bus update")
        old_ids = devices.copy()
        new_ids = {}
        seen_ids = {}
        old_bus = set(self.bus_paths.keys())
        new_bus = set()

        def bus_cb(path):
            if path in old_bus:
                old_bus.remove(path)
            else:
                new_bus.add(path)

        for dev in self.all_devices(bus_cb):
            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.values():
            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.values():
            if dev.bus is self:
                n_dev += 1

        for dev in old_bus:
            bp = self.bus_paths.pop(dev)
            bp.stop()
            simple_event("onewire", "bus", "down", bus=self.name, path=dev)
            simple_event("onewire",
                         "bus",
                         "state",
                         self.name,
                         "/".join(dev),
                         bus=self.name,
                         path=dev,
                         state="down")
        for dev in new_bus:
            self.bus_paths[dev] = OWFSbuspath(self, dev)
            simple_event("onewire", "bus", "up", bus=self.name, path=dev)
            simple_event("onewire",
                         "bus",
                         "state",
                         self.name,
                         "/".join(dev),
                         bus=self.name,
                         path=dev,
                         state="up")

        # success only, error above
        simple_event("onewire",
                     "scanned",
                     *self.name,
                     old=n_old,
                     new=len(new_ids),
                     num=n_dev,
                     deprecated=True)
        simple_event("onewire",
                     "scan",
                     *self.name,
                     run="done",
                     old=n_old,
                     new=len(new_ids),
                     num=n_dev)
コード例 #50
0
ファイル: monitor.py プロジェクト: smurfix/MoaT
	def _monitor(self):
		"""This implements a monitor sequence."""
		self.steps = 0
		self.data = []
		self.new_value = None

		def delay():
			if isinstance(self.delay,tuple):
				sleepUntil(False,time_delta(self.delay))
			else:
				sleepUntil(False,self.delay)

		try:
			while self.job and (self.maxpoints is None or self.steps < self.maxpoints):
				if self.steps and not self.passive:
					delay()

				self.steps += 1

				try:
					val = self.one_value(self.steps)

				except MonitorAgain:
					pass

				except Exception as e:
					fix_exception(e)
					process_failure(e)
					break

				else:
					try:
						val = float(val)
					except (TypeError,ValueError):
						log("monitor",ERROR,self.name,"not a float:",val)
						continue
					if hasattr(self,"factor"):
						try:
							val = val * self.factor + self.offset
						except (TypeError,ValueError) as e:
							log("monitor",ERROR,self.name,val,self.factor,self.offset)
							continue
					self.data.append(val)

					avg = self.filter_data()
					if avg is not None:
						if self.value is None or \
								self.diff is None or \
								abs(self.value-avg) > self.diff:

							try:
								if self.value is not None and \
										self.alarm is not None and \
										abs(self.value-avg) > self.alarm:
									simple_event(self.ectx,"monitor","jump",*self.name, avg=avg,value=self.value,alarm=self.alarm)
							except Exception as e:
								fix_exception(e)
								process_failure(e)
							else:
								self.new_value = avg
						return
					else:
						log("monitor",TRACE,"More data", self.data, "for", u"‹"+" ".join(six.text_type(x) for x in self.name)+u"›")
				
			try:
				simple_event(self.ectx,"monitor","error",*self.name)
			except Exception as e:
				fix_exception(e)
				process_failure(e)

		finally:
			log("monitor",TRACE,"End run", self.name)
			self.stopped_at = now()
コード例 #51
0
ファイル: exec.py プロジェクト: ZigmundRat/moat
def running(event):
    log(TRACE, "PY Event called", event)
コード例 #52
0
ファイル: exec.py プロジェクト: ZigmundRat/moat
def not_running(event):
    log(ERROR, "PY bad event called", event)
コード例 #53
0
    def _parseStep(self, t, txt, beg, end, line):
        from token import NUMBER,NAME,DEDENT,INDENT,OP,NEWLINE,ENDMARKER, \
         STRING
        from moat.tokize import COMMENT, NL
        self.last_pos = beg

        if "logger" in self.ctx:
            self.ctx.logger("T", self.p_state, t, repr(txt), beg, end,
                            repr(line))
        if t == COMMENT:
            return
        if self.p_state == 0:  # begin of statement
            if t == NAME:
                self.p_args = [txt]
                self.p_state = 1
                return
            elif t == DEDENT:
                self.proc.done()
                if self.p_stack:
                    self.proc = self.p_stack.pop()
                    return
                else:
                    raise StopIteration
            elif t == ENDMARKER:
                self.proc.done()
                while self.p_stack:
                    self.proc = self.p_stack.pop()
                    self.proc.done()
                raise StopIteration
            elif t in (NL, NEWLINE):
                self.prompt()
                return
            elif t == OP and txt == ".":
                return  # "I am done"
        elif self.p_state in (1, 2):  # after first word
            if t == NAME:
                self.p_args.append(txt)
                self.p_state = 2
                return
            elif t == OP and txt in ("*", "+", "-"):
                self.p_args.append(txt)
                self.p_state = 1
                return
            elif t == NUMBER:
                self.p_args.append(eval(txt, {}, {}))
                self.p_state = 1
                return
            elif t == STRING:
                self.p_args.append(eval(txt, {}, {}))
                self.p_state = 1
                return
            elif t == OP and txt[0] in ("$", "*"):
                self.p_args.append(txt)
                self.p_state = 1
                return
            elif t == OP and txt == "." and self.p_state == 2:
                self.p_state = 5
                return
            elif t == OP and txt == ":":
                log("parser", TRACE, "RUN2")
                log("parser", TRACE, self.proc.complex_statement, self.p_args)
                self.p_state = 3
                _ = self.proc.complex_statement(self.p_args)

                self.p_stack.append(self.proc)
                self.proc = _
                return
            elif t == NEWLINE:
                log("parser", TRACE, "RUN3")
                log("parser", TRACE, self.proc.simple_statement, self.p_args)
                # defer setting state to zero when pop_after is set
                # because that would break one-line compound statements
                # ("wait :for 2").
                # On the other hand, setting it later anyway breaks
                # statements which terminate the parser ("exit")
                if not self.p_pop_after:
                    self.p_state = 0
                self.proc.simple_statement(self.p_args)

                if self.p_pop_after:
                    self.proc.done()
                    self.proc = self.p_stack.pop()
                    self.p_pop_after = False
                    self.p_state = 0
                self.prompt()
                return
        elif self.p_state == 3:
            if t == NEWLINE:
                self.p_state = 4
                self.prompt()
                return
            elif t == NAME:
                self.p_args = [txt]
                self.p_state = 1
                self.p_pop_after = True
                return
            else:
                self.proc = self.p_stack.pop()
        elif self.p_state == 4:
            if t == INDENT:
                self.p_state = 0
                return
            elif t == NEWLINE:
                # ignore
                return
            else:
                self.proc = self.p_stack.pop()
        elif self.p_state == 5:
            if t == NAME:
                self.p_args[-1] += "." + txt
                self.p_state = 2
                return

        if self.p_pop_after:
            self.proc = self.p_stack.pop()
            self.p_pop_after = False

        raise SyntaxError("Unknown token %s (%s, state %d) in %s:%d" %
                          (repr(txt), tok_name[t] if t in tok_name else t,
                           self.p_state, self.ctx.filename, beg[0]))
コード例 #54
0
ファイル: msg.py プロジェクト: M-o-a-T/moat
			def not_up_event(self,external=False,*a,**k):
				log(TRACE,"!got NOT_UP_EVENT",*self.name)
				msg = MsgClosed()
				self._msg_queue.put(msg)
				super(xself.cls,self).not_up_event(external=external, **k)
コード例 #55
0
 def drop(self, _):
     log("parser", DEBUG, "LAST_SYM drop")
     conns.remove(self)
     self.loseConnection()
     return _
コード例 #56
0
ファイル: msg.py プロジェクト: M-o-a-T/moat
			def up_event(self,*a,**k):
				log(TRACE,"!got UP_EVENT",*self.name)
				msg = MsgOpenMarker()
				self._msg_queue.put(msg)
				super(xself.cls,self).up_event()