Skip to main content

Typed pure Python library to parse HID report descriptors

Project description

python-hid-parser

checks tests codecov PyPI version

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hid_parser-0.1.0.tar.gz (36.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hid_parser-0.1.0-py3-none-any.whl (26.3 kB view details)

Uploaded Python 3

File details

Details for the file hid_parser-0.1.0.tar.gz.

File metadata

  • Download URL: hid_parser-0.1.0.tar.gz
  • Upload date:
  • Size: 36.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-requests/2.32.3

File hashes

Hashes for hid_parser-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e7e96dd7c91772cf2de528e1200c40e571d9a5277ff4e6e04fe82dce1be5db99
MD5 6fa3a8d774568e48fe538449a47e07a4
BLAKE2b-256 d1c80f496dd0fd047c1796c73bdf713d954a28245d8af6f97c4b16105235942c

See more details on using hashes here.

File details

Details for the file hid_parser-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: hid_parser-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 26.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-requests/2.32.3

File hashes

Hashes for hid_parser-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 65111ea2eefb44e526f30e126db626ad6c6a8b83366573670cc07cffb3931665
MD5 7d614c23651d63ecae50be1aa421b4ed
BLAKE2b-256 1aea956a1545c6e2602b6dca99924859e33fcbbf4d3532e7a2fc65f3918e7363

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page