greendeck/greendeck/lib/elgato/streamdeck/plus.py
2022-12-13 14:25:50 -06:00

74 lines
2.2 KiB
Python

import importlib.resources
import struct
from greendeck.lib.elgato.streamdeck import KeyDirection
from greendeck.lib.elgato.streamdeck import resources
from greendeck.lib.elgato.streamdeck.gen2 import StreamDeckGen2Base
class StreamDeckPlus(StreamDeckGen2Base):
"""
Represents a physically attached StreamDeck+ device.
"""
KEY_COLS = 4
KEY_ROWS = 2
KEY_PIXEL_WIDTH = 120
KEY_PIXEL_HEIGHT = 120
KEY_IMAGE_FORMAT = "JPEG"
KEY_FLIP = (True, True)
KEY_ROTATION = 0
KEY_DIRECTION = KeyDirection.LTR
ENCODER_COUNT = 4
LCD_STRIP_WIDTH = 800
LCD_STRIP_HEIGHT = 100
DECK_TYPE = "StreamDeck+"
DECK_VISUAL = True
IMAGE_REPORT_LENGTH = 1024
IMAGE_REPORT_HEADER_LENGTH = 8
BLANK_KEY_IMAGE = importlib.resources.read_binary(resources, "120x120.jpeg")
async def set_lcd_image(
self, key: int, image: bytes, x: int, y: int, width: int, height: int
) -> None:
""" """
if min(max(key, 0), self.KEY_COUNT) != key:
raise IndexError("Invalid key index {}.".format(key))
header_definition = "<BBHHHHBHHx"
PACKET_HEADER_LENGTH = struct.calcsize(header_definition)
MAX_PAYLOAD_SIZE = self.MAX_PACKET_SIZE - PACKET_HEADER_LENGTH
async with self.mutex:
page_number = 0
bytes_remaining = len(image)
while bytes_remaining > 0:
page_length = min(bytes_remaining, MAX_PAYLOAD_SIZE)
bytes_sent = page_number * MAX_PAYLOAD_SIZE
last_page = 1 if page_length == bytes_remaining else 0
header = struct.pack(
header_definition,
0x02,
0x0C,
x,
y,
width,
height,
last_page,
page_number,
page_length,
)
payload = header + image[bytes_sent : bytes_sent + page_length]
padding = b"\x00" * (self.MAX_PACKET_SIZE - len(payload))
await self.device.write(payload + padding)
bytes_remaining = bytes_remaining - page_length
page_number = page_number + 1