Supported HID++ Features in OpenLogi: Complete Registry and Implementation Guide

OpenLogi supports over 40 HID++ 2.0 protocol features—including DPI adjustment, SmartShift, per-key RGB lighting, and battery monitoring—implemented as Rust modules under crates/openlogi-hidpp/src/ with traits for instantiation, event handling, and device communication.

OpenLogi provides a comprehensive open-source implementation of the Logitech HID++ 2.0 protocol, enabling programmatic control of advanced Logitech peripherals through discrete feature modules. Each supported capability is encapsulated in its own source file within the openlogi-hidpp crate, with the central registry and trait definitions located in crates/openlogi-hidpp/src/feature.rs.

Complete Registry of Supported HID++ Features

The following HID++ features are fully implemented and accessible through the OpenLogi library. Each feature resides in a dedicated Rust module at crates/openlogi-hidpp/src/<feature_name>.rs.

Input and Navigation Control

Key Remapping and Configuration

Lighting and Illumination

Power and Battery Management

Device Configuration and Host Management

Audio and Haptic Feedback

Core Architecture and Traits

Feature Traits and Registry

Every HID++ feature in OpenLogi implements the Feature trait as a marker interface. Features supporting automatic instantiation implement CreatableFeature, which provides:

  • A static ID constant (the HID++ feature ID)
  • A STARTING_VERSION constant (protocol version)
  • A new constructor accepting an Arc<HidppChannel>, device index, and feature index

The central registry in crates/openlogi-hidpp/src/feature.rs (lines 61-96) defines FeatureType bitflags describing feature metadata such as obsolescence, hidden, or engineering status. Global feature registration is handled by crates/openlogi-hidpp/src/registry.rs.

Communication Endpoints

Features communicate through a FeatureEndpoint that constructs HID++ request headers and manages protocol-level transactions. The endpoint exposes:

  • call — For short (8-byte) HID++ messages
  • call_long — For long (20-byte) HID++ messages

Event-Driven Architecture

Features emitting unsolicited hardware events implement EmittingFeature<T> and utilize an EventSource<E> to decode broadcast payloads. The event_payload method parses raw HID++ event packets into structured Rust types, enabling asynchronous reactive programming patterns.

Practical Usage Examples

Instantiating Event-Driven Features

The following example demonstrates creating a SmartShift feature instance and listening for status events:

use std::sync::Arc;
use openlogi_hidpp::{channel::HidppChannel, feature::smartshift::SmartShift};

async fn example(chan: Arc<HidppChannel>, dev_idx: u8, feat_idx: u8) {
    // SmartShift implements CreatableFeature
    let smartshift = SmartShift::new(chan.clone(), dev_idx, feat_idx);

    // The feature emits `SmartShiftEvent`s – get a receiver
    let mut rx = smartshift.listen();

    // Process events in an async loop
    while let Ok(event) = rx.recv_async().await {
        println!("SmartShift event: {:?}", event);
    }
}

Configuring DPI Settings

Adjust sensor resolution using the AdjustableDpi feature:

use openlogi_hidpp::feature::adjustable_dpi::AdjustableDpi;

async fn set_dpi(chan: Arc<HidppChannel>, dev: u8, feat: u8, dpi: u16) {
    let dpi_feature = AdjustableDpi::new(chan, dev, feat);
    // `set_dpi` is a short‑report call (example API)
    dpi_feature.set_dpi(dpi).await.expect("failed to set DPI");
}

Reading Battery Telemetry

Query hardware voltage levels through the BatteryVoltage feature:

use openlogi_hidpp::feature::battery_voltage::BatteryVoltage;

async fn read_voltage(chan: Arc<HidppChannel>, dev: u8, feat: u8) {
    let bat = BatteryVoltage::new(chan, dev, feat);
    let volts = bat.read_voltage().await.unwrap();
    println!("Battery voltage: {} mV", volts);
}

Summary

  • OpenLogi implements 40+ HID++ 2.0 features covering input control, lighting, power management, and device configuration.
  • All feature modules reside in crates/openlogi-hidpp/src/ with the central registry defined in feature.rs.
  • Features use the CreatableFeature trait for instantiation and EmittingFeature<T> for event streams.
  • Communication occurs through FeatureEndpoint with call and call_long methods for short and long HID++ messages.
  • High-level device APIs in crates/openlogi-device/src/write/*.rs ultimately delegate to these HID++ feature implementations.

Frequently Asked Questions

What is the HID++ 2.0 protocol used by OpenLogi?

HID++ 2.0 is Logitech's proprietary extension to the USB HID protocol, enabling advanced device features like high-resolution scrolling, per-key lighting, and host switching. OpenLogi implements this protocol in Rust, allowing developers to access these capabilities without relying on Logitech's proprietary software.

How do I determine which HID++ features a specific device supports?

Use the feature_set module (crates/openlogi-hidpp/src/feature_set.rs) to query the device's advertised capabilities. This feature returns a bitmap of supported feature IDs, which you can cross-reference against the CreatableFeature::ID constants in the OpenLogi source code.

What is the difference between CreatableFeature and EmittingFeature?

CreatableFeature marks features that can be instantiated directly with a constructor and static ID, such as BatteryVoltage or AdjustableDpi. EmittingFeature<T> extends this capability for hardware that sends unsolicited status updates (like SmartShift or BatteryStatus), providing an async event receiver through the listen() method.

How does OpenLogi handle asynchronous HID++ events?

Event-driven features implement EmittingFeature<T> and use an EventSource<E> to decode event_payload data. The library spawns async tasks that monitor the HID++ channel for broadcast messages, deserializing them into typed Rust events that can be processed through async receivers without blocking the main execution thread.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →