Пример #1
0
class InfoPoints(enum.Enum):
    """
    Enum used to determine what information is required for what keys
    """

    # We need to know what kind of product the device is to get the label correctly
    VERSION = Point(DeviceMessages.GetVersion(), ["label", "product_id", "cap"], None)

    # We get Label from LIGHT_STATE for lights and from STATE_LABEL for non lights
    LIGHT_STATE = Point(
        LightMessages.GetColor(),
        ["label", "power", "hue", "saturation", "brightness", "kelvin"],
        10,
        # Non lights are unimportant enough at this time to risk sending too many messages to them
        condition=lambda device: device.product_type is not DeviceType.NON_LIGHT,
    )
    LABEL = Point(
        DeviceMessages.GetLabel(),
        ["label"],
        10,
        condition=lambda device: device.product_type is DeviceType.NON_LIGHT,
    )

    FIRMWARE = Point(DeviceMessages.GetHostFirmware(), ["firmware_version"], 300)
    GROUP = Point(DeviceMessages.GetGroup(), ["group_id", "group_name"], 60)
    LOCATION = Point(DeviceMessages.GetLocation(), ["location_id", "location_name"], 60)
Пример #2
0
async def doit(collector):
    lan_target = collector.resolve_target("lan")

    async for pkt in lan_target.send(DeviceMessages.GetVersion(),
                                     FoundSerials()):
        if pkt | DeviceMessages.StateVersion:
            product = Products[pkt.vendor, pkt.product]
            print(f"{pkt.serial}: {product.as_dict()}")
Пример #3
0
async def tile_serials_from_reference(reference, sender):
    """
    Given a reference, return all the serials that has a ``has_matrix`` capability
    """
    serials = []

    async for pkt in sender(DeviceMessages.GetVersion(), reference):
        if pkt | DeviceMessages.StateVersion:
            if Products[pkt.vendor, pkt.product].cap.has_matrix:
                serials.append(pkt.serial)

    return serials
Пример #4
0
class InfoPoints(enum.Enum):
    """
    Enum used to determine what information is required for what keys
    """
    LIGHT_STATE = Point(
        LightMessages.GetColor(),
        ["label", "power", "hue", "saturation", "brightness", "kelvin"])
    VERSION = Point(DeviceMessages.GetVersion(),
                    ["product_id", "product_identifier", "cap"])
    FIRMWARE = Point(DeviceMessages.GetHostFirmware(), ["firmware_version"])
    GROUP = Point(DeviceMessages.GetGroup(), ["group_id", "group_name"])
    LOCATION = Point(DeviceMessages.GetLocation(),
                     ["location_id", "location_name"])
Пример #5
0
async def tile_serials_from_reference(target, reference, afr):
    """
    Given a reference, return all the serials that has a ``has_chain`` capability
    """
    serials = []

    async for pkt, _, _ in target.script(DeviceMessages.GetVersion()).run_with(
            reference, afr):
        if pkt | DeviceMessages.StateVersion:
            cap = capability_for_ids(pkt.product, pkt.vendor)
            if cap.has_chain:
                serials.append(pkt.serial)

    return serials
Пример #6
0
class VersionPlan(Plan):
    """
    Return in a dictionary:

    * vendor: The vendor id of the device.
    * product: The product id of the device.
    """

    messages = [DeviceMessages.GetVersion()]

    class Instance(Plan.Instance):
        def process(self, pkt):
            if pkt | DeviceMessages.StateVersion:
                self.dct = pkt.payload.as_dict()
                return True

        async def info(self):
            return self.dct
Пример #7
0
async def do_apply_theme(target, reference, afr, options):
    aps = appliers[options.theme]

    theme = Theme()
    for color in options.colors:
        theme.add_hsbk(color.hue, color.saturation, color.brightness,
                       color.kelvin)

    tasks = []
    async for pkt, _, _ in target.script(DeviceMessages.GetVersion()).run_with(
            reference, afr):
        serial = pkt.serial
        capability = capability_for_ids(pkt.product, pkt.vendor)
        if capability.has_multizone:
            log.info(hp.lc("Found a strip", serial=serial))
            t = hp.async_as_background(
                apply_zone(aps["1d"], target, afr, pkt.serial, theme,
                           options.overrides))
        elif capability.has_chain:
            log.info(hp.lc("Found a tile", serial=serial))
            t = hp.async_as_background(
                apply_tile(aps["2d"], target, afr, pkt.serial, theme,
                           options.overrides))
        else:
            log.info(hp.lc("Found a light", serial=serial))
            t = hp.async_as_background(
                apply_light(aps["0d"], target, afr, pkt.serial, theme,
                            options.overrides))

        tasks.append((serial, t))

    results = {}

    for serial, t in tasks:
        try:
            await t
        except Exception as error:
            results[serial] = error
        else:
            results[serial] = "ok"

    return results
Пример #8
0
class CapabilityPlan(Plan):
    """
    Return capability information for this device::

        {
          "cap": <capability object with filled out firmware version>,
          "product": <product object>,
          "firmware": <object with build/version_major/version_minor attributes>,
          "state_version": <the StateVersion packet we received from the device>
        }

    The capability and product objects come from the
    :ref:`registry <products_root>`.
    """

    messages = [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()]

    class Instance(Plan.Instance):
        def process(self, pkt):
            if pkt | DeviceMessages.StateHostFirmware:
                self.firmware = FirmwareInfo(
                    build=pkt.build,
                    version_major=pkt.version_major,
                    version_minor=pkt.version_minor,
                )
            elif pkt | DeviceMessages.StateVersion:
                self.version = pkt
            return hasattr(self, "firmware") and hasattr(self, "version")

        async def info(self):
            product = Products[self.version.vendor, self.version.product]
            cap = product.cap(self.firmware.version_major, self.firmware.version_minor)
            return {
                "cap": cap,
                "product": product,
                "firmware": self.firmware,
                "state_version": DeviceMessages.StateVersion.Payload.create(
                    self.version.payload.pack()
                ),
            }
Пример #9
0
async def doit():
    async for pkt, _, _ in lan_target.script(
            DeviceMessages.GetVersion()).run_with(FoundSerials()):
        if pkt | DeviceMessages.StateVersion:
            cap = capability_for_ids(pkt.product, pkt.vendor)
            print("{}: {}".format(pkt.serial, cap))
Пример #10
0
            async for serial, cap in find_multizone(devices.serials, sender):
                assert serial not in got
                got[serial] = cap.has_extended_multizone

            assert got == {
                striplcm1.serial: False,
                striplcm2noextended.serial: False,
                striplcm2extended.serial: True,
            }

        async it "resends messages each time if we reset the gatherer", sender:
            async for serial, cap in find_multizone(devices.serials, sender):
                pass

            want = {
                device: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()]
                for device in devices
            }
            self.compare_received(want)

            del sender.gatherer
            async for serial, cap in find_multizone(devices.serials, sender):
                pass

            want = {
                device: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()]
                for device in devices
            }
            self.compare_received(want)

        async it "uses cached gatherer on the sender", sender:
Пример #11
0
            expected = {
                clean.serial: (True, {"zones": Skip}),
                switch.serial: (True, {"zones": Skip}),
                light1.serial: (True, {"zones": Skip}),
                light2.serial: (True, {"zones": Skip}),
                striplcm1.serial: (True, {"zones": [(i, c) for i, c in enumerate(zones1)]}),
                striplcm2noextended.serial: (
                    True,
                    {"zones": [(i, c) for i, c in enumerate(zones2)]},
                ),
                striplcm2extended.serial: (True, {"zones": [(i, c) for i, c in enumerate(zones3)]}),
            }
            assert got == expected

            expected = {
                clean: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()],
                switch: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()],
                light1: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()],
                light2: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()],
                striplcm1: [
                    DeviceMessages.GetHostFirmware(),
                    DeviceMessages.GetVersion(),
                    MultiZoneMessages.GetColorZones(start_index=0, end_index=255),
                ],
                striplcm2noextended: [
                    DeviceMessages.GetHostFirmware(),
                    DeviceMessages.GetVersion(),
                    MultiZoneMessages.GetColorZones(start_index=0, end_index=255),
                ],
                striplcm2extended: [
                    DeviceMessages.GetHostFirmware(),
Пример #12
0
        assert sorted(list(found)) == sorted(binascii.unhexlify(s)[:6] for s in ss)
        assert ss == sorted(V.serials)
        for device in V.devices:
            V.devices.store(device).assertIncoming(DiscoveryMessages.GetService())
            V.devices.store(device).clear()

        reference = DeviceFinder.from_kwargs(label="kitchen")
        found, ss = await reference.find(V.sender, timeout=5)
        reference.raise_on_missing(found)
        assert sorted(list(found)) == sorted(binascii.unhexlify(s)[:6] for s in ss)
        assert ss == []

        for device in V.devices:
            expected = [
                DiscoveryMessages.GetService(),
                DeviceMessages.GetVersion(),
                LightMessages.GetColor(),
            ]
            if device is V.devices["d4"]:
                expected.append(DeviceMessages.GetLabel)
            V.devices.store(device).assertIncoming(*expected)
            V.devices.store(device).clear()

        await V.d3.change_one("label", "kitchen", event=None)
        reference = DeviceFinder.from_kwargs(label="kitchen")
        found, ss = await reference.find(V.sender, timeout=5)
        reference.raise_on_missing(found)
        assert sorted(list(found)) == sorted(binascii.unhexlify(s)[:6] for s in ss)
        assert ss == [V.d3.serial]

        for device in V.devices:
        V.received(LightMessages.GetColor())
        V.assertTimes({InfoPoints.LIGHT_STATE: 1})
        V.t.add(5)

        assert not (await V.matches(Filter.from_kwargs(label="den")))
        V.received()
        V.assertTimes({InfoPoints.LIGHT_STATE: 1})
        V.t.add(2)

        assert not (await V.matches(Filter.from_kwargs(label="attic", refresh_info=True)))
        V.received(LightMessages.GetColor())
        V.assertTimes({InfoPoints.LIGHT_STATE: 8})
        V.t.add(1)

        assert not (await V.matches(Filter.from_kwargs(group_name="aa", cap=["matrix"])))
        V.received(DeviceMessages.GetVersion(), DeviceMessages.GetGroup())
        V.assertTimes({InfoPoints.LIGHT_STATE: 8, InfoPoints.GROUP: 9, InfoPoints.VERSION: 9})
        V.t.add(2)

        # It never refreshes version
        assert not (
            await V.matches(Filter.from_kwargs(group_name="aa", cap=["matrix"], refresh_info=True))
        )
        V.received(DeviceMessages.GetGroup())
        V.assertTimes({InfoPoints.LIGHT_STATE: 8, InfoPoints.GROUP: 11, InfoPoints.VERSION: 9})
        V.t.add(3)

        assert await V.matches(Filter.from_kwargs(cap=["not_matrix"], refresh_info=True))
        V.received()
        V.assertTimes({InfoPoints.LIGHT_STATE: 8, InfoPoints.GROUP: 11, InfoPoints.VERSION: 9})
Пример #14
0
        assert len(devices) > 0

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

        for device, msgs in expected.items():
            assert device in devices
            devices.store(device).assertIncoming(*msgs, ignore=[DiscoveryMessages.GetService])
            devices.store(device).clear()

    async it "sets the default config", sender:
        expected = {
            light1: [
                DeviceMessages.GetHostFirmware(),
                DeviceMessages.GetVersion(),
                LightMessages.SetHevCycleConfiguration(indication=True, duration_s=3600),
            ],
            light2: [
                DeviceMessages.GetHostFirmware(),
                DeviceMessages.GetVersion(),
                LightMessages.SetHevCycleConfiguration(indication=True, duration_s=3600),
            ],
            light3: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()],
        }
        await self.run_and_compare(
            sender, SetCleanConfig(indication=True, duration_s=3600), expected=expected
        )


