Пример #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 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)
Пример #4
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)
Пример #5
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)
Пример #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 _attr(obj, attr, value, path, eval_, res=None):
    # Sub-attr setter.
    # Special: if eval_ is True, an empty value deletes. A mapping replaces instead of updating.
    if res is None:
        res = await obj.client.get(obj.cfg.knx.prefix + path,
                                   nchain=obj.meta or 1)
    try:
        val = res.value
    except AttributeError:
        res.chain = None
    if eval_:
        if value is None:
            pass  ## value = res_delete(res, attr)
        else:
            value = path_eval(value)
            if isinstance(value, Mapping):
                # replace
                pass  ## value = res_delete(res, attr)
                value = value._update(attr, value=value)
            else:
                value = res_update(res, attr, value=value)
    else:
        if value is None:
            if not attr and obj.meta:
                val = res
            else:
                val = res_get(res, attr)
            yprint(val, stream=obj.stdout)
            return
        value = res_update(res, attr, value=value)

    res = await obj.client.set(obj.cfg.knx.prefix + path,
                               value=value,
                               nchain=obj.meta,
                               chain=res.chain)
    if obj.meta:
        yprint(res, stream=obj.stdout)