openlogi diag battery cannot read a 0x1001-only device, and blames the wrong feature
- Dominant language
- Rust
- Stars
- 21k
- Forks
- 675
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 172
Description
`openlogi diag battery` reads `0x1004` and `0x1000` but not `0x1001`, so it
cannot read a device whose battery the rest of the app reads fine - and the
error blames the wrong feature.
My G502 LIGHTSPEED exposes only `0x1001`:
```
$ openlogi diag features
device: G502 (slot 1 on receiver 82839805)
idx id ver
6 0x1001 v2
```
`openlogi list` reads its battery without trouble:
```
$ openlogi list
Unifying Receiver (…, vid=046d pid=c539)
└─ slot 1 ● G502 (mouse, wpid=407f, battery=49% low (discharging))
```
but `diag battery` cannot:
```
$ openlogi diag battery --device G502
device: G502 (slot 1 on receiver 82839805)
Error: read battery
Caused by:
device does not expose HID++ feature 0x1004
```
## Why
The inventory path already handles all three battery features -
`battery_feature_index` in `crates/openlogi-hid/src/inventory/features.rs`
prefers `0x1004`, then `0x1000`, then `BatteryProbe::Voltage` for `0x1001`.
`read_battery_raw` in `crates/openlogi-hid/src/write/diagnostics.rs` only got
the first two: it tries `UnifiedBatteryFeature`, then `BatteryStatusFeature`,
then gives up. `BatteryVoltageFeature` is never mentioned in that file.
The error text is deliberate, not a mistake - the fallthrough reports the
preferred feature:
```rust
// Reached only when neither 0x1004 nor 0x1000 is present; report the
// preferred feature rather than implying 0x1000 was specifically absent.
Err(WriteError::FeatureUnsupported { feature_hex: 0x1004 })
```
That reads fine when the device has no battery feature at all. It is
misleading when the device has one and the command simply does not speak it,
which is the case for every `0x1001`-only device. `features.rs` names that
class in its own tests: *"The G915 / G903 LS case: 0x1001 with neither 0x1000
nor 0x1004."*
## Why it matters beyond the command
`diag battery` exists to show what the firmware actually reports, so a claim
can be checked against the wire instead of guessed. `0x1001` is the one family
where that is most needed: there is no reported percentage at all, so
`voltage_battery_percentage` interpolates one from the cell voltage against a
fixed curve, and the level is then a display bucket derived from that estimate.
Two layers of inference, and the command that would let anyone check them is
the one that cannot open the feature.
Concretely, I could not use it to confirm whether my G502's `49%` was a real
reading or a curve artifact, which is exactly the question the command is for.
## Possible fix
Add a third arm to `read_battery_raw` for `BatteryVoltageFeature`, printing the
raw fields (`voltage_mv`, `critical`, `status`) rather than the interpolated
percentage - the point of the command is the unmapped value. Then make the
fallthrough error say that no battery feature was found, instead of naming
`0x1004`.
Happy to send a PR if the shape sounds right.
## Environment
- OpenLogi 0.7.1, Windows 11
- G502 LIGHTSPEED on a `0xc539` Lightspeed receiver
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in crates/openlogi-hid/src/write/diagnostics.rs at read_battery_raw, then compare feature selection with battery_feature_index in crates/openlogi-hid/src/inventory/features.rs and its 0x1001 tests. Done means diag battery handles 0x1001-only devices by reporting voltage_mv, critical, and status, while the no-feature fallthrough reports that no battery feature was found.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 84/100