describe "ChangeCleanCycle":
Пример #15
0
        async it "complains if we have more than 16 colors in the palette", runner:
            with assertRaises(PhotonsAppError, "Palette can only be up to 16 colors", got=17):
                SetTileEffect("flame", palette=["red"] * 17)

        async it "can power on devices and set tile effect", runner:
            msg = SetTileEffect("flame")
            got = await runner.sender(msg, runner.serials)
            assert got == []

            for tile in tiles:
                assert tile.attrs.matrix_effect is TileEffectType.FLAME

            self.compare_received(
                {
                    nottile: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()],
                    tile1: [
                        DeviceMessages.GetHostFirmware(),
                        DeviceMessages.GetVersion(),
                        LightMessages.SetLightPower(level=65535, duration=1),
                        TileMessages.SetTileEffect.empty_normalise(
                            type=TileEffectType.FLAME,
                            palette=default_tile_palette,
                            palette_count=len(default_tile_palette),
                        ),
                    ],
                    tile2: [
                        DeviceMessages.GetHostFirmware(),
                        DeviceMessages.GetVersion(),
                        LightMessages.SetLightPower(level=65535, duration=1),
                        TileMessages.SetTileEffect.empty_normalise(
Пример #16
0
        V.received(DeviceMessages.GetGroup())
        V.assertTimes({InfoPoints.LABEL: 8, InfoPoints.GROUP: 11, InfoPoints.VERSION: 1})
        V.t.add(3)

        assert await V.matches(Filter.from_kwargs(cap=["not_matrix"], refresh_info=True))
        V.received()
        V.assertTimes({InfoPoints.LABEL: 8, InfoPoints.GROUP: 11, InfoPoints.VERSION: 1})

    async it "can start an information loop", fake_time, sender, finder, final_future:
        V = VBase(fake_time, sender, finder, final_future)
        await V.choose_device("light")
        fake_time.set(1)

        msgs = [e.value.msg for e in list(InfoPoints) if e is not InfoPoints.LABEL]
        assert msgs == [
            DeviceMessages.GetVersion(),
            LightMessages.GetColor(),
            DeviceMessages.GetHostFirmware(),
            DeviceMessages.GetGroup(),
            DeviceMessages.GetLocation(),
        ]

        message_futs = {}

        class Futs:
            pass

        class Waiter:
            def __init__(s, name, kls):
                s.name = name
                s.kls = kls
Пример #17
0
            reference.raise_on_missing(found)
            assert sorted(list(found)) == sorted(binascii.unhexlify(s)[:6] for s in ss)
            assert ss == [V.d3.serial]

            for device in V.devices:
                device.compare_received([LightMessages.GetColor()])
                device.reset_received()

            reference = DeviceFinder.from_kwargs(cap="matrix")
            found, ss = await reference.find(runner.sender, timeout=5)
            reference.raise_on_missing(found)
            assert sorted(list(found)) == sorted(binascii.unhexlify(s)[:6] for s in ss)
            assert ss == [V.d1.serial]

            for device in V.devices:
                device.compare_received([DeviceMessages.GetVersion()])
                device.reset_received()

            reference = DeviceFinder.from_kwargs(cap=["matrix", "multizone"])
            found, ss = await reference.find(runner.sender, timeout=5)
            reference.raise_on_missing(found)
            assert sorted(list(found)) == sorted(binascii.unhexlify(s)[:6] for s in ss)
            assert ss == [V.d1.serial, V.d2.serial]

            for device in V.devices:
                device.compare_received([DeviceMessages.GetVersion()])
                device.reset_received()

            reference = DeviceFinder.from_kwargs(cap=["not_matrix"], label="kitchen")
            found, ss = await reference.find(runner.sender, timeout=5)
            reference.raise_on_missing(found)
Пример #18
0
        for device in devices:
            if device not in expected:
                assert False, f"No expectation for {device.serial}"

        for device, msgs in expected.items():
            assert device in devices
            devices.store(device).assertIncoming(*msgs, ignore=[DiscoveryMessages.GetService])
            devices.store(device).clear()

    async it "sends the messages to devices with only correct capability", sender:

        msg = ForCapability(hev=LightMessages.GetHevCycle())

        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 = {