55from openrgb .network import NetworkClient
66# from dataclasses import dataclass
77from time import sleep
8+ from os import environ
89
910
1011class 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
8288class 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