Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kraken3: Improve LCD screen setting checks #689

Merged
41 changes: 24 additions & 17 deletions liquidctl/driver/kraken3.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from winusbcdc import WinUsbPy

from liquidctl.driver.usb import PyUsbDevice, UsbHidDriver
from liquidctl.error import NotSupportedByDevice
from liquidctl.error import NotSupportedByDevice, NotSupportedByDriver
from liquidctl.util import (
LazyHexRepr,
normalize_profile,
Expand Down Expand Up @@ -248,11 +248,11 @@ def initialize(self, direct_access=False, **kwargs):
self._status = []

self._read_until({b"\x11\x01": self.parse_firm_info, b"\x21\x03": self.parse_led_info})
self._status.append(("Firmware version", f"{self.fw[0]}.{self.fw[1]}.{self.fw[2]}", ""))
return sorted(self._status)

def parse_firm_info(self, msg):
self.fw = (msg[0x11], msg[0x12], msg[0x13])
self._status.append(("Firmware version", f"{self.fw[0]}.{self.fw[1]}.{self.fw[2]}", ""))

def parse_led_info(self, msg):
channel_count = msg[14]
Expand Down Expand Up @@ -647,6 +647,15 @@ def _find_winusb_device(self, vid, pid, serial):
return True
return False

def _get_fw_version(self, clear_reports=True):
if self.fw is not None:
return # Already cached

if clear_reports:
self.device.clear_enqueued_reports()
self._write([0x10, 0x01]) # firmware info
self._read_until({b"\x11\x01": self.parse_firm_info})

def initialize(self, direct_access=False, **kwargs):
"""Initialize the device and the driver.

Expand Down Expand Up @@ -679,8 +688,8 @@ def initialize(self, direct_access=False, **kwargs):
self._status = []

# request static infos
self._write([0x10, 0x01]) # firmware info
self._read_until({b"\x11\x01": self.parse_firm_info})
self._get_fw_version(clear_reports=False)
self._status.append(("Firmware version", f"{self.fw[0]}.{self.fw[1]}.{self.fw[2]}", ""))

self._write([0x30, 0x01]) # lcd info
self._read_until({b"\x31\x01": self.parse_lcd_info})
Expand Down Expand Up @@ -772,15 +781,15 @@ def parse_lcd_info(msg):
self.orientation = msg[0x1A]

# Firmware 2.0.0 and onwards broke the implemented image setting mechanism for Kraken 2023
# (standard and elite). In those cases, show an error until issue #631 is resolved.
def unsupported_fw_version():
device_product_id = self.bulk_device.product_id
if device_product_id in (0x300C, 0x300E) and self.fw[0] == 2:
_LOGGER.error(
"setting images is not supported on firmware 2.X.Y, please see issue #631"
)
return True
return False
# (non-elite). In those cases, show an error until issue #631 is resolved.
def check_unsupported_fw_version():
device_product_id = self.device.product_id
if device_product_id == 0x300E:
self._get_fw_version()
if self.fw[0] == 2:
raise NotSupportedByDriver(
"setting images is not supported on firmware 2.X.Y, please see issue #631"
)

self._read_until({b"\x31\x01": parse_lcd_info})

Expand All @@ -797,14 +806,12 @@ def unsupported_fw_version():
self._write([0x30, 0x02, 0x01, self.brightness, 0x0, 0x0, 0x1, int(value_int / 90)])
return
elif mode == "static":
if unsupported_fw_version():
return
check_unsupported_fw_version()
data = self._prepare_static_file(value, self.orientation)
self._send_data(data, [0x02, 0x0, 0x0, 0x0] + list(len(data).to_bytes(4, "little")))
return
elif mode == "gif":
if unsupported_fw_version():
return
check_unsupported_fw_version()
data = self._prepare_gif_file(value, self.orientation)
assert (
len(data) / 1000 < _LCD_TOTAL_MEMORY
Expand Down
5 changes: 4 additions & 1 deletion liquidctl/error.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,11 @@ def __str__(self) -> str:
class NotSupportedByDriver(LiquidctlError):
"""Operation not supported by the driver."""

def __init__(self, explanation=None):
self._explanation = explanation

def __str__(self) -> str:
return "operation not supported by the driver"
return f"operation not supported by the driver{f': {self._explanation}' if self._explanation is not None else ''}"


class UnsafeFeaturesNotEnabled(LiquidctlError):
Expand Down
1 change: 1 addition & 0 deletions tests/test_kraken3.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ def __init__(
self.lcd_resolution = lcd_resolution

self.screen_mode = None
self.fw = None

def set_screen(self, channel, mode, value, **kwargs):
self.screen_mode = mode
Expand Down
Loading