Пример #1
0
class Schedule(dictobj.Spec):
    days = dictobj.NullableField(
        sb.listof(enum_spec(None, Days, unpacking=True)))
    hour = dictobj.Field(range_spec(sb.integer_spec(), 0, 23),
                         wrapper=sb.required)
    minute = dictobj.Field(range_spec(sb.integer_spec(), 0, 59),
                           wrapper=sb.required)

    task = dictobj.Field(task_spec)

    hue = dictobj.Field(range_spec(sb.float_spec(), 0, 360), default=0)
    saturation = dictobj.Field(range_spec(sb.float_spec(), 0, 1), default=0)
    brightness = dictobj.Field(range_spec(sb.float_spec(), 0, 1), default=1)
    kelvin = dictobj.Field(range_spec(sb.integer_spec(), 1500, 9000),
                           default=3500)
    transform_options = dictobj.NullableField(
        sb.dictof(sb.string_spec(), sb.boolean()))

    duration = dictobj.NullableField(sb.float_spec)
    power = dictobj.NullableField(power_spec)

    colors = dictobj.NullableField(colors_spec)
    override = dictobj.NullableField(
        sb.dictof(sb.string_spec(), range_spec(sb.float_spec(), 0, 1)))

    reference = dictobj.Field(reference_spec)

    @property
    def hsbk(self):
        if self.task == 'lan:transform':
            keys = ["hue", "saturation", "brightness", "kelvin"]
            options = {k: v for k, v in self.as_dict().items() if k in keys}
            return {k: v for k, v in options.items() if v is not None}
        else:
            return {}

    @property
    def extra(self):
        keys_except = [
            "days", "hour", "minute", "reference", "task", "hue", "saturation",
            "brightness", "kelvin"
        ]
        options = {
            k: v
            for k, v in self.as_dict().items() if k not in keys_except
        }
        return {k: v for k, v in options.items() if v is not None}

    @property
    def dow(self):
        days = self.days
        if not self.days:
            days = list(Days)

        return [day.value for day in days]
Пример #2
0
async def set_chain_state(collector, target, reference, artifact, **kwargs):
    """
    Set the state of colors on your tile

    ``lan:set_chain_state d073d5f09124 -- '{"colors": [[[0, 0, 0, 3500], [0, 0, 0, 3500], ...], [[0, 0, 1, 3500], ...], ...], "tile_index": 1, "length": 1, "x": 0, "y": 0, "width": 8}'``

    Where the colors is a grid of 8 rows of 8 ``[h, s, b, k]`` values.
    """  # noqa
    options = collector.photons_app.extra_as_json

    if "colors" in options:
        spec = sb.listof(
            sb.listof(
                list_spec(sb.integer_spec(), sb.float_spec(), sb.float_spec(),
                          sb.integer_spec())))
        colors = spec.normalise(Meta.empty().at("colors"), options["colors"])

        row_lengths = [len(row) for row in colors]
        if len(set(row_lengths)) != 1:
            raise PhotonsAppError(
                "Please specify colors as a grid with the same length rows",
                got=row_lengths)

        num_cells = sum(len(row) for row in colors)
        if num_cells != 64:
            raise PhotonsAppError("Please specify 64 colors", got=num_cells)

        cells = []
        for row in colors:
            for col in row:
                cells.append({
                    "hue": col[0],
                    "saturation": col[1],
                    "brightness": col[2],
                    "kelvin": col[3]
                })

        options["colors"] = cells
    else:
        raise PhotonsAppError(
            "Please specify colors in options after -- as a grid of [h, s, b, k]"
        )

    missing = []
    for field in TileMessages.Set64.Payload.Meta.all_names:
        if field not in options and field not in ("duration", "reserved6"):
            missing.append(field)

    if missing:
        raise PhotonsAppError("Missing options for the SetTileState message",
                              missing=missing)

    options["res_required"] = False
    msg = TileMessages.Set64.empty_normalise(**options)
    await target.send(msg, reference)
Пример #3
0
    async def execute_task(self, **kwargs):
        extra = self.photons_app.extra_as_json
        positions = sb.listof(sb.listof(sb.float_spec())).normalise(
            Meta.empty(), extra)

        if any(len(position) != 2 for position in positions):
            raise PhotonsAppError(
                "Please enter positions as a list of two item lists of user_x, user_y"
            )

        async def gen(reference, sender, **kwargs):
            ps = sender.make_plans("capability")
            async for serial, _, info in sender.gatherer.gather(
                    ps, reference, **kwargs):
                if info["cap"].has_matrix:
                    for i, (user_x, user_y) in enumerate(positions):
                        yield TileMessages.SetUserPosition(
                            tile_index=i,
                            user_x=user_x,
                            user_y=user_y,
                            res_required=False,
                            target=serial,
                        )

        await self.target.send(FromGenerator(gen), self.reference)
