feat(hid,hidpp): read battery over BatteryVoltage (0x1001) - #575
Open
bobaoapae wants to merge 1 commit into
Open
feat(hid,hidpp): read battery over BatteryVoltage (0x1001)#575bobaoapae wants to merge 1 commit into
bobaoapae wants to merge 1 commit into
Conversation
G-series wireless gaming devices (G915, G903 LS) expose neither the legacy 0x1000 BatteryStatus nor the unified 0x1004 UnifiedBattery: battery is reported only as a measured voltage via 0x1001, which was a name-only row in the feature registry. Their battery therefore showed as "-" even once the device itself enumerated. Implement the 0x1001 wrapper (getBatteryInfo: a big-endian millivolt reading plus a charging-flags byte, decoded as Solaar and libratbag do), register it, and let the inventory probe fall back to it when no percentage-reporting battery feature is present. The displayed percentage is estimated from the voltage with Solaar's measured Li-Po discharge curve, interpolated linearly; the firmware's critical flag outranks the estimated bucket. Verified on real hardware with a G915 (wpid 0x407c): battery=27% low (discharging). Refs AprilNEA#512
Greptile SummaryImplements read-only HID++ BatteryVoltage (0x1001) support for devices that expose voltage rather than a direct battery percentage.
Confidence Score: 5/5The PR appears safe to merge, with no concrete blocking or independently actionable non-blocking issues identified. The new feature is registered, uses the established HID++ endpoint framing and feature-index convention, preserves existing source precedence, and maps bounded voltage readings into the current battery contract.
|
| Filename | Overview |
|---|---|
| crates/openlogi-hid/src/inventory/features.rs | Adds voltage-source discovery, source precedence, and conversion into the existing BatteryInfo refresh path without an identified defect. |
| crates/openlogi-hid/src/mappings.rs | Adds bounded, monotonic voltage interpolation and charging-status mapping with focused curve tests. |
| crates/openlogi-hidpp/src/feature/battery_voltage/mod.rs | Adds the typed 0x1001 request and response decoder, including tests for voltage, status precedence, charging rates, and the critical bit. |
| crates/openlogi-hidpp/src/feature/mod.rs | Exposes the new battery_voltage feature module. |
| crates/openlogi-hidpp/src/feature/registry.rs | Associates feature ID 0x1001 with the new typed producer so feature enumeration can instantiate it. |
Sequence Diagram
sequenceDiagram
participant Inventory
participant FeatureTable
participant Voltage as BatteryVoltage 0x1001
participant Mapping
participant Consumer as CLI / GUI
Inventory->>FeatureTable: Enumerate battery feature IDs
FeatureTable-->>Inventory: Runtime index for 0x1001
Inventory->>Voltage: getBatteryInfo (function 0)
Voltage-->>Inventory: voltage_mv, charging flags, critical
Inventory->>Mapping: Estimate percentage and map status
Mapping-->>Inventory: BatteryInfo
Inventory-->>Consumer: Existing percentage, level, status shape
Reviews (1): Last reviewed commit: "feat(hid,hidpp): read battery over Batte..." | Re-trigger Greptile
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the
BatteryVoltagefeature (0x1001) so G-series wireless gaming devices get a battery reading. These devices (G915, G903 LS, G502 LIGHTSPEED) expose neither the legacy0x1000nor the unified0x1004— battery is reported only as a measured voltage via0x1001, which until now was a name-only row in the feature registry. The probe found no battery feature and the device showedbattery=—inlistand no indicator in the GUI, even once it enumerated fine.This is a read-only slice, mirroring the scope
BatteryStatus(0x1000) keeps:getBatteryInfo(function0) only, no broadcast event — the inventory's per-tick refresh already covers updates.Changes
openlogi-hidpp/feature/battery_voltage— new typed wrapper for0x1001: voltage as a big-endian millivoltu16plus a charging-flags byte. The wire layout is not in a public Logitech spec; the decoding follows Solaar (decipher_battery_voltage) and libratbag's consensus and is marked as reverse-engineered, per the repo's hidpp rules. Flag decoding is total on purpose — a contradictory or future flag combination falls into the nearest charging bucket rather than failing, so a battery reading never vanishes over an unknown bit (the same reasoning as0x1000's value-7 handling). Unit tests cover each decode path.feature/registry.rs— bind the existing0x1001 "BatteryVoltage"row to the new wrapper.openlogi-hid/mappings.rs—voltage_battery_percentage: the feature reports millivolt, not percent, so the percentage is estimated with Solaar's measured Li-Po discharge curve (13 points, 3500–4186 mV), linearly interpolated and clamped at the ends; marked reverse-engineered.map_voltage_battery_statusfolds the charging states into ourBatteryStatusexactly as the0x1000/0x1004mappings do (fast → charging,NotChargingfault → error). Tests: curve endpoints, exact curve points, interpolation, monotonicity across the full 3400–4300 mV range.openlogi-hid/inventory/features.rs—BatteryProbe::Voltage: found by the same feature-table walk, ranked after0x1004and0x1000since those report a real percentage and the voltage path only estimates one. The firmware's critical flag (bit5) outranks the estimated level bucket. Tests cover the new ranking.No IPC change: the reading lands in the existing
BatteryInfo(percentage/level/status), so no new wire variants and noPROTOCOL_VERSIONbump.Testing
Verified on Windows 11 with a real G915 (wpid
0x407c) on its Lightspeed receiver:The agent registers the same reading and the GUI shows the battery indicator. Note: the hardware run had #574's receiver recognition (
046d:c547) applied locally, since a G915 is otherwise unreachable — this PR is receiver-agnostic and independent of it; on current master the immediate beneficiaries are0x1001-only devices behind already-recognised receivers (e.g. a G903 LS on046d:c539).Local gate on this branch:
Notes
1(getShowBatteryStatus) and the broadcast event are intentionally out of scope, as is any UI change — the existing battery indicator lights up through the standardBatteryInfopath.Refs #512