tools: hidconsole can send an HID command non-interactively

This commit is contained in:
Peter F. Patel-Schneider 2025-12-17 15:43:56 -05:00
parent e999b12246
commit a0e19282ec
1 changed files with 20 additions and 13 deletions

View File

@ -135,10 +135,10 @@ def _open(args):
if vid == LOGITECH_VENDOR_ID: if vid == LOGITECH_VENDOR_ID:
return {"vid": vid} return {"vid": vid}
device = args.device device = args.path
if args.hidpp and not device: if not device:
for d in hidapi.enumerate(matchfn): for d in hidapi.enumerate(matchfn):
if d.driver == "logitech-djreceiver": if (d.hidpp_short or d.hidpp_long) and (args.usb is None or args.usb.lower() == d.product_id.lower()):
device = d.path device = d.path
break break
if not device: if not device:
@ -146,13 +146,12 @@ def _open(args):
if not device: if not device:
sys.exit("!! Device path required.") sys.exit("!! Device path required.")
print(".. Opening device", device)
handle = hidapi.open_path(device) handle = hidapi.open_path(device)
if not handle: if not handle:
sys.exit(f"!! Failed to open {device}, aborting.") sys.exit(f"!! Failed to open {device}, aborting.")
print( print(
".. Opened handle %r, vendor %r product %r serial %r." ".. Opened device %r, vendor %r product %r serial %r."
% (handle, hidapi.get_manufacturer(handle), hidapi.get_product(handle), hidapi.get_serial(handle)) % (device, hidapi.get_manufacturer(handle), hidapi.get_product(handle), hidapi.get_serial(handle))
) )
if args.hidpp: if args.hidpp:
if hidapi.get_manufacturer(handle) is not None and hidapi.get_manufacturer(handle) != b"Logitech": if hidapi.get_manufacturer(handle) is not None and hidapi.get_manufacturer(handle) != b"Logitech":
@ -170,12 +169,10 @@ def _parse_arguments():
arg_parser = argparse.ArgumentParser() arg_parser = argparse.ArgumentParser()
arg_parser.add_argument("--history", help="history file (default ~/.hidconsole-history)") arg_parser.add_argument("--history", help="history file (default ~/.hidconsole-history)")
arg_parser.add_argument("--hidpp", action="store_true", help="ensure input data is a valid HID++ request") arg_parser.add_argument("--hidpp", action="store_true", help="ensure input data is a valid HID++ request")
arg_parser.add_argument( arg_parser.add_argument("command", nargs="?", help="command to send (otherwise get commands from input)")
"device", group = arg_parser.add_mutually_exclusive_group()
nargs="?", group.add_argument("-p", "--path", help="HID raw device to connect to (/dev/hidrawX); ")
help="linux device to connect to (/dev/hidrawX); " group.add_argument("-u", "--usb", help="USB model of device to connect to (XXXX)")
"may be omitted if --hidpp is given, in which case it looks for the first Logitech receiver",
)
return arg_parser.parse_args() return arg_parser.parse_args()
@ -183,6 +180,17 @@ def main():
args = _parse_arguments() args = _parse_arguments()
handle = _open(args) handle = _open(args)
if args.command: # send a command
data = _validate_input(args.command, args.hidpp)
if data:
hidapi.write(handle, data)
reply = hidapi.read(handle, 128, 1)
if reply:
hexs = strhex(reply)
s = "[%s %s %s %s] %s" % (hexs[0:2], hexs[2:4], hexs[4:8], hexs[8:], repr(data))
print(s)
exit()
if interactive: if interactive:
print(".. Press ^C/^D to exit, or type hex bytes to write to the device.") print(".. Press ^C/^D to exit, or type hex bytes to write to the device.")
@ -232,7 +240,6 @@ def main():
time.sleep(1) time.sleep(1)
finally: finally:
print(f".. Closing handle {handle!r}")
hidapi.close(handle) hidapi.close(handle)
if interactive: if interactive:
readline.write_history_file(args.history) readline.write_history_file(args.history)