Пример #4
0
async def set_tile_positions(collector, target, reference, **kwargs):
    """
    Set the positions of the tiles in your chain.

    ``lan:set_tile_positions d073d5f09124 -- '[[0, 0], [-1, 0], [-1, 1]]'``
    """
    extra = collector.photons_app.extra_as_json
    positions = sb.listof(sb.listof(sb.float_spec())).normalise(
        Meta.empty(), extra)
    if any(len(position) != 2 for position in positions):
        raise PhotonsAppError(
            "Please enter positions as a list of two item lists of user_x, user_y"
        )

    async def gen(reference, sender, **kwargs):
        ps = sender.make_plans("capability")
        async for serial, _, info in sender.gatherer.gather(
                ps, reference, **kwargs):
            if info["cap"].has_matrix:
                for i, (user_x, user_y) in enumerate(positions):
                    yield TileMessages.SetUserPosition(
                        tile_index=i,
                        user_x=user_x,
                        user_y=user_y,
                        res_required=False,
                        target=serial,
                    )

    await target.send(FromGenerator(gen), reference)
Пример #5
0
    def normalise_filled(self, meta, val):
        if type(val) is str:
            val = val.split(",")

        if type(val) is list:
            res = []
            for pair in val:
                if type(pair) is not str:
                    res.append(pair)
                else:
                    if "-" in pair:
                        res.append(tuple(v.strip() for v in pair.split("-", 1)))
                    else:
                        res.append((pair.strip(), pair.strip()))
            val = res

        return sb.listof(sb.tuple_spec(sb.float_spec(), sb.float_spec())).normalise(meta, val)
Пример #6
0
class Options(dictobj.Spec):
    colors = dictobj.Field(colors_spec)
    duration = dictobj.Field(sb.float_spec(), default=1)
    power_on = dictobj.Field(sb.boolean, default=True)
    overrides = dictobj.Field(Overrides.FieldSpec)

    @hp.memoized_property
    def override_layer(self):
        def layer(point, canvas):
            c = canvas[point]
            if c is not None:
                return canvas.override(point, **self.overrides)
            else:
                return c

        return layer
Пример #7
0
 def __init__(self, minimum, maximum, spec=None):
     self.minimum = minimum
     self.maximum = maximum
     self.spec = spec or sb.float_spec()
Пример #8
0
 def normalise_filled(self, meta, val):
     return int(sb.float_spec().normalise(meta, val))
Пример #9
0
    async def execute_task(self, **kwargs):
        options = self.photons_app.extra_as_json

        width = options.get("width", 8)
        options["width"] = width

        if "colors" in options:
            spec = sb.listof(
                sb.listof(
                    list_spec(sb.integer_spec(), sb.float_spec(),
                              sb.float_spec(), sb.integer_spec())))
            colors = spec.normalise(Meta.empty().at("colors"),
                                    options["colors"])

            row_lengths = [len(row) for row in colors]
            if len(set(row_lengths)) != 1:
                raise PhotonsAppError(
                    "Please specify colors as a grid with the same length rows",
                    got=row_lengths)

            cells = []
            for row in colors:
                while len(row) < width:
                    row.append(None)

                for col in row:
                    if col is None:
                        cells.append({
                            "hue": 0,
                            "saturation": 0,
                            "brightness": 0,
                            "kelvin": 3500
                        })
                        continue

                    cells.append({
                        "hue": col[0],
                        "saturation": col[1],
                        "brightness": col[2],
                        "kelvin": col[3],
                    })

            options["colors"] = cells
        else:
            raise PhotonsAppError(
                "Please specify colors in options after -- as a grid of [h, s, b, k]"
            )

        missing = []
        for field in TileMessages.Set64.Payload.Meta.all_names:
            if field not in options and field not in ("duration", "reserved6"):
                missing.append(field)

        if missing:
            raise PhotonsAppError(
                "Missing options for the SetTileState message",
                missing=missing)

        options["res_required"] = False
        msg = TileMessages.Set64.create(**options)
        await self.target.send(msg, self.reference)
Пример #10
0
# coding: spec

from interactor.commander.spec_description import signature

from delfick_project.norms import sb

describe "signature":

    def assertSignature(self, spec, want):
        assert " ".join(signature(spec)) == want

    it "knows about integer_spec":
        self.assertSignature(sb.integer_spec(), "integer")

    it "knows about float_spec":
        self.assertSignature(sb.float_spec(), "float")

    it "knows about string_spec":
        self.assertSignature(sb.string_spec(), "string")

    it "knows about boolean":
        self.assertSignature(sb.boolean(), "boolean")

    it "knows about dictionary_spec":
        self.assertSignature(sb.dictionary_spec(), "dictionary")

    it "knows about string_choice_spec":
        self.assertSignature(sb.string_choice_spec(["one", "two"]), "choice of (one | two)")

    it "knows about optional_spec":
        self.assertSignature(sb.optional_spec(sb.integer_spec()), "integer (optional)")
Пример #11
0
 def normalise_filled(self, meta, val):
     return sb.listof(tuple_spec(sb.float_spec(), sb.float_spec())).normalise(meta, val)
Пример #12
0
class Options(dictobj.Spec):
    colors = dictobj.Field(colors_spec, wrapper=sb.required)
    theme = dictobj.Field(sb.string_choice_spec(appliers.keys()), default="SPLOTCH")
    duration = dictobj.Field(sb.float_spec(), default=1)
    overrides = dictobj.Field(sb.dictionary_spec)