+ #seems like profile can be anything (just that outside of 0-4 it doesnt persist?)
+ #edit: so apparently profiles outside of 0-4 (at least up until 255) actually persists and is accessible, just that on a reboot it will assume the data doesnt exist
+ #switching to another profile and then switching back would still work
+ #aka the profile restriction only exists in set_simple_light_effect
+ # if profile not in range(5):
+ # raise TypeError('Invalid profile number!')
buf = bytearray(9)
buf[1] = 0x12
buf[3] = profile
- buf[4] = 8 #why?
+ buf[4] = 8 #why? its also always returned by get_custom_light_effect
self.compute_simple_checksum(buf)
sent = self.h.send_feature_report(buf)
if sent == -1:
raise IOError(self.h.error())
- data = pixels.to_bytes()
+ data = pixels.to_bytes(adjust)
for split in [data[i:i+64] for i in range(0, len(data), 64)]:
self.h.write(b'\0' + split)
#writing all at once would just freeze the keyboard
#self.h.write(b'\0' + b'\0'.join([data[i:i+64] for i in range(0, len(data), 64)]))
#aka LoadPictureMatrixValue
#use PictureMatrix.from_bytes to convert it back into a usable PictureMatrix
if dev['vendor_id'] == type.VID and dev['product_id'] in type.PID:
try:
obj = type(dev['path'])
#there should only be one that we can get the firmware version successfully from
obj.get_firmware_version()
return obj
except IOError:
continue
\ No newline at end of file
diff --git a/play.py b/play.py
index 92e9dcf..4c0500c 100644
--- a/play.py
+++ b/play.py
@@ -1,69 +1,130 @@
from fusion.datatypes import *
from fusion.device import get_device
from cv2.typing import MatLike
-import sys, cv2
+import sys, cv2, time, numpy, atexit
+
+#10 is actually not transient - it is persistent as a secondary profile but for our purposes we can treat it as transient
+#since nobody should have the need to write to a profile number this high (switching between profiles require os interaction anyways so might as well write a new image)
+#change to profile for the image stream first (technically only need to change if not transient and current profile is non custom, but we revert afterwards anyway)
+#to avoid any flashing set to black first (mainly when we are in simple modes which means last seen image will be shown right when set_simple_light_effect is called)
+dev.set_custom_light_effect(profile, PictureMatrix([RGB(0,0,0) for i in range(105)]))
+#need to set it to one of the "proper" profiles for it to know to update
-# mat = PictureMatrix([RGB(255, 0, 0) for i in range(105)])
-# dev.set_custom_light_effect(1, mat)
+mat = PictureMatrix([RGB(70, 255, 170) for i in range(105)]) #seems like the rgb algo in the keyboard firmware really sucks - this value seems more true white than anything (edit: it's actually known in the driver and has special cases)
+#test reset (seems like after reset if we set the light effect to custom profiles without data it would crash? not if we immediately set the profile afterwards tho)
+#also seems like if we change profiles right(? seems to last longer than 100ms for sure) after reset some data (e.g wave direction and speed) would get reset