diff --git a/lib/logitech_receiver/base_usb.py b/lib/logitech_receiver/base_usb.py index 3510bb70..86e08480 100644 --- a/lib/logitech_receiver/base_usb.py +++ b/lib/logitech_receiver/base_usb.py @@ -22,6 +22,8 @@ from __future__ import absolute_import, division, print_function, unicode_literals +from .descriptors import DEVICES as _DEVICES + # max_devices is only used for receivers that do not support reading from _R.receiver_info offset 0x03, default to 1 # may_unpair is only used for receivers that do not support reading from _R.receiver_info offset 0x03, default to False ## should this last be changed so that may_unpair is used for all receivers? writing to _R.receiver_pairing doesn't seem right @@ -99,8 +101,6 @@ _ex100_receiver = lambda product_id: { 'ex100_27mhz_wpid_fix': True } -_wired_device = lambda product_id: {'vendor_id': 0x046d, 'product_id': product_id, 'usb_interface': 2, 'isDevice': True} - # standard Unifying receivers (marked with the orange Unifying logo) UNIFYING_RECEIVER_C52B = _unifying_receiver(0xc52b) UNIFYING_RECEIVER_C532 = _unifying_receiver(0xc532) @@ -132,19 +132,6 @@ LIGHTSPEED_RECEIVER_C53d = _lightspeed_receiver(0xc53d) LIGHTSPEED_RECEIVER_C545 = _lightspeed_receiver(0xc545) LIGHTSPEED_RECEIVER_C541 = _lightspeed_receiver(0xc541) -# Wired devices -WIRED_DEVICE_C081 = _wired_device(0xc081) # G900 -WIRED_DEVICE_C082 = _wired_device(0xc082) # G403 -WIRED_DEVICE_C086 = _wired_device(0xc086) # G903 -WIRED_DEVICE_C087 = _wired_device(0xc087) # G703 -WIRED_DEVICE_C088 = _wired_device(0xc088) # GPro -WIRED_DEVICE_C090 = _wired_device(0xc090) # G703 Hero -WIRED_DEVICE_C091 = _wired_device(0xc091) # G903 Hero -WIRED_DEVICE_C08d = _wired_device(0xc08d) # G502 Hero -WIRED_DEVICE_C08a = _wired_device(0xc08a) # MX Vertical - -del _DRIVER, _unifying_receiver, _nano_receiver, _lenovo_receiver, _lightspeed_receiver, _wired_device - ALL = ( UNIFYING_RECEIVER_C52B, UNIFYING_RECEIVER_C532, @@ -169,17 +156,25 @@ ALL = ( LIGHTSPEED_RECEIVER_C541, ) -WIRED_DEVICES = ( - WIRED_DEVICE_C081, - WIRED_DEVICE_C082, - WIRED_DEVICE_C086, - WIRED_DEVICE_C087, - WIRED_DEVICE_C088, - WIRED_DEVICE_C090, - WIRED_DEVICE_C091, - WIRED_DEVICE_C08d, - WIRED_DEVICE_C08a, -) +_wired_device = lambda product_id: { + 'vendor_id': 0x046d, + 'product_id': product_id, + 'bus_id': 0x3, + 'usb_interface': 2, + 'isDevice': True +} + +_bt_device = lambda product_id: {'vendor_id': 0x046d, 'product_id': product_id, 'bus_id': 0x5, 'isDevice': True} + +WIRED_DEVICES = [] + +for _ignore, d in _DEVICES.items(): + if d.usbid: + WIRED_DEVICES.append(_wired_device(d.usbid)) + if d.btid: + WIRED_DEVICES.append(_bt_device(d.btid)) + +del _DRIVER, _unifying_receiver, _nano_receiver, _lenovo_receiver, _lightspeed_receiver, _wired_device, _bt_device def product_information(usb_id): diff --git a/lib/logitech_receiver/descriptors.py b/lib/logitech_receiver/descriptors.py index a541184d..999d17bf 100644 --- a/lib/logitech_receiver/descriptors.py +++ b/lib/logitech_receiver/descriptors.py @@ -32,14 +32,27 @@ from .settings_templates import RegisterSettings as _RS # _DeviceDescriptor = namedtuple( - '_DeviceDescriptor', ('name', 'kind', 'wpid', 'codename', 'protocol', 'registers', 'settings', 'persister') + '_DeviceDescriptor', + ('name', 'kind', 'wpid', 'codename', 'protocol', 'registers', 'settings', 'persister', 'usbid', 'btid') ) del namedtuple +DEVICES_WPID = {} DEVICES = {} -def _D(name, codename=None, kind=None, wpid=None, protocol=None, registers=None, settings=None, persister=None): +def _D( + name, + codename=None, + kind=None, + wpid=None, + protocol=None, + registers=None, + settings=None, + persister=None, + usbid=None, + btid=None +): assert name if kind is None: @@ -81,19 +94,47 @@ def _D(name, codename=None, kind=None, wpid=None, protocol=None, registers=None, protocol=protocol, registers=registers, settings=settings, - persister=persister + persister=persister, + usbid=usbid, + btid=btid ) + if usbid: + found = get_usbid(usbid) + assert found is None, 'duplicate usbid in device descriptors: %s' % (found, ) + if btid: + found = get_btid(btid) + assert found is None, 'duplicate btid in device descriptors: %s' % (found, ) + assert codename not in DEVICES, 'duplicate codename in device descriptors: %s' % (DEVICES[codename], ) DEVICES[codename] = device_descriptor if wpid: - if not isinstance(wpid, tuple): - wpid = (wpid, ) + for w in wpid if isinstance(wpid, tuple) else (wpid, ): + assert w not in DEVICES_WPID, 'duplicate wpid in device descriptors: %s' % (DEVICES_WPID[w], ) + DEVICES_WPID[w] = device_descriptor - for w in wpid: - assert w not in DEVICES, 'duplicate wpid in device descriptors: %s' % (DEVICES[w], ) - DEVICES[w] = device_descriptor + +def get_wpid(wpid): + return DEVICES_WPID.get(wpid) + + +def get_codename(codename): + return DEVICES.get(codename) + + +def get_usbid(usbid): + if isinstance(usbid, str): + usbid = int(usbid, 16) + found = next((x for x in DEVICES.values() if x.usbid == usbid), None) + return found + + +def get_btid(btid): + if isinstance(btid, str): + btid = int(btid, 16) + found = next((x for x in DEVICES.values() if x.btid == btid), None) + return found # @@ -286,7 +327,7 @@ _D( wpid='4032', settings=[_FS.new_fn_swap()], ) -_D('Craft Advanced Keyboard', codename='Craft', protocol=4.5, wpid='4066') +_D('Craft Advanced Keyboard', codename='Craft', protocol=4.5, wpid='4066', btid=0xB350) _D( 'Wireless Keyboard S510', @@ -482,12 +523,9 @@ _D( ], ) -_D( - 'Wireless Mouse MX Vertical', - codename='MX Vertical', - protocol=4.5, - wpid='407B', -) +_D('Wireless Mouse MX Master 3', codename='MX Master 3', protocol=4.5, wpid='4082', btid=0xb023) + +_D('Wireless Mouse MX Vertical', codename='MX Vertical', protocol=4.5, wpid='407B', btid=0xb020, usbid=0xc08a) _D( 'G7 Cordless Laser Mouse', @@ -524,6 +562,16 @@ _D( _RS.side_scroll(), ], ) + +_D('G403 Gaming Mouse', codename='G403', usbid=0xc082) +_D('G502 Hero Gaming Mouse', codename='G502 Hero', usbid=0xc08d) +_D('G703 Lightspeed Gaming Mouse', codename='G703', usbid=0xc087) +_D('G703 Hero Gaming Mouse', codename='G703 Hero', usbid=0xc090) +_D('G900 Chaos Spectrum Gaming Mouse', codename='G900', usbid=0xc081) +_D('G903 Lightspeed Gaming Mouse', codename='G903', usbid=0xc086) +_D('G903 Hero Gaming Mouse', codename='G903 Hero', usbid=0xc091) +_D('GPro Gaming Mouse', codename='GPro', usbid=0xc088) + _D( 'LX5 Cordless Mouse', codename='LX5',