OpenLogi
Features

0x1004 · unifiedBattery

Modern unified battery feature — query charge percentage, coarse level, and charging status, with live push events.

The modern, unified battery feature — one call for percentage, a coarse level, and charge status, replacing the older 0x1000 batteryStatus / 0x1001 batteryVoltage features. getBatteryCapabilities reports what the device can measure; getBatteryInfo returns the charging percentage, a BatteryLevel (full / good / low / critical), and a BatteryStatus (charging, discharging, …). The feature also emits live updates as the device pushes them.

OpenLogi reads it for the battery percentage and charge state shown in the device carousel and the list inventory.

Spec: Logitech HID++ 2.0 — x1004 unifiedBattery. Used by: battery percentage / charge state.

Function reference

The UnifiedBatteryFeature wrapper (0x1004) exposes:

Methods

FunctionHID++ fnSignatureReturns
get_battery_capabilities0()BatteryCapabilities
get_battery_info1()BatteryInfo
listenevent()Receiver<BatteryEvent>

get_battery_capabilities and get_battery_info are async and return Result<…, Hidpp20Error>. listen is synchronous and returns a channel receiver directly.

Types

BatteryCapabilities

Represents the capabilities of this feature and the battery itself.

FieldTypeDescription
reported_levelsHashSet<BatteryLevel>All BatteryLevel variants the feature supports and reports.
rechargeableboolWhether the battery is rechargeable.
percentageboolWhether the device supports reporting the current charge percentage in BatteryInfo::charging_percentage.

BatteryInfo

Represents information about the current battery charge.

FieldTypeDescription
charging_percentageu8The current charge of the battery in percent. Always zero if BatteryCapabilities::percentage is false.
levelBatteryLevelThe current (approximate) level of the battery.
statusBatteryStatusThe current charging status of the battery.

BatteryLevel

Represents an approximate level of the battery charge.

VariantValueDescription
Critical1Critical battery level.
Low2Low battery level.
Good4Good battery level.
Full8Full battery level.

BatteryStatus

Represents the charging status of the battery.

VariantValueDescription
Discharging0Battery is discharging.
Charging1Battery is charging.
ChargingSlow2Battery is charging slowly.
Full3Battery is full.
Error4Battery subsystem reported an error.

Events

UnifiedBatteryFeature implements EmittingFeature<BatteryEvent>. Call listen() to obtain a channel receiver that yields BatteryEvent values pushed by the device.

BatteryEvent

VariantPayloadDescription
InfoUpdateBatteryInfoEmitted whenever the battery information changes. Always enabled.

Wire format

Both request payloads are 3 zero bytes; the device replies with a 16-byte long-format payload and the crate reads the first few bytes via extend_payload().

get_battery_capabilities (fn 0)

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

Response (byte → field):

ByteFieldNotes
0, bit 0reported_levels contains Criticalset if payload[0] & 0x01 != 0
0, bit 1reported_levels contains Lowset if payload[0] & 0x02 != 0
0, bit 2reported_levels contains Goodset if payload[0] & 0x04 != 0
0, bit 3reported_levels contains Fullset if payload[0] & 0x08 != 0
1, bit 0rechargeableset if payload[1] & 0x01 != 0
1, bit 1percentageset if payload[1] & 0x02 != 0

get_battery_info (fn 1)

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

Response (byte → field):

ByteFieldNotes
0charging_percentageraw u8; zero when BatteryCapabilities::percentage is false
1levelBatteryLevel enum value (1 = Critical, 2 = Low, 4 = Good, 8 = Full)
2statusBatteryStatus enum value (0 = Discharging … 4 = Error)
3(external power source indicator)not decoded by the crate; see Linux driver notes in source

InfoUpdate event (fn 0, event sub-id 0)

The device pushes this event unsolicited whenever battery state changes. The crate's message listener parses it identically to get_battery_info:

ByteFieldNotes
0charging_percentageraw u8
1levelBatteryLevel enum value
2statusBatteryStatus enum value

Usage (Rust)

use hidpp::{
    device::Device,
    feature::{EmittingFeature, unified_battery::UnifiedBatteryFeature},
};

// device: &mut Device, already created via Device::new(channel, index)
device.enumerate_features().await?;

if let Some(feat) = device.get_feature::<UnifiedBatteryFeature>() {
    // Query static capabilities once
    let caps = feat.get_battery_capabilities().await?;
    println!("rechargeable={}, percentage={}", caps.rechargeable, caps.percentage);

    // Poll current state
    let info = feat.get_battery_info().await?;
    println!("{}% — {:?} / {:?}", info.charging_percentage, info.level, info.status);

    // Subscribe to live updates pushed by the device
    let rx = feat.listen();
    while let Ok(event) = rx.recv().await {
        println!("battery event: {:?}", event);
    }
}

On this page