Ejemplo n.º 1
0
class StateExtendedColorZones(packet.LifxMessage):
    registers: packet.REGISTER_T = [
        ("count", packet.LifxType.u16, 1),
        ("index", packet.LifxType.u16, 1),
        ("colors_count", packet.LifxType.u8, 1),
        ("colors", packet.Hsbk(), 82),
    ]
Ejemplo n.º 2
0
class SetTileEffect(packet.LifxMessage):
    registers: packet.REGISTER_T = [
        ("reserved_1", packet.LifxType.u8, 1),
        ("reserved_2", packet.LifxType.u8, 1),
        ("instanceid", packet.LifxType.u32, 1),
        ("type", packet.LifxType.u8, 1),
        ("speed", packet.LifxType.u32, 1),
        ("duration", packet.LifxType.u64, 1),
        ("reserved_3", packet.LifxType.u32, 1),
        ("reserved_4", packet.LifxType.u32, 1),
        ("parameters", packet.LifxType.u32, 8),
        ("palette_count", packet.LifxType.u8, 1),
        ("palette", packet.Hsbk(), 16),
    ]

    def set_value(self, name: str, value: Any):
        """The apply register must be an ApplicationRequest type"""
        if name.lower() == "type":
            if isinstance(value, str):
                value = TileEffectType[value].value
            elif isinstance(value, TileEffectType):
                value = value.value
            elif isinstance(value, int):
                if value not in [ar.value for ar in TileEffectType]:
                    raise ValueError(f"Invalid TileType: {value}")
        super().set_value(name, value)
Ejemplo n.º 3
0
class State(packet.LifxMessage):
    registers: packet.REGISTER_T = [
        ("color", packet.Hsbk(), 1),
        ("reserved_1", packet.LifxType.s16, 1),
        ("power", packet.LifxType.u16, 1),
        ("label", packet.LifxType.char, 32),
        ("reserved_2", packet.LifxType.u64, 1),
    ]
Ejemplo n.º 4
0
class StateTileState64(packet.LifxMessage):
    registers: packet.REGISTER_T = [
        ("tile_index", packet.LifxType.u8, 1),
        ("reserved", packet.LifxType.u8, 1),
        ("x", packet.LifxType.u8, 1),
        ("y", packet.LifxType.u8, 1),
        ("width", packet.LifxType.u8, 1),
        ("colors", packet.Hsbk(), 64),
    ]
Ejemplo n.º 5
0
 def test_state_message(self):
     """Mixture of ints and bytes"""
     hsbk = packet.Hsbk()
     hsbk["hue"] = 21845  # Green
     hsbk["saturation"] = 65535
     hsbk["brightness"] = 65535
     hsbk["kelvin"] = 3500
     state = light_messages.State(color=hsbk, label="example", power=True)
     state_bytes = state.to_bytes()
     self.assertEqual(light_messages.State.from_bytes(state_bytes), state)
Ejemplo n.º 6
0
class SetWaveform(packet.LifxMessage):
    registers: packet.REGISTER_T = [
        ("reserved", packet.LifxType.u8, 1),
        ("transient", packet.LifxType.u8, 1),
        ("color", packet.Hsbk(), 1),
        ("period", packet.LifxType.u32, 1),
        ("cycles", packet.LifxType.f32, 1),
        ("skew_ratio", packet.LifxType.s16, 1),
        ("waveform", packet.LifxType.u8, 1),
    ]
Ejemplo n.º 7
0
    def test_set_color(self):
        # Green according to the LIFX packet tutorial:
        # https://lan.developer.lifx.com/docs/building-a-lifx-packet
        hsbk = packet.Hsbk()
        hsbk["hue"] = 21845  # Green
        hsbk["saturation"] = 65535
        hsbk["brightness"] = 65535
        hsbk["kelvin"] = 3500

        hsbk_bytes = hsbk.to_bytes()
        bytes_hex = [hex(bb) for bb in hsbk_bytes]
        bytes_int = [int(bb) for bb in hsbk_bytes]
        logging.info("HSBK green:")
        logging.info(hsbk_bytes)
        logging.info(bytes_hex)
        logging.info(bytes_int)

        color = light_messages.SetColor()
        color["color"] = hsbk
        color["duration"] = 1024

        color_bytes = color.to_bytes()
        color_hex = [hex(bb) for bb in color_bytes]
        color_int = [int(bb) for bb in color_bytes]
        logging.info("SetColor payload green:")
        logging.info(color_bytes)
        logging.info(color_hex)
        logging.info(color_int)
        nominal_payload = [
            0x00,
            0x55,
            0x55,
            0xFF,
            0xFF,
            0xFF,
            0xFF,
            0xAC,
            0x0D,
            0x00,
            0x04,
            0x00,
            0x00,
        ]
        self.assertEqual(color_int, nominal_payload)

        color_from_bytes = light_messages.SetColor.from_bytes(color_bytes)
        self.assertEqual(color_from_bytes["color"]["hue"], hsbk["hue"])
        self.assertEqual(color_from_bytes["color"]["saturation"],
                         hsbk["saturation"])
        self.assertEqual(color_from_bytes["color"]["brightness"],
                         hsbk["brightness"])
        self.assertEqual(color_from_bytes["color"]["kelvin"], hsbk["kelvin"])
        self.assertEqual(color_from_bytes["duration"], color["duration"])
        self.assertEqual(color_from_bytes.type, color.type)
Ejemplo n.º 8
0
class StateTileEffect(packet.LifxMessage):
    registers: packet.REGISTER_T = [
        ("reserved_1", packet.LifxType.u8, 1),
        ("instanceid", packet.LifxType.u32, 1),
        ("type", packet.LifxType.u8, 1),
        ("speed", packet.LifxType.u32, 1),
        ("duration", packet.LifxType.u64, 1),
        ("reserved_2", packet.LifxType.u32, 1),
        ("reserved_3", packet.LifxType.u32, 1),
        ("parameters", packet.LifxType.u32, 8),
        ("palette_count", packet.LifxType.u8, 1),
        ("palette", packet.Hsbk(), 16),
    ]
Ejemplo n.º 9
0
    def to_packet(self) -> packet.Hsbk:
        """Create a message packet from an HSBK tuple"""
        hsbk = packet.Hsbk()
        max_hue = hsbk.get_max("hue") + 1
        max_saturation = hsbk.get_max("saturation")
        max_brightness = hsbk.get_max("brightness")

        hsbk["hue"] = int(self.hue * max_hue / 360) % max_hue
        hsbk["saturation"] = min(int(self.saturation * max_saturation),
                                 max_saturation)
        hsbk["brightness"] = min(int(self.brightness * max_brightness),
                                 max_brightness)
        hsbk["kelvin"] = int(self.kelvin)
        return hsbk
Ejemplo n.º 10
0
    def test_hsbk(self):
        hsbk = packet.Hsbk()
        hsbk["hue"] = 0
        hsbk["saturation"] = 65535
        hsbk["brightness"] = 65535
        hsbk["kelvin"] = 5500

        hsbk_bytes = hsbk.to_bytes()
        bytes_ints = [int(b) for b in hsbk_bytes]
        self.assertEqual(bytes_ints, [0, 0, 255, 255, 255, 255, 124, 21])

        hsbk_from_bytes = packet.Hsbk.from_bytes(hsbk_bytes)
        self.assertEqual(hsbk_from_bytes["hue"], hsbk["hue"])
        self.assertEqual(hsbk_from_bytes["saturation"], hsbk["saturation"])
        self.assertEqual(hsbk_from_bytes["brightness"], hsbk["brightness"])
        self.assertEqual(hsbk_from_bytes["kelvin"], hsbk["kelvin"])
Ejemplo n.º 11
0
 def test_set_waveform(self):
     """contains a float"""
     hsbk = packet.Hsbk()
     hsbk["hue"] = 21845  # Green
     hsbk["saturation"] = 65535
     hsbk["brightness"] = 65535
     hsbk["kelvin"] = 3500
     waveform = light_messages.SetWaveform(transient=1,
                                           color=hsbk,
                                           period=1000,
                                           cycles=3.14,
                                           skew_ratio=10)
     waveform_bytes = waveform.to_bytes()
     recovered = light_messages.SetWaveform.from_bytes(waveform_bytes)
     for (name, _, _) in waveform.registers:
         if name == "cycles":
             self.assertAlmostEqual(waveform[name], recovered[name], 3)
         else:
             self.assertEqual(waveform[name], recovered[name])
Ejemplo n.º 12
0
class SetExtendedColorZones(packet.LifxMessage):
    registers: packet.REGISTER_T = [
        ("duration", packet.LifxType.u32, 1),
        ("apply", packet.LifxType.u8, 1),
        ("index", packet.LifxType.u16, 1),
        ("colors_count", packet.LifxType.u8, 1),
        ("colors", packet.Hsbk(), 82),
    ]

    def set_value(self, name: str, value: Any, index: Optional[int] = None):
        """The apply register must be an ApplicationRequest type"""
        if name.lower() == "apply":
            if isinstance(value, str):
                value = ApplicationRequest[value].value
            elif isinstance(value, ApplicationRequest):
                value = value.value
            elif isinstance(value, int):
                if value not in [ar.value for ar in ApplicationRequest]:
                    raise ValueError(f"Invalid application request: {value}")
        super().set_value(name, value, index)
Ejemplo n.º 13
0
    def test_packet(self):
        hsbk = packet.Hsbk(hue=21845, saturation=65535, brightness=65535, kelvin=3500)
        green = light_messages.SetColor(color=hsbk, duration=1024)
        comm = packet.UdpSender(
            ip="127.0.0.1", port=56700, comm=test_utils.MockSocket(), nonblock_delay=0
        )
        packet_comm = packet.PacketComm(comm)

        payload_bytes, _ = packet_comm.get_bytes_and_source(
            payload=green,
            mac_addr="00:00:00:00:00:00",
            res_required=False,
            ack_required=False,
            sequence=0,
            source=0,
        )

        # Taken from the green light example
        lifx_ref = [
            0x31,
            0x00,
            0x00,
            0x34,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x66,
            0x00,
            0x00,
            0x00,
            0x00,
            0x55,
            0x55,
            0xFF,
            0xFF,
            0xFF,
            0xFF,
            0xAC,
            0x0D,
            0x00,
            0x04,
            0x00,
            0x00,
        ]
        payload_bytes_array = [int(bb) for bb in payload_bytes]
        self.assertEqual(payload_bytes_array, lifx_ref)

        # Test the full encode-send-receive-decode chain
        responses = packet_comm.send_recv(
            payload=green,
            mac_addr="00:00:00:00:00:00",
            res_required=True,
            ack_required=False,
            sequence=123,
            source=1234,
            verbose=True,
        )

        self.assertEqual(len(responses), 1)
        response = responses.pop()
        self.assertEqual(response.addr, ("127.0.0.1", packet.LIFX_PORT))
        self.assertEqual(response.frame["source"], 1234)
        self.assertEqual(response.frame_address["sequence"], 123)
        self.assertEqual(response.protocol_header["type"], light_messages.State.type)
        self.assertEqual(response.payload["color"], hsbk)
Ejemplo n.º 14
0
        elif self._timeout:
            raise socket.timeout
        else:
            raise BlockingIOError


if __name__ == "__main__":
    import coloredlogs
    import logging

    coloredlogs.install(level=logging.INFO)

    udp_sender = packet.UdpSender(ip="127.0.0.1", comm=MockSocket())
    packet_comm = packet.PacketComm(udp_sender, verbose=True)
    set_color = light_messages.SetColor(color=packet.Hsbk(
        hue=16384,
        saturation=65535,
        brightness=65535,
        kelvin=5500,
    ))

    logging.info(
        packet_comm.send_recv(payload=light_messages.SetPower(level=65535),
                              res_required=True))
    logging.info(packet_comm.send_recv(payload=set_color, res_required=True))
    logging.info(
        packet_comm.send_recv(payload=light_messages.SetPower(),
                              ack_required=True))
    logging.info(
        packet_comm.send_recv(payload=light_messages.Get(), res_required=True))
Ejemplo n.º 15
0
class SetColor(packet.LifxMessage):
    registers: packet.REGISTER_T = [
        ("reserved", packet.LifxType.u8, 1),
        ("color", packet.Hsbk(), 1),
        ("duration", packet.LifxType.u32, 1),
    ]