You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Device Request]: G502 X PLUS. G915. PRO X 2 LIGHTSPEED #25
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.
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:
All three receivers plugged in, all devices on.
The G502 X PLUS on its cable.
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?
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
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.
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.
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.
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.
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.
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.
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.
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:
With all three receivers plugged in and no cables.
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.
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%.
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.
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.
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.
Activity
PyFlat-JR commentedon Oct 15, 2026
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:
0x1004) as the G Pro X Superlight 2 that's already supported.FFA0:0001), so it needs a new protocol. I'll most likely need a few rounds of testing on a branch for it.C547with 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 offers0x1004, 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:and paste the output here. Please run it three times:
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
C547receivers), or is the keyboard paired to the mouse's receiver?ReqwiemG commentedon Oct 15, 2026
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:
Both C547 receivers expose:
The PRO X 2 LIGHTSPEED receiver exposes:
Test 2: G502 X PLUS connected by cable only
Detected wired product ID: 046D:C095
Interfaces:
Test 3: G915 connected by cable only
Detected wired product ID: 046D:C33E
Interfaces:
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
PyFlat-JR commentedon Oct 15, 2026
Thanks, that's exactly what I needed! Both
C547receivers and both cables have the sameFF00:0002interface the plugin already uses for the G Pro X Superlight 2, and the PRO X 2 has theFFA0:0001interface I expected.I've put a first step on the branch
feature/logitech-g502-x-plus:C547, cableC095), using the same battery read as the Superlight 2.Could you check out the branch and run these two commands from
tests/DeviceBatteryInfo.Tests?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.
ReqwiemG commentedon Oct 15, 2026
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:
State 1: all three receivers connected
Topology:
Feature test:
Battery read test:
State 2: G502 X PLUS connected by cable
Topology:
Feature test:
Battery read test:
State 3: G915 connected by cable
Topology:
Feature test:
Battery read test:
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
PyFlat-JR commentedon Oct 15, 2026
Thanks, these logs were exactly what I needed! The G502 X PLUS has
0x1004and the G9150x1001, over both receiver and cable, so the twoC547receivers can be told apart by their battery feature.The receiver failure in state 1: when the plugin looks for the mouse, it tries every
C547receiver briefly (400 ms). The keyboard's receiver correctly answers "no0x1004". 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 oneC547(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 fetchandgit reset --hard origin/feature/logitech-g502-x-plus(a plaingit pullwill fail). Then please run this again fromtests/DeviceBatteryInfo.Testswith all three receivers connected and no cables (state 1):and paste the output together with what G HUB shows for the mouse. The
probelines 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.PyFlat-JR commentedon Oct 15, 2026
Quick note: I rebased
feature/logitech-g502-x-plusonto the currentmain, so a plaingit pullwill fail. To update before the next run, usegit fetchand thengit reset --hard origin/feature/logitech-g502-x-plus.ReqwiemG commentedon Oct 16, 2026
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:
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
PyFlat-JR commentedon Oct 16, 2026
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-lightspeednow. It uses the same voltage protocol (0x1001) as the G502 Lightspeed from #21. Could you check it out (git fetchandgit checkout feature/g502-lightspeed; if you had it before,git reset --hard origin/feature/g502-lightspeed) and run these fromtests/DeviceBatteryInfo.Tests?Please run them:
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.
ReqwiemG commentedon Oct 16, 2026
I ran both requested tests in both states.
State 1: all three receivers connected, no cables
G HUB:
Supported device read:
The test passed.
Raw G915 battery voltage:
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:
Supported device read:
The test passed.
Raw G915 battery voltage:
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
PyFlat-JR commentedon Oct 16, 2026
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 fromtests/DeviceBatteryInfo.Tests, with the headset on?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.
ReqwiemG commentedon Oct 16, 2026
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:
Centurion feature test:
Supported device read:
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:
Centurion feature test:
Supported device read:
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:
Supported device read:
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
PyFlat-JR commentedon Oct 16, 2026
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.