Пример #1
0
        async def gen(reference, sender, **kwargs):
            get_power = DeviceMessages.GetPower()

            async for pkt in sender(get_power, reference, **kwargs):
                if pkt | DeviceMessages.StatePower:
                    if pkt.level == 0:
                        yield DeviceMessages.SetPower(level=65535, target=pkt.serial)
                    else:
                        yield DeviceMessages.SetPower(level=0, target=pkt.serial)
Пример #2
0
 def setup(self):
     self.log_args = (PhotonsAppError("stuff happens", one=1),)
     self.log_kwargs = {
         "pkt": DeviceMessages.SetPower(level=65535),
         "other": [1, 2],
         "more": True,
     }
Пример #3
0
    async def start(self, serial, info, target, afr):
        errors = []

        plans = ["chain"]
        if info.get("initial") is None:
            info["initial"] = {"colors": [], "power": 65535}
            plans.append("colors")
            plans.append("power")

        plans = make_plans(*plans)
        gatherer = Gatherer(target)

        got = await gatherer.gather_all(plans,
                                        serial,
                                        afr,
                                        error_catcher=errors)
        if errors:
            return errors, info

        chain = got[serial][1]["chain"]
        power = got[serial][1].get("power")
        colors = got[serial][1].get("colors")

        if power is not None:
            info["initial"]["power"] = power["level"]
        if colors is not None:
            info["initial"]["colors"] = colors

        pixel_coords = user_coords_to_pixel_coords(chain["coords_and_sizes"])
        info["coords"] = [top_left for top_left, _ in pixel_coords]
        info["reorient"] = chain["reorient"]

        if info.get("pixels") is None:
            canvas = Canvas()

            def dcf(i, j):
                return Color(0, 0, 0, 3500)

            canvas.default_color_func = dcf

            length = len(info["coords"])
            self.style_maker.set_canvas(canvas, length)
            info["pixels"], info["color_pixels"] = make_rgb_and_color_pixels(
                canvas, length)

            msgs = [DeviceMessages.SetPower(level=65535)]
            msgs.extend(
                canvas_to_msgs(
                    canvas,
                    coords_for_horizontal_line,
                    duration=1,
                    acks=True,
                    reorient=info["reorient"],
                ))
            await target.script(msgs).run_with_all(serial,
                                                   afr,
                                                   error_catcher=errors)

        return errors, info
Пример #4
0
 async def inner_gen(level, reference, sender2, **kwargs2):
     assert sender is sender2
     del kwargs2["error_catcher"]
     kwargs1 = dict(kwargs)
     del kwargs1["error_catcher"]
     assert kwargs1 == kwargs2
     assert reference in devices.serials
     yield DeviceMessages.SetPower(level=level)
Пример #5
0
    def power_message(self, state):
        power_level = 65535 if state["power"] == "on" else 0

        if state.get("duration") in (sb.NotSpecified, "", 0, None):
            return DeviceMessages.SetPower(level=power_level,
                                           res_required=False)
        else:
            return LightMessages.SetLightPower(level=power_level,
                                               duration=state["duration"],
                                               res_required=False)
Пример #6
0
    async def execute(self):
        fltr = chp.filter_from_matcher(self.matcher, self.refresh)

        result = chp.ResultBuilder()
        afr = await self.finder.args_for_run()
        reference = self.finder.find(filtr=fltr)

        serials = await tile_serials_from_reference(self.target, reference,
                                                    afr)
        if not serials:
            raise FoundNoDevices("Didn't find any tiles")

        await self.target.script(DeviceMessages.SetPower(level=65535)
                                 ).run_with_all(serials,
                                                afr,
                                                error_catcher=result.error)

        result.result["results"]["tiles"] = await tile_dice(
            self.target, serials, afr, error_catcher=result.error)

        return result
Пример #7
0
async def doit(collector):
    lan_target = collector.resolve_target("lan")

    parser = argparse.ArgumentParser()
    parser.add_argument("--reference", default="_")
    parser.add_argument("--brightness", type=float, default=1)
    args = parser.parse_args()

    reference = collector.reference_object(args.reference)

    power_on = DeviceMessages.SetPower(level=65535)

    spread = 1
    color_names = [
        "blue", "red", "orange", "yellow", "cyan", "green", "blue", "purple",
        "pink"
    ]
    color_msgs = [
        ColourParser.msg(
            name,
            overrides={
                "res_required": False,
                "duration": spread,
                "brightness": args.brightness,
            },
        ) for name in color_names
    ]
    colors = Pipeline(*color_msgs, spread=spread, synchronized=True)

    pipeline = Pipeline(power_on,
                        Repeater(colors, min_loop_time=len(color_names)),
                        synchronized=True)

    def e(error):
        log.error(error)

    await lan_target.send(pipeline,
                          reference,
                          message_timeout=1,
                          error_catcher=e)
Пример #8
0
    async def restore(self, serial, initial, target, afr):
        msgs = [DeviceMessages.SetPower(level=initial["power"])]

        for i, colors in enumerate(initial["colors"]):
            msgs.append(
                TileMessages.Set64(
                    tile_index=i,
                    length=1,
                    width=8,
                    x=0,
                    y=0,
                    colors=colors,
                    res_required=False,
                    ack_required=True,
                ))

        def errors(e):
            log.error(hp.lc("Error restoring tile", serial=serial, error=e))

        await target.script(msgs).run_with_all(serial,
                                               afr,
                                               error_catcher=errors)
Пример #9
0
async def doit():
    async with lan_target.session() as afr:
        # By using a pipeline we can introduce a wait time between successful sending of colors
        colors = Pipeline(*color_msgs, spread=spread, synchronized=True)

        # by having power_on and get_color in an array we are sending both at the same time
        # without waiting for the other to get a reply first
        # We use a pipeline so that the power is turned on before we start the colors
        pipeline = Pipeline([power_on, get_color], colors, synchronized=True)

        original_colors = {}
        async for pkt, _, _ in lan_target.script(pipeline).run_with(
                FoundSerials(), afr):
            # We set res_required on the colors to False on line 20
            # Which means only the ``get_color`` messages will return a LightState
            # We use this to record what the color of the light was before the rainbow
            if pkt | LightMessages.LightState:
                color = "kelvin:{kelvin} hue:{hue} saturation:{saturation} brightness:{brightness}"
                original_colors[pkt.target] = (pkt.power,
                                               color.format(
                                                   **pkt.payload.as_dict()))

        await asyncio.sleep(spread)

        msgs = []
        for target, (level, color) in original_colors.items():
            msg1 = Parser.color_to_msg(color, overrides={"duration": spread})
            msg2 = DeviceMessages.SetPower(level=level)

            # By setting the target directly on the message we don't have to
            # provide the references to the run_with_all call
            for msg in (msg1, msg2):
                msg.target = target
                msg.res_required = False
                msgs.append(msg)

        # We share the afr we got from target.session() so that we don't have to search for the ips of the lights again
        await lan_target.script(msgs).run_with_all(None, afr)
Пример #10
0
        )

    async it "has set commands", devices, server:
        expected = {"results": {device.serial: "ok" for device in devices}}

        await server.assertCommand(
            "/v1/lifx/command",
            {"command": "set", "args": {"pkt_type": "SetPower", "pkt_args": {"level": 0}}},
            json_output=expected,
        )

        for device in devices:
            io = device.io["MEMORY"]
            assert (
                devices.store(device).count(
                    Events.INCOMING(device, io, pkt=DeviceMessages.SetPower(level=0))
                )
                == 1
            )
            devices.store(device).clear()

        # With an offline light
        bathroom_light = devices["d073d5000002"]
        async with bathroom_light.offline():
            expected["results"]["d073d5000002"] = {
                "error": {
                    "message": "Timed out. Waiting for reply to a packet",
                    "sent_pkt_type": 21,
                    "source": mock.ANY,
                    "sequence": mock.ANY,
                },
Пример #11
0
                light1.serial: (True, {"hev_status": Skip}),
                clean.serial: (
                    True,
                    {
                        "hev_status": {
                            "current": {
                                "active": False,
                            },
                            "last": {"result": LightLastHevCycleResult.SUCCESS},
                        }
                    },
                ),
            }

        async it "works with different last result", sender, m:
            await sender(DeviceMessages.SetPower(level=65535), clean.serial)
            await sender(LightMessages.SetHevCycle(enable=True, duration_s=2000), clean.serial)
            await m.add(22)

            got = await self.gather(sender, [clean.serial, light1.serial], "hev_status")
            assert got == {
                light1.serial: (True, {"hev_status": Skip}),
                clean.serial: (
                    True,
                    {
                        "hev_status": {
                            "current": {
                                "active": True,
                                "duration_s": 2000,
                                "remaining": 1978,
                                "last_power": 65535,
Пример #12
0
            d.start = pytest.helpers.AsyncMock(name="start")
            d.finish = pytest.helpers.AsyncMock(name="finish")

        with assertRaises(ValueError, "NOPE"):
            async with WithDevices(devices):
                for d in devices:
                    d.start.assert_called_once_with()
                    assert len(d.finish.mock_calls) == 0
                raise ValueError("NOPE")

        for d in devices:
            d.finish.assert_called_once_with()

describe "pktkeys":
    it "can get us deduped keys to represent the packets":
        msg1 = DeviceMessages.SetPower(level=65535, source=1, sequence=2, target="d073d501")
        msg2 = DeviceMessages.SetLabel(label="bob", source=3, sequence=4, target="d073d502")
        msg3 = DeviceMessages.SetLabel(label="bob", source=5, sequence=6, target="d073d503")
        keys = pktkeys([msg1, msg2, msg3])

        assert keys == [(1024, 21, '{"level": 65535}'), (1024, 24, '{"label": "bob"}')]

    it "can be told to keep duplicates":
        msg1 = DeviceMessages.SetPower(level=65535, source=1, sequence=2, target="d073d501")
        msg2 = DeviceMessages.SetLabel(label="bob", source=3, sequence=4, target="d073d502")
        msg3 = DeviceMessages.SetLabel(label="bob", source=5, sequence=6, target="d073d503")
        keys = pktkeys([msg1, msg2, msg3], keep_duplicates=True)

        assert keys == [
            (1024, 21, '{"level": 65535}'),
            (1024, 24, '{"label": "bob"}'),
Пример #13
0
        expected = {
            a19: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()],
            clean: [
                DeviceMessages.GetHostFirmware(),
                DeviceMessages.GetVersion(),
                LightMessages.GetHevCycle(),
            ],
            ir: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()],
        }

        await self.assertScript(sender, msg, expected=expected)

    async it "can send message to groups", sender:

        msg = ForCapability(**{"ir,hev": DeviceMessages.SetPower(level=65535)})

        expected = {
            a19: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()],
            clean: [
                DeviceMessages.GetHostFirmware(),
                DeviceMessages.GetVersion(),
                DeviceMessages.SetPower(level=65535),
            ],
            ir: [
                DeviceMessages.GetHostFirmware(),
                DeviceMessages.GetVersion(),
                DeviceMessages.SetPower(level=65535),
            ],
        }
Пример #14
0
                assert got[device.serial][0] | DeviceMessages.StatePower

    async it "Sends all the messages that are yielded", sender:

        async def gen(reference, sender, **kwargs):
            get_power = DeviceMessages.GetPower()

            async for pkt in sender(get_power, reference, **kwargs):
                if pkt | DeviceMessages.StatePower:
                    if pkt.level == 0:
                        yield DeviceMessages.SetPower(level=65535, target=pkt.serial)
                    else:
                        yield DeviceMessages.SetPower(level=0, target=pkt.serial)

        expected = {
            light1: [DeviceMessages.GetPower(), DeviceMessages.SetPower(level=65535)],
            light2: [DeviceMessages.GetPower(), DeviceMessages.SetPower(level=0)],
            light3: [DeviceMessages.GetPower(), DeviceMessages.SetPower(level=65535)],
        }

        await self.assertScript(sender, gen, expected=expected)

    async it "does not ignore exception in generator", sender:
        error = Exception("NOPE")

        async def gen(reference, sender, **kwargs):
            raise error
            yield DeviceMessages.GetPower()

        expected = {light1: [], light2: [], light3: []}
        with assertRaises(BadRun, _errors=[error]):
Пример #15
0
async def doit():
    color_msg = Parser.color_to_msg("blue")
    on_msg = DeviceMessages.SetPower(level=65535)
    script = lan_target.script([color_msg, on_msg])
    await script.run_with_all(FoundSerials())
Пример #16
0
describe "can send over memory":

    @pytest.fixture()
    async def device(self, final_future, make_device):
        device = make_device()
        async with device.session(final_future):
            yield device

    @pytest.fixture()
    async def sender(self, final_future, device):
        configuration = {"final_future": final_future, "protocol_register": protocol_register}
        async with MemoryTarget.create(configuration, {"devices": [device]}).session() as sender:
            yield sender

    async it "can send and receive messages using memory target", sender, device:
        pkts = await sender(DeviceMessages.SetPower(level=65535), device.serial)
        assert len(pkts) == 1
        pkt = pkts[0]
        assert pkt | DeviceMessages.StatePower
        assert pkt.level == 0

        pkts = await sender(DeviceMessages.GetPower(), device.serial)
        assert len(pkts) == 1
        pkt = pkts[0]
        assert pkt | DeviceMessages.StatePower
        assert pkt.level == 65535

        pkts = await sender(DeviceMessages.SetPower(level=0, res_required=False), device.serial)
        assert len(pkts) == 0

        pkts = await sender(DeviceMessages.GetPower(), device.serial)
Пример #17
0
        assert not e.handled
        assert e.replies == [reply1, reply2]

        e.add_replies([reply3, reply4])
        assert not e.handled
        assert e.replies == [reply1, reply2, reply3, reply4]

        e.add_replies(reply5)
        assert not e.handled
        assert e.replies == [reply1, reply2, reply3, reply4, reply5]

    it "modifies args and kwargs for console output", EKLS, device, io:
        e = EKLS(
            device,
            io,
            pkt=DeviceMessages.SetPower(source=2, sequence=1, target=None, level=65535),
            bts="aa",
            addr=("somewhere", "nice"),
        )
        assertConsoleOutput(
            e,
            "2021-05-16 11:00:01.650000+1000 -> d073d5001337(LCM2_A19:2,80) INCOMING",
            f"  || packet = SetPower(ack=True,res=True,source={e.pkt.source},sequence=1,target=000000000000)",
            "  ^^   level: 65535",
            "  :: bts = 'aa'",
            "  :: io = 'TEST_IO'",
            "  :: addr = ('somewhere', 'nice')",
        )

        e = EKLS(
            device,
Пример #18
0
async def doit(collector):
    lan_target = collector.resolve_target("lan")
    color_msg = ColourParser.msg("blue")
    on_msg = DeviceMessages.SetPower(level=65535)
    await lan_target.send([color_msg, on_msg], FoundSerials())
Пример #19
0
from photons_colour import Parser

import asyncio

collector = library_setup()

lan_target = collector.configuration['target_register'].resolve("lan")

color_names = [
    "blue", "red", "orange", "yellow", "cyan", "green", "blue", "purple",
    "pink"
]

spread = 2

power_on = DeviceMessages.SetPower(level=65535)
get_color = LightMessages.GetColor()
color_msgs = [
    Parser.color_to_msg(name,
                        overrides={
                            "res_required": False,
                            "duration": spread
                        }) for name in color_names
]


async def doit():
    async with lan_target.session() as afr:
        # By using a pipeline we can introduce a wait time between successful sending of colors
        colors = Pipeline(*color_msgs, spread=spread, synchronized=True)
Пример #20
0
        )
        await runner.sender(msg, runner.serials)

        assert len(runner.devices) > 0

        for device in runner.devices:
            if device not in expected:
                assert False, f"No expectation for {device.serial}"

            device.compare_received(expected[device])

    async it "returns an empty list if no power or color options":
        assert Transformer.using({}) == []

    async it "Uses SetPower if no duration", runner:
        msg = DeviceMessages.SetPower(level=0, res_required=False)
        expected = {device: [msg] for device in runner.devices}
        await self.transform(runner, {"power": "off"}, expected=expected)

        await runner.reset_devices()
        msg = DeviceMessages.SetPower(level=65535, res_required=False)
        expected = {device: [msg] for device in runner.devices}
        await self.transform(runner, {"power": "on"}, expected=expected)

    async it "uses SetLightPower if we have duration", runner:
        msg = LightMessages.SetLightPower(level=0, duration=100, res_required=False)
        expected = {device: [msg] for device in runner.devices}
        await self.transform(runner, {"power": "off", "duration": 100}, expected=expected)

        await runner.reset_devices()
        msg = LightMessages.SetLightPower(level=65535, duration=20, res_required=False)
Пример #21
0
        wait = hp.create_future()

        async def see_request(event):
            if event | DeviceMessages.SetPower:
                called.append(event.pkt.serial)
                if len(called) == 3 and not wait.done():
                    wait.set_result(True)
                    await asyncio.sleep(0)
                await wait

        isr1 = light1.io["MEMORY"].packet_filter.intercept_see_request(see_request)
        isr2 = light2.io["MEMORY"].packet_filter.intercept_see_request(see_request)
        isr3 = light3.io["MEMORY"].packet_filter.intercept_see_request(see_request)

        msgs = [
            DeviceMessages.SetPower(level=0),
            LightMessages.SetColor(hue=0, saturation=0, brightness=1, kelvin=4500),
        ]

        got = defaultdict(list)

        with isr1, isr2, isr3:
            async for pkt in sender(msgs, reference):
                print(pkt.serial, type(pkt.payload))
                got[pkt.serial].append(pkt)

        assert all(serial in got for serial in devices.serials), got

        for serial, pkts in got.items():
            print(f"GOT: {serial}")
            for p in pkts:
Пример #22
0
 async def gen(reference, sender, **kwargs):
     with alter_called(("secondary", i)):
         async with hp.tick(0.1) as ticks:
             async for _ in ticks:
                 called.append(("secondary", i))
                 yield DeviceMessages.SetPower(level=0)
Пример #23
0
            )
            await device.assertResponse(
                DeviceMessages.SetLabel(label="sam"),
                [DeviceMessages.StateLabel(label="sam")],
                label="sam",
            )
            await device.assertResponse(
                DeviceMessages.GetLabel(), [DeviceMessages.StateLabel(label="sam")], label="sam"
            )

        async it "responds to power messages", device:
            await device.assertResponse(
                DeviceMessages.GetPower(), [DeviceMessages.StatePower(level=0)]
            )
            await device.assertResponse(
                DeviceMessages.SetPower(level=200), [DeviceMessages.StatePower(level=0)], power=200
            )
            await device.assertResponse(
                DeviceMessages.GetPower(), [DeviceMessages.StatePower(level=200)], power=200
            )

        async it "responds to light power messages", device:
            await device.assertResponse(
                DeviceMessages.GetPower(), [DeviceMessages.StatePower(level=0)]
            )
            await device.assertResponse(
                LightMessages.SetLightPower(level=200),
                [LightMessages.StateLightPower(level=0)],
                power=200,
            )
            await device.assertResponse(