Fix G502 X receiver persistence matching
This commit is contained in:
parent
4d1f9dc6c1
commit
e5bd8db19e
|
|
@ -423,6 +423,7 @@ _D("G703 Hero Gaming Mouse", codename="G703 Hero", usbid=0xC090)
|
|||
_D("G903 Hero Gaming Mouse", codename="G903 Hero", usbid=0xC091)
|
||||
_D(None, kind=DEVICE_KIND.mouse, usbid=0xC092, interface=1) # two mice share this ID
|
||||
_D("M500S Mouse", codename="M500S", usbid=0xC093, interface=1)
|
||||
_D("G502 X Lightspeed Gaming Mouse", codename="G502 X Lightspeed", wpid="409F", usbid=0xC098)
|
||||
# _D('G600 Gaming Mouse', codename='G600 Gaming', usbid=0xc24a, interface=1) # not an HID++ device
|
||||
_D("G500 Gaming Mouse", codename="G500 Gaming", usbid=0xC068, interface=1, protocol=1.0)
|
||||
_D("G500s Gaming Mouse", codename="G500s Gaming", usbid=0xC24E, interface=1, protocol=1.0)
|
||||
|
|
|
|||
|
|
@ -224,16 +224,23 @@ yaml.add_representer(NamedInt, named_int_representer)
|
|||
|
||||
|
||||
# A device can be identified by a combination of WPID and serial number (for receiver-connected devices)
|
||||
# or a combination of modelId and unitId (for direct-connected devices).
|
||||
# or a combination of modelId and unitId (for direct-connected devices). Some devices report the same
|
||||
# physical ID as the receiver serial in one mode and as the direct unitId in another, so match those too
|
||||
# when another stable identifier agrees.
|
||||
# But some devices have empty (all zero) modelIds and unitIds. Use the device name as a backup for the modelId.
|
||||
# The worst situation is a receiver-connected device that Solaar has never seen on-line
|
||||
# that is directly connected. Here there is no way to realize that the two devices are the same.
|
||||
# So new entries are not created for unseen off-line receiver-connected devices
|
||||
def persister(device):
|
||||
def match(wpid, serial, modelId, unitId, c):
|
||||
same_model = modelId and modelId == c.get(_KEY_MODEL_ID)
|
||||
same_wpid = wpid and wpid == c.get(_KEY_WPID)
|
||||
same_name = device_name and device_name == c.get(_KEY_NAME)
|
||||
cross_unit_serial = (unitId and unitId == c.get(_KEY_SERIAL)) or (serial and serial == c.get(_KEY_UNIT_ID))
|
||||
return (
|
||||
(wpid and wpid == c.get(_KEY_WPID) and serial and serial == c.get(_KEY_SERIAL))
|
||||
or (modelId and modelId == c.get(_KEY_MODEL_ID) and unitId and unitId == c.get(_KEY_UNIT_ID))
|
||||
(same_wpid and serial and serial == c.get(_KEY_SERIAL))
|
||||
or (same_model and unitId and unitId == c.get(_KEY_UNIT_ID))
|
||||
or (cross_unit_serial and (same_model or same_wpid or same_name))
|
||||
or (
|
||||
c.get(_KEY_WPID) is None
|
||||
and c.get(_KEY_SERIAL) is None
|
||||
|
|
@ -250,6 +257,7 @@ def persister(device):
|
|||
# some devices report modelId and unitId as zero so use name and serial for them
|
||||
modelId = device.modelId if device.modelId != "000000000000" else device._name if device._name else None
|
||||
unitId = device.unitId if device.unitId != "00000000" else device._serial if device._serial else None
|
||||
device_name = device.name
|
||||
for c in _config:
|
||||
if isinstance(c, _DeviceEntry) and match(device.wpid, device._serial, modelId, unitId, c):
|
||||
entry = c
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
from dataclasses import dataclass
|
||||
|
||||
import pytest
|
||||
|
||||
from solaar import configuration
|
||||
|
||||
|
||||
@dataclass
|
||||
class FakeDevice:
|
||||
name: str
|
||||
wpid: str
|
||||
_serial: str
|
||||
modelId: str
|
||||
unitId: str
|
||||
online: bool = True
|
||||
|
||||
@property
|
||||
def _name(self):
|
||||
return self.name
|
||||
|
||||
@property
|
||||
def serial(self):
|
||||
return self._serial
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def reset_config():
|
||||
original_config = configuration._config
|
||||
configuration._config = ["test-version"]
|
||||
yield
|
||||
configuration._config = original_config
|
||||
|
||||
|
||||
def test_persister_matches_receiver_serial_to_direct_unit_id():
|
||||
direct_entry = configuration._DeviceEntry(
|
||||
_NAME="G502 X LIGHTSPEED",
|
||||
_wpid="409F",
|
||||
_modelId="409FC0980000",
|
||||
_unitId="92050B60",
|
||||
sensitivity=1200,
|
||||
)
|
||||
configuration._config.append(direct_entry)
|
||||
|
||||
receiver_device = FakeDevice(
|
||||
name="G502 X LIGHTSPEED",
|
||||
wpid="409F",
|
||||
_serial="92050B60",
|
||||
modelId="409FC0980000",
|
||||
unitId=None,
|
||||
)
|
||||
|
||||
entry = configuration.persister(receiver_device)
|
||||
|
||||
assert entry is direct_entry
|
||||
assert entry["sensitivity"] == 1200
|
||||
assert entry["_serial"] == "92050B60"
|
||||
|
||||
|
||||
def test_persister_matches_direct_unit_id_to_receiver_serial():
|
||||
receiver_entry = configuration._DeviceEntry(
|
||||
_NAME="G502 X LIGHTSPEED",
|
||||
_wpid="409F",
|
||||
_serial="92050B60",
|
||||
sensitivity=1200,
|
||||
)
|
||||
configuration._config.append(receiver_entry)
|
||||
|
||||
direct_device = FakeDevice(
|
||||
name="G502 X LIGHTSPEED",
|
||||
wpid="409F",
|
||||
_serial=None,
|
||||
modelId="409FC0980000",
|
||||
unitId="92050B60",
|
||||
)
|
||||
|
||||
entry = configuration.persister(direct_device)
|
||||
|
||||
assert entry is receiver_entry
|
||||
assert entry["sensitivity"] == 1200
|
||||
assert entry["_modelId"] == "409FC0980000"
|
||||
assert entry["_unitId"] == "92050B60"
|
||||
Loading…
Reference in New Issue