Skip to content

Instantly share code, notes, and snippets.

@webermn15
Created September 6, 2018 09:56
Show Gist options
  • Select an option

  • Save webermn15/dfbcf37129c4cb8e18fe1b2dad629926 to your computer and use it in GitHub Desktop.

Select an option

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
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