Repository: pwr-Solaar/Solaar

Issue:
Cannot see the G815 keyboard in the Solaar window
**Information**
- Solaar version (`solaar --version` or `git describe --tags` if cloned from this repository): `solaar 1.1.1`
- Distribution: Arch
- Kernel version (ex. `uname -srmo`): `Linux 5.16.2-arch1-1 x86_64 GNU/Linux`
- Output of `solaar show`:

<details>

```
solaar: error: Traceback (most recent call last):
  File "/usr/lib/python3.10/site-packages/solaar/cli/__init__.py", line 200, in run
    raise Exception('No devices found')
Exception: No devices found
```
</details>

**Describe the bug**

I have a G815 keyboard connected via USB cable and I would like to reprogram the macro keys. Solaar doesn't recognize the keyboard. `lsusb` returns it as `Bus 002 Device 023: ID 046d:c33f Logitech, Inc. G815 Mechanical Keyboard`


Discussion:
Solaar can only handle devices that use the Logitech HID++ protocol.  It looks as if the G815 might use this protocol.  To find out:

Look at output of `lsusb` to find ID of device or receiver.  (You have done this.)
Provide output of `lsusb -vv -d xxxx:yyyy` where xxxx:yyyy is ID of device or receiver.  (046d:c33f for you.)

Look at output of `grep -H . /sys/class/hidraw/hidraw*/device/uevent` to find directory for the device or receiver, e.g., `/sys/class/hidraw/hidraw3/device/uevent:HID_NAME=Logitech USB Receiver`.
Provide contents of the file `/sys/class/hidraw/hidrawN/device/report_descriptor` where N was found above.  You will have to copy the contents to a file with txt extension before attaching it.
Or, better, install hidrd-convert and provide output of `hidrd-convert -o spec /sys/class/hidraw/hidrawN/device/report_descriptor`.
Hi,

First of all, thank you for your work :+1: 

Output of `lsusb -vv -d`:

<details>

```
Bus 002 Device 023: ID 046d:c33f Logitech, Inc. G815 Mechanical Keyboard
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x046d Logitech, Inc.
  idProduct          0xc33f G815 Mechanical Keyboard
  bcdDevice           31.02
  iManufacturer           1 Logitech
  iProduct                2 G815 RGB MECHANICAL GAMING KEYBOARD
  iSerial                 3 087E303E3836
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x003b
    bNumInterfaces          2
    bConfigurationValue     1
    iConfiguration          4 U131.02_B0018
    bmAttributes         0xa0
      (Bus Powered)
      Remote Wakeup
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      1 Keyboard
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      65
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength     188
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
can't get device qualifier: Resource temporarily unavailable
can't get debug descriptor: Resource temporarily unavailable
Device Status:     0x0000
  (Bus Powered)
```

</details>

It's interesting that the keyboard registers itself at two `hidraw` folders, possibly because the keyboard comes with two USB cables (presumably for its USB hub function?). Here's the output of both:

`hidrd-convert -o spec /sys/class/hidraw/hidraw0/device/report_descriptor`: 

```
Usage Page (Desktop),               ; Generic desktop controls (01h)
Usage (Keyboard),                   ; Keyboard (06h, application collection)
Collection (Application),
    Usage Page (Keyboard),          ; Keyboard/keypad (07h)
    Usage Minimum (KB Leftcontrol), ; Keyboard left control (E0h, dynamic value)
    Usage Maximum (KB Right GUI),   ; Keyboard right GUI (E7h, dynamic value)
    Logical Minimum (0),
    Logical Maximum (1),
    Report Size (1),
    Report Count (8),
    Input (Variable),
    Report Count (1),
    Report Size (8),
    Input (Constant),
    Report Count (3),
    Report Size (1),
    Usage Page (LED),               ; LEDs (08h)
    Usage Minimum (01h),
    Usage Maximum (03h),
    Output (Variable),
    Report Count (5),
    Report Size (1),
    Output (Constant),
    Report Count (6),
    Report Size (8),
    Logical Minimum (0),
    Logical Maximum (255),
    Usage Page (Keyboard),          ; Keyboard/keypad (07h)
    Usage Minimum (None),           ; No event (00h, selector)
    Usage Maximum (FFh),
    Input,
End Collection
```


`hidrd-convert -o spec /sys/class/hidraw/hidraw1/device/report_descriptor`: 

