commit b837813f187dfb5aa4415cebeca7cad61eb8cc35
Author: sqozz <sqozz@geekify.de>
Date:   Sat Dec 5 01:48:39 2020 +0100

    Initial commit

diff --git a/gk1100.py b/gk1100.py
new file mode 100644
index 0000000..87aa6d6
--- /dev/null
+++ b/gk1100.py
@@ -0,0 +1,76 @@
+import usb.core
+import usb.util
+from array import array
+import pdb
+
+class GK1100():
+    COMMANDS = ["", "SET_ANIMATION"]
+
+    def __init__(self):
+        self.ANIMATIONS = ["OFF", "STATIC", "CIRCLE", "CUSTOM", "COLOR_CYCLE", "AFTER_GLOW", "STARS", "ROW_ROCKET"]
+        self.COLORS = ["RED", "WHITE", "GREEN", "BLUE", "PINK", "YELLOW", "LIGHT_BLUE", "VAR"]
+        dev = usb.core.find(idVendor=0x0b05, idProduct=0x1835)
+        if dev is None:
+            raise ValueError('GK1100 keyboard not found!')
+
+        cfg = dev.get_active_configuration()
+        led_interface = cfg[(1,0)]
+        if dev.is_kernel_driver_active(1):
+            dev.detach_kernel_driver(1)
+            usb.util.claim_interface(dev, 1)
+
+        self.led_out = led_interface.endpoints()[1]
+        self.led_in = led_interface.endpoints()[0]
+
+    def set_animation(self, animation, color, speed, brightness):
+        data = array("B", [0x06, 0x0b, 0x01, self.ANIMATIONS.index(animation), brightness, speed, self.COLORS.index(color)])
+        self.led_out.write(data)
+        self.pprint_reply(self.fetch_reply())
+
+    def pprint_reply(self, data):
+        # TODO: is byte 0 alway 0x06 (magic header?)?
+        # TODO: what is byte 1?
+        # TODO: what is byte 2?
+        animation = data[3]
+        brightness = data[4]
+        speed = data[5]
+        animation_color = data[6]
+        success = data[7]
+        # TODO: byte 8 could be some kind of checksum
+        print("Animation:", animation, "->", self.ANIMATIONS[animation])
+        if animation != 2 and animation != 4 and animation != 7 and animation != 0:
+            print("Color:", animation_color, "->", self.COLORS[animation_color])
+        print("Speed:", speed)
+        print("Brightness:", brightness)
+        print("Command was successful executed:", True if success == 1 else False)
+        print("Left-over data:", data[8:])
+        print()
+        
+
+    def fetch_reply(self):
+        try:
+            data = self.led_in.read(128, timeout=None)
+            return data
+        except Exception:
+            return None
+
+#class HID_message():
+#    def __init__(self, command, payload):
+#        self.data = array("B", [0]*64)
+#        self.set_header()
+#        if command in GK1100.COMMANDS:
+#            self.data[2] = GK1100.COMMAND.index(command)
+#        else:
+#            raise ValueError("Command \"{}\" not found".format(command))
+#
+#    def set_header(self):
+#        self.data[0] = 6
+#        self.data[1] = 11
+        
+
+keyboard = GK1100()
+keyboard.set_animation("STATIC", "PINK", 0, 3)
+keyboard.set_animation("STATIC", "RED", 0, 3)
+keyboard.set_animation("STATIC", "RED", 0, 4)
+keyboard.set_animation("STATIC", "RED", 1, 3)
+pdb.set_trace()