OpenLogi

0x1990 · illumination

Device illumination control — toggle the light on or off and independently read or write brightness (Lumens) and color temperature (Kelvin).

Controls the illumination light of a device, with independent brightness (in Lumens) and color_temperature (in Kelvin) axes. Both axes share the same shape: an info query (get_{brightness,color_temperature}_infoControlInfo), a current-value getter/setter, and a paginated level-list getter/setter. get_illumination / set_illumination toggle the light on or off as a whole.

Feature version 1 adds get_brightness_effective_max — a dynamic ceiling that may be lower than the static maximum — plus two events: BrightnessEffectiveMaxChanged and BrightnessClamped (carrying a BrightnessClampedSource that identifies whether a HID++ request or a hardware button triggered the clamp).

  • ControlInfocapabilities flags (HAS_EVENTS, HAS_LINEAR_LEVELS, HAS_NON_LINEAR_LEVELS, HAS_DYNAMIC_MAXIMUM), min, max, resolution, max_levels.
  • LevelConfigLinear { min, max, step } or NonLinear { start_index, level_count, values }.
  • IlluminationStateOn / Off.
  • EventsIlluminationChanged, BrightnessChanged, ColorTemperatureChanged, BrightnessEffectiveMaxChanged, BrightnessClamped.

Spec: Logitech HID++ 2.0 — illumination. Used by: Typed wrapper in openlogi-hidpp.

Function reference

The IlluminationFeature wrapper (0x1990) exposes:

Methods

FunctionHID++ fnSignatureReturns
get_illumination0()IlluminationState
set_illumination1(state: IlluminationState)()
get_brightness_info2()ControlInfo
get_brightness3()u16
set_brightness4(brightness: u16)()
get_brightness_levels5(start_index: u8)LevelConfig
set_brightness_levels6(levels: &SetLevels)()
get_color_temperature_info7()ControlInfo
get_color_temperature8()u16
set_color_temperature9(color_temperature: u16)()
get_color_temperature_levels10(start_index: u8)LevelConfig
set_color_temperature_levels11(levels: &SetLevels)()
get_brightness_effective_max12()u16
listenevent()Receiver<IlluminationEvent>

All async methods return Result<…, Hidpp20Error>. listen is synchronous and returns a channel receiver.

Types

ControlCapabilities

Capabilities of an illumination control (brightness or color temperature), from get_brightness_info / get_color_temperature_info.

FlagBitDescription
HAS_EVENTS0The control emits change events.
HAS_LINEAR_LEVELS1The control supports linear (min/max/step) levels.
HAS_NON_LINEAR_LEVELS2The control supports an explicit list of non-linear levels.
HAS_DYNAMIC_MAXIMUM3The control has a dynamic effective maximum (brightness only).

ControlInfo

Capabilities and range of an illumination control. Values are in Lumens for brightness and Kelvin for color temperature.

FieldTypeDescription
capabilitiesControlCapabilitiesControl capabilities.
minu16Minimum value. When min == max only one setting exists and the corresponding setter is unsupported.
maxu16Maximum value.
resolutionu16Resolution: valid values satisfy (value - min) % resolution == 0.
max_levelsu8Maximum number of non-linear levels (0 if non-linear levels are unsupported).

LevelConfig

The level configuration of an illumination control, returned by get_brightness_levels and get_color_temperature_levels.

VariantFieldsDescription
Linearmin: u16, max: u16, step: u16Evenly spaced levels from min to max inclusive in steps of step.
NonLinearstart_index: u8, level_count: u8, values: Vec<u16>An explicit list of level values; 1..=7 values per page.

SetLevels

A level configuration to write with set_brightness_levels / set_color_temperature_levels.

VariantFieldsDescription
ResetReset the level configuration to the factory defaults.
Linearmin: u16, max: u16, step: u16Configure evenly spaced linear levels.
NonLinearstart_index: u8, level_count: u8, values: Vec<u16>Configure an explicit list of non-linear levels (1..=7 values, monotonically increasing).

IlluminationState

On/off state of the illumination.

VariantValueDescription
Off0Illumination is off.
On1Illumination is on.

BrightnessClampedSource

What caused a brightness clamp event.

VariantValueDescription
Unknown0The source is unknown.
HidPlusPlus1A HID++ setBrightness request triggered the clamp.
Button2A hardware button triggered the clamp.

Events

IlluminationFeature implements EmittingFeature<IlluminationEvent> and broadcasts variants via listen():

VariantPayloadDescription
IlluminationChangedIlluminationStateThe on/off illumination state changed.
BrightnessChangedu16 (Lumens)The brightness changed.
ColorTemperatureChangedu16 (Kelvin)The color temperature changed.
BrightnessEffectiveMaxChangedu16 (Lumens; 0 = no limit)The effective maximum brightness changed. Requires feature version 1.
BrightnessClampedsource: BrightnessClampedSource, brightness: u16A brightness request was clamped to the effective maximum. Requires feature version 1.

Wire format

Requests use a 3-byte short payload unless noted; responses are parsed from the 16-byte extended payload. All multi-byte fields are big-endian.

get_illumination (fn 0)

Request: [0x00, 0x00, 0x00]

Response (byte → field):

ByteFieldNotes
0stateBit 0: 1 = On, 0 = Off

set_illumination (fn 1)

Request: [state, 0x00, 0x00]state is IlluminationState as u8 (0 = Off, 1 = On).

Response: empty (acknowledgement only).

get_brightness_info (fn 2) / get_color_temperature_info (fn 7)

Request: [0x00, 0x00, 0x00]

Response (byte → field):

ByteFieldNotes
0capabilitiesControlCapabilities bitfield
1–2minBE u16
3–4maxBE u16
5–6resolutionBE u16
7max_levelsLow nibble only (& 0x0f)

get_brightness (fn 3) / get_color_temperature (fn 8) / get_brightness_effective_max (fn 12)

Request: [0x00, 0x00, 0x00]

Response (byte → field):

ByteFieldNotes
0–1valueBE u16 (Lumens or Kelvin); 0 means no effective limit for fn 12

set_brightness (fn 4) / set_color_temperature (fn 9)

Request: [value_hi, value_lo, 0x00] — big-endian u16.

Response: empty.

get_brightness_levels (fn 5) / get_color_temperature_levels (fn 10)

Request: [start_index << 4, 0x00, 0x00]start_index in the high nibble of byte 0 (must be ≤ 0x0f).

Response (byte → field):

ByteFieldNotes
0flagsBit 0 = linear; bits [7:5] = valid value count (non-linear only)
1page infoBits [7:4] = start_index, bits [3:0] = level_count (non-linear only)
2–3min / value[0]Linear: min BE u16; NonLinear: first level value
4–5max / value[1]Linear: max BE u16
6–7step / value[2]Linear: step BE u16
8–9 … 14–15value[3] … value[6]Non-linear pages only; up to 7 values total

set_brightness_levels (fn 6) / set_color_temperature_levels (fn 11)

Uses call_long with a 16-byte payload from SetLevels::to_payload():

VariantByte 0Byte 1Bytes 2–7Remaining
Reset0x02 (bit 1)0x000x00 …ignored
Linear0x01 (bit 0)0x00min BE u16, max BE u16, step BE u160x00
NonLinear(count & 0x07) << 5(start_index << 4) | level_countup to 7 BE u16 values packed starting at byte 20x00

Events

Events are received as unsolicited messages; the sub-id (low nibble of the message's function byte) selects the event:

Sub-idEventByte → field
0IlluminationChangedByte 0 bit 0 = IlluminationState
1BrightnessChangedBytes 0–1 BE u16 = Lumens
2ColorTemperatureChangedBytes 0–1 BE u16 = Kelvin
3BrightnessEffectiveMaxChangedBytes 0–1 BE u16 = Lumens (0 = no limit)
4BrightnessClampedByte 0 = BrightnessClampedSource; bytes 1–2 BE u16 = clamped Lumens

Usage (Rust)

use hidpp::{device::Device, feature::illumination::{IlluminationFeature, IlluminationState, SetLevels}};

// device: &mut Device, already created via Device::new(channel, index)
device.enumerate_features().await?;
if let Some(feat) = device.get_feature::<IlluminationFeature>() {
    // Turn illumination on
    feat.set_illumination(IlluminationState::On).await?;

    // Read brightness range, then set to halfway point
    let info = feat.get_brightness_info().await?;
    let mid = info.min + (info.max - info.min) / 2;
    feat.set_brightness(mid).await?;

    // Subscribe to events
    let rx = feat.listen();
    while let Ok(event) = rx.recv().await {
        println!("{event:?}");
    }
}

On this page