Skip to content

[Device Request]: G502 X PLUS. G915. PRO X 2 LIGHTSPEED #25

Closed

Description

@ReqwiemG

Device

Logitech: G502 X PLUS, G915, PRO X 2 LIGHTSPEED

How does the plugin process reach it?

USB HID (wired or dongle)

Battery protocol details, if you know any

I own all three devices and am willing to test a backend on real hardware.

Current setup: all three devices are connected through their USB wireless receivers. The mouse and keyboard are not connected by cable.

Windows currently shows:

  • G502 X PLUS: VID_046D&PID_C547
  • G915: VID_046D&PID_C547
  • PRO X 2 LIGHTSPEED: VID_046D&PID_0AF7

The G502 X PLUS and G915 appear as separate present USB devices, but share PID_C547. They need to be distinguished beyond the receiver PID.

I also checked the mouse and keyboard when connected by cable:

  • G502 X PLUS: VID_046D&PID_C095
  • G915: VID_046D&PID_C33E

For protocol references, Halo Battery reports hardware-tested support for the G502 X PLUS through HID++ 2.0 and for the PRO X 2 LIGHTSPEED through Logitech's Centurion transport:
https://github.com/HeyOkay/HaloBattery/blob/main/docs/protocols.md#logitech-g502-lightspeed-g502-x-plus
https://github.com/HeyOkay/HaloBattery/blob/main/docs/protocols.md#logitech-g-pro-x-2-lightspeed

I have not verified the battery-reading protocol for my G915 or tested battery readings in Device Battery Info yet. I can compare results with Logitech G HUB and test builds using the receivers and, for the mouse and keyboard, USB cables. Please let me know what diagnostics or captures would be most useful.

Contribution

  • I own this device and am willing to help test a backend for it.
  • I'd like to implement this myself and am opening this issue to track it.

Activity

  1. PyFlat-JR commented on Oct 15, 2026

    @PyFlat-JR
    Member

    Thanks for the detailed report and for offering to test all three!

    These are really three different pieces of work, so I'll handle them one at a time:

    • G502 X PLUS should be closest to what the plugin already does. It uses the same HID++ 2.0 battery feature (0x1004) as the G Pro X Superlight 2 that's already supported.
    • PRO X 2 LIGHTSPEED uses a different transport ("Centurion" on FFA0:0001), so it needs a new protocol. I'll most likely need a few rounds of testing on a branch for it.
    • G915 shares the receiver product id C547 with the G502 X PLUS. When the plugin looks for a device, it tries the battery read on every matching receiver and keeps the one that answers. If the G915 reports a voltage (0x1001) like the G502 Lightspeed in [Device Request]: Logitech G502 Lightspeed #21, the two receivers can already be told apart this way, and the voltage support from [Device Request]: Logitech G502 Lightspeed #21 can be reused. If it also offers 0x1004, the plugin needs another way to tell them apart first.

    To get started, could you run the hardware listing once? You need the .NET 10 SDK and a clone of this repository. Then, from tests/DeviceBatteryInfo.Tests, run:

    dotnet test --filter Category=Hardware --logger "console;verbosity=detailed"
    

    and paste the output here. Please run it three times:

    1. All three receivers plugged in, all devices on.
    2. The G502 X PLUS on its cable.
    3. The G915 on its cable.

    It lists every Logitech HID interface with its usage page and report sizes, and it tries to read the battery on the devices it already knows.

    Also, a quick question: does each device use its own receiver (two separate C547 receivers), or is the keyboard paired to the mouse's receiver?

  2. ReqwiemG commented on Oct 15, 2026

    @ReqwiemG
    Author

    Thanks! I ran the requested hardware listing in all three connection states.

    Each wireless device has its own physical receiver. The G502 X PLUS and G915 use two separate C547 receivers. The keyboard is not paired to the mouse receiver.

    Test 1: all three receivers connected, all devices powered on, no mouse or keyboard cables connected

    Detected:

    • G502 X PLUS receiver: 046D:C547
    • G915 receiver: 046D:C547
    • PRO X 2 LIGHTSPEED receiver: 046D:0AF7

    Both C547 receivers expose:

    • Interface 0, usage 0001:0002, input 14, output 0, feature 0
    • Interface 1, usage 0001:0080, input 2, output 0, feature 0
    • Interface 1, usage 0001:0006, input 17, output 2, feature 0
    • Interface 1, usage without a reported page/value, input 5, output 0, feature 0
    • Interface 2, usage FF00:0001, input 7, output 7, feature 0
    • Interface 2, usage FF00:0002, input 20, output 20, feature 0

    The PRO X 2 LIGHTSPEED receiver exposes:

    • Interface 3, usage FF13:0001, input 62, output 62, feature 0
    • Interface 3, usage 000C:0001, input 2, output 0, feature 0
    • Interface 3, usage FFA0:0001, input 64, output 64, feature 0

    Test 2: G502 X PLUS connected by cable only

    Detected wired product ID: 046D:C095

    Interfaces:

    • Interface 0, usage 0001:0002, input 14, output 0, feature 0
    • Interface 1, usage 0001:0080, input 2, output 0, feature 0
    • Interface 1, usage 0001:0006, input 9, output 2, feature 0
    • Interface 1, usage without a reported page/value, input 5, output 0, feature 0
    • Interface 2, usage FF00:0001, input 7, output 7, feature 0
    • Interface 2, usage FF00:0002, input 20, output 20, feature 0

    Test 3: G915 connected by cable only

    Detected wired product ID: 046D:C33E

    Interfaces:

    • Interface 0, usage 0001:0006, input 17, output 2, feature 0
    • Interface 1, usage 0001:0002, input 9, output 0, feature 0
    • Interface 1, usage 0001:0080, input 2, output 0, feature 0
    • Interface 1, usage without a reported page/value, input 5, output 0, feature 0
    • Interface 2, usage FF00:0001, input 7, output 7, feature 0
    • Interface 2, usage FF00:0002, input 20, output 20, feature 0

    The HID interface-listing test succeeded in all three states. The supported-device read test reported "No supported HID device answered", which is expected because these exact models are not currently in the plugin's supported-device list.

    Logitech G HUB was running during the tests.

    I have attached the complete console output for all three runs. I can test branch builds and compare the reported battery levels and charging states with G HUB.

    logitech-hardware-test-results.zip

  3. PyFlat-JR commented on Oct 15, 2026

    @PyFlat-JR
    Member

    Thanks, that's exactly what I needed! Both C547 receivers and both cables have the same FF00:0002 interface the plugin already uses for the G Pro X Superlight 2, and the PRO X 2 has the FFA0:0001 interface I expected.

    I've put a first step on the branch feature/logitech-g502-x-plus:

    • The G502 X PLUS is added (receiver C547, cable C095), using the same battery read as the Superlight 2.
    • A new hardware test lists the HID++ features of every Logitech device it finds, with the device name. That tells us which battery feature the G915 has.

    Could you check out the branch and run these two commands from tests/DeviceBatteryInfo.Tests?

    dotnet test --filter "Category=Hardware&Name=Lists_the_hidpp_features_of_every_logitech_device" --logger "console;verbosity=detailed"
    dotnet test --filter "Category=Hardware&Name=Reads_every_supported_hid_device_through_the_plugin" --logger "console;verbosity=detailed"
    

    Please run them in the same three states as before (all receivers, G502 X PLUS on cable, G915 on cable). For the second command, please also write what G HUB shows for the mouse at that moment, and whether it is charging.

    The PRO X 2 comes after that, as its own step.

  4. ReqwiemG commented on Oct 15, 2026

    @ReqwiemG
    Author

    Thanks! I ran both requested tests from the feature/logitech-g502-x-plus branch in all three states. The six complete logs are attached.

    The feature listing confirms that the devices can be distinguished by their battery features:

    • G502 X PLUS offers feature 0x1004.
    • G915 offers feature 0x1001.
    • The same features are reported over their receivers and cables.

    State 1: all three receivers connected

    Topology:

    • G502 X PLUS through its own C547 receiver
    • G915 through its own separate C547 receiver
    • PRO X 2 LIGHTSPEED through its 0AF7 receiver
    • No mouse or keyboard cables connected

    Feature test:

    • Passed
    • G502 X PLUS: feature 0x1004
    • G915: feature 0x1001

    Battery read test:

    • Failed with: "Logitech G502 X PLUS read failed: The device does not have that battery feature."
    • G HUB showed G502 X PLUS at 91%, not charging.
    • G HUB showed G915 at 93%, not charging.
    • PRO X 2 LIGHTSPEED was at 100% and charging, while communicating through its receiver.

    State 2: G502 X PLUS connected by cable

    Topology:

    • G502 X PLUS by cable, 046D:C095
    • G915 through its C547 receiver
    • PRO X 2 LIGHTSPEED through its 0AF7 receiver

    Feature test:

    • Passed
    • G502 X PLUS over cable: feature 0x1004
    • G915 over receiver: feature 0x1001

    Battery read test:

    • Passed
    • Plugin result: G502 X PLUS 91% Charging
    • G HUB result: G502 X PLUS 91%, charging
    • The percentage and charging state matched G HUB.

    State 3: G915 connected by cable

    Topology:

    • G915 by cable, 046D:C33E
    • G502 X PLUS through its C547 receiver
    • PRO X 2 LIGHTSPEED through its 0AF7 receiver

    Feature test:

    • Passed
    • G915 over cable: feature 0x1001
    • G502 X PLUS over receiver: feature 0x1004

    Battery read test:

    • Passed
    • Plugin result: G502 X PLUS 91% Discharging
    • G HUB result: G502 X PLUS 91%, not charging
    • The percentage and charging state matched G HUB.

    So the G502 X PLUS cable path works correctly, including its charging state. Its receiver path is detected and exposes 0x1004, but the battery read currently fails with "The device does not have that battery feature."

    I can test another branch build for the receiver fix and the G915 voltage support.

    feature-logitech-g502-x-plus-results.zip

  5. PyFlat-JR commented on Oct 15, 2026

    @PyFlat-JR
    Member

    Thanks, these logs were exactly what I needed! The G502 X PLUS has 0x1004 and the G915 0x1001, over both receiver and cable, so the two C547 receivers can be told apart by their battery feature.

    The receiver failure in state 1: when the plugin looks for the mouse, it tries every C547 receiver briefly (400 ms). The keyboard's receiver correctly answers "no 0x1004". The mouse's own receiver most likely needed longer than 400 ms. When nothing answered in time, the plugin fell back to the first receiver, which was the keyboard's, and every read after that failed with "does not have that battery feature". With only one C547 (state 3) that fallback happened to be the right one, so the problem was hidden.

    I've fixed that on the branch: a receiver that answers as a different device is never used as the fallback anymore. I also made the read test print why each receiver was skipped, so we can see whether it really was the 400 ms.

    I rebased the branch, so please update it with git fetch and git reset --hard origin/feature/logitech-g502-x-plus (a plain git pull will fail). Then please run this again from tests/DeviceBatteryInfo.Tests with all three receivers connected and no cables (state 1):

    dotnet test --filter "Category=Hardware&Name=Reads_every_supported_hid_device_through_the_plugin" --logger "console;verbosity=detailed"
    

    and paste the output together with what G HUB shows for the mouse. The probe lines at the top are the new part.

    G915: it reports a voltage (0x1001), like the G502 Lightspeed in #21. That voltage support isn't on main yet, so I'll add the G915 once #21 is merged. The PRO X 2 comes after that.

  6. PyFlat-JR commented on Oct 15, 2026

    @PyFlat-JR
    Member

    Quick note: I rebased feature/logitech-g502-x-plus onto the current main, so a plain git pull will fail. To update before the next run, use git fetch and then git reset --hard origin/feature/logitech-g502-x-plus.

  7. ReqwiemG commented on Oct 16, 2026

    @ReqwiemG
    Author

    I updated the branch and repeated the requested test with all three receivers connected and no mouse or keyboard cables.

    G HUB at the time of the test:

    • G502 X PLUS: 91%, not charging
    • G915: 84%, not charging
    • PRO X 2 LIGHTSPEED: 98%, not charging

    The updated test passed.

    The new probe output was:

    probe HID candidate "\?\hid#vid_046d&pid_c547&mi_02&col02#9&ce7508d&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}" did not answer. (HID report exchange on \?\hid#vid_046d&pid_c547&mi_02&col02#9&ce7508d&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030} was not answered within 400 ms.)
    probe HID device "logitech-g502-x-plus" answered on interface 2 ("USB Receiver").

    The battery result was:

    Logitech G502 X PLUS 91% Discharging

    This matches G HUB exactly: 91% and not charging.

    So the first C547 candidate did time out after 400 ms, while the G502 X PLUS receiver answered correctly. The updated fallback behavior selected the correct receiver and the test completed successfully.

    three-receivers-supported-read.txt

  8. PyFlat-JR commented on Oct 16, 2026

    @PyFlat-JR
    Member

    Thanks again, that run confirmed the G502 X PLUS works over its receiver with the other receivers plugged in. It's merged in #29 and will be in the next release.

    The G915 is on the branch feature/g502-lightspeed now. It uses the same voltage protocol (0x1001) as the G502 Lightspeed from #21. Could you check it out (git fetch and git checkout feature/g502-lightspeed; if you had it before, git reset --hard origin/feature/g502-lightspeed) and run these from tests/DeviceBatteryInfo.Tests?

    dotnet test --filter "Category=Hardware&Name=Reads_every_supported_hid_device_through_the_plugin" --logger "console;verbosity=detailed"
    dotnet test --filter "Category=Hardware&Name=Reads_the_raw_logitech_battery_voltage" --logger "console;verbosity=detailed"
    

    Please run them:

    1. With all three receivers plugged in and no cables.
    2. With the G915 on its cable.

    Each time, please also write what G HUB shows for the keyboard (level, and whether it is charging). The keyboard reports a voltage, not a percentage, so the plugin's value is an estimate. The second command prints the raw mV, so we can see how close it gets to G HUB.

  9. ReqwiemG commented on Oct 16, 2026

    @ReqwiemG
    Author

    I ran both requested tests in both states.

    State 1: all three receivers connected, no cables

    G HUB:

    • G502 X PLUS: 88%, not charging
    • G915: 82%, not charging
    • PRO X 2 LIGHTSPEED: 91%, not charging

    Supported device read:

    • G502 X PLUS: 88% Discharging
    • G915: 80% Discharging

    The test passed.

    Raw G915 battery voltage:

    • 3990 mV
    • flags 0x00
    • calculated result: 80% Discharging

    The plugin correctly distinguished the two C547 receivers. The G502 X PLUS receiver answered with 0x1004, while the other C547 receiver was identified as a different device because it did not have that battery feature.

    State 2: G915 connected by cable

    The G915 receiver was disconnected and the keyboard was connected by USB cable. The G502 X PLUS and PRO X 2 LIGHTSPEED remained connected through their receivers.

    G HUB:

    • G915: 82%, charging

    Supported device read:

    • G502 X PLUS: 88% Discharging
    • G915: 87% Charging

    The test passed.

    Raw G915 battery voltage:

    • 4042 mV
    • flags 0x80
    • calculated result: 87% Charging

    The charging state was detected correctly. The plugin's estimated percentage was 87%, while G HUB showed 82%.

    The complete logs for both states are attached.

    g915-voltage-test-results.zip

  10. PyFlat-JR commented on Oct 16, 2026

    @PyFlat-JR
    Member

    Thanks for the quick test! The G915 is merged in #30 and will be in the next release together with the G502 X PLUS, which should come soon. Following your results, the keyboard now shows only "charging" without a percentage while it's on the cable, because the voltage reads too high there (87% against G HUB's 82%).

    I've started on the PRO X 2 LIGHTSPEED, on the branch feature/logitech-pro-x-2-lightspeed. It uses Logitech's "Centurion" protocol through the receiver, which is new in the plugin. Could you check it out and run these from tests/DeviceBatteryInfo.Tests, with the headset on?

    dotnet test --filter "Category=Hardware&Name=Lists_the_centurion_features_of_the_logitech_headset" --logger "console;verbosity=detailed"
    dotnet test --filter "Category=Hardware&Name=Reads_every_supported_hid_device_through_the_plugin" --logger "console;verbosity=detailed"
    

    Please run them once on battery and once while the headset charges, and write what G HUB shows each time. The first command prints the headset's features and the raw battery answer, so if the read fails we can see exactly where. If you have time, one run with the headset switched off would also help.

  11. ReqwiemG commented on Oct 16, 2026

    @ReqwiemG
    Author

    I ran both requested tests in all three states. The complete logs are attached.

    The PRO X 2 LIGHTSPEED always communicated through its 046D:0AF7 receiver. The charging cable was used only for charging.

    State 1: headset on, running on battery

    G HUB initially showed:

    • 90%
    • Not charging

    Centurion feature test:

    • Receiver features: 0000 0001 0100 0003 010A
    • Headset features through bridge 3: 0000 0001 0101 0100 0104 010A 0108 0604 0602 0636
    • Raw battery answer: 59 59 00
    • Parsed result: 89% Discharging

    Supported device read:

    • Logitech G Pro X 2 Lightspeed: 89% Discharging

    Both tests passed. The one-point change from the initial G HUB value appears to be a real update, as G HUB showed 89% shortly afterward.

    State 2: headset on and charging

    G HUB showed:

    • 89%
    • Charging

    Centurion feature test:

    • Raw battery answer: 5B 5B 02
    • Parsed result: 91% Charging

    Supported device read:

    • Logitech G Pro X 2 Lightspeed: 91% Charging

    Both tests passed. The charging state was detected correctly. The device reported 91% during the tests while G HUB had shown 89% immediately before them.

    State 3: headset switched off, charging cable disconnected, receiver still connected

    Centurion feature test:

    • The receiver still answered and listed features: 0000 0001 0100 0003 010A
    • Reading stopped at the headset feature list because the headset did not answer within 2000 ms.

    Supported device read:

    • The receiver was still detected.
    • The headset battery read timed out after 2000 ms.
    • No stale battery percentage was returned.

    This looks correct for the powered-off state: the receiver remains present, but the headset itself does not answer.

    The complete logs for all six runs are attached.

    pro-x-2-centurion-test-results.zip

  12. PyFlat-JR commented on Oct 16, 2026

    @PyFlat-JR
    Member

    That worked on the first try, thanks for the detailed runs! The feature tables are exactly the layout I built it against, and the readings match G HUB. Switched off, the plugin keeps the last value and shows it as stale until the headset answers again.

    If anything looks off in Macro Deck, just tell me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions