flozz / rivalcfg

CLI tool and Python library to configure SteelSeries gaming mice
https://flozz.github.io/rivalcfg/
Do What The F*ck You Want To Public License
804 stars 66 forks source link

Request: Support for Rival 5 #165

Open maaattes opened 3 years ago

maaattes commented 3 years ago

I already received my Rival 5 which was released a few days ago. I think I'm one of the first who is not a brand ambassador/influencer.

sudo lsusb -d 1038:183c --verbose
Bus 001 Device 008: ID 1038:183c SteelSeries ApS SteelSeries Rival 5
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x1038 SteelSeries ApS
  idProduct          0x183c 
  bcdDevice            1.00
  iManufacturer           1 SteelSeries
  iProduct                2 SteelSeries Rival 5
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x006d
    bNumInterfaces          4
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xa0
      (Bus Powered)
      Remote Wakeup
    MaxPower              200mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      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      37
         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     0x0040  1x 64 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      2 Mouse
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      98
         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     0x000c  1x 12 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      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      21
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      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      76
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0009  1x 9 bytes
        bInterval               1
Device Status:     0x0000
  (Bus Powered)
rivalcfg --print-debug
RIVALCFG
========
Version: 4.3.0
udev rules installed: True
udev rules up to date: True
Installation path: /usr/local/lib/python3.9/site-packages/rivalcfg

OPERATING SYSTEM
================
OS: Linux
Platform: Linux-5.11.20-300.fc34.x86_64-x86_64-with-glibc2.33
Version: #1 SMP Wed May 12 12:45:10 UTC 2021
Distribution issue: \S
Kernel \r on an \m (\l)

PYTHON
======
Python version: 3.9.5
HIDAPI version: 0.10.1

PLUGGED STEELSERIES DEVICES ENDPOINTS
=====================================
1038:183c | 00 |  (firmware v0)
1038:183c | 01 |  (firmware v0)
1038:183c | 02 |  (firmware v0)
1038:183c | 03 |  (firmware v0)

I guess someone has to do more reverse engineering because of the new hardware (e. g. the “switch” button). Is this method still the way to go? At the moment I'm a little bit short on time but will try to do my best to provide information for adding it to rivalcfg.

Edit: Configuring via Steelseries Engine 3.20.0 in a Windows 10 VM worked as expected. Sadly, whenever I unplug the mouse, my settings for LED and the CPI toggle button gets reset. I'm still investigating why this happens.

flozz commented 3 years ago

Hello,

Yes someone should do some reverse engineering, and yes you can find some documentation in this article and in that one too.

Strange that the settings are not saved when you unplug the mouse... Have you clicked the "Save" button on the SSE? (else it does not save the setting in the mouse)

maaattes commented 3 years ago

Yes someone should do some reverse engineering, and yes you can find some documentation in this article and in that one too.

Okay, I will look into it (The two articles you mentioned have the same link).

Strange that the settings are not saved when you unplug the mouse... Have you clicked the "Save" button on the SSE? (else it does not save the setting in the mouse)

Yes, that's a bit strange. Especially because the other settings (for example, for the thumb keys or the toggle switch) are retained. Only the settings for the illumination and the CPI button are lost as soon as you unplug the mouse. I've clicked "Save" on SSE.

For example: I've bind Win + PageUp and Win + PageDown to thumb buttons 6/7 to switch between workspaces in gnome-shell and those setting are retained even after reconnecting the mouse. Thumb button 5, which I've bind to WinKey for app expose also works. It's only the CPI-button and lighting that get's lost. At first I suspected that this was related to the usb port (the mouse was connected to my monitor, which is connected to my laptop via usb-c). But that doesn't seem to make a difference. I guess it has something to do with gnome/mutter/wayland/libinput (as always). If I unplug the mouse and then reconnect it, LEDs turns on again and the CPI-button is back to it's default setting (switching between sensitivity levels). I can press the CPI button once to get a higher sensitivity although I've only set up one level in Steelseries Engine (1200 CPI). If I press it again, I can no longer move the mouse.

Nevertheless, so far I'm really happy with my purchase. Weight, sensor, shape and buttons are great. QC, mousefeet and cable are above average. I am optimistic about the problems. The mouse has already received a firmware update.

flozz commented 3 years ago

Okay, I will look into it (The two articles you mentioned have the same link).

Oops sorry I did not saw that the URL does not change while navigating in translated version... The original links to article are:

I am optimistic about the problems. The mouse has already received a firmware update.

I hope updates will fix that

PandorasFox commented 3 years ago

Got a rival 5, did some preliminary poking.

I set the 'reactive' color to 'Steady' #704ca6 and then the active zones to f997c[1-a], like so:

image

This produces a corresponding SET_REPORT data fragment of:

0000  21 ff 03 f9 97 c1 f9 97  c2 f9 97 c6 f9 97 c3 f9   !······· ········
0010  97 c7 f9 97 c4 f9 97 c8  f9 97 c5 f9 97 c9 f9 97   ········ ········
0020  ca 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ········ ········
0030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ········ ········

So it looks like it orders them strictly left to right and my guess was wrong :)

Unsure about where the 'reactive' color is set. These config packets are basically constantly sent (while the SSE is open?), and the mouse doesn't seem to retain anything after hitting 'save' when I then plug it into my linux laptop. Notably, like the other guy, if I hit the palm 'switch profile' button once, its colors switch back to what I had set, for about 5 seconds or so, and the buttons do not update to their 'saved' values from the saved profile.

If I then hit the 'Cycle CPI' button again, the mouse stops responding until I un/replug it. So that's great, definitely a solid firmware on this mouse.

I'll get to the button binding in a bit (tomorrow, hopefully). I'm not sure yet if it needs to be constantly sent updates for the colors (might be a side effect of the animations and shit it supports? My guess here is that the 'reactive' effect (zones flash a color from top to bottom) and animations are just computed in their software and it just updates the active color 60 times a second or something) or if the software/driver just do that, and it holds colors on its own just fine, or what.

The button binds do seem to at least be send-once and it's set until the mouse is power cycled, at least, so configuring them should be fine. My to-do list for this thing is:

maaattes commented 3 years ago

Just FYI, I've had a lengthy discussion with the Steelseries support about my issues. At some point I've asked for a refund and purchased a Steelseries Prime which has real On-Board-Memory and therefore does not need any software. (The first one I got had a faulty scrollwheel, the second one was fine. Because scrolling was still a bit noisey for my taste, I applied some Krytox 205g0. Since then I am very happy with this mouse).

Some statements by the customer service may be of interest for you: > May 27, 2021 > This is due to the Rival 5 only having one onboard profile. Whatever profile is active when you unplug/quit Engine, is designated as the onboard profile. These features require Engine to be running in order to function: * All button mappings EXCEPT keyboard and mouse button functions * Angle snapping * Accel/Decel * Lighting EXCEPT disabled lighting, reactive lighting, and device brightness Changes made to these features should be saved to the mouse, even when Engine is quit or uninstalled: * Keyboard and mouse button function mappings * CPI * Polling rate * Disabled lighting * Reactive lighting * Lighting brightness This answer was later corrected: > Jun 15, 2021 > I have been advised that the Rival 5 does need Engine to run for the lighting settings on the mouse to work. Once you quit Engine, the mouse will go back to defaults. This means that if you plug the mouse to a PC that does not have Engine installed, it will only have the default settings. > Jun 18, 2021 > The default being LED off is not currently a feature in Engine. Apologies for any inconvenience. > Jun 25, 2021 > I am very sorry for the delayed response. I have sent this ticket to our team who works directly on mouse effects. I understand installing software on multiple PCs is not always feasible. In addition, I reviewed the CPI button issue and I have been informed that this is actually a known issue on the mouse and we have our development team working on a firmware update to correct the issue. We do not currently have an ETA for the firmware update release but I am happy to follow up with you when released. In my experience not all firmware updates are mentioned in the release notes at [https://techblog.steelseries.com/](https://techblog.steelseries.com/). But according to your observations it seems like this firmware update is still not available.
PandorasFox commented 3 years ago

oh that's incredibly cursed

I might end up returning it and switching to a Rival 600 (since the only functional difference is the two extra side buttons on the 5, and those are annoying enough to just not matter to me), in that case. Still probably going to figure out the button config packet though, since it seems like a minor amount of active management of the mouse isn't too hard.

daftinquisitor commented 2 years ago

I checked the two links posted above about the reverse engineering, are similar instructions available in English? I'd like to help out here, but I'm not sure if something will be lost if I just throw the pages through Google Translate.

maaattes commented 2 years ago

FYI: Only one year after the release of this mouse they fixed some of the bugs I reported. At least according to the changelog of GG 17.1.0. Almost every release of GG had some bugfixes for Rival 5. Just take a look at GG 18.0.0 🤦‍♂️. Well, I guess it wasn't their best device…

CLKRUN commented 2 years ago

Any news?

MoonlightWave-12 commented 1 year ago

There is some information about the SteelSeries Rival 5 over there: https://github.com/libratbag/libratbag/issues/1252#issuecomment-1510457809 I think it will be useful for this.

MoonlightWave-12 commented 1 year ago

I tried to create a device-file for this, but can't set the LEDs other than the one for the mouse-wheel, because they all need to be set at the same time with a command like this: \x21\xff\x03\x11\x11\x11\x22\x22\x22\x33\x33\x33\x44\x44\x44\x55\x55\x55\x66\x66\x66\x77\x77\x77\x88\x88\x88\x99\x99\x99\x00\x00\x00" Is there some way to do it in the device-file?

DeRaafMedia commented 11 months ago

Any hope for support for the Rival 5? Just got one as a gift, looks and feels like a nice enough mouse to give it some love. Been reading into it a for the afternoon ... don't have a clue how to try some code for myself.

Saltblob commented 11 months ago

No idea if this has been tried, or if it has any chance of working, but the Aerox 5 Wireless (and wired mode) are already supported and except for the wireless parts, that one seems to be build identical to the Rival 5. So using the Information in this thread and throwing it into the Aerox 5 Device file, might yield some results. Or it might not, no idea.

I dont actually know how to add a Device file to rivalcfg, to try this out tho.

Saltblob commented 11 months ago

Well, i have done some poking my self and came up with this here file. Not all information contained within is new and CPI and Button-Mapping is still missing, but i would like to test, what i have.

However under Windows it seems to be hard to talk to a USB-Device directly, if just there was a handy little tool to do that... oh well.

That said, i have no idea how to throw that into a incomplete device file and even less of a clue on how to get rivalcfg to actually use that device file, to test this.

If a test with the whole LED and Polling-Rate stuff would be successful, i would poke around with the CPI and Button-Mapping stuff.

Any help is appreciated. Rival_5_LEDs_Pollingrate.txt

-No idea what i am doing sry :/ --Also not a native English speaker, so my spelling is... rough. Sorry for that.

Saltblob commented 11 months ago

I have now modified the Aerox5_Wireless_Wired device file. rival5.txt

Now i would like to test it, because there is a chance, that some things might work and most wont. Still, how would i go about adding this to rivalcfg and testing it? @flozz

Sorry for the multiple rambling posts and thanks in advance.

flozz commented 11 months ago

Hello,


First setup the project for development:

# clone this repository
git clone https://github.com/flozz/rivalcfg.git

# go to the project directory
cd rivalcfg

# create a virtualenv (note: this require to install the `python3-venv` package on Debian / Ubuntu)
python3 -m venv __env__

# activate the virtualenv
source __env__/bin/activate        # Linux / Bash
source __env__/Scripts/activate    # Windows / Git bash
__env__\Scripts\activate.bat       # Windows / CMD.exe
__env__\Scripts\activate.ps1       # Windows / PowerShell

# Install dependencies etc.
pip install -e .

[LINUX ONLY] On Linux, you will need to add udev rules to have the permission to communicate with the device. Create or edit /etc/udev/rules.d/99-steelseries-rival.rules and add the following lines:

SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1038", ATTRS{idProduct}=="183c", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1038", ATTRS{idProduct}=="183c", MODE="0666"

Then reload udev rules:

udevadm control --reload-rules

And finally unplug/replug the device


To test you Rival 5 profile:

Then you should be able to test with commands like:

python3 -m rivalcfg --help  # should display the options specific to you device
python3 -m rivalcfg --color red  # shoud turn the LEDs to red color
...

NOTE: I have not many time to work on this project currently and I may not be able to work on my open source projects at all for a while (probably for few weeks)... so I may not answer quickly

Saltblob commented 11 months ago

Hello,

thank you for providing the above post, it made it possible for me, to create this device file, based on the Aerox5: (As .txt here, cause i am new to Github.) rival5.py.txt

However, creating this device file was the "easy" part and only half the battle, because the Rival5 is special when it comes to giving color values to the LEDs.

First of all, the LED color is the only thing, the mouse wont remember (e.g. DPI, Buttonmappings... will stay). If you close SteelSeriesGG, it will default to rainbow. If you use rivalcfg, the mouse will only keep the color values, as long as it is connected to the PC, while it is running. On reboot you will have to call rivalcfg again once.

Secondly and more important: Other mice, with multiple LEDs use different commands for different LEDs in their datafragments, like this: (no actual device, just demonstration):

LED_1 green: 02aa01 00ff00

LED_2 green: 02aa02 00ff00 ...

The Rival5 knows only one command for all 10 LEDs at once: example, for color green:

[command] [LED1] [LED2] [LED3] ... 
21ff03    00ff00 00ff00 00ff00 ...

So even if one would use --z1-color, --z2-color, ... like in the Aerox5 device file and just change the position of the value, you would not only set that one LED to the desired color, but also set all others to "000000", wich turns them off.

So you have to set ALL LEDs at once in one datafragment.

The handler "rgbcolor" does unfortunately not support the needed in and outputs, even if I played around in the device file. None of the other handlers seemed to fit as well.

So I wrote a new handler, based on the "rgbcolor "handler and called it "onestr_rgbcolor": (As .txt here, cause i am new to Github.) onestr_rgbcolor.py.txt

Because of me being a total beginner to Python and programming in general, it is probably really janky, but it does work. (I have not tested the python.api suff with the [0, 255,0] type color values tho, because I dont know how.)

For the color values it takes the same inputs like the "rgbcolor" handler (00ff00, "yellow", "#f00...) and checks them for validity. It also checks for the number of inputs and compares them to the number of LEDs, wich you can specify in the device file. If the number of inputs exceeds the number of LEDs, it will throw an exception, however if the input is less, it will only set the first LEDs (as many as values are given) and sets all others to "000000", wich turns them off. If the input of all LEDs should be forced, then the handler can be easily modified.

The input is as follows: --c / --color

rivalcfg --c "COLOR_LED_1; COLOR_LED_2; COLOR_LED_3; ... COLOR_LED_10"

An example, for setting all 10 LEDs to green: rivalcfg --color "00ff00; 00ff00; 00ff00; 00ff00; 00ff00; 00ff00; 00ff00; 00ff00; 00ff00; 00ff00"

The physical layout of the LEDs is this: Screenshot 2023-12-13 191853 Dont mind the white LED in the back, this is just an example screenshot.

The physical Buttonlayout is this: Screenshot 2023-12-13 192811 (Sorry for the German in there)

Note: that Buttons 6, 7, 8 are disabled by default.

I have tested everything reasonably and it works well enough, tho the -e and -d commands dont like to be used consecutively, wich disables -e and to fix this you need to replug the mouse. It is recommend to remove the -e functionality in the device file, because you can get "rainbow" witch -d instead.

It would be nice, if someone, preferably a Rival5 owner, could test and verify tho.

While I did my own poking around with Wireshark and the USB stuff, the information and links contained within this thread where really helpful.

Hope, this helps and will lead to the eventual addition of support for the Rival5 in rivalcfg.

Cheers,

-blob

tomarus commented 1 month ago

I have tested everything reasonably and it works well enough, tho the -e and -d commands dont like to be used consecutively, wich disables -e and to fix this you need to replug the mouse. It is recommend to remove the -e functionality in the device file, because you can get "rainbow" witch -d instead.

It would be nice, if someone, preferably a Rival5 owner, could test and verify tho.

I just got a Rival5 and while I haven't tested everything, I can confirm the color settings are working perfect with your changes. Thanks a lot for your work!