3 # Python doesn't define any sort of ABI string, so we need to manually probe for it.
4 # If your OS/arch isn't supported yet, see lib/README for help.
9 def _get_shared_lib_name():
10 if sys.platform.startswith('linux'):
11 # This may fail for a x86_32 userland on a x86_64 kernel. platform.architecture can be used to work around it, if necessary
12 arch = platform.machine()
16 if arch == 'x86_64' and platform.architecture()[0] == '32bit':
17 # Whee! 32-bit python on a 64-bit kernel. The horror!
19 if arch[0] == 'i' and arch[2:] == '86':
21 # Any other variations need to be dealt with here.
23 return "lib/hidapi-%(platform)s-%(arch)s.so" % {"platform": sys.platform, "arch": arch}
24 elif sys.platform == 'darwin':
25 # This is completely backwards... both 32 and 64 report an i386.
26 # However, it may not matter; darwin supports fat binaries.
27 # If necessary, here's what I've found (very incomplete):
29 # arch* machine desired build
31 return "lib/hidapi-darwin.dylib"
32 elif sys.platform == 'win32':
33 # not yet fully supported. For now, assuming 32-bit x86.
34 return "lib/hidapi-win32-x86_32.dll"
36 print >>sys.stderr, "Your platform is not yet supported. Please let the devs know, or read lib/README for help fixing it."
37 raise Exception("Unsupported platform")
39 if __name__ == '__main__':
40 print "Would try to load %s" % _get_shared_lib_name()
42 _hidapi = CDLL(_get_shared_lib_name())
44 class _HidDeviceInfo(Structure):
47 _HidDeviceInfo._fields_ = [
49 ("vendor_id", c_ushort),
50 ("product_id", c_ushort),
51 ("serial_number", c_wchar_p),
52 ("release_number", c_ushort),
53 ("manufacturer_string", c_wchar_p),
54 ("product_string", c_wchar_p),
55 ("usage_page", c_ushort),
57 ("interface_number", c_int),
58 ("next", POINTER(_HidDeviceInfo))]
60 class HidDeviceInfo(object):
61 """User-facing version of the _HidDeviceInfo structure."""
63 def __init__(self, raw):
64 for attr in ("path", "vendor_id", "product_id", "serial_number", "release_number", "manufacturer_string", "product_string", "usage_page", "usage", "interface_number"):
65 setattr(self, attr, getattr(raw, attr))
68 return HidDevice(self.vendor_id, self.product_id, self.serial_number)
70 class _HidDevice_p(c_void_p):
73 class HidDevice(object):
74 def __init__(self, vid, pid=None, serial=None):
76 assert pid is None and serial is None
77 self._device = _hidapi.hid_open_path(vid)
79 self._device = _hidapi.hid_open(vid, pid, serial)
81 raise IOError("Failed to open device")
83 def write(self, string):
84 return _hidapi.hid_write(self._device, create_string_buffer(string), len(string))
85 def read(self, length):
86 buf = create_string_buffer(length)
87 olen = _hidapi.hid_read(self._device, buf, length)
88 return buf.raw[:length]
89 def set_nonblocking(self, nonblocking = True):
90 _hidapi.hid_set_nonblocking(self._device, nonblocking)
91 def send_feature_report(self, report_id, data):
92 buf = create_string_buffer(chr(report_id) + data)
94 return _hidapi.hid_send_feature_report(self._device, buf, len(data) + 1)
95 def get_feature_report(self, report_id, length):
96 # length does not include report id
97 buf = create_string_buffer(length + 1)
99 olen = _hidapi.hid_get_feature_report(self._device, buf, length + 1)
100 # BUG(thequux): Possible off-by-one error
101 return buf.raw[1:olen]
104 _hidapi.hid_close(self._device)
107 def get_manufacturer_string(_device):
108 buf = create_unicode_buffer(257)
109 _hidapi.hid_get_manufacturer_string(self._device, buf, 257)
112 def get_product_string(_device):
113 buf = create_unicode_buffer(257)
114 _hidapi.hid_get_product_string(self._device, buf, 257)
117 def get_serial_number_string(_device):
118 buf = create_unicode_buffer(257)
119 _hidapi.hid_get_serial_number_string(self._device, buf, 257)
122 def get_indexed_string(_device, index):
123 buf = create_unicode_buffer(257)
124 _hidapi.hid_get_indexed_string(self._device, index, buf, 257)
130 class HidApiError(IOError):
133 def _check_hid_error(result, func, args):
135 print args, _hidapi.hid_error(args[0])
136 raise HidApiError(_hidapi.hid_error(args[0]))
140 _hidapi.hid_enumerate.argtypes = [c_ushort, c_ushort]
141 _hidapi.hid_enumerate.restype = POINTER(_HidDeviceInfo)
143 _hidapi.hid_free_enumeration.argtypes = [POINTER(_HidDeviceInfo)]
145 _hidapi.hid_open.argtypes = [c_ushort, c_ushort, c_wchar_p]
146 _hidapi.hid_open.restype = _HidDevice_p
148 _hidapi.hid_open_path.argtypes = [c_char_p]
149 _hidapi.hid_open_path.restype = _HidDevice_p
151 _hidapi.hid_write.argtypes = [_HidDevice_p, POINTER(c_char), c_size_t]
152 _hidapi.hid_write.restype = c_int
153 _hidapi.hid_write.errcheck = _check_hid_error
155 _hidapi.hid_read.argtypes = [_HidDevice_p, POINTER(c_char), c_size_t]
156 _hidapi.hid_read.restype = c_int
157 _hidapi.hid_read.errcheck = _check_hid_error
159 _hidapi.hid_set_nonblocking.argtypes = [_HidDevice_p, c_int]
160 _hidapi.hid_set_nonblocking.restype = c_int
161 _hidapi.hid_set_nonblocking.errcheck = _check_hid_error
163 _hidapi.hid_send_feature_report.argtypes = [_HidDevice_p, POINTER(c_char), c_size_t]
164 _hidapi.hid_send_feature_report.restype = c_int
165 _hidapi.hid_send_feature_report.errcheck = _check_hid_error
167 _hidapi.hid_get_feature_report.argtypes = [_HidDevice_p, POINTER(c_char), c_size_t]
168 _hidapi.hid_get_feature_report.restype = c_int
169 _hidapi.hid_get_feature_report.errcheck = _check_hid_error
171 _hidapi.hid_close.argtypes = [_HidDevice_p]
173 _hidapi.hid_get_manufacturer_string.argtypes = [_HidDevice_p, POINTER(c_wchar), c_size_t]
174 _hidapi.hid_get_manufacturer_string.restype = c_int
175 _hidapi.hid_get_manufacturer_string.errcheck = _check_hid_error
177 _hidapi.hid_get_product_string.argtypes = [_HidDevice_p, POINTER(c_wchar), c_size_t]
178 _hidapi.hid_get_product_string.restype = c_int
179 _hidapi.hid_get_product_string.errcheck = _check_hid_error
181 _hidapi.hid_get_serial_number_string.argtypes = [_HidDevice_p, POINTER(c_wchar), c_size_t]
182 _hidapi.hid_get_serial_number_string.restype = c_int
183 _hidapi.hid_get_serial_number_string.errcheck = _check_hid_error
185 _hidapi.hid_get_indexed_string.argtypes = [_HidDevice_p, c_int, POINTER(c_wchar), c_size_t]
186 _hidapi.hid_get_indexed_string.restype = c_int
187 _hidapi.hid_get_indexed_string.errcheck = _check_hid_error
189 _hidapi.hid_error.argtypes = [_HidDevice_p]
190 _hidapi.hid_error.restype = c_wchar_p
192 def hid_enumerate(vid=0, pid=0):
193 """Enumerate the HID devices.
195 If vid == pid == 0, will enumerate all hid devices. Otherwise, just the ones with the given vid/pid.
198 List of HidDeviceInfo structures.
201 devs = _hidapi.hid_enumerate(vid,pid)
206 raw = raw_list.contents
208 ret.append(HidDeviceInfo(raw))
210 _hidapi.hid_free_enumeration(devs)
213 def hid_open(vid, pid, serial_number = None):
214 return HidDevice(vid, pid, serial_number)
216 def hid_open_path(path):
217 return HidDevice(path)
219 if __name__ == '__main__':
220 for dev in hid_enumerate():
221 print "%04x:%04x %30s <%s> <%s> %d" % (dev.vendor_id, dev.product_id, dev.serial_number, dev.manufacturer_string, dev.product_string, dev.interface_number)