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}_info → ControlInfo), 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).
ControlInfo—capabilitiesflags (HAS_EVENTS,HAS_LINEAR_LEVELS,HAS_NON_LINEAR_LEVELS,HAS_DYNAMIC_MAXIMUM),min,max,resolution,max_levels.LevelConfig—Linear { min, max, step }orNonLinear { start_index, level_count, values }.IlluminationState—On/Off.- Events —
IlluminationChanged,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
| Function | HID++ fn | Signature | Returns |
|---|---|---|---|
get_illumination | 0 | () | IlluminationState |
set_illumination | 1 | (state: IlluminationState) | () |
get_brightness_info | 2 | () | ControlInfo |
get_brightness | 3 | () | u16 |
set_brightness | 4 | (brightness: u16) | () |
get_brightness_levels | 5 | (start_index: u8) | LevelConfig |
set_brightness_levels | 6 | (levels: &SetLevels) | () |
get_color_temperature_info | 7 | () | ControlInfo |
get_color_temperature | 8 | () | u16 |
set_color_temperature | 9 | (color_temperature: u16) | () |
get_color_temperature_levels | 10 | (start_index: u8) | LevelConfig |
set_color_temperature_levels | 11 | (levels: &SetLevels) | () |
get_brightness_effective_max | 12 | () | u16 |
listen | event | () | 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.
| Flag | Bit | Description |
|---|---|---|
HAS_EVENTS | 0 | The control emits change events. |
HAS_LINEAR_LEVELS | 1 | The control supports linear (min/max/step) levels. |
HAS_NON_LINEAR_LEVELS | 2 | The control supports an explicit list of non-linear levels. |
HAS_DYNAMIC_MAXIMUM | 3 | The 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.
| Field | Type | Description |
|---|---|---|
capabilities | ControlCapabilities | Control capabilities. |
min | u16 | Minimum value. When min == max only one setting exists and the corresponding setter is unsupported. |
max | u16 | Maximum value. |
resolution | u16 | Resolution: valid values satisfy (value - min) % resolution == 0. |
max_levels | u8 | Maximum 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.
| Variant | Fields | Description |
|---|---|---|
Linear | min: u16, max: u16, step: u16 | Evenly spaced levels from min to max inclusive in steps of step. |
NonLinear | start_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.
| Variant | Fields | Description |
|---|---|---|
Reset | — | Reset the level configuration to the factory defaults. |
Linear | min: u16, max: u16, step: u16 | Configure evenly spaced linear levels. |
NonLinear | start_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.
| Variant | Value | Description |
|---|---|---|
Off | 0 | Illumination is off. |
On | 1 | Illumination is on. |
BrightnessClampedSource
What caused a brightness clamp event.
| Variant | Value | Description |
|---|---|---|
Unknown | 0 | The source is unknown. |
HidPlusPlus | 1 | A HID++ setBrightness request triggered the clamp. |
Button | 2 | A hardware button triggered the clamp. |
Events
IlluminationFeature implements EmittingFeature<IlluminationEvent> and broadcasts variants via listen():
| Variant | Payload | Description |
|---|---|---|
IlluminationChanged | IlluminationState | The on/off illumination state changed. |
BrightnessChanged | u16 (Lumens) | The brightness changed. |
ColorTemperatureChanged | u16 (Kelvin) | The color temperature changed. |
BrightnessEffectiveMaxChanged | u16 (Lumens; 0 = no limit) | The effective maximum brightness changed. Requires feature version 1. |
BrightnessClamped | source: BrightnessClampedSource, brightness: u16 | A 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):
| Byte | Field | Notes |
|---|---|---|
| 0 | state | Bit 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):
| Byte | Field | Notes |
|---|---|---|
| 0 | capabilities | ControlCapabilities bitfield |
| 1–2 | min | BE u16 |
| 3–4 | max | BE u16 |
| 5–6 | resolution | BE u16 |
| 7 | max_levels | Low 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):
| Byte | Field | Notes |
|---|---|---|
| 0–1 | value | BE 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):
| Byte | Field | Notes |
|---|---|---|
| 0 | flags | Bit 0 = linear; bits [7:5] = valid value count (non-linear only) |
| 1 | page info | Bits [7:4] = start_index, bits [3:0] = level_count (non-linear only) |
| 2–3 | min / value[0] | Linear: min BE u16; NonLinear: first level value |
| 4–5 | max / value[1] | Linear: max BE u16 |
| 6–7 | step / value[2] | Linear: step BE u16 |
| 8–9 … 14–15 | value[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():
| Variant | Byte 0 | Byte 1 | Bytes 2–7 | Remaining |
|---|---|---|---|---|
Reset | 0x02 (bit 1) | 0x00 | 0x00 … | ignored |
Linear | 0x01 (bit 0) | 0x00 | min BE u16, max BE u16, step BE u16 | 0x00 |
NonLinear | (count & 0x07) << 5 | (start_index << 4) | level_count | up to 7 BE u16 values packed starting at byte 2 | 0x00 |
Events
Events are received as unsolicited messages; the sub-id (low nibble of the message's function byte) selects the event:
| Sub-id | Event | Byte → field |
|---|---|---|
| 0 | IlluminationChanged | Byte 0 bit 0 = IlluminationState |
| 1 | BrightnessChanged | Bytes 0–1 BE u16 = Lumens |
| 2 | ColorTemperatureChanged | Bytes 0–1 BE u16 = Kelvin |
| 3 | BrightnessEffectiveMaxChanged | Bytes 0–1 BE u16 = Lumens (0 = no limit) |
| 4 | BrightnessClamped | Byte 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:?}");
}
}