python-hid-parser
Typed pure Python library to parse HID report descriptors
Example
>>> import hid_parser
>>> simple_mouse_rdesc_raw = [
... 0x05, 0x01, # .Usage Page (Generic Desktop) 0
... 0x09, 0x02, # .Usage (Mouse) 2
... 0xa1, 0x01, # .Collection (Application) 4
... 0x09, 0x02, # ..Usage (Mouse) 6
... 0xa1, 0x02, # ..Collection (Logical) 8
... 0x09, 0x01, # ...Usage (Pointer) 10
... 0xa1, 0x00, # ...Collection (Physical) 12
... 0x05, 0x09, # ....Usage Page (Button) 14
... 0x19, 0x01, # ....Usage Minimum (1) 16
... 0x29, 0x03, # ....Usage Maximum (3) 18
... 0x15, 0x00, # ....Logical Minimum (0) 20
... 0x25, 0x01, # ....Logical Maximum (1) 22
... 0x75, 0x01, # ....Report Size (1) 24
... 0x95, 0x03, # ....Report Count (3) 26
... 0x81, 0x02, # ....Input (Data,Var,Abs) 28
... 0x75, 0x05, # ....Report Size (5) 30
... 0x95, 0x01, # ....Report Count (1) 32
... 0x81, 0x03, # ....Input (Cnst,Var,Abs) 34
... 0x05, 0x01, # ....Usage Page (Generic Desktop) 36
... 0x09, 0x30, # ....Usage (X) 38
... 0x09, 0x31, # ....Usage (Y) 40
... 0x15, 0x81, # ....Logical Minimum (-127) 42
... 0x25, 0x7f, # ....Logical Maximum (127) 44
... 0x75, 0x08, # ....Report Size (8) 46
... 0x95, 0x02, # ....Report Count (2) 48
... 0x81, 0x06, # ....Input (Data,Var,Rel) 50
... 0xc0, # ...End Collection 52
... 0xc0, # ..End Collection 53
... 0xc0, # .End Collection 54
... ]
>>> rdesc = hid_parser.ReportDescriptor(simple_mouse_rdesc_raw)
>>> rdesc.get_input_report_size()
3bytes
>>> for item in rdesc.get_input_items():
... print(item)
...
VariableItem(offset=0bits, size=1bit, usage=Usage(page=Button, usage=Button 1 (primary/trigger)))
VariableItem(offset=1bit, size=1bit, usage=Usage(page=Button, usage=Button 2 (secondary)))
VariableItem(offset=2bits, size=1bit, usage=Usage(page=Button, usage=Button 3 (tertiary)))
PaddingItem(offset=3bits, size=5bits)
VariableItem(offset=1byte, size=1byte, usage=Usage(page=Generic Desktop Controls, usage=X))
VariableItem(offset=2bytes, size=1byte, usage=Usage(page=Generic Desktop Controls, usage=Y))
>>> for usage, value in rdesc.parse_input_report([0b10100000, 0x50, 0x60]):
... print(f'{usage} = {value}')
...
Usage(page=Button, usage=Button 2 (secondary)) = False
Usage(page=Button, usage=Button 3 (tertiary)) = True
Usage(page=Button, usage=Button 1 (primary/trigger)) = True
Usage(page=Generic Desktop Controls, usage=X) = 80
Usage(page=Generic Desktop Controls, usage=Y) = 96
>>> import hid_parser
>>> keyboard_rdesc_raw = [
... 0x05, 0x01, # Usage Page (Generic Desktop) 0
... 0x09, 0x06, # Usage (Keyboard) 2
... 0xa1, 0x01, # Collection (Application) 4
... 0x05, 0x07, # Usage Page (Keyboard) 6
... 0x19, 0xe0, # Usage Minimum (224) 8
... 0x29, 0xe7, # Usage Maximum (231) 10
... 0x15, 0x00, # Logical Minimum (0) 12
... 0x25, 0x01, # Logical Maximum (1) 14
... 0x75, 0x01, # Report Size (1) 16
... 0x95, 0x08, # Report Count (8) 18
... 0x81, 0x02, # Input (Data,Var,Abs) 20
... 0x95, 0x01, # Report Count (1) 22
... 0x75, 0x08, # Report Size (8) 24
... 0x81, 0x01, # Input (Cnst,Arr,Abs) 26
... 0x95, 0x03, # Report Count (3) 28
... 0x75, 0x01, # Report Size (1) 30
... 0x05, 0x08, # Usage Page (LEDs) 32
... 0x19, 0x01, # Usage Minimum (1) 34
... 0x29, 0x03, # Usage Maximum (3) 36
... 0x91, 0x02, # Output (Data,Var,Abs) 38
... 0x95, 0x05, # Report Count (5) 40
... 0x75, 0x01, # Report Size (1) 42
... 0x91, 0x01, # Output (Cnst,Arr,Abs) 44
... 0x95, 0x06, # Report Count (6) 46
... 0x75, 0x08, # Report Size (8) 48
... 0x15, 0x00, # Logical Minimum (0) 50
... 0x26, 0xff, 0x00, # Logical Maximum (255) 52
... 0x05, 0x07, # Usage Page (Keyboard) 55
... 0x19, 0x00, # Usage Minimum (0) 57
... 0x2a, 0xff, 0x00, # Usage Maximum (255) 59
... 0x81, 0x00, # Input (Data,Arr,Abs) 62
... 0xc0, # End Collection 64
... ]
>>> rdesc = hid_parser.ReportDescriptor(keyboard_rdesc_raw)
>>> for item in rdesc.get_input_items():
... print(item)
...
VariableItem(offset=0bits, size=1bit, usage=Usage(page=Keyboard/Keypad, usage=Keyboard LeftControl))
VariableItem(offset=1bit, size=1bit, usage=Usage(page=Keyboard/Keypad, usage=Keyboard LeftShift))
VariableItem(offset=2bits, size=1bit, usage=Usage(page=Keyboard/Keypad, usage=Keyboard LeftAlt))
VariableItem(offset=3bits, size=1bit, usage=Usage(page=Keyboard/Keypad, usage=Keyboard Left GUI))
VariableItem(offset=4bits, size=1bit, usage=Usage(page=Keyboard/Keypad, usage=Keyboard RightControl))
VariableItem(offset=5bits, size=1bit, usage=Usage(page=Keyboard/Keypad, usage=Keyboard RightShift))
VariableItem(offset=6bits, size=1bit, usage=Usage(page=Keyboard/Keypad, usage=Keyboard RightAlt))
VariableItem(offset=7bits, size=1bit, usage=Usage(page=Keyboard/Keypad, usage=Keyboard Right GUI))
PaddingItem(offset=1byte, size=1byte)
ArrayItem(
offset=2bytes, size=1byte, count=6,
usages=[
Usage(page=Keyboard/Keypad, usage=No event indicated),
...
Usage(page=Keyboard/Keypad, usage=0x00ff),
],
)
>>> for usage, value in rdesc.parse_input_report([0b10100101, 0x00, 0x04, 0x05, 0x06, 0x00, 0x00, 0x00]):
... print(f'{usage} = {value}')
...
Usage(page=Keyboard/Keypad, usage=Keyboard Left GUI) = 0
Usage(page=Keyboard/Keypad, usage=Keyboard LeftAlt) = 1
Usage(page=Keyboard/Keypad, usage=Keyboard RightControl) = 0
Usage(page=Keyboard/Keypad, usage=Keyboard RightShift) = 1
Usage(page=Keyboard/Keypad, usage=Keyboard RightAlt) = 0
Usage(page=Keyboard/Keypad, usage=Keyboard Right GUI) = 1
Usage(page=Keyboard/Keypad, usage=Keyboard a and A) = True
Usage(page=Keyboard/Keypad, usage=Keyboard b and B) = True
Usage(page=Keyboard/Keypad, usage=Keyboard c and C) = True
Usage(page=Keyboard/Keypad, usage=Keyboard LeftShift) = 0
Usage(page=Keyboard/Keypad, usage=Keyboard LeftControl) = 1
>>> import hid_parser
>>> vendor_command_rdesc_raw = [
... 0x06, 0x00, 0xff, # .Usage Page (Vendor Defined Page 1) 0
... 0x09, 0x01, # .Usage (Vendor Usage 1) 3
... 0xa1, 0x01, # .Collection (Application) 5
... 0x85, 0x10, # ..Report ID (16) 7
... 0x75, 0x08, # ..Report Size (8) 9
... 0x95, 0x06, # ..Report Count (6) 11
... 0x15, 0x00, # ..Logical Minimum (0) 12
... 0x26, 0xff, 0x00, # ..Logical Maximum (255) 15
... 0x09, 0x01, # ..Usage (Vendor Usage 1) 18
... 0x81, 0x00, # ..Input (Data,Arr,Abs) 20
... 0x09, 0x01, # ..Usage (Vendor Usage 1) 22
... 0x91, 0x00, # ..Output (Data,Arr,Abs) 24
... 0xc0, # .End Collection 26
... ]
>>> rdesc = hid_parser.ReportDescriptor(vendor_command_rdesc_raw)
>>> rdesc.get_input_report_size(0x10)
6bytes
>>> for item in rdesc.get_input_items(0x10):
... print(item)
...
ArrayItem(
offset=0bits, size=1byte, count=6,
usages=[
Usage(page=Vendor Page, usage=0x0001),
],
)
>>> for usage, value in rdesc.parse_input_report([0x10, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]))
... print(f'{usage} = {value}')
...
Usage(page=Vendor Page, usage=0x0001) = 257
Usage(page=Vendor Page, usage=0x0002) = 514
Usage(page=Vendor Page, usage=0x0003) = 771
Usage(page=Vendor Page, usage=0x0004) = 1028
Usage(page=Vendor Page, usage=0x0005) = 1285
Usage(page=Vendor Page, usage=0x0006) = 1542
Metadata
Release files for hid-parser 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| hid_parser-0.1.0.tar.gz | 36.7 kB | Without provenance | Details for hid_parser-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| hid_parser-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for hid_parser-0.1.0-py3-none-any.whl |
Total release size: 63.0 kB
Release files / hid_parser-0.1.0.tar.gz
| Download URL | hid_parser-0.1.0.tar.gz |
|---|---|
| Size | 36.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e7e96dd7c91772cf2de528e1200c40e571d9a5277ff4e6e04fe82dce1be5db99
|
|
BLAKE2b-256 checksum How to use checksums |
d1c80f496dd0fd047c1796c73bdf713d954a28245d8af6f97c4b16105235942c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
python-requests/2.32.3
|
Release files / hid_parser-0.1.0-py3-none-any.whl
| Download URL | hid_parser-0.1.0-py3-none-any.whl |
|---|---|
| Size | 26.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
65111ea2eefb44e526f30e126db626ad6c6a8b83366573670cc07cffb3931665
|
|
BLAKE2b-256 checksum How to use checksums |
1aea956a1545c6e2602b6dca99924859e33fcbbf4d3532e7a2fc65f3918e7363
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
python-requests/2.32.3
|
Security for hid-parser 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.