initial commit

This commit is contained in:
Denis Lehmann 2021-04-21 02:33:22 +02:00
commit c3ed9af8a0
7 changed files with 519 additions and 0 deletions

138
.gitignore vendored Normal file
View file

@ -0,0 +1,138 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/

12
README.org Normal file
View file

@ -0,0 +1,12 @@
* rzr
Apply lightmaps to Razer devices.
** Troubleshooting
If config file not found error:
#+begin_example sh
systemctl --user stop openrazer-daemon.service
openrazer-daemon -Fv
#+end_example

View file

@ -0,0 +1,109 @@
logo = [0, 20]
esc = [0, 1]
f1 = [0, 3]
f2 = [0, 4]
f3 = [0, 5]
f4 = [0, 6]
f5 = [0, 7]
f6 = [0, 8]
f7 = [0, 9]
f8 = [0, 10]
f9 = [0, 11]
f10 = [0, 12]
f11 = [0, 13]
f12 = [0, 14]
print = [0, 15]
roll = [0, 16]
pause = [0, 17]
m1 = [1, 0]
roof = [1, 1]
1 = [1, 2]
2 = [1, 3]
3 = [1, 4]
4 = [1, 5]
5 = [1, 6]
6 = [1, 7]
7 = [1, 8]
8 = [1, 9]
9 = [1, 10]
0 = [1, 11]
ß = [1, 12]
apostroph = [1, 13]
backspace = [1, 14]
insert = [1, 15]
pos1 = [1, 16]
pgup = [1, 17]
num = [1, 18]
div = [1, 19]
mult = [1, 20]
min = [1, 21]
m2 = [2, 0]
tab = [2, 1]
q = [2, 2]
w = [2, 3]
e = [2, 4]
r = [2, 5]
t = [2, 6]
z = [2, 7]
u = [2, 8]
i = [2, 9]
o = [2, 10]
p = [2, 11]
ü = [2, 12]
+ = [2, 13]
del = [2, 15]
end = [2, 16]
pgdown = [2, 17]
n7 = [2, 18]
n8 = [2, 19]
n9 = [2, 20]
plus = [2, 21]
m3 = [3, 0]
caps = [3, 1]
a = [3, 2]
s = [3, 3]
d = [3, 4]
f = [3, 5]
g = [3, 6]
h = [3, 7]
j = [3, 8]
k = [3, 9]
l = [3, 10]
ö = [3, 11]
ä = [3, 12]
hash = [3, 13]
ret = [3, 14]
n4 = [3, 18]
n5 = [3, 19]
n6 = [3, 20]
m4 = [4, 0]
lshift = [4, 1]
lower = [4, 2]
y = [4, 3]
x = [4, 4]
c = [4, 5]
v = [4, 6]
b = [4, 7]
n = [4, 8]
m = [4, 9]
comma = [4, 10]
dot = [4, 11]
dash = [4, 12]
rshift = [4, 14]
up = [4, 16]
n1 = [4, 18]
n2 = [4, 19]
n3 = [4, 20]
nreturn = [4, 21]
m5 = [5, 0]
lctrl = [5, 1]
super = [5, 2]
alt = [5, 3]
altgr = [5, 11]
menu = [5, 13]
rctrl = [5, 14]
left = [5, 15]
down = [5, 16]
right = [5, 17]
n0 = [5, 19]
ndel = [5, 20]

View file

@ -0,0 +1,20 @@
wheel = [0, 0]
logo = [0, 1]
l0 = [0, 2]
l1 = [0, 3]
l2 = [0, 4]
l3 = [0, 5]
l4 = [0, 6]
l5 = [0, 7]
l6 = [0, 8]
l7 = [0, 9]
l8 = [0, 10]
r0 = [0, 11]
r1 = [0, 12]
r2 = [0, 13]
r3 = [0, 14]
r4 = [0, 15]
r5 = [0, 16]
r6 = [0, 17]
r7 = [0, 18]
r8 = [0, 19]

181
main.py Normal file
View file

@ -0,0 +1,181 @@
#!/usr/bin/env python
from colour import Color
from openrazer.client import DeviceManager
from openrazer.client import constants as razer_constants
from pathlib import Path
import argparse
import os
import time
import toml
def get_color_tuple(color_string):
# Convert color string to RGB tuple
try:
color = Color(color_string).rgb
except:
raise Exception("'{}' is not a valid color".format(color_string))
# Scale RGB tuple from [0, 1] to [0, 255]
color_tuple = tuple(map(lambda x: int(x * 255), color))
return color_tuple
def apply_lightmap(device_profile):
global device_manager, lightmap_directory
# Get openrazer device
device = next(
(
d
for d in device_manager.devices
if d.name.lower() == device_profile["name"].lower()
),
None,
)
if device == None:
print("device '{}' not found".format(device_profile["device"]))
exit(1)
# Open lightmap
try:
lightmap = toml.load(
"{}/{}.toml".format(lightmap_directory, device_profile["lightmap"])
)
except FileNotFoundError:
print("the lightmap '{}' doesn't exist".format(device_profile["lightmap"]))
if len(os.listdir(lightmap_directory)) > 0:
print("found the following lightmaps:")
for lightmap_file in os.listdir(lightmap_directory):
print(" - {}".format(lightmap_file[:-5]))
else:
print("found no lightmaps")
exit(1)
except Exception as e:
print("failed to load lightmap '{}': {}".format(device_profile["lightmap"], e))
exit(1)
# Set light colors
try:
for light in device_profile["lights"]:
color_tuple = get_color_tuple((device_profile["lights"][light]))
device.fx.advanced.matrix[
lightmap[light][0], lightmap[light][1]
] = color_tuple
except KeyError:
print(
"light '{}' is not available in lightmap '{}'".format(
light, device_profile["lightmap"]
)
)
exit(1)
except Exception as e:
print("failed to set light '{}': {}".format(light, e))
exit(1)
# Apply light colors
device.fx.advanced.draw()
def iterate_lights():
global device_manager
# Print number of devices
print("found the following devices:")
for device in device_manager.devices:
print(" - {}".format(device.name))
# Turn all lights off
for device in device_manager.devices:
device.fx.none()
device.fx.advanced.draw()
# Iterate through device matrices and turn on one light every second
for device in device_manager.devices:
# Wait five seconds
for i in range(5, 0, -1):
print("{} will be iterated in {} seconds".format(device.name, i))
time.sleep(1)
for i in range(device.fx.advanced.rows):
for j in range(device.fx.advanced.cols):
device.fx.advanced.matrix[i, j] = (255, 255, 255)
device.fx.advanced.draw()
print("{}: [{}, {}]".format(device.name, i, j))
time.sleep(1)
if __name__ == "__main__":
global device_manager, lightmap_directory
# Initialise variables
profile_directory = "{}/.config/rzr/profiles".format(Path.home())
lightmap_directory = "{}/.config/rzr/lightmaps".format(Path.home())
# Create config folders if not existent
Path(profile_directory).mkdir(parents=True, exist_ok=True)
Path(lightmap_directory).mkdir(parents=True, exist_ok=True)
# Create device manager
try:
device_manager = DeviceManager()
except Exception as e:
print("failed to load device manager: {}".format(e))
print("is the openrazer-daemon running?")
exit(1)
# Parse arguments
parser = argparse.ArgumentParser(
description="Set color profiles of your Razer devices."
)
parser.add_argument(
"profile",
metavar="PROFILE",
nargs="?",
help="the profile which shall be applied (ignored if --iterate is set)",
)
parser.add_argument(
"-i",
"--iterate",
action="store_true",
help="iterate through all Razer devices and turn on one light after another",
)
args = parser.parse_args()
# Print greeter
print("rzr")
if args.iterate:
iterate_lights()
elif args.profile:
# Load profile
try:
profile = toml.load("{}/{}.toml".format(profile_directory, args.profile))
except FileNotFoundError:
print("the profile '{}' doesn't exist".format(args.profile))
if len(os.listdir(profile_directory)) > 0:
print("found the following profiles:")
for profile_file in os.listdir(profile_directory):
print(" - {}".format(profile_file[:-5]))
else:
print("found no profiles")
exit(1)
except Exception as e:
print(type(e))
print("error while loading profile: {}".format(args.profile))
exit(1)
for device in profile:
apply_lightmap(profile[device])
print("profile '{}' applied".format(args.profile))
else:
parser.error("either set a profile or --iterate")

20
profiles/template.toml Normal file
View file

@ -0,0 +1,20 @@
[mouse]
name = "Razer Mamba Elite"
lightmap = "razer_mamba_elite"
[mouse.lights]
wheel = "red"
logo = "red"
l0 = "red"
r0 = "red"
[keyboard]
name = "Razer BlackWidow Chroma"
lightmap = "razer_blackwidow_chroma_de"
[keyboard.lights]
w = "red"
a = "red"
s = "red"
d = "red"
logo = "green"

39
shell.nix Normal file
View file

@ -0,0 +1,39 @@
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = with pkgs; [
python3
python3Packages.virtualenv
python3Packages.colour
python3Packages.openrazer
python3Packages.toml
];
shellHook = ''
function log_header {
echo -ne "==> \e[32m\e[1m$1\e[0m\n"
}
function log_subheader {
echo -ne "--> \e[33m\e[1m$1\e[0m\n"
}
function log {
echo -ne " $1\n"
}
echo ""
log_header "python_environment"
if [ ! -d .venv ]; then
python -m venv .venv
fi
source .venv/bin/activate
log_subheader "upgrading pip"
pip install --upgrade pip
echo ""
if [ -s requirements.txt ]; then
log_subheader "found requirements.txt, installing packages"
pip install -r requirements.txt
echo ""
fi
log_header "package versions"
log "$(python --version)"
log "$(pip --version)"
'';
}