Created
September 6, 2018 09:56
-
-
Save webermn15/dfbcf37129c4cb8e18fe1b2dad629926 to your computer and use it in GitHub Desktop.
small python script I wrote to handle generic usb controller binary data as keyboard inputs on linux using the PyUserInput module for issuing commands
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import time | |
| import threading | |
| import struct | |
| from pykeyboard import PyKeyboard | |
| # init keyboard | |
| kb = PyKeyboard() | |
| # declare local variables for reading controller's binary data | |
| # path to usb controller | |
| file_path = "/dev/input/js0" | |
| # calculate the size of the binary chunks | |
| event_size = struct.calcsize("LhBB") | |
| # pass Thread's get_info() method as an argument to check values for action | |
| def check_scroll(tup): | |
| # Thread.get_info() tuple deconstructed | |
| (value, itype, number) = tup | |
| if itype == 2 and number == 1: | |
| if value > 0: | |
| kb.press_keys(['Control_L', 'Down']) | |
| if value < 0: | |
| kb.press_keys(['Control_L', 'Up']) | |
| elif itype == 1 and number == 0: | |
| if value == 1: | |
| kb.press_key('Up') | |
| if value == 0: | |
| kb.release_key('Up') | |
| elif itype == 1 and number == 1: | |
| if value == 1: | |
| kb.press_key('Down') | |
| if value == 0: | |
| kb.release_key('Down') | |
| # Thread creating class with device binary reading loop when start() is called | |
| class ControllerPoller (threading.Thread): | |
| def __init__(self, path, calcsize): | |
| threading.Thread.__init__(self) | |
| self.path = path | |
| self.calcsize = calcsize | |
| self.value = 0 | |
| self.itype = 0 | |
| self.number = 0 | |
| """ | |
| the device file 'js0' is a special character file. when you read the file, | |
| as seen by opening the path and declaring 'r(read)b(binary)', then reading | |
| it with the appropriately prepared size of the buffer, it blocks in the | |
| `while event` loop. when new binary data is written, the loop reads it | |
| immediately and maps the latest device input values to the corresponding | |
| Thread values. | |
| """ | |
| def run(self): | |
| portal = open(self.path, "rb") | |
| event = portal.read(self.calcsize) | |
| while event: | |
| # print(struct.unpack("LhBB", event)) | |
| (msec, value, itype, number) = struct.unpack("LhBB", event) | |
| self.value = value | |
| self.itype = itype | |
| self.number = number | |
| event = portal.read(self.calcsize) | |
| # returns the current thread values as a tuple | |
| def get_info(self): | |
| return (self.value, self.itype, self.number) | |
| # instantiate a Thread | |
| poll_usb = ControllerPoller(file_path, event_size) | |
| # start the device polling | |
| poll_usb.start() | |
| # this is polling the controller via the updating Thread values every .0.25s | |
| while True: | |
| check_scroll(poll_usb.get_info()) | |
| time.sleep(0.025) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment