Repository navigation
Open
Labels
Description
Description
Logitech G PRO X 2 LIGHTSPEED battery remains at 100%
Description
HeadsetControl always reports 100% battery for my Logitech G PRO X 2 LIGHTSPEED, even after more than two hours of active wireless use with no charging cable connected.
The value remains at 100% after switching the headset off, unplugging the LIGHTSPEED receiver, waiting, reconnecting the receiver, and switching the headset back on.
Headset
- Device: Logitech G PRO X 2 LIGHTSPEED
- USB receiver vendor ID:
0x046d - USB receiver product ID:
0x0af7 - Connection: LIGHTSPEED USB receiver
- Charging cable connected: No
Environment
- Operating system: Windows 11 x64 (
10.0.26200) - HeadsetControl version:
continuous-52-gfe086cd - HeadsetControl commit:
fe086cda8fc50d15c3aea90c748c8f3346b6e601 - HIDAPI version reported by HeadsetControl:
0.15.0 - Command:
headsetcontrol.exe -b -o json
Steps to reproduce
- Connect the LIGHTSPEED USB receiver.
- Switch the headset on and use it wirelessly for more than two hours.
- Ensure no charging cable is connected.
- Run
headsetcontrol.exe -b -o jsonrepeatedly. - Observe that every query reports 100%.
- Switch the headset off.
- Unplug the receiver and wait 10 seconds.
- Reconnect the receiver, switch the headset on, and query again.
Expected result
The reported battery percentage should decrease after extended active wireless use.
Actual result
Every query reports:
{
"name": "HeadsetControl",
"version": "continuous-52-gfe086cd",
"api_version": "1.4",
"hidapi_version": "0.15.0",
"device_count": 1,
"devices": [
{
"status": "success",
"device": "Logitech G PRO X 2 LIGHTSPEED",
"vendor": "Logitech",
"product": "PRO X 2 LIGHTSPEED",
"id_vendor": "0x046d",
"id_product": "0x0af7",
"battery": {
"status": "BATTERY_AVAILABLE",
"level": 100
}
}
]
}Five consecutive direct queries returned the same result:
Battery BatteryStatus DeviceStatus
100 BATTERY_AVAILABLE success
100 BATTERY_AVAILABLE success
100 BATTERY_AVAILABLE success
100 BATTERY_AVAILABLE success
100 BATTERY_AVAILABLE success
Scheduled queries over more than two hours also returned 100% with exit code 0 and empty stderr.
Additional information
- Packaged HeadsetControl 3.1.0 detects this receiver but says the headset does not support battery reporting.
- The continuous build detects the newer
CAP_BATTERY_STATUScapability, but the returned value does not change. - No experimental HID commands were sent. Only the standard battery/JSON command was used.
- No Logitech audio driver or G Hub is installed for this test; Windows uses its generic audio driver.
On which OS does the problem happen?
Win11
Activity
platonz commentedon Jul 15, 2026
Comment for #539 — ready to post (copy below the line)
Follow-up with new data: I reverse-engineered the receiver protocol directly
(Python + hidapi, raw HID captures against
VID 046D / PID 0AF7, Windows 11,no G HUB installed) and can now describe exactly what the battery channel
returns and when it changes.
Protocol summary (verified on hardware, 2026-07-15)
The receiver's vendor interface is usage page
0xFFA0, report ID0x51,64-byte reports. Framing:
The receiver exposes a small service table (enumerable via service
0x01):service
0x03is a proxy that tunnels messages to the headset — the samemechanism the sidetone/noise/timeout commands from #314 use. Through it, the
headset's own service table can be walked (inner service
0x01):Battery read
Payload is
[level%, 0x64, chargeFlag]. The charge flag is live: it flips00 → 02within seconds of plugging the charging cable in, and back onunplug (verified repeatedly while polling every 15 s). So the channel itself
works and is not a stale snapshot.
Drain-test result: not a bug — the level is just very slow
Overnight drain test (polling the raw service every 5 minutes during
continuous playback):
The level byte decrements honestly at ~1% per 25–35 minutes — consistent
with the advertised ~50-hour battery. So neither HeadsetControl nor the
firmware is stuck: a typical 2-hour test session drains ~4%, and near
full charge the value simply sits at 100 long enough that every short test
I ran (including the one this issue is based on) never saw it move. I
consider the original report resolved as a misunderstanding, though the
protocol details below may still be useful.
Notes
timeline, drain log) available on request, plus standalone Python probe
scripts.
93/93 across the whole drain) — a duplicate/secondary level field.
read that returns the level already contains it (byte 3: 0x00 on
battery, 0x02 with the cable in), so
BATTERY_CHARGINGcould bereported for this headset instead of always
BATTERY_AVAILABLE.0x01fn0/fn1 enumerate the service directory(
[count]/ suffix-list of[id_hi id_lo ver_hi ver_lo]entries) — handyfor supporting future devices generically.
ChrisLauinger77 commentedon Jul 29, 2026
I have this headset running - works like a charm but it seems you need to update headsetcontrol. It will report much more in JSON in the newer version. see also #512
You also wanna check if there is a firmware update for the headset.
I use https://github.com/ChrisLauinger77/QontrolPanel which build headsetcontrol lib in CI. Maybe you wanna try it ... No headsetcontrol seperatly installed would be needed then.