PEP8 fixes

This commit is contained in:
Daniel Pavel 2012-09-19 07:43:09 +03:00
parent b45f9bfe49
commit 4b074e7dc2
3 changed files with 108 additions and 88 deletions

View File

@ -1,3 +1,3 @@
# pass # pass
__all__ = [ 'unifying_receiver' ] __all__ = ['unifying_receiver']

View File

@ -4,7 +4,8 @@ It is little more than a thin ctypes layer over a native hidapi implementation.
The docstrings are mostly copied from the hidapi API header, with changes where The docstrings are mostly copied from the hidapi API header, with changes where
necessary. necessary.
The native HID API implemenation is available at https://github.com/signal11/hidapi. The native HID API implemenation is available at
https://github.com/signal11/hidapi.
Using the native hidraw implementation is recommended. Using the native hidraw implementation is recommended.
Currently the native libusb implementation (temporarily) detaches the device's Currently the native libusb implementation (temporarily) detaches the device's
@ -19,22 +20,26 @@ from collections import namedtuple
from ctypes import ( from ctypes import (
cdll, create_string_buffer, create_unicode_buffer, cdll, create_string_buffer, create_unicode_buffer,
c_int, c_ushort, c_size_t, c_char_p, c_wchar_p, c_void_p, POINTER, Structure c_int, c_ushort, c_size_t,
c_char_p, c_wchar_p, c_void_p,
POINTER, Structure
) )
_hidapi = None _api = None
native_path = os.path.dirname(__file__) native_path = os.path.dirname(__file__)
for native_implementation in ('hidraw', 'libusb'): for native_implementation in ('hidraw', 'libusb'):
try: try:
native_lib = os.path.join(native_path, 'libhidapi-' + native_implementation + '.so') native_name = 'libhidapi-' + native_implementation + '.so'
_hidapi = cdll.LoadLibrary(native_lib) native_libfile = os.path.join(native_path, native_name)
_api = cdll.LoadLibrary(native_libfile)
break break
except OSError: except OSError:
pass pass
del native_path, native_lib, native_implementation del native_path, native_name, native_libfile, native_implementation
if _hidapi is None: if _api is None:
raise ImportError(__file__, 'failed to load any HID API native implementation') raise ImportError(__file__,
'failed to load any HID API native implementation')
# internally used by native hidapi, no need to expose it # internally used by native hidapi, no need to expose it
@ -84,59 +89,59 @@ def _DevInfoTuple(hid_device):
# set-up arguments and return types for each hidapi function # set-up arguments and return types for each hidapi function
# #
_hidapi.hid_init.argtypes = None _api.hid_init.argtypes = None
_hidapi.hid_init.restype = c_int _api.hid_init.restype = c_int
_hidapi.hid_exit.argtypes = None _api.hid_exit.argtypes = None
_hidapi.hid_exit.restype = c_int _api.hid_exit.restype = c_int
_hidapi.hid_enumerate.argtypes = [ c_ushort, c_ushort ] _api.hid_enumerate.argtypes = [c_ushort, c_ushort]
_hidapi.hid_enumerate.restype = POINTER(_DeviceInfo) _api.hid_enumerate.restype = POINTER(_DeviceInfo)
_hidapi.hid_free_enumeration.argtypes = [ POINTER(_DeviceInfo) ] _api.hid_free_enumeration.argtypes = [POINTER(_DeviceInfo)]
_hidapi.hid_free_enumeration.restype = None _api.hid_free_enumeration.restype = None
_hidapi.hid_open.argtypes = [ c_ushort, c_ushort, c_wchar_p ] _api.hid_open.argtypes = [c_ushort, c_ushort, c_wchar_p]
_hidapi.hid_open.restype = c_void_p _api.hid_open.restype = c_void_p
_hidapi.hid_open_path.argtypes = [ c_char_p ] _api.hid_open_path.argtypes = [c_char_p]
_hidapi.hid_open_path.restype = c_void_p # POINTER(_hid_device) _api.hid_open_path.restype = c_void_p
_hidapi.hid_close.argtypes = [ c_void_p ] _api.hid_close.argtypes = [c_void_p]
_hidapi.hid_close.restype = None _api.hid_close.restype = None
_hidapi.hid_write.argtypes = [ c_void_p, c_char_p, c_size_t ] _api.hid_write.argtypes = [c_void_p, c_char_p, c_size_t]
_hidapi.hid_write.restype = c_int _api.hid_write.restype = c_int
# _hidapi.hid_read.argtypes = [ c_void_p, c_char_p, c_size_t ] _api.hid_read.argtypes = [c_void_p, c_char_p, c_size_t]
# _hidapi.hid_read.restype = c_int _api.hid_read.restype = c_int
_hidapi.hid_read_timeout.argtypes = [ c_void_p, c_char_p, c_size_t, c_int ] _api.hid_read_timeout.argtypes = [c_void_p, c_char_p, c_size_t, c_int]
_hidapi.hid_read_timeout.restype = c_int _api.hid_read_timeout.restype = c_int
# _hidapi.hid_set_nonblocking.argtypes = [ c_void_p, c_int ] _api.hid_set_nonblocking.argtypes = [c_void_p, c_int]
# _hidapi.hid_set_nonblocking.restype = c_int _api.hid_set_nonblocking.restype = c_int
_hidapi.hid_send_feature_report.argtypes = [ c_void_p, c_char_p, c_size_t ] _api.hid_send_feature_report.argtypes = [c_void_p, c_char_p, c_size_t]
_hidapi.hid_send_feature_report.restype = c_int _api.hid_send_feature_report.restype = c_int
_hidapi.hid_get_feature_report.argtypes = [ c_void_p, c_char_p, c_size_t ] _api.hid_get_feature_report.argtypes = [c_void_p, c_char_p, c_size_t]
_hidapi.hid_get_feature_report.restype = c_int _api.hid_get_feature_report.restype = c_int
_hidapi.hid_get_manufacturer_string.argtypes = [ c_void_p, c_wchar_p, c_size_t ] _api.hid_get_manufacturer_string.argtypes = [c_void_p, c_wchar_p, c_size_t]
_hidapi.hid_get_manufacturer_string.restype = c_int _api.hid_get_manufacturer_string.restype = c_int
_hidapi.hid_get_product_string.argtypes = [ c_void_p, c_wchar_p, c_size_t ] _api.hid_get_product_string.argtypes = [c_void_p, c_wchar_p, c_size_t]
_hidapi.hid_get_product_string.restype = c_int _api.hid_get_product_string.restype = c_int
_hidapi.hid_get_serial_number_string.argtypes = [ c_void_p, c_wchar_p, c_size_t ] _api.hid_get_serial_number_string.argtypes = [c_void_p, c_wchar_p, c_size_t]
_hidapi.hid_get_serial_number_string.restype = c_int _api.hid_get_serial_number_string.restype = c_int
# _hidapi.hid_get_indexed_string.argtypes = [ c_void_p, c_int, c_wchar_p, c_size_t ] _api.hid_get_indexed_string.argtypes = [c_void_p, c_int, c_wchar_p, c_size_t]
# _hidapi.hid_get_indexed_string.restype = c_int _api.hid_get_indexed_string.restype = c_int
# _hidapi.hid_error.argtypes = [ c_void_p ] _api.hid_error.argtypes = [c_void_p]
# _hidapi.hid_error.restype = c_wchar_p _api.hid_error.restype = c_wchar_p
# #
@ -157,7 +162,7 @@ def init():
:returns: True if successful. :returns: True if successful.
""" """
return _hidapi.hid_init() == 0 return _api.hid_init() == 0
def exit(): def exit():
@ -169,7 +174,7 @@ def exit():
:returns: True if successful. :returns: True if successful.
""" """
return _hidapi.hid_exit() == 0 return _api.hid_exit() == 0
def enumerate(vendor_id=None, product_id=None, interface_number=None): def enumerate(vendor_id=None, product_id=None, interface_number=None):
@ -182,7 +187,7 @@ def enumerate(vendor_id=None, product_id=None, interface_number=None):
""" """
results = [] results = []
devices = _hidapi.hid_enumerate(vendor_id, product_id) devices = _api.hid_enumerate(vendor_id, product_id)
d = devices d = devices
while d: while d:
if interface_number is None or interface_number == d.contents.interface: if interface_number is None or interface_number == d.contents.interface:
@ -190,19 +195,21 @@ def enumerate(vendor_id=None, product_id=None, interface_number=None):
d = d.contents.next d = d.contents.next
if devices: if devices:
_hidapi.hid_free_enumeration(devices) _api.hid_free_enumeration(devices)
return results return results
def open(vendor_id, product_id, serial=None): def open(vendor_id, product_id, serial=None):
"""Open a HID device using a Vendor ID, Product ID and optionally a serial number. """Open a HID device using a Vendor ID, Product ID and optionally a serial
number.
If no serial_number is provided, the first device with the specified ids is opened. If no serial_number is provided, the first device with the specified ids
is opened.
:returns: an opaque device handle, or None. :returns: an opaque device handle, or None.
""" """
return _hidapi.hid_open(vendor_id, product_id, serial) or None return _api.hid_open(vendor_id, product_id, serial) or None
def open_path(device_path): def open_path(device_path):
@ -212,7 +219,7 @@ def open_path(device_path):
:returns: an opaque device handle, or None. :returns: an opaque device handle, or None.
""" """
return _hidapi.hid_open_path(device_path) or None return _api.hid_open_path(device_path) or None
def close(device_handle): def close(device_handle):
@ -220,14 +227,15 @@ def close(device_handle):
:param device_handle: a device handle returned by open() or open_path(). :param device_handle: a device handle returned by open() or open_path().
""" """
_hidapi.hid_close(device_handle) _api.hid_close(device_handle)
def write(device_handle, data): def write(device_handle, data):
"""Write an Output report to a HID device. """Write an Output report to a HID device.
:param device_handle: a device handle returned by open() or open_path(). :param device_handle: a device handle returned by open() or open_path().
:param data: the data bytes to send including the report number as the first byte. :param data: the data bytes to send including the report number as the
first byte.
The first byte of data[] must contain the Report ID. For The first byte of data[] must contain the Report ID. For
devices which only support a single report, this must be set devices which only support a single report, this must be set
@ -245,7 +253,7 @@ def write(device_handle, data):
:returns: True if the write was successful. :returns: True if the write was successful.
""" """
bytes_written = _hidapi.hid_write(device_handle, c_char_p(data), len(data)) bytes_written = _api.hid_write(device_handle, c_char_p(data), len(data))
return bytes_written > -1 return bytes_written > -1
@ -265,7 +273,8 @@ def read(device_handle, bytes_count, timeout_ms=-1):
:returns: the bytes read, or None if a timeout was reached. :returns: the bytes read, or None if a timeout was reached.
""" """
out_buffer = create_string_buffer('\x00' * (bytes_count + 1)) out_buffer = create_string_buffer('\x00' * (bytes_count + 1))
bytes_read = _hidapi.hid_read_timeout(device_handle, out_buffer, bytes_count, timeout_ms) bytes_read = _api.hid_read_timeout(device_handle,
out_buffer, bytes_count, timeout_ms)
if bytes_read > -1: if bytes_read > -1:
return out_buffer[:bytes_read] return out_buffer[:bytes_read]
@ -274,7 +283,8 @@ def send_feature_report(device_handle, data, report_number=None):
"""Send a Feature report to the device. """Send a Feature report to the device.
:param device_handle: a device handle returned by open() or open_path(). :param device_handle: a device handle returned by open() or open_path().
:param data: the data bytes to send including the report number as the first byte. :param data: the data bytes to send including the report number as the
first byte.
:param report_number: if set, it is sent as the first byte with the data. :param report_number: if set, it is sent as the first byte with the data.
Feature reports are sent over the Control endpoint as a Feature reports are sent over the Control endpoint as a
@ -293,7 +303,8 @@ def send_feature_report(device_handle, data, report_number=None):
""" """
if report_number is not None: if report_number is not None:
data = chr(report_number) + data data = chr(report_number) + data
bytes_written = _hidapi.hid_send_feature_report(device_handle, c_char_p(data), len(data)) bytes_written = _api.hid_send_feature_report(
device_handle, c_char_p(data), len(data))
return bytes_written > -1 return bytes_written > -1
@ -309,7 +320,8 @@ def get_feature_report(device_handle, bytes_count, report_number=None):
out_buffer = create_string_buffer('\x00' * (bytes_count + 2)) out_buffer = create_string_buffer('\x00' * (bytes_count + 2))
if report_number is not None: if report_number is not None:
out_buffer[0] = chr(report_number) out_buffer[0] = chr(report_number)
bytes_read = _hidapi.hid_get_feature_report(device_handle, out_buffer, bytes_count) bytes_read = _api.hid_get_feature_report(
device_handle, out_buffer, bytes_count)
if bytes_read > -1: if bytes_read > -1:
return out_buffer[:bytes_read] return out_buffer[:bytes_read]
@ -330,7 +342,7 @@ def get_manufacturer(device_handle):
:param device_handle: a device handle returned by open() or open_path(). :param device_handle: a device handle returned by open() or open_path().
""" """
return _read_wchar(_hidapi.hid_get_manufacturer_string, device_handle) return _read_wchar(_api.hid_get_manufacturer_string, device_handle)
def get_product(device_handle): def get_product(device_handle):
@ -338,7 +350,7 @@ def get_product(device_handle):
:param device_handle: a device handle returned by open() or open_path(). :param device_handle: a device handle returned by open() or open_path().
""" """
return _read_wchar(_hidapi.hid_get_product_string, device_handle) return _read_wchar(_api.hid_get_product_string, device_handle)
def get_serial(device_handle): def get_serial(device_handle):
@ -346,7 +358,7 @@ def get_serial(device_handle):
:param device_handle: a device handle returned by open() or open_path(). :param device_handle: a device handle returned by open() or open_path().
""" """
serial = _read_wchar(_hidapi.hid_get_serial_number_string, device_handle) serial = _read_wchar(_api.hid_get_serial_number_string, device_handle)
if serial is not None: if serial is not None:
return ''.join(hex(ord(c)) for c in serial) return ''.join(hex(ord(c)) for c in serial)
@ -355,4 +367,4 @@ def get_serial(device_handle):
# """ # """
# :param device_handle: a device handle returned by open() or open_path(). # :param device_handle: a device handle returned by open() or open_path().
# """ # """
# return _read_wchar(_hidapi.hid_get_indexed_string, device_handle, index) # return _read_wchar(_api.hid_get_indexed_string, device_handle, index)

