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
def run(self, ctx, **k): event = self.params(ctx) if self.dest is None: if len(event) < 2: raise SyntaxError(u'Usage: %s ‹name› ‹typ› ‹params›' % (self.name, )) self.dest = Name(event[0]) typ = event[1] d = 1 else: if len(event) < 1: raise SyntaxError(u'Usage: %s ‹typ› ‹params›' % (self.name, )) typ = event[0] d = 0 de = len(event) while de > d: try: reg = self.registry[Name(event[d:de])] except KeyError: de -= 1 else: reg(self.dest.apply(ctx), event.apply(ctx, drop=de), self.addons, self.ranges, self.values) return raise
def check(self, *args): conn = None if len(args) == 2: conn = getattr(self, "storage2", {}).get(Name(*args), None) if conn is None: conn = self.storage.get(Name(*args)) if conn is None: return False return conn.job is not None ## TODO: correct?
def run(self, ctx, **k): event = self.params(ctx) name = self.dest if name is None: name = Name(event[0]) event = event[1:] else: name = Name(*name.apply(ctx)) val = u" ".join(six.text_type(s) for s in event) self.storage[name].write(val.encode('utf-8'))
def run(self,ctx,**k): event = self.params(ctx) name = self.dest if name is None: name = Name(event[0]) event = event[1:] else: name = Name(*name.apply(ctx)) val = u" ".join(six.text_type(s) for s in event) self.storage[name].write(val.encode('utf-8'))
def run(self,ctx,**k): event = self.params(ctx) server = self.dest if server is None: server = Name(event[0]) path = event[1] name = Name(*event[2:]) else: server = Name(*server.apply(ctx)) path = event[0] name = Name(*event[1:]) RRDfile(RRDservers[server],path,name)
def run(self, ctx, **k): event = self.params(ctx) name = self.dest if name is None: name = Name(event[0]) event = event[1:] else: name = Name(*name.apply(ctx)) val = u" ".join(six.text_type(s) for s in event) msg = WAGOrawRun(val) WAGOservers[name].enqueue(msg) res = msg.result.get()
def run(self,ctx,**k): event = self.params(ctx) name = self.dest if name is None: name = Name(event[0]) event = event[1:] else: name = Name(*name.apply(ctx)) val = u" ".join(six.text_type(s) for s in event) msg = WAGOrawRun(val) WAGOservers[name].enqueue(msg) res = msg.result.get()
def run(self, ctx, **k): event = self.params(ctx) var = event[0] name = Name(*event[1:]) s = States[name] setattr(self.parent.ctx, var, s.value if not s.working else s.old_value)
def get(self, key): if not self.bus: raise DisconnectedDeviceError(self.id) if not isinstance(key, tuple): key = Name(key) p = self.path if self.bus_id is not None: p += (self.bus_id, ) p += key msg = ATTRgetmsg(p) msg.queue(self.bus) try: res = msg.result.get() except Exception as ex: fix_exception(ex) self.go_down(ex) raise if isinstance(res, bytes): res = res.decode('utf-8') try: res = int(res) except (ValueError, TypeError): try: res = float(res) except (ValueError, TypeError): pass return res
def run(self, ctx, **k): event = self.params(ctx) if len(event) > 3 or len(event) + (self.dest is not None) < 2: raise SyntaxError( u'Usage: connect qbroker ‹name› [‹host› [‹port›]]') if self.dest is None: dest = Name(event[0]) event = event[1:] else: dest = self.dest if len(event) > 1: host = event[1] else: host = "localhost" if len(event) > 2: port = int(event[2]) else: port = 5672 q = QBconn(dest, host, port, self.vhost, self.app, self.codec, self.username, self.password) try: q.start() except Exception: q.delete() raise
def run(self, ctx, **k): event = self.params(ctx) if self.dest is None and len(event): self.dest = Name(event[0]) event = event[1:] if (self.host is None and self.port is None and len(event) < 2) or \ ((self.host is None or self.port is None) and len(event) == 1) or \ len(event) > 2: raise SyntaxError( u"Usage: %s ‹name› ‹host›%s ‹port›%s" % (" ".join(self.name), "" if self.host is None else "?", "" if self.port is None else "?")) if self.port is None: if len(event): self.port = event[-1] event = event[:-1] if len(event): self.host = event[0] event = event[1:] else: if len(event): self.host = event[0] event = event[1:] if len(event): self.port = event[-1] event = event[:-1] self.start_up()
def run(self, ctx, **k): event = self.params(ctx) if len(event) < 2: raise SyntaxError("Usage: %s NAME INPUTNAME..." % (self.name, )) var = event[0] dev = self.storage[Name(*event[1:])] setattr(self.parent.ctx, var, dev.read())
class main_words(ComplexStatement): """\ This is the top-level dictionary. It is named in a strange way as to make the Help output look nice. """ name = Name("Main") doc = "word list:"
def run(self,ctx,**k): event = self.params(ctx) if len(event) < 1: raise SyntaxError('Usage: set pwm ‹value› ‹name…›') pwm = PWMs[Name(*event[1:])] pwm.value = float(event[0])
def run(self,ctx,**k): event = self.params(self.ctx) if len(event) < 3: raise SyntaxError(u"Usage: set fs20 em ‹type› ‹value› ‹name…›") d = EMs[Name(*event[2:])] if d.last_data is None: d.last_data = {} d.last_data[event[0]] = float(event[1])
def __init__(self, name, params, addons, ranges, values): if len(params) < 3: raise SyntaxError(u"Usage: %s wago ‹name…› ‹card› ‹port›" % (self.what, )) self.server = Name(*params[:-2]) self.card = int(params[-2]) self.port = int(params[-1]) super(WAGOio, self).__init__(name, params, addons, ranges, values)
def check(self, *args): assert len(args) == 1, "This test requires the connection name" try: bus = WAGOservers[Name(*args)] except KeyError: return False else: return bus.channel is not None
def run(self,ctx,**k): event = self.params(ctx) name = self.dest if name is None: val = (event[0],) name = Name(*event[1:]) else: val = list(event) name = Name(*name.apply(ctx)) rrdf = RRDfiles[name] rrdf.last_sent = val rrdf.last_sent_at = now() msg = RRDsendUpdate(rrdf,val) res = msg.result.get() if isinstance(res,Exception): reraise(res)
def run(self, ctx, **k): event = self.params(ctx) if len(event) < 3: raise SyntaxError( u'Usage: rrd "/path/to/the.rrd" ‹varname› ‹name…›') fn = event[0] assert os.path.exists(fn), "the RRD file does not exist: ‹%s›" % (fn, ) RRD(path=fn, dataset=event[1], name=Name(*event[2:]))
def check(self, *args): assert len(args), "This test requires the connection name" try: bus = buses[Name(*args)] except KeyError: return False else: return bus.conn is not None
def report(self, verbose=False): try: yield u"END: " + six.text_type(Name(self.name[1:])) except Exception as e: fix_exception(e) print("LOGGER CRASH 4", file=sys.stderr) print_exception(e, file=sys.stderr) yield "END: REPORT_ERROR: " + repr(self.name[1:])
def run(self, ctx, **k): event = self.params(ctx) var = event[0] name = Name(*event[1:]) if self.src is None: value = Avgs[name]._calc() else: value = getattr(Avgs[name], self.src) setattr(self.parent.ctx, var, value)
def __init__(self, ctx, *name): """\ Events have a context and at least one name. For example: Event(ctx, "startup") Event(ctx, "switch","toggle","sw12") Event(ctx, "switch","dim","livingroom","lamp12") Event(ctx, "timer","timeout","t123") """ self._name_check(name) #print("E_INIT",name,"with",ctx) self.name = Name(name) self.ctx = ctx if ctx is not None else Context() if "loglevel" in self.ctx: self.loglevel = ctx.loglevel self.timestamp = now() global event_id event_id += 1 self.id = event_id
def delete(self, key): key = " ".join(Name(key)).encode("utf-8") with self.db() as db: try: db.Do( "delete from HE_State where category=${cat} and name=${name}", cat=self.category, name=key) except NoData: raise KeyError((self.category, key))
class ExistsCheck(Check): name = Name("exists", *self.name) doc = "check if a named %s object exists" % (self.name, ) def check(xself, *args): if not len(args): raise SyntaxError(u"Usage: if exists %s ‹name…›" % (" ".join(self.name), )) oname = Name(*args) return oname in self
def run(self, ctx, **k): event = self.params(ctx) if len(event) < 3: raise SyntaxError("Usage: monitor wago ‹server…› ‹slot› ‹port›") self.values["card"] = int(event[-2]) self.values["port"] = int(event[-1]) self.values["server"] = Name(*event[:-2]) self.values["params"] = ("wago", ) + tuple(event) super(WAGOmonitor, self).run(ctx, **k)
def __init__(self, level): self.level = level global logger_nr logger_nr += 1 if not hasattr(self, "name") or self.name is None: self.name = Name(self.__class__.__name__, "x" + str(logger_nr)) super(BaseLogger, self).__init__() self._init()
def run(self, ctx, **k): event = self.params(ctx) if len(event) < 2: raise SyntaxError("Usage: set output VALUE OUTPUTNAME...") val = event[0] dev = Outputs[Name(*event[1:])] if self.timespec is None: timer = None else: timer = self.timespec() dev.write(val, timer=timer, nextval=self.nextval, async=self. async)
def run(self, ctx, **k): event = self.params(ctx) if len(event) < 1: raise SyntaxError(u'Usage: listen amqp ‹conn…›') conn = AMQPclients[SName(event)] dest = self.dest if dest is None: global _seq _seq += 1 dest = Name("_amqp", "a" + str(_seq)) AMQPrecv(self, dest, conn)
def run(self, ctx, **k): event = self.params(ctx) if len(event) < 3: raise SyntaxError(u'Usage: var rrd ‹variable› ‹item› ‹name…›') s = RRDs[Name(*event[2:])] try: setattr(self.parent.ctx, event[0], rrdtool.info(s.upath)["ds"][s.dataset][event[1]]) except KeyError: setattr(self.parent.ctx, event[0], rrdtool.info(s.upath)["ds[%s].%s" % (s.dataset, event[1])])
def check(self, *args): if len(args) < 2: raise SyntaxError(u"Usage: if last state ‹value› ‹name…›") value = args[0] name = Name(*args[1:]) s = States[name] if hasattr(s, "old_value"): return s.old_value == value else: return value == "-"
def __init__(self, name, dot=True, level=TRACE): self.dot = dot self.filename = name self.name = Name(name) self.try_init() try: self.data = open(os.path.join("real", name), "w") except IOError: print("ERROR, no log file", file=sys.stderr) self.data = sys.stderr self.line = 0 super(run_logger, self).__init__(level)
class MakeIO(AttributedStatement): """Common base class for input and output creation statements""" ranges = None values = None addons = None registry = None # override in subclass dest = None def __init__(self,*a,**k): super(MakeIO,self).__init__(*a,**k) self.ranges = [] self.values = [] self.addons = {} def run(self,ctx,**k): event = self.params(ctx) if self.dest is None: if len(event) < 2: raise SyntaxError(u'Usage: %s ‹name› ‹typ› ‹params›'%(self.name,)) self.dest = Name(event[0]) typ = event[1] d = 1 else: if len(event) < 1: raise SyntaxError(u'Usage: %s ‹typ› ‹params›'%(self.name,)) typ = event[0] d = 0 de=len(event) while de > d: try: reg = self.registry[Name(event[d:de])] except KeyError: de -= 1 else: reg(self.dest.apply(ctx), event.apply(ctx,drop=de), self.addons,self.ranges,self.values) return raise
def run(self,ctx,**k): event = self.params(ctx) if self.dest is None: if len(event) < 2: raise SyntaxError(u'Usage: %s ‹name› ‹typ› ‹params›'%(self.name,)) self.dest = Name(event[0]) typ = event[1] d = 1 else: if len(event) < 1: raise SyntaxError(u'Usage: %s ‹typ› ‹params›'%(self.name,)) typ = event[0] d = 0 de=len(event) while de > d: try: reg = self.registry[Name(event[d:de])] except KeyError: de -= 1 else: reg(self.dest.apply(ctx), event.apply(ctx,drop=de), self.addons,self.ranges,self.values) return raise
class Event(object): """\ This is an event. It happens and gets analyzed by the system. """ loglevel = None timestamp = None def __init__(self, ctx, *name): """\ Events have a context and at least one name. For example: Event(ctx, "startup") Event(ctx, "switch","toggle","sw12") Event(ctx, "switch","dim","livingroom","lamp12") Event(ctx, "timer","timeout","t123") """ self._name_check(name) #print("E_INIT",name,"with",ctx) self.name = Name(name) self.ctx = ctx if ctx is not None else Context() if "loglevel" in self.ctx: self.loglevel = ctx.loglevel self.timestamp = now() global event_id event_id += 1 self.id = event_id def _name_check(self,name): if not len(name): raise EventNoNameError def __repr__(self): if not hasattr(self,"name"): return "%s(<uninitialized>)" % (self.__class__.__name__,) return "%s(%s)" % (self.__class__.__name__, ",".join(repr(n) for n in self.name)) def __str__(self): try: return u"↯."+six.text_type(self.name) except Exception: return "↯ REPORT_ERROR: "+repr(self.name) def report(self, verbose=False): try: yield u"EVENT: "+six.text_type(self.name) for k,v in sorted(self.ctx): yield u" : "+k+u"="+six.text_type(v) except Exception: yield "EVENT: REPORT_ERROR: "+repr(self.name) def list(self): yield (six.text_type(self.name),) if self.__class__ is not Event: yield ("type",self.__class__.__name__) if self.timestamp is not None: yield ("timestamp",self.loglevel) if self.loglevel is not None: yield ("log level",self.loglevel) yield ("ctx",self.ctx) s = super(Event,self) if hasattr(s,'list'): yield s def __getitem__(self,i): u"""… so that you can write e[0] instead of e.name[0]""" return self.name[i] def __getslice__(self,i,j): u"""… so that you can write e[2:] instead of e.name[2:]""" return list(self.name[i:j]) # list() because the result may need to be modified by the caller def __setitem__(self,i,j): raise RuntimeError("You cannot modify an event!") def __len__(self): return len(self.name) def __bool__(self): return True def __iter__(self): return self.name.__iter__() def __eq__(self,x): return self.name.__eq__(x) def __ne__(self,x): return self.name.__ne__(x) def apply(self, ctx=None, drop=0): """\ Copy an event, applying substitutions. This code dies with an AttributeError if there are no matching substitutes. This is intentional. """ w = [] if ctx is None: ctx = self.ctx else: ctx = ctx(ctx=self.ctx) for n in self.name[drop:]: if hasattr(n,"startswith") and n.startswith('$'): r = ctx[n[1:]] # if n == "$X": # import sys # print("c@%x %s %s"%(id(ctx),n,r), file=sys.stderr) # for x in ctx._report(): # print(": ",x, file=sys.stderr) n = r w.append(n) return self.__class__(ctx, *self.name.apply(ctx=ctx,drop=drop)) def dup(self, ctx=None, drop=0): """\ Copy an event, NOT applying substitutions. """ w = [] if ctx is None: ctx = self.ctx else: ctx = ctx(ctx=self.ctx) return self.__class__(ctx, *self.name[drop:])