# How OpenLogi Controls RGB Keyboard Static Effects Using the HID++ Protocol

> Discover how OpenLogi controls RGB keyboard static effects with the HID++ protocol. Learn to write backlight configurations and set static lighting via non-volatile memory.

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

---

**OpenLogi controls static RGB keyboard lighting by leveraging the Logitech HID++ Backlight feature (ID 0x1982), writing the `BacklightEffect::Static` discriminant value `0` to the device's non-volatile memory via the `set_backlight_config` method.**

The OpenLogi open-source project provides a Rust-based implementation for managing Logitech HID++ devices, enabling precise control over keyboard illumination. By interfacing directly with the HID++ protocol's backlight feature, the codebase allows developers to set persistent static color effects or apply temporary lighting changes in RAM. This article examines the specific mechanisms OpenLogi uses to configure static RGB effects, referencing the actual implementation in the AprilNEA/OpenLogi repository.

## Understanding the HID++ Backlight Feature

OpenLogi implements the Logitech HID++ Backlight feature (`ID 0x1982`, version 3) to drive keyboard lighting operations. The `BacklightFeature` struct, defined in [`crates/openlogi-hidpp/src/feature/backlight.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/feature/backlight.rs), implements the `FeatureEndpoint` trait to handle HID++ communication. This feature registration occurs in the feature registry at [`crates/openlogi-hidpp/src/feature/registry.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/feature/registry.rs), where the backlight capability is mapped to its protocol identifier.

## Enumerating Available Effects

Before setting a static effect, OpenLogi checks device capabilities through the `BacklightEffectList` bitfield. The "static" effect corresponds to the `STATIC` flag, defined as `1 << 0` within the supported effects list.

According to the source code in [`crates/openlogi-hidpp/src/feature/backlight.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/feature/backlight.rs) (lines 63-66), the effect enumeration allows the host to determine whether the target device supports static illumination before attempting to configure it.

## Persisting Static Effects with set_backlight_config

To permanently store a static RGB configuration in the keyboard's non-volatile memory, OpenLogi uses the `BacklightFeature::set_backlight_config` method. This function accepts a `SetBacklightConfig` struct, which contains an `Option<BacklightEffect>` field named `effect`.

When configuring static lighting, the code passes `Some(BacklightEffect::Static)`, which writes the literal value `0` (the discriminant of `BacklightEffect::Static`) into the request payload. As defined in lines 78-80 of [`backlight.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/backlight.rs), the `SetBacklightConfig` struct encodes this value into a 16-byte argument array, placing the effect byte at index 2.

If the caller passes `None` for the effect field, OpenLogi uses the sentinel value `0xff` (`EFFECT_UNCHANGED`) to instruct the device to retain its current effect setting. The payload construction logic appears in lines 101-104 of [`crates/openlogi-hidpp/src/feature/backlight.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/feature/backlight.rs).

## Applying Transient Effects with set_backlight_effect

For temporary, RAM-only changes that do not persist after power cycling, OpenLogi provides `BacklightFeature::set_backlight_effect`. This method sends the desired `BacklightEffect` value directly via HID++ sub-command 3, allowing for rapid effect previews without altering stored configuration.

The transient setter implementation resides in lines 132-135 of [`crates/openlogi-hidpp/src/feature/backlight.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/feature/backlight.rs), offering a lightweight alternative to the persistent configuration pathway.

## High-Level Device Integration

The HID++ protocol details are abstracted by the higher-level device layer in [`crates/openlogi-device/src/write/backlight.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-device/src/write/backlight.rs). This module opens the backlight feature, retrieves the current configuration, updates the `effect` field to `Static`, and invokes `set_backlight_config` to apply changes. This architecture separates UI concerns from low-level HID++ communication, ensuring that application code interacts with a clean, type-safe API while the library handles byte-level protocol compliance.

## Practical Implementation Examples

The following examples demonstrate how to configure static RGB effects using the OpenLogi API.

To persistently set the static color effect on a keyboard:

```rust
// Acquire device instance and open backlight feature
let device = /* acquire openlogi-device instance */ ;
let backlight = openlogi_hidpp::feature::BacklightFeature::open(&mut device).await?;

// Read current config and modify effect to Static
let mut cfg = backlight.get_backlight_config().await?;
cfg.effect = Some(openlogi_hidpp::feature::BacklightEffect::Static);

// Write to non-volatile memory
backlight.set_backlight_config(cfg).await?;

```

To apply a temporary static effect (RAM only):

```rust
// Open backlight feature
let backlight = openlogi_hidpp::feature::BacklightFeature::open(&mut device).await?;

// Send transient command without persisting
backlight.set_backlight_effect(openlogi_hidpp::feature::BacklightEffect::Static).await?;

```

## Summary

- OpenLogi uses **HID++ feature ID 0x1982** (Backlight feature, version 3) to control RGB lighting according to the Logitech protocol specification.
- The **static effect** is represented by the `STATIC` flag (`1 << 0`) in the `BacklightEffectList` bitfield and discriminant value `0` in the `BacklightEffect` enum.
- Persistent configuration uses **`set_backlight_config`**, writing the effect value to byte index 2 of a 16-byte payload sent via `call_long(1, …)`.
- The **`SetBacklightConfig`** struct uses `0xff` (`EFFECT_UNCHANGED`) as a sentinel value when preserving the current effect is desired.
- Transient effects use **`set_backlight_effect`** via HID++ sub-command 3 for RAM-only changes that disappear after device reset.
- Core implementation resides in **[`crates/openlogi-hidpp/src/feature/backlight.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/feature/backlight.rs)**, with high-level abstractions in **[`crates/openlogi-device/src/write/backlight.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-device/src/write/backlight.rs)**.

## Frequently Asked Questions

### What HID++ feature ID controls keyboard backlighting in OpenLogi?

OpenLogi implements **feature ID 0x1982**, version 3, which corresponds to the Logitech HID++ Backlight feature. This ID is registered in [`crates/openlogi-hidpp/src/feature/registry.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/feature/registry.rs) and enables the `BacklightFeature` struct to communicate lighting commands to compatible keyboards.

### What value represents the static effect in the HID++ protocol?

The static effect is represented by the discriminant value **0** within the `BacklightEffect` enumeration. When OpenLogi constructs a `SetBacklightConfig` payload, it places this value at byte index 2 of the 16-byte argument array to instruct the device to display a static solid color.

### How does OpenLogi distinguish between persistent and temporary RGB effects?

OpenLogi provides two distinct methods: **`set_backlight_config`** writes to non-volatile memory for permanent changes, while **`set_backlight_effect`** uses HID++ sub-command 3 for temporary, RAM-only modifications. The persistent method requires constructing a full `SetBacklightConfig` struct, whereas the transient method accepts only the effect enum directly.

### Where is the backlight feature registered in the OpenLogi codebase?

The backlight feature is registered in **[`crates/openlogi-hidpp/src/feature/registry.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/feature/registry.rs)**, where `BacklightFeature` is associated with HID++ feature ID 0x1982. The actual protocol implementation, including effect definitions and configuration structs, resides in **[`crates/openlogi-hidpp/src/feature/backlight.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/feature/backlight.rs)**.