# How to Set Up SmartShift on Logitech Mice Using OpenLogi

> Learn how to set up SmartShift on Logitech mice with OpenLogi. Configure wheel modes and auto-disengage sensitivity using Rust APIs or CLI commands for advanced control.

- Repository: [Xuan Zhang/OpenLogi](https://github.com/AprilNEA/OpenLogi)
- Tags: how-to-guide
- Published: 2026-09-08

---

**OpenLogi enables SmartShift configuration on Logitech mice by implementing HID++ 2.0 features 0x2110 and 0x2111, allowing you to toggle wheel modes and adjust auto-disengage sensitivity through both Rust APIs and CLI commands.**

OpenLogi is an open-source Rust library that provides low-level control over Logitech HID++ 2.0 devices. When you need to set up SmartShift on Logitech mice using OpenLogi, you gain access to automatic wheel-mode switching capabilities that work across both legacy and enhanced hardware implementations.

## How SmartShift Works in OpenLogi

SmartShift (the automatic wheel-mode switch between free-spin and ratchet) is implemented through two HID++ 2.0 feature IDs: **0x2110** (legacy) and **0x2111** (enhanced). The library automatically detects which feature your mouse supports and opens the appropriate interface.

The core logic resides in [`crates/openlogi-device/src/write/smartshift.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-device/src/write/smartshift.rs). This module normalizes both feature variants onto the public `SmartShiftMode` enum and handles the underlying protocol differences transparently. When writing configurations, the code checks for transient errors that can arise from concurrent HID++ traffic and implements automatic retry logic with a short delay.

## CLI Configuration Commands

The `openlogi` CLI provides the `diag smartshift` subcommand (implemented in [`crates/openlogi-cli/src/cmd/diag/smartshift.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-cli/src/cmd/diag/smartshift.rs)) for immediate device configuration without writing code.

### Toggle Between Free and Ratchet Modes

To switch the wheel mode and verify the change, run:

```bash
openlogi diag smartshift

```

This reads the current status, flips the mode, writes it back, and restores the original state after verification.

### Set Auto-Disengage Sensitivity

To adjust the threshold that triggers automatic mode switching while preserving the current wheel mode:

```bash
openlogi diag smartshift --sensitivity 30

```

### Persistent Mode Changes

To toggle the mode and leave it in the new state (useful for visual verification):

```bash
openlogi diag smartshift --leave-flipped

```

## Programmatic Control with the Rust API

For integration into applications, the `openlogi_hid` crate exposes three primary functions that interact with the device route.

### Reading Current Status

Use `get_smartshift_status` to retrieve the current mode, auto-disengage value, and tunable torque data:

```rust
use openlogi_hid::get_smartshift_status;
use openlogi_device::DeviceRoute;

// Assume `route` points to the target mouse
let status = get_smartshift_status(&route).await?;
println!("Current mode: {:?}", status.mode);

```

### Toggling SmartShift Modes

The `toggle_smartshift` function flips between Free and Ratchet modes while preserving sensitivity settings:

```rust
use openlogi_hid::{toggle_smartshift, get_smartshift_status};
use openlogi_device::DeviceRoute;

let before = get_smartshift_status(&route).await?;
println!("Current mode: {:?}", before.mode);

let new_mode = toggle_smartshift(&route).await?;
println!("Toggled to: {:?}", new_mode);

let after = get_smartshift_status(&route).await?;
assert_ne!(before.mode, after.mode);

```

### Configuring Sensitivity Values

To set a custom auto-disengage threshold, use `set_smartshift_sensitivity` with a `SmartShiftAutoDisengage` value. The value must be non-zero, as 0 is rejected by the device:

```rust
use openlogi_hid::{set_smartshift_sensitivity, SmartShiftAutoDisengage};
use openlogi_device::DeviceRoute;

let value = SmartShiftAutoDisengage::from(20u8);
let status = set_smartshift_sensitivity(&route, value).await?;
println!("New sensitivity: {}", status.auto_disengage);

```

## Error Handling and Concurrency Safety

All write operations in [`smartshift.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/smartshift.rs) first verify whether the device already matches the desired configuration using `status_matches_desired`. This prevents unnecessary HID++ transactions.

When the library encounters transient errors from concurrent HID++ traffic (issue #485), it automatically retries once after the `TRANSIENT_RETRY_DELAY` interval. This makes the operation robust against race conditions with other software accessing the device simultaneously.

## Summary

- OpenLogi implements SmartShift through HID++ 2.0 features **0x2110** (legacy) and **0x2111** (enhanced) in [`crates/openlogi-device/src/write/smartshift.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-device/src/write/smartshift.rs).
- The **CLI** provides `openlogi diag smartshift` with flags for `--sensitivity` and `--leave-flipped` for immediate configuration.
- The **Rust API** exposes `get_smartshift_status`, `toggle_smartshift`, and `set_smartshift_sensitivity` through the `openlogi_hid` crate.
- All operations include **transient error handling** with automatic retry logic to ensure reliable device communication.
- Configuration changes preserve existing settings unless explicitly overwritten.

## Frequently Asked Questions

### What HID++ protocol features does OpenLogi use to control SmartShift?

OpenLogi uses HID++ 2.0 feature **0x2110** for legacy SmartShift implementations and **0x2111** for enhanced versions. The library automatically detects which feature your mouse supports and normalizes both onto the `SmartShiftMode` enum in [`crates/openlogi-core/src/hid/smartshift.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/hid/smartshift.rs).

### How do I check if my mouse supports SmartShift before attempting configuration?

Call `get_smartshift_status(&route).await?` from the `openlogi_hid` crate. If the device does not support SmartShift, the function will return an error indicating the feature is unavailable. The CLI command `openlogi diag smartshift` performs this check automatically before attempting writes.

### What values are valid for the auto-disengage sensitivity setting?

The sensitivity value must be a `NonZeroU8` (1-255). The value **0 is rejected by the device**. In practice, values between 10 and 50 provide noticeable differences in auto-disengage behavior, though the exact acceptable range depends on your specific Logitech mouse model.

### Does OpenLogi handle concurrent access from Logitech Options or other software?

Yes. The write logic in [`smartshift.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/smartshift.rs) checks for `status_matches_desired` before writing and implements a retry mechanism with `TRANSIENT_RETRY_DELAY` for transient errors. This handles race conditions that occur when Logitech Options or other HID++ clients access the device simultaneously.