OpenLogi

0x1F20 · adcMeasurement

Battery voltage and link state for wireless G-series headsets, including the G733.

adcMeasurement reports a headset battery voltage and link or charging flags. Wireless G-series headsets such as G733 expose it without 0x1000, 0x1001, or 0x1004. The feature does not report a percentage.

Spec: No public Logitech specification. Layout reverse-engineered from Logi Options+ 2.8 (static analysis). Cross-checked: Linux HID++ driver, Solaar, G HUB (static analysis). Used by: device inventory and openlogi list.

Function reference

AdcMeasurementFeature (0x1F20) implements one request method.

Methods

FunctionHID++ fnSignatureReturns
get_adc_measurement0()AdcMeasurement
is_status_broadcastevent helper(function_id: u8)bool

get_adc_measurement is async and returns Result<AdcMeasurement, Hidpp20Error>. This wrapper does not expose the extended-settings or sleep-timeout operations found in G HUB static analysis.

Types

AdcMeasurement

VariantFieldsDescription
Unlinked/Battery-powered headset is not linked. No reading is available.
Linkedvoltage_mv: u16, status: AdcChargingStatusLive battery reading.

AdcChargingStatus

VariantValueDescription
Discharging0x01Headset runs on battery.
Charging0x03External power is present and the headset is charging.
Full0x07External power is present and charging is complete.

Events

This wrapper does not implement EmittingFeature or expose a typed event. is_status_broadcast(function_id) returns true only for function 0.

Wire format

get_adc_measurement (fn 0)

Request: [0x00, 0x00, 0x00] (no parameters).

Response:

ByteFieldNotes
0–1voltage_mvu16, BE, in millivolts.
2flagsLink and charging state.

Flags:

BitMeaningNotes
0LinkedClear produces Unlinked, regardless of other flags.
1ChargingSet in the known charging value 0x03.
2Charge completeSet in the known full value 0x07.
3–7/No meaning is modeled.

The known linked flag values are 0x01, 0x03, and 0x07. Other linked values return Hidpp20Error::UnsupportedResponse.

A LogitechInternal feature error (0x05) returns AdcMeasurement::Unlinked. A G733 dongle reports that error while its headset is switched off. Other feature errors remain errors.

Status broadcast (event fn 0)

An unsolicited function-0 report carries the same three bytes as get_adc_measurement. It announces a changed voltage or headset link state.

How OpenLogi uses it

Inventory selects ADC measurement only when 0x1004, 0x1000, and 0x1001 are absent. A live sample maps through OpenLogi's 13-point single-cell Li-Po voltage curve. The result becomes an estimated percentage and a local battery level.

PR #1601 shipped this G733 battery and power-state support in v0.8.13. A captured G733 sample of 3,905 mV with flags 0x01 maps to an estimated 67%. A LogitechInternal error or a clear link bit marks the headset unlinked.

The persistent inventory listener accepts an unsolicited software-ID-0, function-0 report. It queues one coalesced reconciliation even when the flags are unknown. The subsequent read decides whether the headset is linked or unavailable.

OpenLogi only reads this feature.

Open questions

For linked flags 0x0F, Linux treats the result as unknown or offline. Logi Options+ preserves the individual flag bits. OpenLogi returns UnsupportedResponse, and inventory treats that read as unavailable.

OpenLogi uses the same 13-point curve as 0x1001 and Solaar. The Linux headset curve uses different values, about 3.4–4.03 V. No hardware comparison with the Logi Options+ percentage display establishes the correct headset calibration.

G HUB static analysis identifies extended-settings and sleep-timeout operations. It does not establish their function indexes or packet layouts. OpenLogi does not expose them.

Usage (Rust)

use hidpp::{
    device::Device,
    feature::{
        adc_measurement::{AdcMeasurement, AdcMeasurementFeature},
    },
};

// `channel` and `device_index` identify an already opened HID++ device.
let mut device = Device::new(channel, device_index).await?;
device.enumerate_features().await?;

if let Some(feature) = device.get_feature::<AdcMeasurementFeature>() {
    match feature.get_adc_measurement().await? {
        AdcMeasurement::Linked { voltage_mv, status } => {
            println!("{} mV: {status:?}", voltage_mv);
        }
        AdcMeasurement::Unlinked => println!("headset is unlinked"),
    }
}

See also: 0x1001 batteryVoltage and 0x1004 unifiedBattery.

On this page