import asyncio import struct from typing_extensions import Self from greendeck.lib.elgato.streamdeck import StreamDeck from greendeck.lib.hidapi.library import HIDAPIError from greendeck.lib.util import task_done_callback class StreamDeckGen2Base(StreamDeck): MAX_PACKET_SIZE: int = 1024 async def _read(self: Self) -> None: try: while self.run_read_task: data = await self.device.read(64) if data is None: continue match data[0]: case 0x01: key_count = data[2] states = [bool(s) for s in data[4 : 4 + key_count]] t = asyncio.create_task(self.handleKeyReport(states)) t.add_done_callback(task_done_callback) case 0x02: # lcd input # position1 = struct.unpack(" None: async with self.mutex: payload = struct.pack(f" None: async with self.mutex: payload = struct.pack(" str: """ Gets the serial number of the attached StreamDeck. :rtype: str :return: String containing the serial number of the attached device. """ if self._serial_number is not None: return self._serial_number async with self.mutex: if self._serial_number is None: data = await self.device.read_feature(0x06, 32) self._serial_number = self._extract_string(data[2:]) return self._serial_number async def get_firmware_version(self) -> str: """ Gets the firmware version of the attached StreamDeck. :rtype: str :return: String containing the firmware version of the attached device. """ if self._firmware_version is not None: return self._firmware_version async with self.mutex: if self._firmware_version is None: data = await self.device.read_feature(0x05, 32) self._firmware_version = self._extract_string(data[6:]) return self._firmware_version async def set_key_image(self, key: int, image: bytes | None) -> None: """ Sets the image of a button on the StreamDeck to the given image. The image being set should be in the correct format for the device, as an enumerable collection of bytes. .. seealso:: See :func:`~StreamDeck.get_key_image_format` method for information on the image format accepted by the device. :param int key: Index of the button whose image is to be updated. :param enumerable image: Raw data of the image to set on the button. If `None`, the key will be cleared to a black color. """ IMAGE_REPORT_HEADER_LENGTH = struct.calcsize(" 0: page_length = min(bytes_remaining, IMAGE_REPORT_PAYLOAD_LENGTH) bytes_sent = page_number * IMAGE_REPORT_PAYLOAD_LENGTH last_page = 1 if page_length == bytes_remaining else 0 header = struct.pack( "