initial commit
This commit is contained in:
commit
c3ed9af8a0
7 changed files with 519 additions and 0 deletions
138
.gitignore
vendored
Normal file
138
.gitignore
vendored
Normal 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
12
README.org
Normal 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
|
||||||
109
lightmaps/razer_blackwidow_chroma_de.toml
Normal file
109
lightmaps/razer_blackwidow_chroma_de.toml
Normal 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]
|
||||||
20
lightmaps/razer_mamba_elite.toml
Normal file
20
lightmaps/razer_mamba_elite.toml
Normal 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
181
main.py
Normal 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
20
profiles/template.toml
Normal 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
39
shell.nix
Normal 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)"
|
||||||
|
'';
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue