-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathaimo.py
159 lines (126 loc) · 4.61 KB
/
aimo.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/usr/bin/python3
# pyaimo # (2020) by ninnghazad and Metaln00b
# This sets the RGB leds of a Roccat Kone Aimo mouse.
# Supposed to be run using python 3 with pyusb module (pip install pyusb).
# Either execute as root or make sure your user has whatever permissions
# needed to control usb devices on your system.
# 1e7d:2e27 ROCCAT ROCCAT Kone Aimo
VID=0x1e7d
PID=0x2e27
# there are 11 leds, each gets three values, RGB, as float 0-1.
# the first led is the wheel, then leds are numbered anti-clockwise, the last two are the lower side ones.
# at least on my mouse the wheel led has slightly different colors than the other leds - set to white, it is slighty red
# if you hate the leds, set all colors to 0,0,0 - that will disable them.
# default colors: all bright red.
colors = [
[1,0,0], # wheel, WHEEL
[1,0,0], # left strip top, STRIP_LEFT_0
[1,0,0], # left strip below top, STRIP_LEFT_1
[1,0,0], # left strip above bottom, STRIP_LEFT_2
[1,0,0], # left strip bottom, STRIP_LEFT_3
[1,0,0], # right strip top, STRIP_RIGHT_0
[1,0,0], # right strip below top, STRIP_RIGHT_1
[1,0,0], # right strip above bottom, STRIP_RIGHT_2
[1,0,0], # right strip bottom, STRIP_RIGHT_3
[1,0,0], # left lower side, LOWER_LEFT
[1,0,0] # right lower side, LOWER_RIGHT
]
### internals
import usb.core
import usb.util
import atexit
import time
import sys
import math
import random
import codecs
RED=0
GREEN=1
BLUE=2
WHEEL=0
STRIP_LEFT_0=1
STRIP_LEFT_1=2
STRIP_LEFT_2=3
STRIP_LEFT_3=4
STRIP_RIGHT_0=5
STRIP_RIGHT_1=6
STRIP_RIGHT_2=7
STRIP_RIGHT_3=8
LOWER_LEFT=9
LOWER_RIGHT=10
def colors_to_msg(colors):
# header
msg = "0d2e";
for color in colors:
# each triplet is followed by a null byte
msg += "%02x%02x%02x00" % (color[0]*255,color[1]*255,color[2]*255)
# add padding, device expects 46 bytes.
msg = msg.ljust(46,'0')
# return as binary data
return codecs.decode(msg,"hex")
def set_colors(colors):
msg = colors_to_msg(colors)
dev.ctrl_transfer(0x21, 0x9, wValue=0x030d, wIndex=0x0, data_or_wLength=msg)
dev.ctrl_transfer(0xA1, 0x01, wValue=0x0304, wIndex=0x0, data_or_wLength=3)
def deinit():
global dev
usb.util.dispose_resources(dev)
dev.attach_kernel_driver(0)
dev.attach_kernel_driver(1)
def init():
global dev
dev = usb.core.find(idVendor=VID, idProduct=PID)
if dev is None:
raise ValueError('No ROCCAT KONE AIMO found.')
atexit.register(deinit)
dev.reset()
# free up the device from the kernal
if dev.is_kernel_driver_active(0):
dev.detach_kernel_driver(0)
if dev.is_kernel_driver_active(1):
dev.detach_kernel_driver(1)
dev.set_configuration()
try:
usb.util.claim_interface(dev, 0)
except usb.core.USBError as e:
sys.exit("Error occurred on claiming")
# ask the device something we don't actually care about. swarm does it, but i think we might not need it.
result=dev.ctrl_transfer(0xA1, 0x01, wValue=0x0304, wIndex=0x0, data_or_wLength=3)
# print("INIT:",result)
# send some magic init msg, just like swarm-software does
data = codecs.decode("0E06010100FF","hex")
result=dev.ctrl_transfer(0x21, 0x9, wValue=0x030E, wIndex=0x00, data_or_wLength=data)
result=dev.ctrl_transfer(0x21, 0x9, wValue=0x030E, wIndex=0x00, data_or_wLength=data)
### end of internals
if __name__ == "__main__":
init()
# simply set colors specified. doing this once after plugging in is enough if you just want static colors.
set_colors(colors)
# stuff below doesn't work on linux, might on window: animating the colors currently makes the mouse unusable.
# something a little more fancy, for this, the script has to run in a loop to update the colors:
# - slowly pulse the red component of the two 8 "stripe" leds on the back.
# - slowly pulse the red component of the two 2 "side", but at a different speed.
# - slowly pulse the red component of the wheel, but at yet another different speed.
# while(True):
# # use good old sin(time) to get a pulsing value
# s0 = math.sin(time.time()) * .5 + .5
# s1 = math.sin(time.time()/2) * .5 + .5
# s2 = math.sin(time.time()*3.5) * .5 + .5
#
# for i in range(1,9):
# colors[i][RED] = s0
#
# colors[LOWER_LEFT][RED] = s1
# colors[LOWER_RIGHT][RED] = s1
# colors[WHEEL][RED] = s2
#
# set_colors(colors)
# time.sleep(1.0/30.0) # do this at 30hz - thats more than enough
# example: total eyesore-party-mode (don't actually use this...)
# while(True):
# for i in range(0,11):
# colors[i][RED] = random.uniform(0,1)
# colors[i][GREEN] = random.uniform(0,1)
# colors[i][BLUE] = random.uniform(0,1)
# set_colors(colors)
# time.sleep(1.0/30.0) # do this at 30hz - thats more than enough