Skip to content

Commit

Permalink
added mode setting, fixed style, cleaned up extra dependancies.
Browse files Browse the repository at this point in the history
  • Loading branch information
jath03 committed Jun 5, 2020
1 parent 00fcc86 commit 54a597e
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 72 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ SDK Feature Support:
- [x] Setting color by device
- [x] Setting color by zone
- [x] Setting color by led
- [ ] Setting mode
- [ ] Setting custom modes
- [x] Setting mode
- [x] Setting custom mode
- [ ] resizing zones

# Installation

requires python >= 3.7

Use this method for the newest, but probably buggy, package:
Use this method for the newest, but possibly buggy, package:

`pip3 install git+https://github.com/jath03/openrgb-python#egg=openrgb-python`

Expand Down Expand Up @@ -51,4 +51,4 @@ motherboard.zones[1].leds[0].set_color(RGBColor.fromHSV(0, 100, 100))
https://openrgb-python.readthedocs.io/en/stable/


For a more fully-featured python implementation, check out [B Horn](https://github.com/bahorn)'s [OpenRGB-PyClient](https://github.com/bahorn/OpenRGB-PyClient)
For an alternative python implementation, check out [B Horn](https://github.com/bahorn)'s [OpenRGB-PyClient](https://github.com/bahorn/OpenRGB-PyClient)
8 changes: 4 additions & 4 deletions docs/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ SDK Feature Support:
- [x] Setting color by device
- [x] Setting color by zone
- [x] Setting color by led
- [ ] Setting mode
- [ ] Setting custom modes
- [x] Setting mode
- [x] Setting custom mode
- [ ] resizing zones

# Installation

requires python >= 3.7

Use this method for the newest, but probably buggy, package:
Use this method for the newest, but possibly buggy, package:

`pip3 install git+https://github.com/jath03/openrgb-python#egg=openrgb-python`

Expand All @@ -46,4 +46,4 @@ motherboard.zones[1].leds[0].set_color(RGBColor.fromHSV(0, 100, 100))
```


For a more fully-featured python implementation, check out [B Horn](https://github.com/bahorn)'s [OpenRGB-PyClient](https://github.com/bahorn/OpenRGB-PyClient)
For an alternative python implementation, check out [B Horn](https://github.com/bahorn)'s [OpenRGB-PyClient](https://github.com/bahorn/OpenRGB-PyClient)
39 changes: 12 additions & 27 deletions openrgb/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
import struct
import threading
from openrgb import utils
from typing import Callable, List, Union, Tuple
from typing import Callable
from time import sleep


class NetworkClient(object):
'''
A class for interfacing with the OpenRGB SDK
'''

def __init__(self, update_callback: Callable, address: str = "127.0.0.1", port: int = 1337, name: str = "openrgb-python"):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
for x in range(5):
Expand Down Expand Up @@ -87,29 +88,27 @@ def parseDeviceDescription(self, data: bytearray) -> utils.ControllerData:
device_type = buff[1]
metadata = []
for x in range(5):
location, val = self.parseSizeAndString(data, location)
location, val = utils.parse_string(data, location)
metadata.append(val)
buff = struct.unpack("=Hi", data[location:location + struct.calcsize("=Hi")])
location += struct.calcsize("=Hi")
num_modes = buff[0]
active_mode = buff[-1]
modes = []
for x in range(num_modes):
location, val = self.parseSizeAndString(data, location)
location, val = utils.parse_string(data, location)
buff = list(struct.unpack("i8IH", data[location:location + struct.calcsize("i8IH")]))
location += struct.calcsize("i8IH")
buff[4] = utils.intToRGB(buff[4])
buff[5] = utils.intToRGB(buff[5])
colors = []
for x in range(buff[-1]):
colors.append(utils.RGBColor.unpack(data[location:location + struct.calcsize("I")]))
location += struct.calcsize('BBBx')
modes.append(utils.ModeData(val.strip('\x00'), buff[0], utils.ModeFlags(buff[1]), *buff[2:7], utils.ModeDirections(buff[8]), utils.ModeColors(buff[9]), colors))
for i in range(buff[-1]):
location, color = utils.RGBColor.unpack(data, location)
colors.append(color)
modes.append(utils.ModeData(x, val.strip('\x00'), buff[0], utils.ModeFlags(buff[1]), *buff[2:7], utils.ModeDirections(buff[8]), utils.ModeColors(buff[9]), colors))
num_zones = struct.unpack("H", data[location:location + struct.calcsize("H")])[0]
location += struct.calcsize("H")
zones = []
for x in range(num_zones):
location, val = self.parseSizeAndString(data, location)
location, val = utils.parse_string(data, location)
buff = list(struct.unpack("iIIIH", data[location:location + struct.calcsize("iIIIH")]))
location += struct.calcsize("iIIIH")

Expand All @@ -128,16 +127,16 @@ def parseDeviceDescription(self, data: bytearray) -> utils.ControllerData:
location += struct.calcsize("H")
leds = []
for x in range(num_leds):
location, name = self.parseSizeAndString(data, location)
location, name = utils.parse_string(data, location)
value = struct.unpack("I", data[location:location + struct.calcsize("I")])[0]
location += struct.calcsize("I")
leds.append(utils.LEDData(name.strip("\x00"), value))
num_colors = struct.unpack("H", data[location:location + struct.calcsize("H")])[0]
location += struct.calcsize("H")
colors = []
for x in range(num_colors):
colors.append(utils.RGBColor.unpack(data[location:location + struct.calcsize("BBBx")]))
location += struct.calcsize("BBBx")
location, color = utils.RGBColor.unpack(data, location)
colors.append(color)
for zone in zones:
zone.leds = []
zone.colors = []
Expand Down Expand Up @@ -167,20 +166,6 @@ def parseDeviceDescription(self, data: bytearray) -> utils.ControllerData:
active_mode
)

def parseSizeAndString(self, data: bytes, start: int = 0) -> Tuple[int, str]:
'''
Parses a string based on a size.
:param data: the raw data to parse
:param start: the location in the data to start parsing at
:returns: the location in the data of the end of the string and the string itself
'''
size = struct.unpack('H', data[start:start + struct.calcsize('H')])[0]
start += struct.calcsize("H")
val = struct.unpack(f"{size}s", data[start:start + size])[0].decode()
start += size
return start, val.strip("\x00")

def send_header(self, device_id: int, packet_type: int, packet_size: int):
'''
Sends a header to the SDK
Expand Down
71 changes: 57 additions & 14 deletions openrgb/orgb.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
import struct
from openrgb import utils
from typing import Callable, List, Union, Tuple
from typing import List, Union
from openrgb.network import NetworkClient
# from dataclasses import dataclass
from time import sleep
Expand All @@ -11,6 +11,7 @@ class LED(utils.RGBObject):
'''
A class to represent individual LEDs
'''

def __init__(self, data: utils.LEDData, led_id: int, device_id: int, network_client: NetworkClient):
self.name = data.name
self.id = led_id
Expand All @@ -32,6 +33,7 @@ class Zone(utils.RGBObject):
'''
A class to represent a zone
'''

def __init__(self, data: utils.ZoneData, zone_id: int, device_id: int, network_client: NetworkClient):
self.name = data.name
self.type = data.zone_type
Expand Down Expand Up @@ -81,6 +83,7 @@ class Device(utils.RGBObject):
'''
A class to represent a RGB Device
'''

def __init__(self, data: utils.ControllerData, device_id: int, network_client: NetworkClient):
self.name = data.name
self.metadata = data.metadata
Expand All @@ -101,13 +104,16 @@ def set_color(self, color: utils.RGBColor, start: int = 0, end: int = 0):
:param start: the first LED to change
:param end: the last LED to change
'''
self._set_color(
self.leds,
if end == 0:
end = len(self.leds)
self.comms.send_header(
self.id,
utils.PacketType.NET_PACKET_ID_RGBCONTROLLER_UPDATELEDS,
color,
start,
end
struct.calcsize(f"IH{3*(end - start)}b{(end - start)}x")
)
buff = struct.pack("H", end - start) + (color.pack())*(end - start)
buff = struct.pack("I", len(buff)) + buff
self.comms.sock.send(buff)

def set_colors(self, colors: List[utils.RGBColor], start: int = 0, end: int = 0):
'''
Expand All @@ -117,20 +123,55 @@ def set_colors(self, colors: List[utils.RGBColor], start: int = 0, end: int = 0)
:param start: the first LED to change
:param end: the last LED to change
'''
self._set_colors(
self.leds,
if end == 0:
end = len(self.leds)
if len(colors) != (end - start):
raise IndexError("Number of colors doesn't match number of LEDs")
self.comms.send_header(
self.id,
utils.PacketType.NET_PACKET_ID_RGBCONTROLLER_UPDATELEDS,
colors,
start,
end
struct.calcsize(f"IH{3*(end - start)}b{(end - start)}x")
)
buff = struct.pack("H", end - start) + b''.join((color.pack() for color in colors))
buff = struct.pack("I", len(buff)) + buff
self.comms.sock.send(buff)

def set_mode(self, mode: Union[int, str, utils.ModeData]):
'''
Sets the device's mode
:param mode: the id, name, or the ModeData object itself to set as the mode
'''
if type(mode) == utils.ModeData:
pass
elif type(mode) == int:
mode = self.modes[mode]
elif type(mode) == str:
mode = next((m for m in self.modes if m.name.lower() == mode.lower()))
# print(mode)
size, data = mode.pack()
self.comms.send_header(
self.id,
utils.PacketType.NET_PACKET_ID_RGBCONTROLLER_UPDATEMODE,
size
)
self.comms.sock.send(data)

def set_custom_mode(self):
self.comms.send_header(
self.id,
utils.PacketType.NET_PACKET_ID_RGBCONTROLLER_SETCUSTOMMODE,
0
)
# def set_mode(self, )


class OpenRGBClient(object):
'''
This is the only class you should ever need to instantiate. It initializes the communication, gets the device information, and creates Devices, Zones, and LEDs for you.
This is the only class you should ever need to instantiate. It initializes
the communication, gets the device information, sets the devices to the
custom mode and creates Devices, Zones, and LEDs for you.
'''

def __init__(self, address: str = "127.0.0.1", port: int = 1337, name: str = "openrgb-python"):
self.comms = NetworkClient(self._callback, address, port, name)
self.address = address
Expand All @@ -142,7 +183,9 @@ def __init__(self, address: str = "127.0.0.1", port: int = 1337, name: str = "op
self.devices = [None for x in range(self.device_num)]
for x in range(self.device_num):
self.comms.requestDeviceData(x)
sleep(1) # Giving the client time to recieve the device data
sleep(1) # Giving the client time to recieve the device data
for dev in self.devices:
dev.set_custom_mode()

def __repr__(self):
return f"OpenRGBClient(address={self.address}, port={self.port}, name={self.name})"
Expand Down
Loading

0 comments on commit 54a597e

Please sign in to comment.