Skip to content

Commit cc5c84c

Browse files
committed
added loading and saving profiles, .pack to dataclasses, updated example
1 parent 5c631ec commit cc5c84c

File tree

9 files changed

+251
-58
lines changed

9 files changed

+251
-58
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ dist
77
_build
88
_static
99
_templates
10+
_test.py

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ SDK Feature Support:
1515
- [x] Setting color by led
1616
- [x] Setting mode
1717
- [x] Setting custom mode
18-
- [ ] resizing zones
18+
- [ ] Resizing zones
19+
- [x] Loading profiles
20+
- [x] Saving profiles
1921

2022
# Installation
2123

@@ -45,6 +47,7 @@ motherboard.set_color(RGBColor(0, 255, 0))
4547
motherboard.zones[0].set_color(RGBColor(255, 0, 0))
4648
motherboard.zones[1].leds[0].set_color(RGBColor.fromHSV(0, 100, 100))
4749
motherboard.set_mode("breathing")
50+
client.save_profile("profile1")
4851
```
4952

5053
# API docs

docs/intro.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ SDK Feature Support:
1515
- [x] Setting mode
1616
- [x] Setting custom mode
1717
- [ ] resizing zones
18+
- [x] Loading profiles
19+
- [x] Saving profiles
1820

1921
# Installation
2022

@@ -44,6 +46,7 @@ motherboard.set_color(RGBColor(0, 255, 0))
4446
motherboard.zones[0].set_color(RGBColor(255, 0, 0))
4547
motherboard.zones[1].leds[0].set_color(RGBColor.fromHSV(0, 100, 100))
4648
motherboard.set_mode("breathing")
49+
client.save_profile("profile1")
4750
```
4851

4952

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
pysensors
2-
nvidia-ml-py3
2+
py3nvml
33
psutil

examples/temperature/temperature.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from openrgb.utils import RGBColor, DeviceType
44
import sensors
55
from time import sleep
6-
from pynvml import nvmlInit, nvmlDeviceGetHandleByIndex, nvmlDeviceGetTemperature, NVML_TEMPERATURE_GPU
6+
from py3nvml.py3nvml import nvmlInit, nvmlDeviceGetHandleByIndex, nvmlDeviceGetTemperature, NVML_TEMPERATURE_GPU
77
# import psutil
88

99

openrgb/network.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ class NetworkClient(object):
1313
'''
1414

1515
def __init__(self, update_callback: Callable, address: str = "127.0.0.1", port: int = 1337, name: str = "openrgb-python"):
16+
'''
17+
:param update_callback: the function to call when data is received
18+
:param address: the ip address of the SDK server
19+
:param port: the port of the SDK server
20+
:param name: the string that will be displayed on the OpenRGB SDK tab's list of clients
21+
'''
1622
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1723
for x in range(5):
1824
try:

openrgb/orgb.py

Lines changed: 83 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from openrgb.network import NetworkClient
66
# from dataclasses import dataclass
77
from time import sleep
8+
from os import environ
89

910

1011
class LED(utils.RGBObject):
@@ -60,6 +61,7 @@ def set_color(self, color: utils.RGBColor, start: int = 0, end: int = 0):
6061
buff = struct.pack("IH", self.id, end - start) + (color.pack())*(end - start)
6162
buff = struct.pack("I", len(buff)) + buff
6263
self.comms.sock.send(buff)
64+
self.comms.requestDeviceData(self.device_id)
6365

6466
def set_colors(self, colors: List[utils.RGBColor], start: int = 0, end: int = 0):
6567
'''
@@ -77,6 +79,10 @@ def set_colors(self, colors: List[utils.RGBColor], start: int = 0, end: int = 0)
7779
buff = struct.pack("IH", self.id, end - start) + b''.join((color.pack() for color in colors))
7880
buff = struct.pack("I", len(buff)) + buff
7981
self.comms.sock.send(buff)
82+
self.comms.requestDeviceData(self.device_id)
83+
84+
def update_device_colors(self):
85+
pass
8086

8187

