diff --git a/examples/black.py b/examples/black.py index e8b6b41..57596ce 100644 --- a/examples/black.py +++ b/examples/black.py @@ -1,8 +1,6 @@ -import time -import sys,os -import random - +import sys, os sys.path.append(os.path.realpath('.')) + from openrgb import OpenRGB client = OpenRGB('localhost', 6742) diff --git a/examples/color-change.py b/examples/color-change.py index f015f32..7463734 100644 --- a/examples/color-change.py +++ b/examples/color-change.py @@ -1,7 +1,6 @@ -import time import sys, os - sys.path.append(os.path.realpath('.')) + from openrgb import OpenRGB seq = [ diff --git a/examples/cpuload.py b/examples/cpuload.py index 29205db..dc86881 100644 --- a/examples/cpuload.py +++ b/examples/cpuload.py @@ -1,19 +1,17 @@ import time import psutil -import sys,os +import sys, os sys.path.append(os.path.realpath('.')) -from openrgb import OpenRGB +from openrgb import OpenRGB client = OpenRGB('localhost', 6742) - # find and clear for device in client.devices(): device.set((0, 0, 0)) - while True: load = psutil.cpu_percent() for device in client.devices(): diff --git a/examples/get-modes.py b/examples/get-modes.py index 389dbbd..919bb24 100644 --- a/examples/get-modes.py +++ b/examples/get-modes.py @@ -1,7 +1,6 @@ -import time -import sys,os - +import sys, os sys.path.append(os.path.realpath('.')) + from openrgb import OpenRGB client = OpenRGB('localhost', 6742) diff --git a/examples/getting-started.py b/examples/getting-started.py index 18729e3..756f02a 100644 --- a/examples/getting-started.py +++ b/examples/getting-started.py @@ -1,16 +1,13 @@ -# Adding the library to our PYTHONPATH -import sys,os +import sys, os sys.path.append(os.path.realpath('.')) from openrgb import OpenRGB client = OpenRGB('localhost', 6742) -devices = {} -for i in range(client.controller_count()): - devices[i] = client.controller_data(device_id=i) +devices = list(client.devices()) print(devices) -for _, device in devices.items(): +for device in devices: print('{} has {} LED(s)'.format(device.name, len(device.leds))) diff --git a/examples/load-profiles.py b/examples/load-profiles.py new file mode 100644 index 0000000..ef6eb4c --- /dev/null +++ b/examples/load-profiles.py @@ -0,0 +1,11 @@ +import sys, os +sys.path.append(os.path.realpath('.')) + +from openrgb import OpenRGB + +client = OpenRGB('localhost', 6742) + +profiles = client.profiles() +print(profiles) + +client.load_profile(profiles[0]) diff --git a/examples/objects.py b/examples/objects.py index 5ff9b23..b3001c0 100644 --- a/examples/objects.py +++ b/examples/objects.py @@ -1,12 +1,10 @@ -import sys -import os - +import sys, os sys.path.append(os.path.realpath('.')) - from openrgb import OpenRGB - client = OpenRGB('localhost', 6742) -devices = [d for d in client.devices()] -print(devices[4].modes[1].active()) + +devices = list(client.devices()) + +print(devices[0].modes[1].active()) diff --git a/examples/ram.py b/examples/ram.py index d8d6318..82e08e2 100644 --- a/examples/ram.py +++ b/examples/ram.py @@ -1,9 +1,9 @@ import time -import sys -import os import random +import sys, os sys.path.append(os.path.realpath('.')) + from openrgb import OpenRGB client = OpenRGB('localhost', 6742) @@ -15,6 +15,7 @@ for mode in device.modes: if mode.name == "Direct": mode.active() + break device.set((0, 0, 0)) devices.append(device) diff --git a/examples/set-mode.py b/examples/set-mode.py index 2b1db31..1cf9642 100644 --- a/examples/set-mode.py +++ b/examples/set-mode.py @@ -1,8 +1,8 @@ -import time -import sys,os import random +import sys, os sys.path.append(os.path.realpath('.')) + from openrgb import OpenRGB client = OpenRGB('localhost', 6742) diff --git a/examples/single-led.py b/examples/single-led.py index eb5d282..87a92dc 100644 --- a/examples/single-led.py +++ b/examples/single-led.py @@ -1,10 +1,10 @@ -import time -import sys,os - +import sys, os sys.path.append(os.path.realpath('.')) + from openrgb import OpenRGB client = OpenRGB('localhost', 6742) + for device in client.devices(): print(device) device.leds[0].set((255, 0, 255)) diff --git a/examples/try-all-zones.py b/examples/try-all-modes.py similarity index 65% rename from examples/try-all-zones.py rename to examples/try-all-modes.py index bae3d54..a79a505 100644 --- a/examples/try-all-zones.py +++ b/examples/try-all-modes.py @@ -1,17 +1,9 @@ import time -import sys,os +import sys, os sys.path.append(os.path.realpath('.')) -from openrgb import OpenRGB - -seq = [ - (214, 2, 112), - (0, 56, 168), - (155, 79, 150), - (0, 56, 168), - (214, 2, 112) -] +from openrgb import OpenRGB client = OpenRGB('localhost', 6742) diff --git a/examples/version.py b/examples/version.py index d672e93..5fdc998 100644 --- a/examples/version.py +++ b/examples/version.py @@ -1,6 +1,6 @@ import sys, os - sys.path.append(os.path.realpath('.')) + from openrgb import OpenRGB client = OpenRGB('localhost', 6742) diff --git a/examples/zone-change.py b/examples/zone-change.py index 407182f..0fb1405 100644 --- a/examples/zone-change.py +++ b/examples/zone-change.py @@ -1,9 +1,7 @@ -import time -import sys,os - +import sys, os sys.path.append(os.path.realpath('.')) -from openrgb import OpenRGB +from openrgb import OpenRGB seq = [ (214, 2, 112), diff --git a/openrgb/ORGBDevice.py b/openrgb/ORGBDevice.py index ea89cbe..0c2e0aa 100644 --- a/openrgb/ORGBDevice.py +++ b/openrgb/ORGBDevice.py @@ -63,8 +63,8 @@ def active(self): return # We belong to an ORGBDevice, which belongs to the main OpenRGB class. device = self.owner - con = device.owner - con.set_update_mode(self, device_id=device.id) + client = device.owner + client.set_update_mode(self, device_id=device.id) # serialize this for the wire. def __bytes__(self): @@ -113,7 +113,7 @@ def __init__(self, def set(self, colors, interpolate=False): """ - This will set the LEDs belong to this zone to the color(s) in + This will set the LEDs belonging to this zone to the color(s) in `colors`. If provided with a single tuple, it will set all LEDs in the zone to @@ -131,10 +131,10 @@ def set(self, colors, interpolate=False): Interpolate has no effect if not given a list. """ device = self.owner - con = device.owner + client = device.owner n_leds = self.leds_count _set_batch( - lambda c, did: con.update_zone_leds(self.id, c, did), + lambda c, did: client.update_zone_leds(self.id, c, did), device, n_leds, colors, @@ -147,11 +147,11 @@ def __getitem__(self, item): class ORGBLED(object): """ - ORGBLED is a class that contains a reference to a Single LED. - This is constructed by ORGBDevice and shouldn't ever need to be created + `ORGBLED` is a class that contains a reference to a single LED. + This is constructed by `ORGBDevice` and shouldn't ever need to be created manually. - It does however provide the LED Name, current value, and a reference to the + It does however provide the LED name, current value, and a reference to the device that owns it. @@ -172,9 +172,9 @@ def set(self, color): as a tuple of RGB values. """ device = self.owner - con = device.owner + client = device.owner self.value = color - con.update_single_led(self.id, color, device_id=device.id) + client.update_single_led(self.id, color, device_id=device.id) def __getitem__(self, item): return self.__dict__[item] @@ -182,7 +182,7 @@ def __getitem__(self, item): class ORGBDevice: """ - ORGB is used to read device responses from the OpenRGB SDK server + `ORGBDevice` is used to read device responses from the OpenRGB SDK server. :attribute id: Device ID. :attribute type: Device Type. @@ -196,7 +196,6 @@ class ORGBDevice: :attribute zones: List of zones :attribute leds: List of LEDs :attribute colors: List of colors - """ def __init__(self, data, device_id=0, owner=None): @@ -300,7 +299,7 @@ def __init__(self, data, device_id=0, owner=None): def set(self, colors, interpolate=False): """ - This will set the LEDs belong to this device to the color(s) in + This will set the LEDs belonging to this device to the color(s) in `colors`. If provided with a single tuple, it will set all LEDs in the device to @@ -316,11 +315,10 @@ def set(self, colors, interpolate=False): range of values in `colors` Interpolate has no effect if not given a list. - """ - con = self.owner + client = self.owner n_leds = len(self.leds) - _set_batch(con.update_leds, self, n_leds, colors, interpolate) + _set_batch(client.update_leds, self, n_leds, colors, interpolate) def __repr__(self): return '{} - {}'.format(self.name, self.type) diff --git a/openrgb/OpenRGB.py b/openrgb/OpenRGB.py index 401d673..3cea1c1 100644 --- a/openrgb/OpenRGB.py +++ b/openrgb/OpenRGB.py @@ -1,5 +1,6 @@ import struct +from .binreader import Blob from .ORGBDevice import ORGBDevice, ORGBMode from .consts import ORGBPkt, ORGBProtoVersion from .utils import pack_color, prepend_length @@ -22,7 +23,7 @@ def client_name(self, name=None): self.client_string = name self.con.send_message( ORGBPkt.SET_CLIENT_NAME, - bytes(self.client_string, 'ascii') + bytes(self.client_string, 'utf-8') ) def controller_count(self): @@ -50,7 +51,7 @@ def controller_data(self, device_id=0): # Generator for getting devices def devices(self): """ - This provides a generator for iterating though all the devices OpenRGB + This provides a generator for iterating through all the devices OpenRGB can find. This is the recommended interface for finding devices. @@ -81,11 +82,9 @@ def resize_zone(self, zone_id, new_size, device_id=0): def set_custom_mode(self, device_id=0): """ - This calls set_custom_mode in the RGBController, which in most cases + This calls `RGBController::SetCustomMode`, which in most cases sets the active mode to 0. """ - # this just calls the function SetCustomMode() in the RGB controller, - # which in most cases just sets the active mode to 0. self.con.send_message( ORGBPkt.RGBCONTROLLER_SETCUSTOMMODE, device_id=device_id @@ -96,7 +95,7 @@ def set_update_mode(self, mode, device_id=0, speed=None, direction=None, """ This is the protocol level way of setting the mode. - mode can either be the mode id, or the ORGBMode object, though in the + `mode` can either be the mode id, or an `ORGBMode` object, though in the second case it's preferable to use it directly to set the active mode. """ data = None @@ -117,6 +116,7 @@ def set_update_mode(self, mode, device_id=0, speed=None, direction=None, ) # LED Control + def update_leds(self, color_collection, device_id=0): """ This is the protocol level function for setting multiple LEDs at once. @@ -134,8 +134,9 @@ def update_leds(self, color_collection, device_id=0): def update_zone_leds(self, zone_id, color_collection, device_id=0): """ This is the protocol level function for setting a zones LEDs. + + Essentially the same as update_leds, but with a zone_id. """ - # Essentially the same as update_leds, but with a zone_id. c_buf = struct.pack('IH', zone_id, len(color_collection)) for i in color_collection: c_buf += pack_color(i) @@ -156,10 +157,59 @@ def update_single_led(self, led, color, device_id=0): data=msg, device_id=device_id ) + + # Profile Control + + def profiles(self): + """ + This returns a list of profiles. + """ + self.con.send_message(ORGBPkt.REQUEST_PROFILE_LIST) + msg = self.con.recv_message() + _, data = msg + + blob = Blob(data) + length = blob.uint() + if length != len(data): + raise Exception('Length incorrect?') + + profiles_count = blob.ushort() + profiles = [blob.string() for _ in range(profiles_count)] + + return profiles + + def load_profile(self, profile_name): + """ + This loads a profile given the name. + + Note that loading fails when the OpenRGB GUI is open and a different profile is selected in the dropdown. + """ + self.con.send_message( + ORGBPkt.REQUEST_LOAD_PROFILE, + data=bytes(profile_name, 'utf-8') + ) + + def save_profile(self, profile_name): + """ + This saves a profile given the name. + """ + self.con.send_message( + ORGBPkt.REQUEST_SAVE_PROFILE, + data=bytes(profile_name, 'utf-8') + ) + + def delete_profile(self, profile_name): + """ + This deletes a profile given the name. + """ + self.con.send_message( + ORGBPkt.REQUEST_DELETE_PROFILE, + data=bytes(profile_name, 'utf-8') + ) def get_version(self): """ - Gets the protocol version. + This returns the protocol version. """ self.con.send_message( ORGBPkt.REQUEST_PROTOCOL_VERSION diff --git a/openrgb/binreader.py b/openrgb/binreader.py index 30b2a2f..83b60fe 100644 --- a/openrgb/binreader.py +++ b/openrgb/binreader.py @@ -50,14 +50,14 @@ def string(self, value=None): total_len = len(value)+1 self.ushort(total_len) packed = self._pack( - '{}s'.format(total_len), bytes(value, 'ascii')+b'\x00' + '{}s'.format(total_len), bytes(value, 'utf-8')+b'\x00' ) return packed else: total_len = self.ushort() unpacked = self._unpack( '{}s'.format(total_len) - )[0].decode('ascii') + )[0].decode('utf-8') if unpacked[-1] == '\x00': return unpacked[:-1] return unpacked diff --git a/openrgb/consts.py b/openrgb/consts.py index 7db68e3..84bdcf4 100644 --- a/openrgb/consts.py +++ b/openrgb/consts.py @@ -47,6 +47,6 @@ class ORGBProtoVersion(Enum): V2 = 2 V3 = 3 -MagicBytes = bytes('ORGB', 'ascii') +MagicBytes = bytes('ORGB', 'utf-8') HeaderFmt = '4sIII' HeaderSize = struct.calcsize(HeaderFmt) diff --git a/requirements.txt b/requirements.txt index 37ef8b1..2194222 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ Babel==2.8.0 bleach==3.3.0 CacheControl==0.12.6 certifi==2019.11.28 -cffi==1.14.0 +cffi==1.15.1 chardet==3.0.4 colorama==0.4.3 contextlib2==0.6.0