Пример #1
0
async def attr_(obj, bus, group, vars_, eval_, path_):
    """Set/get/delete an attribute on a given KNX element.

    `--eval` without a value deletes the attribute.
    """
    group = (int(x) for x in group.split("/")) if group else ()
    path = Path(bus, *group)
    if len(path) != 4:
        raise click.UsageError("Group address must be 3 /-separated elements.")

    res = await obj.client.get(obj.cfg.knx.prefix + path, nchain=obj.meta or 1)

    if vars_ or eval_ or path_:
        res = await node_attr(obj,
                              obj.cfg.knx.prefix + path,
                              vars_,
                              eval_,
                              path_,
                              res=res)
        if obj.meta:
            yprint(res, stream=obj.stdout)
    else:
        if not obj.meta:
            res = res.value
        yprint(res, stream=obj.stdout)
Пример #2
0
async def addr(obj, bus, group, typ, mode, attr):
    """Set/get/delete device settings. This is a shortcut for the "attr" command."""
    group = (int(x) for x in group.split("/"))
    path = Path(bus, *group)
    if len(path) != 4:
        raise click.UsageError("Group address must be 3 /-separated elements.")
    res = await obj.client.get(obj.cfg.knx.prefix + path, nchain=obj.meta or 1)
    val = res.get("value", attrdict())

    if typ == "-":
        res = await obj.client.delete(obj.cfg.knx.prefix + path,
                                      nchain=obj.meta)
        if obj.meta:
            yprint(res, stream=obj.stdout)
        return

    if typ:
        attr = (("type", typ), ) + attr
    if mode:
        attr = (("mode", mode), ) + attr
    for k, v in attr:
        if k in {"src", "dest"}:
            v = P(v)
        else:
            try:
                v = int(v)
            except ValueError:
                try:
                    v = float(v)
                except ValueError:
                    pass
        val[k] = v

    await _attr(obj, (), val, path, False, res)
Пример #3
0
async def server_(obj, name, host, port, delete):
    """
    Configure a server.

    No arguments: list them.
    """
    if not name:
        if host or port or delete:
            raise click.UsageError("Use a server name to set parameters")
        async for r in obj.client.get_tree(obj.cfg.akumuli.prefix,
                                           min_depth=1,
                                           max_depth=1):
            print(r.path[-1], file=obj.stdout)
        return
    elif len(name) > 1:
        raise click.UsageError("Only one server allowed")
    name = name[0]
    if host or port:
        if delete:
            raise click.UsageError(
                "You can't delete and set at the same time.")
        value = attrdict()
        if host:
            value.host = host
        if port:
            if port == "-":
                value.port = NotGiven
            else:
                value.port = int(port)
    elif delete:
        res = await obj.client.delete_tree(obj.cfg.akumuli.prefix + name,
                                           nchain=obj.meta)
        if obj.meta:
            yprint(res, stream=obj.stdout)
        return
    else:
        value = None
    res = await node_attr(obj, obj.cfg.akumuli.prefix | name, ("server", ),
                          value)

    if obj.meta:
        yprint(res, stream=obj.stdout)
Пример #4
0
async def attr_(obj, attr, value, path, eval_, path_):
    """Set/get/delete an attribute on a given akumuli element.

    `--eval` without a value deletes the attribute.
    """
    path = P(path)

    if path_ and eval_:
        raise click.UsageError("split and eval don't work together.")
    if value and not attr:
        raise click.UsageError("Values must have locations ('-a ATTR').")
    if path_:
        value = P(value)
    res = await node_attr(obj,
                          obj.cfg.akumuli.prefix + path,
                          P(attr),
                          value,
                          eval_=eval_)

    if obj.meta:
        yprint(res, stream=obj.stdout)
Пример #5
0
async def list_(obj, path):
    """List the next stage."""
    path = P(path)
    if len(path) > 4:
        raise click.UsageError("Only up to four path elements allowed")

    async for r in obj.client.get_tree(obj.cfg.knx.prefix + path,
                                       nchain=obj.meta,
                                       min_depth=1,
                                       max_depth=1,
                                       empty=True):
        if len(path) and not isinstance(r.path[-1], int):
            continue
        print(r.path[-1], file=obj.stdout)
Пример #6
0
async def set_(obj, path, source, mode, attr, series, tags):
    """Set/delete part of a series.
    \b
    path: the name of this copy command. Unique path, non-empty.
    source: the element with the data. unique path, non-empty.
    series: the Akumuli series to write to.
    tags: any number of "name=value" Akumuli tags to use for the series.

    A series of '-' deletes.
    """
    path = P(path)
    attr = P(attr)
    source = P(source)
    mode = getattr(DS, mode)
    tagged = {}
    if series == "-":
        if tags:
            raise click.UsageError("You can't add tags when deleting")
        series = None
        await obj.client.delete(obj.cfg.akumuli.prefix + path)
        return

    if not tags:
        raise click.UsageError("You can't write to a series without tags")
    for x in tags:
        try:
            k, v = x.split("=", 2)
        except ValueError:
            raise click.UsageError("Tags must be key=value") from None
        tagged[k] = v

    val = dict(source=source, series=series, tags=tagged, mode=mode.name)
    if attr:
        val["attr"] = attr
    res = await obj.client.set(obj.cfg.akumuli.prefix + path, val)
    if obj.meta:
        yprint(res, stream=obj.stdout)
Пример #7
0
async def dump(obj, path):
    """Emit the current state as a YAML file."""
    res = {}
    path = P(path)
    if len(path) > 4:
        raise click.UsageError("Only up to four path elements allowed")

    async for r in obj.client.get_tree(obj.cfg.knx.prefix + path,
                                       nchain=obj.meta,
                                       max_depth=4 - len(path)):
        # pl = len(path) + len(r.path)
        rr = res
        if r.path:
            for rp in r.path:
                rr = rr.setdefault(rp, {})
        rr["_"] = r if obj.meta else r.value
    yprint(res, stream=obj.stdout)
Пример #8
0
async def monitor(obj, bus, server, local_ip, initial):
    """Stand-alone task to talk to a single server."""
    from distkv_ext.knx.task import task
    from distkv_ext.knx.model import KNXroot

    knx = await KNXroot.as_handler(obj.client)
    await knx.wait_loaded()

    if not server and " " in bus:
        bus, server = bus.split(" ")
    elif len(server) != 1:
        raise click.UsageError("Use a single server name")
    else:
        server = server[0]

    async with as_service(obj) as srv:
        await task(obj.client,
                   obj.cfg.knx,
                   knx[bus][server],
                   srv,
                   local_ip=local_ip,
                   initial=initial)
Пример #9
0
async def run(obj, checks, as_list):
    """
    Run a one-shot call.
    """
    if not checks:
        checks = list(k for k,v in obj.calls.items() if as_list or not v.test.skip)
    if not checks:
        raise click.UsageError("No tests known. Missing config file?")

    if as_list:
        for c in checks:
            c = obj.calls[c]
            print(c.name, "m" if c.test.skip else "-", c.info, sep="\t")
        return

    ast = obj.cfg.asterisk
    url = "http://%s:%d/" % (ast.host,ast.port)
    async with asyncari.connect(url, ast.app, username=ast.username, password=ast.password) as client:
        client._calltest_config = obj.cfg
        async with anyio.create_task_group() as tg:
            for c in checks:
                await tg.spawn(obj.calls[c], client)