8288
class Device(utils.RGBObject):
@@ -93,6 +99,7 @@ def __init__(self, data: utils.ControllerData, device_id: int, network_client: N
9399
self.modes = data.modes
94100
self.colors = data.colors
95101
self.active_mode = data.active_mode
102+
self.data = data
96103
self.id = device_id
97104
self.comms = network_client
98105

@@ -114,6 +121,7 @@ def set_color(self, color: utils.RGBColor, start: int = 0, end: int = 0):
114121
buff = struct.pack("H", end - start) + (color.pack())*(end - start)
115122
buff = struct.pack("I", len(buff)) + buff
116123
self.comms.sock.send(buff)
124+
self.comms.requestDeviceData(self.id)
117125

118126
def set_colors(self, colors: List[utils.RGBColor], start: int = 0, end: int = 0):
119127
'''
@@ -135,6 +143,7 @@ def set_colors(self, colors: List[utils.RGBColor], start: int = 0, end: int = 0)
135143
buff = struct.pack("H", end - start) + b''.join((color.pack() for color in colors))
136144
buff = struct.pack("I", len(buff)) + buff
137145
self.comms.sock.send(buff)
146+
self.comms.requestDeviceData(self.id)
138147

139148
def set_mode(self, mode: Union[int, str, utils.ModeData]):
140149
'''
@@ -148,14 +157,16 @@ def set_mode(self, mode: Union[int, str, utils.ModeData]):
148157
mode = self.modes[mode]
149158
elif type(mode) == str:
150159
mode = next((m for m in self.modes if m.name.lower() == mode.lower()))
151-
# print(mode)
152-
size, data = mode.pack()
160+
data = mode.pack()
153161
self.comms.send_header(
154162
self.id,
155163
utils.PacketType.NET_PACKET_ID_RGBCONTROLLER_UPDATEMODE,
156-
size
164+
len(data)
157165
)
158166
self.comms.sock.send(data)
167+
self.active_mode = mode.id
168+
if len(mode.colors) == len(self.colors):
169+
self.colors = mode.colors
159170

160171
def set_custom_mode(self):
161172
self.comms.send_header(
@@ -187,8 +198,7 @@ def __init__(self, address: str = "127.0.0.1", port: int = 1337, name: str = "op
187198
while self.device_num == 0:
188199
sleep(.2)
189200
self.devices = [None for x in range(self.device_num)]
190-
for x in range(self.device_num):
191-
self.comms.requestDeviceData(x)
201+
self.get_device_info()
192202
while any((dev is None for dev in self.devices)):
193203
sleep(.2)
194204
if custom:
@@ -205,7 +215,7 @@ def _callback(self, device: int, type: int, data):
205215
if self.devices[device] is None:
206216
self.devices[device] = Device(data, device, self.comms)
207217
else:
208-
self.devices[device].data = data
218+
self.devices[device].__init__(data, device, self.comms)
209219

210220
def set_color(self, color: utils.RGBColor):
211221
'''
@@ -223,3 +233,70 @@ def get_devices_by_type(self, type: utils.DeviceType) -> List[Device]:
223233
:param type: what type of device you want to get
224234
'''
225235
return [device for device in self.devices if device.type == type]
236+
237+
def load_profile(self, name: str, directory: str):
238+
'''
239+
Loads an OpenRGB profile file
240+
241+
:param name: the name of the profile
242+
:param directory: what directory the profile is in. Defaults to HOME/.config/OpenRGB
243+
'''
244+
if directory == None:
245+
directory = environ['HOME'].rstrip("/") + "/.config/OpenRGB"
246+
with open(f'{directory}/{name}.orp', 'rb') as f:
247+
header = f.read(16 + struct.calcsize("I"))
248+
if struct.unpack("16s", header[:16])[0] != b"OPENRGB_PROFILE\x00":
249+
raise ValueError("The file is not an OpenRGB profile")
250+
version = struct.unpack("I", header[16:])[0]
251+
if version == 1:
252+
controllers = []
253+
while True:
254+
d = f.read(struct.calcsize("I"))
255+
if len(d) < struct.calcsize("I"):
256+
break
257+
size = struct.unpack("I", d)[0]
258+
f.seek(f.tell() - struct.calcsize("I"))
259+
new_data = utils.ControllerData.unpack(f.read(size))
260+
controllers.append(new_data)
261+
pairs = []
262+
for device in self.devices:
263+
for new_controller in controllers:
264+
if new_controller.name == device.name \
265+
and new_controller.device_type == device.type \
266+
and new_controller.metadata.description == device.metadata.description:
267+
controllers.remove(new_controller)
268+
pairs.append((new_controller, device))
269+
# print("Pairs:")
270+
for new_controller, device in pairs:
271+
# print(device.name, new_controller.name)
272+
if new_controller.colors != device.colors:
273+
device.set_colors(new_controller.colors)
274+
# print(new_controller.active_mode)
275+
if new_controller.active_mode != device.active_mode:
276+
device.set_mode(new_controller.active_mode)
277+
278+
def save_profile(self, name: str, directory: str):
279+
'''
280+
Saves the current state of all of your devices to an OpenRGB profile
281+
file
282+
283+
:param name: the name of the profile to save
284+
:param directory: what directory to save the profile in. Defaults to HOME/.config/OpenRGB
285+
'''
286+
if directory == None:
287+
directory = environ['HOME'].rstrip("/") + "/.config/OpenRGB"
288+
with open(f'{directory.rstrip("/")}/{name}.orp', 'wb') as f:
289+
data = bytearray()
290+
data += struct.pack("16sI", b'OPENRGB_PROFILE\x00', 1)
291+
for dev in self.devices:
292+
data += dev.data.pack()
293+
f.write(data)
294+
295+
def get_device_info(self):
296+
'''
297+
Gets the current state of your devices from the SDK server. Useful if
298+
you change something from the gui or another SDK client and need to
299+
sync up the changes.
300+
'''
301+
for x in range(self.device_num):
302+
self.comms.requestDeviceData(x)

0 commit comments

Comments
 (0)