-
Notifications
You must be signed in to change notification settings - Fork 0
/
elite-prism-ctl.py
executable file
·156 lines (124 loc) · 4.99 KB
/
elite-prism-ctl.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
#!/usr/bin/python
import appindicator
import logging
import gtk
import pyudev
import webcolors
import subprocess
import argparse
import os
import yaml
import sys
PRISM_HID_ID = '0003:00001038:00001225'
CONFIG_FILE_NAME = '.prism.config'
logger = logging.getLogger("Prism")
def eval(command):
return subprocess.Popen(command, shell=True, bufsize=0, stdin=subprocess.PIPE, stdout=subprocess.PIPE).stdout.read().decode()
def reload():
set_led_color(Config.read().color, False)
def find_device_path():
context = pyudev.Context()
for device in context.list_devices(HID_ID=PRISM_HID_ID):
if device.sequence_number == 0:
children = list(device.children)
if children:
child = children[0]
if child.subsystem == 'hidraw':
return child['DEVNAME']
raise ValueError("Couldn't detect any SteelSeries Elite Prism sound card")
def prompt_for_led_color():
dialog = gtk.ColorSelectionDialog('SteelSeries Elite Prism color picker')
colorselect = dialog.colorsel
current_color = Config.read().color
colorselect.set_current_color(gtk.gdk.Color(current_color))
colorselect.connect("color_changed", lambda widget: set_led_color(__gdk_color_to_hex(colorselect.get_current_color()), False))
if dialog.run() != gtk.RESPONSE_OK:
set_led_color(current_color, False)
logger.warn('No color selected.')
else:
set_led_color(__gdk_color_to_hex(colorselect.get_current_color()))
dialog.destroy()
def set_led_color(color, persist=True):
color = __parseColor(color)
device_path = find_device_path()
# set the color
__send("0x010x000x040x000x090x000x000x230x2d0xb30x010x000x000x000x000x000x000x000x010x000x000x000x200x%0.2x0x%0.2x0x%0.2x" % color, device_path)
# probably commit
__send("0x010x000x010x000x0a0x000x000x230x2d0xb30x01", device_path)
if persist is True:
hex = "#%0.2x%0.2x%0.2x" % color
logger.debug("persisting led color as " + hex + " for device " + device_path)
Config(hex).write()
def __send(report, device_path):
eval("echo " + report + " | xxd -r -p > " + device_path)
def __parseColor(color):
try:
return webcolors.name_to_rgb(color)
except ValueError:
if not color.startswith('#'):
color = "#" + color
return webcolors.hex_to_rgb(color)
def __gdk_color_to_hex(color):
return "#%0.2x%0.2x%0.2x" % (color.red / 256, color.green / 256, color.blue / 256)
class Config:
def __init__(self, color):
self.color = color
def write(self):
config = {
'color': self.color
}
with open(os.path.expanduser("~") + '/' + CONFIG_FILE_NAME, 'w') as f:
yaml.dump(config, f, default_flow_style=False)
@staticmethod
def read():
try:
with open(os.path.expanduser("~") + '/' + CONFIG_FILE_NAME, 'r') as f:
config = yaml.load(f)
return Config(config['color'])
except IOError:
return Config('#40e0d0')
class PrismIndicator:
def __init__(self):
self.__isopen = False
reload()
indicator = appindicator.Indicator("PrismIndicator", os.path.dirname(os.path.realpath(__file__)) + "/steelseries.png", appindicator.CATEGORY_HARDWARE)
indicator.set_status(appindicator.STATUS_ACTIVE)
menu = gtk.Menu()
color_picker = gtk.MenuItem("Change color")
color_picker.connect("activate", self.pick_color)
menu.append(color_picker)
menu.show_all()
indicator.set_menu(menu)
gtk.main()
def pick_color(self, item):
if self.__isopen is False:
self.__isopen = True
prompt_for_led_color()
self.__isopen = False
else:
logger.warn("color picker dialog is already open ... ignoring")
def main():
# a simple console logger
console = logging.StreamHandler()
console.setFormatter(logging.Formatter("%(asctime)-15s %(levelname)-7s [%(name)s] %(message)s"))
logging.getLogger().addHandler(console)
logging.getLogger().setLevel(logging.DEBUG)
# command line arguments
parser = argparse.ArgumentParser(description="A tool to configure the SteelSeries Elite Prism Headset")
parser.add_argument("--set-color", type=str, metavar="COLOR", help="set the color to the given valid css color name or hex string and exit")
parser.add_argument("--reload", default=None, action='store_true', help="reload settings from the configuration file and exit")
parser.add_argument("--as-indicator", default=None, action='store_true', help="start as a panel indicator")
if len(sys.argv) == 1:
parser.print_help()
else:
args = parser.parse_args()
if args.set_color is not None:
set_led_color(args.set_color)
elif args.reload is not None:
reload()
elif args.as_indicator is not None:
PrismIndicator()
else:
parser.print_help()
if __name__ == "__main__":
main()