```
Usage Page (Desktop),               ; Generic desktop controls (01h)
Usage (Keyboard),                   ; Keyboard (06h, application collection)
Collection (Application),
    Usage Page (Keyboard),          ; Keyboard/keypad (07h)
    Usage Minimum (None),           ; No event (00h, selector)
    Usage Maximum (KB Right GUI),   ; Keyboard right GUI (E7h, dynamic value)
    Logical Minimum (0),
    Logical Maximum (231),
    Report Size (8),
    Report Count (20),
    Report ID (1),
    Input,
End Collection,
Usage Page (Desktop),               ; Generic desktop controls (01h)
Usage (Mouse),                      ; Mouse (02h, application collection)
Collection (Application),
    Report ID (2),
    Usage (Pointer),                ; Pointer (01h, physical collection)
    Collection (Physical),
        Usage Page (Button),        ; Button (09h)
        Usage Minimum (01h),
        Usage Maximum (10h),
        Logical Minimum (0),
        Logical Maximum (1),
        Report Count (16),
        Report Size (1),
        Input (Variable),
        Usage Page (Desktop),       ; Generic desktop controls (01h)
        Logical Minimum (-32767),
        Logical Maximum (32767),
        Report Size (16),
        Report Count (2),
        Usage (X),                  ; X (30h, dynamic value)
        Usage (Y),                  ; Y (31h, dynamic value)
        Input (Variable, Relative),
        Logical Minimum (-127),
        Logical Maximum (127),
        Report Size (8),
        Report Count (1),
        Usage (Wheel),              ; Wheel (38h, dynamic value)
        Input (Variable, Relative),
        Usage Page (Consumer),      ; Consumer (0Ch)
        Usage (AC Pan),             ; AC pan (0238h, linear control)
        Report Count (1),
        Input (Variable, Relative),
    End Collection,
End Collection,
Usage Page (Consumer),              ; Consumer (0Ch)
Usage (Consumer Control),           ; Consumer control (01h, application collection)
Collection (Application),
    Report ID (3),
    Logical Minimum (0),
    Logical Maximum (1),
    Report Size (1),
    Report Count (7),
    Usage (Scan Next Track),        ; Scan next track (B5h, one-shot control)
    Usage (Scan Previous Track),    ; Scan previous track (B6h, one-shot control)
    Usage (Stop),                   ; Stop (B7h, one-shot control)
    Usage (Play Pause),             ; Play/pause (CDh, one-shot control)
    Usage (Volume Inc),             ; Volume increment (E9h, re-trigger control)
    Usage (Volume Dec),             ; Volume decrement (EAh, re-trigger control)
    Usage (Mute),                   ; Mute (E2h, on/off control)
    Input (Variable),
    Report Count (1),
    Input (Constant),
End Collection,
Usage Page (FF43h),                 ; FF43h, vendor-defined
Usage (0602h),
Collection (Application),
    Report ID (17),
    Report Size (8),
    Report Count (19),
    Logical Minimum (0),
    Logical Maximum (255),
    Usage (02h),
    Input,
    Usage (02h),
    Output,
End Collection,
Usage Page (FF43h),                 ; FF43h, vendor-defined
Usage (0604h),
Collection (Application),
    Report ID (18),
    Report Size (8),
    Report Count (63),
    Logical Minimum (0),
    Logical Maximum (255),
    Usage (04h),
    Input,
    Usage (04h),
    Output,
End Collection
```
I tried disconnecting one of the USB cables and the keyboard still works, but two `hidraw` entries remain.
It looks as if this device uses a different interface number than Solaar expects by default.  The fix is quite simple though.
Anything I can help test? I'm a developer, though with very limited Python experience, but I can give it a go perhaps?

Resolving patch:
diff --git a/lib/logitech_receiver/descriptors.py b/lib/logitech_receiver/descriptors.py
--- a/lib/logitech_receiver/descriptors.py
+++ b/lib/logitech_receiver/descriptors.py
@@ -219,6 +219,7 @@ def get_btid(btid):
 _D('MX Keys Keyboard', codename='MX Keys', protocol=4.5, wpid='408A', btid=0xB35B)
 _D('G915 TKL LIGHTSPEED Wireless RGB Mechanical Gaming Keyboard', codename='G915 TKL', protocol=4.2, wpid='408E', usbid=0xC343)
 _D('G512 RGB Mechanical Gaming Keyboard', codename='G512', usbid=0xc33c, interface=1)
+_D('G815 Mechanical Keyboard', codename='G815', usbid=0xc33f, interface=1)
 
 # Mice
 
@@ -447,6 +448,7 @@ class _PerformanceMXDpi(_ST.RegisterDpi):
 _D('G703 Lightspeed Gaming Mouse', codename='G703', usbid=0xc087)
 _D('GPro Gaming Mouse', codename='GPro', usbid=0xc088)
 _D('G502 Hero Gaming Mouse', codename='G502 Hero', usbid=0xc08d)
+_D('MX518 Gaming Mouse', codename='MX518', usbid=0xc08e, interface=1)
 _D('G703 Hero Gaming Mouse', codename='G703 Hero', usbid=0xc090)
 _D('G903 Hero Gaming Mouse', codename='G903 Hero', usbid=0xc091)
 _D('G102 Lightsync Mouse', codename='G102', usbid=0xc092, interface=1)


Test patch: