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
761 stars 62 forks source link

Aerox 3 Wireless #167

Closed gort818 closed 1 year ago

gort818 commented 2 years ago

I did some reverse engineering this week, got quite a bit done, Attached is what I have found so far. ACTIVE LED colors are not saved to device memory all other settings seem to be. I could not write to the device unless I was root.. Udev rules are in place and no luck.

For the LEDs I have a systemd service running every few seconds just like the Steel Series Software.

Wireless Mode: VID:1038 PID:1838

Wired Mode: VID:1038 PID:183a

Below is what I have found out so far.

WIRELESS: aerox3-wireless.txt

WIRED: aerox3-wireless-wired.txt

Here is repo I created as well, I will update it as I find more info https://github.com/gort818/aerox3-wireless

flozz commented 2 years ago

Hello,

I am working on the Aerox 3 (#156).

flozz commented 2 years ago

A first shot is available on the aerox3 branch, more info here:

please test and report info in the issue #156, we will keep that one (#167) for the wireless mode of the mouse :)

flozz commented 2 years ago

I updated the branch with this mouse. Currently, ONLY wired mode is supported, not the wireless one.

Available settings are:

SteelSeries Aerox 3 Wireless (wired mode) Options:
  -s SENSITIVITY, --sensitivity SENSITIVITY
                        Set sensitivity preset (DPI) (up to 5 settings, from 200 dpi to 8500
                        dpi, default: '800, 1600')
  -p POLLING_RATE, --polling-rate POLLING_RATE
                        Set polling rate (Hz) (values: 125, 250, 500, 1000, default: 1000)
  --top-color Z1_COLOR, --z1 Z1_COLOR
                        Set the color of the top LED (e.g. red, #ff0000, ff0000, #f00, f00,
                        default: red)
  --middle-color Z2_COLOR, --z2 Z2_COLOR
                        Set the color of the middle LED (e.g. red, #ff0000, ff0000, #f00,
                        f00, default: lime)
  --bottom-color Z3_COLOR, --z3 Z3_COLOR
                        Set the color of the bottom LED (e.g. red, #ff0000, ff0000, #f00,
                        f00, default: blue)
  -l LED_BRIGHTNESS, --led-brightness LED_BRIGHTNESS
                        Set the brightness of the LEDs (from 0 to 16, default: 16)
  -r, --reset           Reset all settings to their factory default

can you check it work?

if it do not work at all, try to change the endpoint (https://github.com/flozz/rivalcfg/blob/aerox3/rivalcfg/devices/aerox3_wireless.py#L11)

fluffynuts commented 2 years ago

@flozz wired mode works fine (tested colors). Wireless mode - not so much, after adding a model with product_id of 0x1838. The app does --help correctly and looks like it attempts to do stuff, but I don't see any effect.

--print-debug mentions 5 endpoints - trying 0-4 makes no difference (and 5 errors, predictably)

flozz commented 2 years ago

For the wireless mode it is normal it do not work, all command number are different, I will add it after ;)

gort818 commented 2 years ago

In Wired mode colors are working, sensitivity is working, not sure how to check polling rate, LED brightness is not working ValueError: Input range and output range must have the same length

gort818 commented 2 years ago

Ok fixed it input range should be input_range": [0, 15, 1],

Here is the device file for wireless mode. https://gist.github.com/gort818/590f3c43b77afb917f81da0ec4bac877

gort818 commented 2 years ago

Added button mappings, rainbow effect, and reactive led

fluffynuts commented 2 years ago

@gort818 YAS, works like a charm. Nicely done.

fluffynuts commented 2 years ago

I have an orange-to-red static color flow over my rig and this was the final piece of the puzzle

image

gort818 commented 2 years ago

Nice, there are a few more settings I need to add, also the colors will not stay after a reboot or if the mouse goes inactive.. might want a script to keep writing the colors. use the no-save option since the colors are not written to memory

fluffynuts commented 2 years ago

yeah, I noticed that they don't persist after the mouse sleeps; I gather that SS removed practically everything to get the weight down on this device.

gort818 commented 2 years ago

I am going to need some help with the sensitivity settings.. they are 100–18,000 in 100 CPI Increments

fluffynuts commented 2 years ago

how can I help?

flozz commented 2 years ago

Updates:

→ Can you check it works?


Questions:

NOTE: I still work only on the wired mode as the wireless one is identical with only the command ids that change (once the wired mode finished I will duplicate the profile for the wireless mode)

gort818 commented 2 years ago

Brightness command and button mapping work in wired mode.

  1. Rainbow effect only affects all the LEDs.
  2. The same settings are available in both wired and wireless modes.
  3. That was actually the response I got when the mouse as plugged in couldn't see any corresponding command. I haven't found the command to get battery level yet.
fluffynuts commented 2 years ago

I also need to figure out how to determine when the mouse "wakes up" - if I cron a script to ping the mouse with colors every minute, the mouse never goes to sleep, so ideally, I'd like to ping it once when it wakes up / connects and not again until next time; as noted before, colors are forgotten when the mouse has a nap.

Battery level indicator would be aces - I'd like to configure a plasmoid to watch that.

flozz commented 2 years ago

That was actually the response I got when the mouse as plugged in couldn't see any corresponding command. I haven't found the command to get battery level yet.

Can you try sending the 0x12 command to the mouse (maybe it worth trying with 0x52 too in wireless mode) to see if the device respond with the battery level?

Here is a Python code that can help you to test:

import hid

def open_device(vendor_id, product_id, endpoint):
    path = None
    device = hid.device()
    for interface in hid.enumerate(vendor_id, product_id):
        if interface["interface_number"] == endpoint:
            path = interface["path"]
            break
    if path:
        device.open_path(path)
        return device
    raise Exception("Requested device or endpoint not found: %04x:%04x:%02x" % (  # noqa
        vendor_id, product_id, endpoint))

# Mabe try with 0x183a in wired mode too?
device = open_device(0x1038, 0x1838, 0x03)
device.write(b"\x12")  # Mabe try with \x52 in wireless mode too?
print(device.read(31))
device.close()
fluffynuts commented 2 years ago

ok, I've tried all combinations for:

Initially, 0x12 against wireless hung, 0x52 returned an array of mostly zeros, leading with 64, 255. However, after switching to wired and performing the tests there (both hung) now wireless hangs on the read for both input bytes. I've tried turning the mouse off and on again - no difference. Even if I reduce the buffer size to 1 byte, the script hangs on the read now.

flozz commented 2 years ago

That mean this is not the right command to get the battery level...

Thank you for the tests! :D

flozz commented 2 years ago

Updates... :)


I added the rainbow effect command. To try it: rivalcfg --rainbow-effect (it takes no parameter).

After trying this command, please check the content of the ~/.config/rivalcfg/1838_183*.device.json files: the rainbow_effect setting sould not be present. :)


I added the profile for the Aerox 3 Wireless in 2.4 GHz mode. Can you try everything work as expected?

gort818 commented 2 years ago

Everything seems to be working great.. the sensitivity is wrong though.. it is 100–18,000 in 100 CPI Increments

flozz commented 2 years ago

he sensitivity is wrong though.. it is 100–18,000 in 100 CPI Increments

Oh yes, you are right, I forget to update it /o\

Should be OK now :)

flozz commented 2 years ago

Update: I added the reactive color option:

  -a REACTIVE_COLOR, --reactive-color REACTIVE_COLOR
                        Set the color of the LEDs in reaction to a button click (e.g. off,
                        disable, red, #ff0000, ff0000, #f00, f00, default: off)

can you check it works in both wired and 2.4 GHz wireless mode? :)

mewtlu commented 2 years ago

Both rainbow and reactive worked perfectly first time for me over wireless, thanks a lot! :D

gort818 commented 2 years ago

@fluffynuts Think I got the battery level sorted WIRED

    Device.write(b"\x92")
    data = device.read(2)
    print(data)
    percent = "{:.0%}".format(data[1] / 149)
    print(percent)

WIRELESS

    device.write(b"\xD2")
    data = device.read(2)
    print(data)
    percent = "{:.0%}".format(data[1] / 21)
    print(percent)
flozz commented 2 years ago

Thank you for the tests, I will work on this as soon as possible.

Also it seems we should read-back after each commands on this device. I will implement that too, but I do not know how much Bytes I should read. If you can check that too... :)

flozz commented 2 years ago

Hello,

I implemented the battery level:

  --battery-level       Print the battery level of the mouse and exit

You should have results like

Charging [========= ] 95 %
Discharging [========= ] 95 %

Can you check it works?

mewtlu commented 2 years ago

Both charging states look to work well for me including discharging when on wireless, and the level appears to be displaying correctly before and after a quick charge!

vith commented 2 years ago

aerox 3 tests in wireless mode (2.4G) on commit 7357c7d:

working

not working

Traceback (most recent call last):
  File "/usr/bin/rivalcfg", line 33, in <module>
    sys.exit(load_entry_point('rivalcfg==4.3.0', 'console_scripts', 'rivalcfg')())
  File "/usr/lib/python3.9/site-packages/rivalcfg/__main__.py", line 100, in main
    mouse.reset_settings()
  File "/usr/lib/python3.9/site-packages/rivalcfg/mouse.py", line 168, in reset_settings
    method(setting_info["default"])
KeyError: 'default'
vith commented 2 years ago

For the device in the above report, SteelSeries GG on Windows reports these versions:

ABOUT AEROX 3 WIRELESS
Dongle: 1.2.17
Mouse: 1.8.1

I think there was a firmware update in the past few weeks that I applied.

flozz commented 2 years ago

Oh nice catch for the --reset.... rainbow_effect has no default value as it has no value at all.... It is now fixed! :)

For other non-working commands, I do not know what I can do as I have not the device.... :(

Can you also try in wired mode to check if it do not work too?

vith commented 2 years ago

Retested on d589f19:

in wired mode:

in wireless 2.4G mode:

flozz commented 2 years ago

@vith Ok thank you. I do not know why the sensitivity do not work for you... Can other people in this thread share the version of their firmware?


I made a little pause on this project as I am working on an other one, but I will be back soon :)

mewtlu commented 2 years ago

Don't currently have my firmware version (any way there could be an option in the CLI to get this?) but will grab it soon if needed, but it looks like the sensitivity option also isn't working for me.

(No prob at all on the pause, thanks a lot for the great work you've been doing!)

flozz commented 2 years ago

I am back on the project (yeah it took me some time).

I will probably merge the Aerox 3 support on master without the Aerox 3 Wireless as there is some more work needed:

mewtlu commented 2 years ago

Great to hear! I checked and I'm on firmare 1.8.1 too facing the same issue with changing the sensitivity not working, let me know if there's anything else I can do/check to help diagnose!

flozz commented 2 years ago

Ok, the non-wireless Aerox 3 support is merged on master. I can now focus on the Aerox 3 Wireless.

The work continue on the aerox3-wireless.

@mewtlu I think I found the issue with the DPI... I will work on this tomorrow... But I will need someone to check it works :)

flozz commented 2 years ago

Can someone try something for me with DPIs?

Can you test if there is differences in the cursor speed when you run following commands?

rivalcfg -s 100,100
rivalcfg -s 100,2000

(only changing the value of the second preset... I think the second preset is the one automatically selected when updating the values)

mewtlu commented 2 years ago

Looks like you're right, just changing the second value seems to adjust it exactly to whatever I input!

flozz commented 2 years ago

Yes, good news! :)

I just have to handle this in the multidpi_range handler now :)

flozz commented 2 years ago

It should now work. Can you try it?

rivalcfg -s 100
rivalcfg -s 18000
mewtlu commented 2 years ago

Awesome, seems to work great now

flozz commented 2 years ago

Can you test one last thing on DPIs?

Can you try to first set it to 18000

rivalcfg -s 18000

Then set it to 200

rivalcfg -s 200

Does it work as expected?

mewtlu commented 2 years ago

Yep that seems to do exactly what I'd expect, super high DPI when I set it to 18000 then went down to a low 200, and works fine to reset it back to my standard 800.

flozz commented 2 years ago

Ok, thank you very much :)

vith commented 2 years ago

sensitivity is working for me too 🎉

flozz commented 2 years ago

I pushed a thing to test in the branch. Can you try to run some command and to tell me what was the command and the output?

vith commented 2 years ago
❯ rivalcfg -s 2400
Data:
[109, 0, 0, 46, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
mewtlu commented 2 years ago

When I ran rivalcfg -s 800 for the first time I got: [109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

I then ran rivalcfg -s 600 and got: [81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

and it appears running any other sensitivity command past that gives me the same response as the second, so I then tried rivalcfg -e which gave me: [98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Then running the first command again gave me the same response as it did the first time. Hope this helps, let me know if there's anything else I can do!