diff --git a/create_keyboard_map.py b/create_keyboard_map.py index 636c0bc..444c7b3 100755 --- a/create_keyboard_map.py +++ b/create_keyboard_map.py @@ -1,34 +1,20 @@ #! /bin/python3 +from .keyboard import Keyboard +from .keymap import Keymap +from .color import Color import openrazer.client -import json -from pathlib import Path -from pynput import keyboard -def get_keyboard(): - devman = openrazer.client.DeviceManager() +from pynput import keyboard as keyboardnput - for device in devman.devices: - if (device.name == "Razer BlackWidow Chroma V2"): - return device - return None -def clear_all(kbd): - # Set full keyboard to green - for row in range(0,kbd_rows): - for column in range(0, kbd_columns): - kbd.fx.advanced.matrix[row,column] = [0, 0, 0] +keyboard = Keyboard(no_keymap=True) - -kbd = get_keyboard() -if (kbd == None): - print("No Razer device with devicename 'Razer Blackwidow Chroma V2' found.") +if not keyboard.found_keyboard(): + print("No keyboard was found") exit() -kbd_rows, kbd_columns = kbd.fx.advanced.rows, kbd.fx.advanced.cols - - last_key_pressed = None def on_press(key): global last_key_pressed @@ -36,35 +22,30 @@ def on_press(key): return False def get_key(): - with keyboard.Listener(on_press=on_press) as listener: + with keyboardnput.Listener(on_press=on_press) as listener: listener.join() def set_key_columns(keymap, column_range, prefix=""): - for row in range(0,kbd_rows): + for row in range(0, 6): for column in column_range: - clear_all(kbd) - kbd.fx.advanced.matrix[row,column] = [255, 255, 255] - kbd.fx.advanced.draw() + keyboard.clear() + keyboard.set_key(row,column, Color(255, 255, 255)) + keyboard.draw() get_key() print('{} was pressed'.format(last_key_pressed)) - keymap[prefix + str(last_key_pressed)] = row * kbd_columns + column + keymap[prefix + str(last_key_pressed)] = row * 22 + column def iter_keys(): keymap = dict() print("Make sure caps lock and numpad are disabled, if not, do it now and restart the script") print("This script will iterate over all keys, row by row. When a key lights up white, press it, and use the mouse to cancel any F-key effects. First, we'll skip the numpad. If no key lights up, press the bottom-right most key, excluding the numpad().") - set_key_columns(keymap, range(0,18)) + set_key_columns(keymap, range(0, 18)) print("Now we'll iterate over the numpad, if no key lights up, press the bottom right key(enter)") - set_key_columns(keymap, range(18,kbd_columns), "num_") + set_key_columns(keymap, range(18, 22), "num_") return keymap -def write_keymap_file(dictionary): - keymap_json = json.dumps(keymap) - path = Path.home() / '.config/openrazer_scripter/keymap.json' - Path(path.parent).mkdir(parents=True, exist_ok=True) - with open(path,'w') as keymap_file: - keymap_file.write(keymap_json) -keymap = iter_keys() -write_keymap_file(keymap) +keymap = Keymap() +keymap.set_keys(iter_keys()) +keymap.write_keymap_file() print('Saved keymap to file (.config/openrazer_scripter/keymap.json)') diff --git a/keyboard.py b/keyboard.py index 771b48a..9b1fe9a 100644 --- a/keyboard.py +++ b/keyboard.py @@ -1,26 +1,71 @@ -import openrazer.client -import json import warnings -from pathlib import Path +from collections.abc import Iterable + +import openrazer.client -class keyboard: +from .color import Color +from .keymap import Keymap + + +class Keyboard: """Provides tooling to call openrazer.client.device""" - def __init__(self): + def __init__(self, no_keymap = False): self.kbd = None self.find_keyboard() if self.kbd is None: warnings.warn('Compatible keyboard was not detected', RuntimeWarning) + if not no_keymap: + self.keymap = Keymap() + self.keymap.load_from_file() + def find_keyboard(self): if self.kbd is not None: print('keyboard was already initiated') - return + return True devman = openrazer.client.DeviceManager() for device in devman.devices: if (device.name == "Razer BlackWidow Chroma V2"): self.kbd = device - return \ No newline at end of file + return True + return False + + def found_keyboard(self): + return self.kbd is not None + + def set_keys(self, color, *keys): + if not isinstance(color, Color): + print(f"Color {color} for key(s) '{keys}' is no instance of Color, skipping.") + return False + for key in keys: + if isinstance(key, Iterable) and not isinstance(key, str): # Allow for iterables (lists etc) of keys to be parsed + for single_key in key: + self.set_keys(color, single_key) + else: + location = self.keymap.get_location(key) + self.kbd.fx.advanced.matrix[location] = [color.red, color.green, color.blue] + return True + + def set_key(self, row, column, color): + if not isinstance(color, Color): + print(f"Color '{color}' for key {row},{column} is no instance of Color, skipping.") + return False + self.kbd.fx.advanced.matrix[row, column] = [color.red, color.green, color.blue] + + def set_static(self, color): + if not isinstance(color, Color): + print(f"Color for set_static() is no instance of Color, skipping.") + return False + for row in range(0,6): + for column in range(0, 22): + self.kbd.fx.advanced.matrix[row,column] = [color.red, color.green, color.blue] + + def clear(self): + self.set_static(Color(0, 0, 0)) + + def draw(self): + self.kbd.fx.advanced.draw() diff --git a/main.py b/main.py index 400654f..f2f0480 100755 --- a/main.py +++ b/main.py @@ -1,80 +1,15 @@ -import openrazer.client +from .keyboard import Keyboard +from .color import Color import json from pathlib import Path import math -def get_keyboard(): - devman = openrazer.client.DeviceManager() - for device in devman.devices: - if (device.name == 'Razer BlackWidow Chroma V2'): - return device - return None +keyboard = Keyboard() -def read_keymap_file(path = ''): - if path == '': - path = Path.home() / '.config/openrazer_scripter/keymap.json' - keymap = None - with open(path,'r') as keymap_file: - keymap = json.load(keymap_file) - return keymap - -kbd = get_keyboard() -if (kbd == None): - print("No Razer device with devicename 'Razer Blackwidow Chroma V2' found.") +if not keyboard.found_keyboard(): + print("No keyboard was found") exit() -keymap = read_keymap_file() - -def set_static(kbd, color): - color = get_rgb(color) - if color is None: - print(f"Color set_static() was incorrect, skipping.") - return - for row in range(0,6): - for column in range(0, 22): - kbd.fx.advanced.matrix[row,column] = [color[0], color[1], color[2]] - -def check_color_value(value): - if not isinstance(value, int): - print(f"Colorvalue '{value}' is not a number") - return False - if value < 0 or value > 255: - print(f"Color value '{value}' is out of bounds (0-255)") - return False - return True - -def get_rgb(color): - r, g, b = None, None, None - if isinstance(color, str): - if len(color) == 6: - color = tuple(int(color[i:i+2], 16) for i in (0, 2, 4)) - if len(color) == 3: - r = color[0] - g = color[1] - b = color[2] - else: - print(f"Could not interpert color '{color}'") - return None - if check_color_value(r) and check_color_value(g) and check_color_value(b): - return r, g, b - else: - print(f"Color '{color}' is out of range") - return None - -def get_row_column(index): - row = math.floor(index / 22) - column = index % 22 - return row, column - -def set_keys(kbd, color, *keys): - color = get_rgb(color) - if color is None: - print(f"Color for key(s) '{keys}' was incorrect, skipping.") - return - for key in keys: - if key in keymap: - position = get_row_column(keymap[key]) - kbd.fx.advanced.matrix[position[0], position[1]] = [color[0], color[1], color[2]] -set_static(kbd, (255,255,255)) -set_keys(kbd, 'ff0000', 'enter') -kbd.fx.advanced.draw() +keyboard.set_static(Color(255,255,255)) +keyboard.set_keys('ff0000', 'enter') +keyboard.draw() \ No newline at end of file diff --git a/test_keyboard_map.py b/test_keyboard_map.py index 8da9b75..5faa427 100755 --- a/test_keyboard_map.py +++ b/test_keyboard_map.py @@ -1,65 +1,30 @@ #! /bin/python3 -import openrazer.client -import json -from pathlib import Path -import math +from .keyboard import Keyboard +from .color import Color +from .keymap import Keymap -def get_keyboard(): - devman = openrazer.client.DeviceManager() - - for device in devman.devices: - if (device.name == "Razer BlackWidow Chroma V2"): - return device - - return None - -def clear_all(kbd): - # Set full keyboard to green - for row in range(0, 6): - for column in range(0, 22): - kbd.fx.advanced.matrix[row,column] = [0, 0, 0] - - -kbd = get_keyboard() -if (kbd == None): - print("No Razer device with devicename 'Razer Blackwidow Chroma V2' found.") +keyboard = Keyboard(no_keymap=False) +if not keyboard.found_keyboard(): + print("No keyboard was found") exit() -def read_keymap_file(): - path = Path.home() / '.config/openrazer_scripter/keymap.json' - keymap = None - with open(path,'r') as keymap_file: - keymap = json.load(keymap_file) - return keymap - -def get_row_column(index): - row = math.floor(index / 22) - column = index % 22 - return row, column - -def set_all_white(kbd, keymap): - clear_all(kbd) - for key, value in keymap.items(): - position = get_row_column(value) - kbd.fx.advanced.matrix[position[0], position[1]] = [255,255,255] - kbd.fx.advanced.draw() - def sort_dict(dictionary): return {k: v for k, v in sorted(dictionary.items(), key=lambda item: item[1])} -def iter_keys(kbd, keymap): - keymap = sort_dict(keymap) - for key, value in keymap.items(): - clear_all(kbd) - position = get_row_column(value) +def iter_keys(keymap): + sorted_keys = sort_dict(keymap.keys) + for key in sorted_keys.keys(): + keyboard.clear() print(f'key: {key}') - kbd.fx.advanced.matrix[position[0], position[1]] = [255,255,255] - kbd.fx.advanced.draw() + keyboard.set_keys(Color(255, 255, 255), key) + keyboard.draw() input() -keymap = read_keymap_file() +keymap = keyboard.keymap + while True: - set_all_white(kbd, keymap) + keyboard.set_keys(Color(255, 255, 255), list(keymap.keys.keys())) + keyboard.draw() input("Press Enter to continue...") - iter_keys(kbd, keymap) + iter_keys(keymap)