示例#1
0
 async def process_outgoing_light1(reply, req_event, Cont):
     if req_event | TileMessages.GetTileEffect:
         yield TileMessages.StateTileEffect.create(
             type=TileEffectType.FLAME,
             speed=10,
             duration=1,
             palette_count=2,
             palette=[hp.Color(120, 1, 1, 3500), hp.Color(360, 1, 1, 3500)],
             **reply,
         )
     else:
         raise Cont()
示例#2
0
 async def process_outgoing(reply, req_event, Cont):
     if req_event | MultiZoneMessages.GetColorZones:
         yield MultiZoneMessages.StateMultiZone.create(
             zones_count=22,
             zone_index=0,
             colors=[hp.Color(i, 1, 1, 3500) for i in range(8)],
             **reply,
         )
         yield MultiZoneMessages.StateMultiZone.create(
             zones_count=22,
             zone_index=8,
             colors=[hp.Color(i, 1, 1, 3500) for i in range(8, 16)],
         )
     else:
         raise Cont()
示例#3
0
    async def __call__(self, event, options):
        palette_count = options.palette_count
        if not options.palette and not options.palette_count:
            palette_count = 0
        elif not options.palette_count:
            palette_count = len(options.palette)

        if event.zerod:
            palette = [hp.Color(0, 0, 0, 0) for _ in range(palette_count)]

        else:
            palette = [p.clone() for p in options.palette]
            while len(palette) < palette_count:
                palette.append(hp.Color(0, 0, 0, 0))

            palette = palette[:palette_count]

        yield event.device.attrs.attrs_path("palette").changer_to(palette)
示例#4
0
    def normalise(self, meta, val):
        if val is sb.NotSpecified:
            return hp.Color(0, 0, 1, 3500)

        keys = ("hue", "saturation", "brightness", "kelvin")

        if isinstance(val, (list, tuple)):
            while len(val) < 4:
                val = (*val, 0)
        elif isinstance(val, dict):
            for k in keys:
                if k not in val:
                    val = {**val, k: 0}
            val = tuple(val[k] for k in keys)
        elif any(hasattr(val, k) for k in keys):
            val = tuple(getattr(val, k, 0) for k in keys)
        else:
            raise BadSpecValue("Unknown value for color", got=val, meta=meta)

        return hp.Color(*val[:4])
示例#5
0
    async def __call__(self, event, options):
        zones_count = options.zones_count
        if not options.zones and not options.zones_count:
            zones_count = 16
        elif not options.zones_count:
            zones_count = len(options.zones)

        if zones_count > 82:
            zones_count = 82
        if zones_count < 0:
            zones_count = 0

        if event.zerod:
            zones = [hp.Color(0, 1, 1, 3500) for _ in range(zones_count)]

        else:
            zones = [c.clone() for c in options.zones]
            while len(zones) < zones_count:
                zones.append(hp.Color(0, 0, 1, 3500))

            zones = zones[:zones_count]

        yield event.device.attrs.attrs_path("zones").changer_to(zones)
示例#6
0
    async def __call__(self, event, options):
        chain_length = options.chain_length
        if not options.chain and not options.chain_length:
            chain_length = 5
        elif not options.chain_length:
            chain_length = len(options.chain)

        spec = TileChild.FieldSpec()

        if event.zerod:
            chain = [spec.empty_normalise() for _ in range(chain_length)]

        else:
            chain = [ch.clone() for ch in options.chain]
            while len(chain) < chain_length:
                chain.append(spec.empty_normalise())

            chain = chain[:chain_length]

        for ch in chain:
            ch.firmware_build = event.device.firmware.build
            ch.firmware_version_minor = event.device.firmware.minor
            ch.firmware_version_major = event.device.firmware.major

            if "candle" in event.device.cap.product.name.lower():
                ch.width = 5
                ch.height = 6
            else:
                ch.width = 8
                ch.height = 8

            ch.device_version_vendor = event.device.cap.product.vendor.vid
            ch.device_version_product = event.device.cap.product.pid

            while len(ch.colors) < ch.height * ch.width:
                ch.colors.append(hp.Color(0, 1, 1, 3500))

        yield event.device.attrs.attrs_path("chain").changer_to(chain)
示例#7
0
    async def respond(self, event):
        if event | Events.SET_ZONES:
            changes = []
            for index, color in event.zones:
                if index >= len(self.device.attrs.zones):
                    continue
                changes.append(
                    self.device.attrs.attrs_path("zones",
                                                 index).changer_to(color))
            await self.device.attrs.attrs_apply(*changes, event=event)

        elif event | MultiZoneMessages.GetMultiZoneEffect:
            event.add_replies(
                self.state_for(MultiZoneMessages.StateMultiZoneEffect))

        elif event | MultiZoneMessages.GetColorZones:
            getter = self.state_for(GetZonesCallable())
            for state in getter(event.pkt.start_index, event.pkt.end_index):
                event.add_replies(state)

        elif event | MultiZoneMessages.SetMultiZoneEffect:
            state = self.state_for(MultiZoneMessages.StateMultiZoneEffect)
            await self.change_one("zones_effect", event.pkt.type, event=event)
            event.add_replies(state)

        elif event | MultiZoneMessages.SetColorZones:
            getter = self.state_for(GetZonesCallable())
            state = getter(event.pkt.start_index, event.pkt.end_index)
            event.add_replies(*state)

            zones = []
            color = hp.Color(event.pkt.hue, event.pkt.saturation,
                             event.pkt.brightness, event.pkt.kelvin)
            for i in range(event.pkt.start_index, event.pkt.end_index + 1):
                zones.append((i, color))
            await self.respond(Events.SET_ZONES(self.device, zones=zones))
示例#8
0
        s.equal = None

    def __eq__(s, other):
        print(f"Item {s.index}")
        pytest.helpers.assertPayloadsEquals(other, s.item, allow_missing=True)
        s.equal = other
        return True

    def __repr__(s):
        if s.equal:
            return repr(s.equal)
        else:
            return f"<DIFFERENT: {repr(s.item)}>"


zones1 = [hp.Color(i, 1, 1, 3500) for i in range(30)]
zones2 = [hp.Color(60 - i, 1, 1, 6500) for i in range(20)]
zones3 = [hp.Color(90 - i, 1, 1, 9000) for i in range(40)]

devices = pytest.helpers.mimic()

light1 = devices.add("light1")(
    next(devices.serial_seq),
    Products.LCM3_TILE,
    hp.Firmware(3, 50),
    value_store=dict(
        power=0,
        label="bob",
        infrared=100,
        color=hp.Color(100, 0.5, 0.5, 4500),
    ),
示例#9
0
from photons_messages import DeviceMessages, LightMessages, DiscoveryMessages

from photons_products import Products

import pytest

devices = pytest.helpers.mimic()

light1 = devices.add("light1")(
    "d073d5000001",
    Products.LCM3_A19_CLEAN,
    hp.Firmware(3, 70),
    value_store=dict(
        power=0,
        color=hp.Color(0, 1, 0.3, 2500),
    ),
)

light2 = devices.add("light2")(
    "d073d5000002",
    Products.LCM3_A19_CLEAN,
    hp.Firmware(3, 70),
    value_store=dict(
        power=65535,
        indication=True,
        color=hp.Color(100, 1, 0.5, 2500),
    ),
)

light3 = devices.add("light3")(
示例#10
0
        it "supports colors by name":
            for name in ColourParser.named_colors:
                self.assertCorrect(name, *ColourParser.named_colors[name])

        it "supports stacking":
            self.assertCorrect("hsb:240,0.1,0.8 kelvin:2500", 240, 0, 0.8, 2500)
            self.assertCorrect("#010101 hue:240 kelvin:2500", 240, 0, 0.00392156862745098, 2500)
            self.assertCorrect("blue kelvin:3500 saturation:0.4", 250, 0.4, None, 3500)

    describe "color_to_msg":
        it "creates a SetWaveformOptional":
            h, s, b, k = 240, 0.1, None, 2500
            hsbk = mock.Mock(name="hsbk", return_value=(h, s, b, k))
            components = mock.Mock(name="components")

            c = hp.Color(h, s, 0, k)

            with mock.patch.object(ColourParser, "hsbk", hsbk):
                msg = ColourParser.msg(components)
                assert msg | LightMessages.SetWaveformOptional
                pytest.helpers.assertPayloadsEquals(
                    msg.payload,
                    {
                        "transient": 0,
                        "hue": c.hue,
                        "saturation": c.saturation,
                        "brightness": c.brightness,
                        "kelvin": c.kelvin,
                        "period": 0.0,
                        "cycles": 1.0,
                        "skew_ratio": 0.0,
示例#11
0
        assert thing.blah is blah
        assert called == [1]

        assert thing._blah == blah
        assert thing.blah is blah
        assert called == [1]

        del thing.blah
        assert not hasattr(thing, "_blah")

        assert thing.blah is blah
        assert called == [1, 1]

describe "Color":
    it "can be made and cloned":
        c1 = hp.Color(2, 0, 0.3, 3500)
        c2 = c1.clone()

        assert c1 is not c2

        for c in (c1, c2):
            assert c.hue == 2
            assert c["hue"] == 2

            assert c.saturation == 0
            assert c["saturation"] == 0

            assert c.brightness == 0.3
            assert c["brightness"] == 0.3

            assert c.kelvin == 3500
示例#12
0
        )

    async it "responds to tile effect messages", device, assertResponse:
        await assertResponse(
            TileMessages.GetTileEffect(),
            [
                TileMessages.StateTileEffect.create(
                    type=TileEffectType.OFF, speed=0.005, palette_count=0, parameters={}
                )
            ],
        )
        await assertResponse(
            TileMessages.SetTileEffect(
                type=TileEffectType.FLAME,
                palette_count=1,
                palette=[hp.Color(1, 0, 1, 3500)],
            ),
            [
                TileMessages.StateTileEffect.create(
                    type=TileEffectType.OFF, speed=0.005, palette_count=0, parameters={}, palette=[]
                )
            ],
            matrix_effect=TileEffectType.FLAME,
        )
        await assertResponse(
            TileMessages.GetTileEffect(),
            [
                TileMessages.StateTileEffect.create(
                    type=TileEffectType.FLAME,
                    palette_count=1,
                    speed=0.005,
示例#13
0
group_two_label = "Bathroom"
group_two_uuid = identifier()

group_three_label = "desk"
group_three_uuid = identifier()

location_one_label = "Home"
location_one_uuid = identifier()

location_two_label = "Work"
location_two_uuid = identifier()

zones = []
for i in range(16):
    zones.append(hp.Color(i * 10, 1, 1, 2500))

ds.add("a19_1")(
    next(ds.serial_seq),
    Products.LCM2_A19,
    hp.Firmware(2, 75),
    value_store=dict(
        label="kitchen",
        power=0,
        group={
            "label": group_one_label,
            "identity": group_one_uuid
        },
        location={
            "label": location_one_label,
            "identity": location_one_uuid
示例#14
0
from photons_messages import (
    DeviceMessages,
    LightMessages,
    MultiZoneMessages,
    MultiZoneEffectType,
    DiscoveryMessages,
)
from photons_products.lifx import Capability
from photons_products import Products

from delfick_project.errors_pytest import assertRaises
import pytest


zeroColor = hp.Color(0, 0, 0, 3500)
zones1 = [hp.Color(i, 1, 1, 3500) for i in range(30)]
zones2 = [hp.Color(90 - i, 1, 1, 3500) for i in range(6)]
zones3 = [hp.Color(300 - i, 1, 1, 3500) for i in range(16)]

devices = pytest.helpers.mimic()

light1 = devices.add("light1")(
    "d073d5000001",
    Products.LCM3_TILE,
    hp.Firmware(3, 50),
    value_store=dict(
        power=0,
        label="bob",
        infrared=100,
        color=hp.Color(100, 0.5, 0.5, 4500),
示例#15
0
    async def respond(self, event):
        if event | TileMessages.GetTileEffect:
            event.add_replies(self.state_for(TileMessages.StateTileEffect))

        elif event | TileMessages.SetTileEffect:
            state = self.state_for(TileMessages.StateTileEffect)
            state.instanceid = event.pkt.instanceid
            event.add_replies(state)

            palette_count = max(
                [len(self.device.attrs.palette),
                 len(event.pkt.palette)])

            changes = []
            for i, palette in enumerate(self.device.attrs.palette):
                if i >= palette_count:
                    changes.append(
                        self.device.attrs.attrs_path("palette", i).changer_to(
                            hp.Color(0, 0, 0, 0)))
                else:
                    if self.device.attrs.palette[i] != event.pkt.palette[i]:
                        changes.append(
                            self.device.attrs.attrs_path(
                                "palette", i).changer_to(event.pkt.palette[i]))

            for i in range(palette_count):
                if i >= len(self.device.attrs.palette):
                    changes.append(
                        self.device.attrs.attrs_path("palette", i).changer_to(
                            event.pkt.palette[i]))

            if event.pkt.palette_count > len(self.device.attrs.palette):
                changes.append(
                    self.device.attrs.attrs_path("palette").reduce_length_to(
                        event.pkt.palette_count))

            changes.append(
                self.device.attrs.attrs_path("matrix_effect").changer_to(
                    event.pkt.type))
            await self.device.attrs.attrs_apply(*changes, event=event)

        elif event | TileMessages.GetDeviceChain:
            event.add_replies(self.state_for(TileMessages.StateDeviceChain))

        elif event | TileMessages.Get64:
            state = []
            res = {
                ch.tile_index: ch
                for ch in self.state_for(TileMessages.State64,
                                         expect_one=False)
            }
            for i in range(event.pkt.tile_index,
                           event.pkt.tile_index + event.pkt.length):
                if i in res:
                    state.append(res[i])
            event.add_replies(*state)

        if event | TileMessages.SetUserPosition:
            if event.pkt.tile_index < len(self.device.attrs.chain):
                await self.device.change(
                    (("chain", event.pkt.tile_index, "user_x"),
                     event.pkt.user_x),
                    (("chain", event.pkt.tile_index, "user_y"),
                     event.pkt.user_y),
                    event=event,
                )
            event.set_replies()

        elif event | TileMessages.Set64:

            state = []
            res = {
                ch.tile_index: ch
                for ch in self.state_for(TileMessages.State64,
                                         expect_one=False)
            }
            for i in range(event.pkt.tile_index,
                           event.pkt.tile_index + event.pkt.length):
                if i in res:
                    state.append(res[i])
            event.add_replies(*state)

            for i in range(event.pkt.tile_index,
                           event.pkt.tile_index + event.pkt.length):
                if i < len(self.device.attrs.chain):
                    # For efficiency, not gonna make events for this
                    chain = self.device.attrs.chain[i]
                    chain.colors.clear()
                    chain.colors.extend([
                        hp.Color(c.hue, c.saturation, c.brightness, c.kelvin)
                        for c in event.pkt.colors
                    ])
示例#16
0
class LightState(Operator):
    class Options(dictobj.Spec):
        color = dictobj.Field(color_spec)

    @classmethod
    def select(kls, device):
        if not kls.only_io_and_viewer_operators(
                device.value_store) and device.cap.is_light:
            return kls(device, device.value_store)

    attrs = [
        Operator.Attr.Lambda(
            "color",
            from_zero=lambda event, options: hp.Color(0, 1, 1, 3500),
            from_options=lambda event, options: options.color,
        )
    ]

    async def respond(self, event):
        if event | LightMessages.GetColor:
            event.add_replies(self.state_for(LightMessages.LightState))

        elif event | LightMessages.GetLightPower:
            event.add_replies(self.state_for(DeviceMessages.StatePower))

        elif event | LightMessages.SetLightPower:
            event.add_replies(self.state_for(LightMessages.StateLightPower))
            await self.change_one("power", event.pkt.level, event=event)

        elif event | LightMessages.SetColor or event | LightMessages.SetWaveform:
            event.add_replies(self.state_for(LightMessages.LightState))
            await self.change(
                (("color", "hue"), event.pkt.hue),
                (("color", "saturation"), event.pkt.saturation),
                (("color", "brightness"), event.pkt.brightness),
                (("color", "kelvin"), event.pkt.kelvin),
                event=event,
            )
        elif event | LightMessages.SetWaveformOptional:
            event.add_replies(self.state_for(LightMessages.LightState))

            changes = []

            for k in ("hue", "saturation", "brightness", "kelvin"):
                if getattr(event.pkt, f"set_{k}"):
                    changes.append(
                        self.device.attrs.attrs_path("color", k).changer_to(
                            event.pkt[k]))

            if changes:
                await self.device.attrs.attrs_apply(*changes, event=event)

    def make_state_for(self, kls, result):
        if kls | LightMessages.StateLightPower:
            result.append(kls(level=self.device.attrs.power))

        elif kls | LightMessages.LightState:
            result.append(
                kls(
                    label=self.device.attrs.label,
                    power=self.device.attrs.power,
                    **self.device.attrs.color.as_dict(),
                ))
from photons_products import Products

import pytest

devices = pytest.helpers.mimic()


devices.add("striplcm1")(
    "d073d5000003",
    Products.LCM1_Z,
    hp.Firmware(1, 22),
    value_store=dict(
        power=0,
        label="lcm1-no-extended",
        zones=[hp.Color(0, 0, 0, 0)] * 16,
    ),
)

devices.add("striplcm2noextended")(
    "d073d5000004",
    Products.LCM2_Z,
    hp.Firmware(2, 70),
    value_store=dict(
        power=0,
        label="lcm2-no-extended",
        zones=[hp.Color(0, 0, 0, 0)] * 16,
    ),
)

devices.add("striplcm2extended")(
示例#18
0
def convert(c):
    return hp.Color(c["hue"], c["saturation"], c["brightness"], c["kelvin"]).as_dict()
示例#19
0
 def device(self):
     device = devices["a19"]
     devices.store(device).assertAttrs(label="", power=0, color=hp.Color(0, 0, 1, 3500))
     return device
示例#20
0
 def hsbk(*args, **kwargs):
     h, s, b, k = ColourParser.hsbk(*args, **kwargs)
     return hp.Color(h, s, b, k)
示例#21
0
from photons_canvas.theme import ApplyTheme

from photons_app.special import FoundSerials
from photons_app import helpers as hp

from photons_products import Products

import pytest

devices = pytest.helpers.mimic()

devices.add("bulb")(
    "d073d5000002",
    Products.LMB_MESH_A21,
    hp.Firmware(2, 2),
    value_store=dict(power=0, label="sam", infrared=0, color=hp.Color(0, 0, 0, 0)),
)

devices.add("tile")(
    "d073d5000001",
    Products.LCM3_TILE,
    hp.Firmware(3, 50),
    value_store=dict(
        power=0,
        label="bob",
        infrared=100,
        color=hp.Color(100, 0.5, 0.5, 4500),
    ),
)

devices.add("striplcm1")(
示例#22
0
from contextlib import contextmanager
from collections import defaultdict
from functools import partial
import asyncio
import pytest
import time
import sys

devices = pytest.helpers.mimic()


light1 = devices.add("light1")(
    "d073d5000001",
    Products.LCM2_A19,
    hp.Firmware(2, 80),
    value_store=dict(power=0, color=hp.Color(0, 1, 0.3, 2500)),
)

light2 = devices.add("light2")(
    "d073d5000002",
    Products.LCM2_A19,
    hp.Firmware(2, 80),
    value_store=dict(power=65535, color=hp.Color(100, 1, 0.5, 2500)),
)

light3 = devices.add("light3")(
    "d073d5000003",
    Products.LCM2_A19,
    hp.Firmware(2, 80),
    value_store=dict(color=hp.Color(100, 1, 0.5, 2500)),
)
示例#23
0
            assert devices.store(device) == [
                devices.Events.INCOMING(device, device.io["MEMORY"], pkt=original),
                devices.Events.OUTGOING(
                    device,
                    device.io["MEMORY"],
                    pkt=CoreMessages.Acknowledgement,
                    replying_to=original,
                ),
                devices.Events.OUTGOING(
                    device, device.io["MEMORY"], pkt=expected, replying_to=original
                ),
            ]

        async it "can get multiple replies", send_single, device:
            await device.event(
                devices.Events.SET_ZONES, zones=[(i, hp.Color(i, 1, 1, 3500)) for i in range(22)]
            )
            devices.store(device).clear()

            original = MultiZoneMessages.GetColorZones(start_index=0, end_index=255)
            expected = [
                (
                    MultiZoneMessages.StateMultiZone,
                    {
                        "zones_count": 22,
                        "zone_index": 0,
                        "colors": [hp.Color(i, 1, 1, 3500) for i in range(8)],
                    },
                ),
                (
                    MultiZoneMessages.StateMultiZone,