diff --git a/.idea/misc.xml b/.idea/misc.xml index a6218fe..99352d3 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/.idea/pyspacemouse.iml b/.idea/pyspacemouse.iml index b5ad51a..06d5607 100644 --- a/.idea/pyspacemouse.iml +++ b/.idea/pyspacemouse.iml @@ -1,8 +1,10 @@ - - + + + + diff --git a/README.md b/README.md index 34ee53c..2046dfc 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,27 @@ if success: ```` More examples can be found in the [/examples](https://github.com/JakubAndrysek/PySpaceMouse/tree/master/examples) directory or in page with [Examples](https://spacemouse.kubaandrysek.cz/mouseApi/examples/). +## Available CLI test commands +```bash +usage: pyspacemouse [-h] [--version] [--list-spacemouse] + [--list-supported-devices] [--list-all-hid-devices] + [--test-connect] + +PySpaceMouse CLI + +options: + -h, --help show this help message and exit + --version Version of pyspacemouse + --list-spacemouse List connected SpaceMouse devices + --list-supported-devices + List supported SpaceMouse devices + --list-all-hid-devices + List all connected HID devices + --test-connect Test connect to the first available device + +For more information, visit https://spacemouse.kubaandrysek.cz +``` + ## Troubleshooting diff --git a/docs/README.md b/docs/README.md index 34ee53c..2046dfc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -121,6 +121,27 @@ if success: ```` More examples can be found in the [/examples](https://github.com/JakubAndrysek/PySpaceMouse/tree/master/examples) directory or in page with [Examples](https://spacemouse.kubaandrysek.cz/mouseApi/examples/). +## Available CLI test commands +```bash +usage: pyspacemouse [-h] [--version] [--list-spacemouse] + [--list-supported-devices] [--list-all-hid-devices] + [--test-connect] + +PySpaceMouse CLI + +options: + -h, --help show this help message and exit + --version Version of pyspacemouse + --list-spacemouse List connected SpaceMouse devices + --list-supported-devices + List supported SpaceMouse devices + --list-all-hid-devices + List all connected HID devices + --test-connect Test connect to the first available device + +For more information, visit https://spacemouse.kubaandrysek.cz +``` + ## Troubleshooting diff --git a/pyspacemouse/pyspacemouse.py b/pyspacemouse/pyspacemouse.py index 540c824..b5751cb 100644 --- a/pyspacemouse/pyspacemouse.py +++ b/pyspacemouse/pyspacemouse.py @@ -380,7 +380,7 @@ def config_remove(self): # ButtonSpec(channel=3, byte=5, bit=5), # ButtonSpec(channel=3, byte=5, bit=6), # ButtonSpec(channel=3, byte=5, bit=7), - + ButtonSpec(channel=3, byte=2, bit=4), # 1 ButtonSpec(channel=3, byte=2, bit=5), # 2 ButtonSpec(channel=3, byte=2, bit=6), # 3 @@ -408,7 +408,7 @@ def config_remove(self): ButtonSpec(channel=3, byte=4, bit=1), # CTRL ButtonSpec(channel=3, byte=4, bit=2), # LOCK - + ], axis_scale=350.0, @@ -756,7 +756,8 @@ def list_devices(): hid = Enumeration() except AttributeError as e: raise Exception( - "HID API is probably not installed. See README.md for details." + "HID API is probably not installed. " + "Look at https://spacemouse.kubaandrysek.cz for details." ) from e all_hids = hid.find() @@ -773,6 +774,35 @@ def list_devices(): ) return devices +def list_available_devices(): + """Return a list of all supported devices from config + + Returns: + A list of string names of the devices supported (device_name, vid_id, pid_id) + """ + return [ + (device_name, spec.hid_id[0], spec.hid_id[1]) + for device_name, spec in device_specs.items() + ] + +def list_all_hid_devices(): + """Return a list of all HID devices connected + + Returns: + A list of HID devices (product_string, manufacturer_string, vendor_id, product_id) + """ + try: + hid = Enumeration() + except AttributeError as e: + raise Exception( + "HID API is probably not installed." + "Look at https://spacemouse.kubaandrysek.cz for details." + ) from e + + return [ + (device.product_string, device.manufacturer_string, device.vendor_id, device.product_id) + for device in hid.find() + ] def openCfg(config: Config, set_nonblocking_loop: bool = True, device=None, DeviceNumber=0): """ @@ -824,7 +854,7 @@ def open( if len(all_devices) > 0: device = all_devices[0] else: - raise Exception("No device connected/supported!") + raise Exception("No found any connected or supported devices.") found_devices = [] hid = Enumeration() diff --git a/pyspacemouse/pyspacemouse_cli.py b/pyspacemouse/pyspacemouse_cli.py new file mode 100644 index 0000000..a194acc --- /dev/null +++ b/pyspacemouse/pyspacemouse_cli.py @@ -0,0 +1,104 @@ +import argparse +import time + +from pyspacemouse import list_devices, list_available_devices, open as open_mouse, read as read_mouse, \ + close as close_mouse, list_all_hid_devices +from pkg_resources import get_distribution + + +def print_version_cli(): + distribution = get_distribution("pyspacemouse") + print(f"pyspacemouse version {distribution.version}") + + +def list_spacemouse_cli(): + devices = list_devices() + if devices: + print("Connected SpaceMouse devices:") + for device in devices: + print(f"- {device}") + else: + print("Error: No connected SpaceMouse devices found.") + +def list_all_hid_devices_cli(): + devices = list_all_hid_devices() + if devices: + print("All HID devices:") + for (product_string, manufacturer_string, vendor_id, product_id) in devices: + if product_string == "": + product_string = "Unknown" + if manufacturer_string == "": + manufacturer_string = "Unknown" + print(f"- {product_string} by {manufacturer_string} [VID: {hex(vendor_id)}, PID: {hex(product_id)}]") + else: + print("Error: No HID devices found.") + +def list_supported_devices_cli(): + available_devices = list_available_devices() + if available_devices: + print("Available SpaceMouse devices:") + for (device_name, vid_id, pid_id) in available_devices: + print(f"- {device_name} [VID: {hex(vid_id)}, PID: {hex(pid_id)}]") + else: + print("Error: No available SpaceMouse devices found.") + +def test_connect_cli(): + try: + success = open_mouse() + except Exception as e: + print(f"Failed to open SpaceMouse: {e}") + return + + if not success: + print("Failed to open SpaceMouse") + return + + print("SpaceMouse opened successfully, reading x, y, z values...") + time.sleep(1) + + try: + while True: + state = read_mouse() + print(state.x, state.y, state.z) + time.sleep(0.01) + except KeyboardInterrupt: + print("KeyboardInterrupt: Exiting...") + finally: + close_mouse() + +def main(): + parser = argparse.ArgumentParser(description="PySpaceMouse CLI", + epilog="For more information, visit https://spacemouse.kubaandrysek.cz/") + parser.add_argument( + "--version", action="store_true", help="Version of pyspacemouse" + ) + parser.add_argument( + "--list-spacemouse", action="store_true", help="List connected SpaceMouse devices" + ) + parser.add_argument( + "--list-supported-devices", action="store_true", help="List supported SpaceMouse devices" + ) + parser.add_argument( + "--list-all-hid-devices", action="store_true", help="List all connected HID devices" + ) + parser.add_argument( + "--test-connect", action="store_true", help="Test connect to the first available device" + ) + args = parser.parse_args() + + if args.version: + print_version_cli() + elif args.list_spacemouse: + list_spacemouse_cli() + elif args.list_supported_devices: + list_supported_devices_cli() + elif args.list_all_hid_devices: + list_all_hid_devices_cli() + elif args.test_connect: + test_connect_cli() + else: + parser.print_help() + + +if __name__ == "__main__": + main() diff --git a/setup.py b/setup.py index 7229092..fce3caa 100644 --- a/setup.py +++ b/setup.py @@ -10,40 +10,45 @@ long_description = (HERE / "README.md").read_text() setuptools.setup( - name='pyspacemouse', - version='1.1.2', - author='Jakub Andrýsek', - author_email='email@kubaandrysek.cz', - description='Multiplatform Python interface to the 3DConnexion Space Mouse - forked from pyspacenavigator', - url='https://github.com/JakubAndrysek/pyspacemouse', + name="pyspacemouse", + version="1.1.3", + author="Jakub Andrýsek", + author_email="email@kubaandrysek.cz", + description="Multiplatform Python interface to the 3DConnexion Space Mouse - forked from pyspacenavigator", + url="https://github.com/JakubAndrysek/pyspacemouse", long_description=long_description, - long_description_content_type='text/markdown', - keywords='pyspacemouse, 3d, 6 DoF, HID, python, open-source, spacemouse, spacenavigator, 3dconnection, 3d-mouse', - license='MIT', - packages=['pyspacemouse'], + long_description_content_type="text/markdown", + keywords="pyspacemouse, 3d, 6 DoF, HID, python, open-source, spacemouse, spacenavigator, 3dconnection, 3d-mouse", + license="MIT", + packages=["pyspacemouse"], install_requires=[ "easyhid", ], extras_require={ - 'develop': [ - 'mkdocs', - 'mkdocs-material', - 'mkdocs-glightbox', - 'mkdocs-redirects', - 'mkdoxy', - 'mkdocs-open-in-new-tab', - 'mkdocs-git-revision-date-localized-plugin'], + "develop": [ + "mkdocs", + "mkdocs-material", + "mkdocs-glightbox", + "mkdocs-redirects", + "mkdoxy", + "mkdocs-open-in-new-tab", + "mkdocs-git-revision-date-localized-plugin", + ], }, - zip_safe=False, include_package_data=True, classifiers=[ - 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Operating System :: OS Independent', + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Operating System :: OS Independent", ], python_requires=">=3.8", + entry_points={ + "console_scripts": [ + "pyspacemouse=pyspacemouse.pyspacemouse_cli:main", + ], + }, )