View File

@ -5,10 +5,10 @@ Incomplete. Based on a bit of documentation, trial-and-error, and guesswork.
References: References:
http://julien.danjou.info/blog/2012/logitech-k750-linux-support http://julien.danjou.info/blog/2012/logitech-k750-linux-support
http://6xq.net/git/lars/lshidpp.git/plain/doc/logitech_hidpp_2.0_specification_draft_2012-06-04.pdf http://6xq.net/git/lars/lshidpp.git/plain/doc
""" """
# import logging import logging
from . import hidapi from . import hidapi
@ -36,7 +36,8 @@ FEATURE_GET_SOLAR_CHARGE = '\x43\x01'
FEATURE_UNKNOWN_4 = '\x45\x20' FEATURE_UNKNOWN_4 = '\x45\x20'
DEVICE_TYPES = ( "Keyboard", "Remote Control", "NUMPAD", "Mouse", "Touchpad", "Trackball", "Presenter", "Receiver" ) DEVICE_TYPES = ("Keyboard", "Remote Control", "NUMPAD", "Mouse",
"Touchpad", "Trackball", "Presenter", "Receiver")
_DEVICE_FEATURES = {} _DEVICE_FEATURES = {}
@ -45,7 +46,7 @@ def _write(receiver, device, data):
# just in case # just in case
# hidapi.read(receiver, 128, 0) # hidapi.read(receiver, 128, 0)
data = '\x10' + chr(device) + data data = '\x10' + chr(device) + data
# print "w[", data.encode("hex"), "]", logging.debug("w[%s]", data.encode("hex"))
return hidapi.write(receiver, data) return hidapi.write(receiver, data)
@ -81,7 +82,7 @@ def _read(receiver, device, timeout=_TIMEOUT):
def _get_feature_index(receiver, device, feature_id): def _get_feature_index(receiver, device, feature_id):
if device not in _DEVICE_FEATURES: if device not in _DEVICE_FEATURES:
_DEVICE_FEATURES[device] = [ 0 ] * 0x10 _DEVICE_FEATURES[device] = [0] * 0x10
pass pass
elif feature_id in _DEVICE_FEATURES[device]: elif feature_id in _DEVICE_FEATURES[device]:
return _DEVICE_FEATURES[device].index(feature_id) return _DEVICE_FEATURES[device].index(feature_id)
@ -110,13 +111,15 @@ def _get_feature_index(receiver, device, feature_id):
return 0 return 0
def _request(receiver, device, feature_id, function='\x00', param1='\x00', param2='\x00', param3='\x00', reply_function=None): def _req(receiver, device, feature_id, function='\x00',
param1='\x00', param2='\x00', param3='\x00', reply_function=None):
feature_index = _get_feature_index(receiver, device, feature_id) feature_index = _get_feature_index(receiver, device, feature_id)
if not feature_index or feature_index == -1: if not feature_index:
return None return None
feature_index = chr(feature_index) feature_index = chr(feature_index)
if not _write(receiver, device, feature_index + function + param1 + param2 + param3): if not _write(receiver, device,
feature_index + function + param1 + param2 + param3):
# print "write failed, closing receiver" # print "write failed, closing receiver"
close(receiver) close(receiver)
raise NoReceiver() raise NoReceiver()
@ -143,11 +146,11 @@ def _request(receiver, device, feature_id, function='\x00', param1='\x00', param
def _get_feature_set(receiver, device): def _get_feature_set(receiver, device):
features = [ 0 ] * 0x10 features = [0] * 0x10
reply = _request(receiver, device, FEATURE_GET_FEATURE_SET) reply = _req(receiver, device, FEATURE_GET_FEATURE_SET)
if reply: if reply:
for index in range(1, 1 + ord(reply[4])): for index in range(1, 1 + ord(reply[4])):
reply = _request(receiver, device, FEATURE_GET_FEATURE_SET, '\x10', chr(index)) reply = _req(receiver, device, FEATURE_GET_FEATURE_SET, '\x10', chr(index))
if reply: if reply:
features[index] = reply[4:6].upper() features[index] = reply[4:6].upper()
# print "feature", reply[4:6].encode('hex'), "index", index # print "feature", reply[4:6].encode('hex'), "index", index
@ -189,7 +192,7 @@ def open():
# print "nope" # print "nope"
pass pass
elif reply[:4] == "\x10\x00\x8F\x00": elif reply[:4] == "\x10\x00\x8F\x00":
# print "found" # print "found", receiver
return receiver return receiver
# print "unknown" # print "unknown"
else: else:
@ -234,13 +237,13 @@ def ping(receiver, device):
def get_name(receiver, device): def get_name(receiver, device):
reply = _request(receiver, device, FEATURE_GET_NAME) reply = _req(receiver, device, FEATURE_GET_NAME)
if reply: if reply:
charcount = ord(reply[4]) charcount = ord(reply[4])
name = '' name = ''
index = 0 index = 0
while len(name) < charcount: while len(name) < charcount:
reply = _request(receiver, device, FEATURE_GET_NAME, '\x10', chr(index)) reply = _req(receiver, device, FEATURE_GET_NAME, '\x10', chr(index))
if reply: if reply:
name += reply[4:4 + charcount - index] name += reply[4:4 + charcount - index]
index = len(name) index = len(name)
@ -250,35 +253,39 @@ def get_name(receiver, device):
def get_type(receiver, device): def get_type(receiver, device):
reply = _request(receiver, device, FEATURE_GET_NAME, '\x20') reply = _req(receiver, device, FEATURE_GET_NAME, '\x20')
if reply: if reply:
return DEVICE_TYPES[ord(reply[4])] return DEVICE_TYPES[ord(reply[4])]
def get_firmware_version(receiver, device, firmware_type=0): def get_firmware_version(receiver, device, firmware_type=0):
reply = _request(receiver, device, FEATURE_GET_FIRMWARE, '\x10', chr(firmware_type)) reply = _req(receiver, device,
FEATURE_GET_FIRMWARE, '\x10', chr(firmware_type))
if reply: if reply:
return '%s %s.%s' % (reply[5:8], reply[8:10].encode('hex'), reply[10:12].encode('hex')) return '%s %s.%s' % (
reply[5:8], reply[8:10].encode('hex'), reply[10:12].encode('hex'))
def get_battery_level(receiver, device): def get_battery_level(receiver, device):
reply = _request(receiver, device, FEATURE_GET_BATTERY) reply = _req(receiver, device, FEATURE_GET_BATTERY)
if reply: if reply:
return ( ord(reply[4]), ord(reply[5]), ord(reply[6]) ) return (ord(reply[4]), ord(reply[5]), ord(reply[6]))
def get_reprogrammable_keys(receiver, device): def get_reprogrammable_keys(receiver, device):
count = _request(receiver, device, FEATURE_GET_REPROGRAMMABLE_KEYS) count = _req(receiver, device, FEATURE_GET_REPROGRAMMABLE_KEYS)
if count: if count:
keys = [] keys = []
for index in range(ord(count[4])): for index in range(ord(count[4])):
key = _request(receiver, device, FEATURE_GET_REPROGRAMMABLE_KEYS, '\x10', chr(index)) key = _req(receiver, device,
keys.append( key[4:6], keys[6:8], ord(key[8]) ) FEATURE_GET_REPROGRAMMABLE_KEYS, '\x10', chr(index))
keys.append(key[4:6], keys[6:8], ord(key[8]))
return keys return keys
def get_solar_charge(receiver, device): def get_solar_charge(receiver, device):
reply = _request(receiver, device, FEATURE_GET_SOLAR_CHARGE, '\x03', '\x78', '\x01', reply_function='\x10') reply = _req(receiver, device,
FEATURE_GET_SOLAR_CHARGE, '\x03', '\x78', '\x01', reply_function='\x10')
if reply: if reply:
charge = ord(reply[4]) charge = ord(reply[4])
lux = ord(reply[5]) << 8 | ord(reply[6]) lux = ord(reply[5]) << 8 | ord(reply[6])
@ -298,7 +305,8 @@ def find_device(receiver, match_device_type=None, match_name=None):
_DEVICE_FEATURES[device] = _get_feature_set(receiver, device) _DEVICE_FEATURES[device] = _get_feature_set(receiver, device)
# print get_reprogrammable_keys(receiver, device) # print get_reprogrammable_keys(receiver, device)
# d_firmware = get_firmware_version(receiver, device) # d_firmware = get_firmware_version(receiver, device)
# print "device", device, "[", d_name, "/", d_type, "] firmware", d_firmware, "features", _DEVICE_FEATURES[device] # print "device", device, "[", d_name, "/", d_type, "]"
# print "firmware", d_firmware, "features", _DEVICE_FEATURES[device]
if match_device_type: if match_device_type:
d_type = get_type(receiver, device) d_type = get_type(receiver, device)
if d_type is None or match_device_type.lower() != d_type.lower(): if d_type is None or match_device_type.lower() != d_type.lower():