Created
December 12, 2019 21:12
-
-
Save mdkcore0/bb11af19470ab6f741d971fc6eef1f5a to your computer and use it in GitHub Desktop.
python hid/pyusb test (linux/macos)
This file contains 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
# hid==1.0.4 | |
# pyusb==1.0.2 | |
# NOTE: should install hidpai (brew/package manager) | |
import hid | |
import binascii | |
# MAYBE, we can register a callback to be notified about device | |
# add/remove (https://github.com/pyusb/pyusb/pull/160) | |
from usb import core | |
from usb import util | |
def dec_to_hex(value): | |
return "{0:x}".format(value) | |
def str_to_int(value): | |
return int(value, base=16) | |
def str_to_hex(value): | |
return hex(str_to_int(value)) | |
class find_class(object): | |
def __init__(self, class_): | |
self._class = class_ | |
def __call__(self, device): | |
if device.bDeviceClass == self._class: | |
return True | |
for cfg in device: | |
intf = util.find_descriptor(cfg, bInterfaceClass=self._class) | |
if intf is not None: | |
return True | |
return False | |
# some info can be gathered by: | |
# $ lsusb -v | |
# or device specific: | |
# $ lsusb -d vid:pid -v | |
supported_devices = { | |
'Tipro': {'vendor_id': '1222', | |
'devices': [ | |
{'name': 'Handset Controller', | |
'product_id': 'facb'} | |
] | |
} | |
} | |
devices_to_bind = {} | |
# we can enumarate with vendor_id and product_id as well, useful after some | |
# type of hotplug event | |
for dev in hid.enumerate(): | |
manufacturer = dev.get('manufacturer_string') | |
product = dev.get('product_string') | |
if manufacturer in supported_devices: | |
for device in supported_devices[manufacturer]['devices']: | |
vendor_id = str_to_int( | |
supported_devices[manufacturer]['vendor_id']) | |
if product == device['name'] and \ | |
dec_to_hex(dev.get('product_id')) == device['product_id']: | |
product_id = str_to_int(device['product_id']) | |
# 3 == hid, 1 == audio | |
usb_device = core.find(custom_match=find_class(3), | |
idVendor=vendor_id, | |
idProduct=product_id) | |
# bInterfaceProtocol 0 (0 == None, 1 == Keyboard, 2 == Mouse) | |
# iInterface 7? | |
for conf in usb_device: | |
for interface in conf: | |
if interface.bInterfaceProtocol == 0 and \ | |
interface.bInterfaceNumber == dev.get( | |
'interface_number'): | |
devices_to_bind["%s %s" % (manufacturer, | |
product)] = \ | |
{'path': dev.get('path'), | |
'packet_size': interface[0].wMaxPacketSize} | |
print("devices to bind:", devices_to_bind) | |
# open a device to read it's data | |
# on linux we can open hidraw directly; check if we can do it on macos as well | |
d = hid.Device(path=devices_to_bind['Tipro Handset Controller']['path']) | |
packet_size = devices_to_bind['Tipro Handset Controller']['packet_size'] | |
while True: | |
# macos keep reading "0000000000000000" (or "0100000000000000") while idle | |
data = binascii.hexlify(d.read(packet_size)).decode() | |
if data: | |
print(data) | |
d.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment