142 lines
4.7 KiB
Python
Raw Normal View History

from StreamDock.FeatrueOption import device_type
from .StreamDock import StreamDock
from ..InputTypes import InputEvent, ButtonKey, EventType, KnobId, Direction
from PIL import Image
import os
import io
from ..ImageHelpers.PILHelper import *
class StreamDockN3(StreamDock):
"""StreamDockN3 device class (N3V25 variant) - 6 LCD keys + 3 bottom buttons + 3 knobs"""
KEY_COUNT = 18
KEY_MAP = False
_IMAGE_KEY_MAP = {
ButtonKey.KEY_1: 1,
ButtonKey.KEY_2: 2,
ButtonKey.KEY_3: 3,
ButtonKey.KEY_4: 4,
ButtonKey.KEY_5: 5,
ButtonKey.KEY_6: 6,
ButtonKey.KEY_7: 0x25,
ButtonKey.KEY_8: 0x30,
ButtonKey.KEY_9: 0x31,
}
_HW_TO_LOGICAL_KEY = {v: k for k, v in _IMAGE_KEY_MAP.items()}
def __init__(self, transport1, devInfo):
super().__init__(transport1, devInfo)
def get_image_key(self, logical_key: ButtonKey) -> int:
if logical_key in self._IMAGE_KEY_MAP:
return self._IMAGE_KEY_MAP[logical_key]
raise ValueError(f"StreamDockN3: Unsupported key {logical_key}")
def decode_input_event(self, hardware_code: int, state: int) -> InputEvent:
normalized_state = 1 if state == 0x01 else 0
if hardware_code in self._HW_TO_LOGICAL_KEY:
return InputEvent(
event_type=EventType.BUTTON,
key=self._HW_TO_LOGICAL_KEY[hardware_code],
state=normalized_state,
)
knob_rotate_map = {
0x90: (KnobId.KNOB_1, Direction.LEFT),
0x91: (KnobId.KNOB_1, Direction.RIGHT),
0x60: (KnobId.KNOB_2, Direction.LEFT),
0x61: (KnobId.KNOB_2, Direction.RIGHT),
0x50: (KnobId.KNOB_3, Direction.LEFT),
0x51: (KnobId.KNOB_3, Direction.RIGHT),
}
if hardware_code in knob_rotate_map:
knob_id, direction = knob_rotate_map[hardware_code]
return InputEvent(
event_type=EventType.KNOB_ROTATE, knob_id=knob_id, direction=direction
)
knob_press_map = {
0x33: KnobId.KNOB_1,
0x34: KnobId.KNOB_2,
0x35: KnobId.KNOB_3,
}
if hardware_code in knob_press_map:
return InputEvent(
event_type=EventType.KNOB_PRESS,
knob_id=knob_press_map[hardware_code],
state=normalized_state,
)
return InputEvent(event_type=EventType.UNKNOWN)
def set_brightness(self, percent):
return self.transport.set_key_brightness(percent)
def set_touchscreen_image(self, path):
try:
if not os.path.exists(path):
print(f"Error: The image file '{path}' does not exist.")
return -1
image = Image.open(path)
image = to_native_touchscreen_format(self, image)
buf = io.BytesIO()
image.save(buf, format="JPEG", quality=85)
jpeg_data = buf.getvalue()
res = self.transport.set_background_image_stream(jpeg_data)
return res
except Exception as e:
print(f"Error: {e}")
return -1
def set_key_image(self, key, path):
try:
if isinstance(key, int):
if key not in range(1, 19):
print(f"key '{key}' out of range. you should set (1 ~ 18)")
return -1
logical_key = ButtonKey(key)
else:
logical_key = key
if not os.path.exists(path):
print(f"Error: The image file '{path}' does not exist.")
return -1
hardware_key = self.get_image_key(logical_key)
if hardware_key > 6:
return -1
image = Image.open(path)
image = to_native_key_format(self, image)
buf = io.BytesIO()
image.save(buf, format="JPEG", quality=90)
jpeg_data = buf.getvalue()
res = self.transport.set_key_image_stream(jpeg_data, hardware_key)
return res
except Exception as e:
print(f"Error: {e}")
return -1
def get_serial_number(self):
return self.serial_number
def key_image_format(self):
return {
"size": (64, 64),
"format": "JPEG",
"rotation": -90,
"flip": (False, False),
}
def touchscreen_image_format(self):
return {
"size": (320, 240),
"format": "JPEG",
"rotation": -90,
"flip": (False, False),
}
def set_device(self):
self.transport.set_report_size(513, 1025, 0)
self.feature_option.deviceType = device_type.dock_n3