OpenLogi
功能(Features)

0x4301 · solarKeyboardDashboard

太阳能键盘的电池与环境光监测——调度周期性光照报告、覆盖 CheckLight LED 颜色,并接收包含电量与勒克斯值的广播事件。

适用于 Logitech 太阳能键盘(如 K750)的电池与环境光监测功能。 set_light_measure 通过指定报告次数和间隔秒数来调度周期性光照报告;将任一参数设为 0 可取消正在进行的调度。 set_led 以指定颜色点亮 CheckLight LED 并持续固件定义的时长——应在 CheckLightButton 事件触发后 250 ms 窗口内调用,以抢在固件自行显示状态之前介入。

全部三种广播事件均携带 SolarStatus 载荷,包含 battery_level(百分比)和 light_level(勒克斯,0511):

  • Battery —— 自发报告,约每 90 秒、上电及重连时触发;此事件的 light_level 始终为 0
  • LightMeasure —— 按 set_light_measure 设定的周期,每期发送一次。
  • CheckLightButton —— 用户按下 CheckLight 按钮时触发,携带最新的电池与光照读数。

set_led 接受 LedId 枚举值:OffRedOrangeGreen

规格: Logitech HID++ 2.0 —— solarKeyboardDashboard用于: openlogi-hidpp 中的类型化封装。

Function reference

The SolarDashboardFeature wrapper (0x4301) exposes:

Methods

FunctionHID++ fnSignatureReturns
set_light_measure0(max_reports: u8, report_period: u8)()
set_led1(led: LedId)()
listenevent()async_channel::Receiver<SolarEvent>

set_light_measure and set_led are async and return Result<(), Hidpp20Error>. listen is synchronous and returns an async_channel::Receiver<SolarEvent> that yields decoded broadcast events.

Types

LedId

A CheckLight LED color passed to set_led.

VariantValueDescription
Off0All LEDs off.
Red1Red.
Orange2Orange.
Green3Green.

SolarStatus

Battery and light readings shared by every solar-dashboard event.

FieldTypeDescription
battery_levelu8Remaining battery capacity, as a percentage.
light_levelu16Current light measure in lux (0..=511).

Events

SolarDashboardFeature implements EmittingFeature<SolarEvent>; call listen() to subscribe. Each variant wraps a SolarStatus payload.

VariantDescription
Battery(SolarStatus)Spontaneous battery report (every ~90 s, at power-up, and on reconnect). light_level is always 0 for this variant.
LightMeasure(SolarStatus)Battery and light report sent per the set_light_measure schedule.
CheckLightButton(SolarStatus)The CheckLight button was pressed; carries the latest battery and light readings.

Wire format

set_light_measure and set_led each carry a 3-byte short request payload with no meaningful response bytes; both functions are fire-and-acknowledge. Broadcast events arrive as 16-byte long payloads decoded by SolarStatus::from_payload.

set_light_measure (fn 0)

Request: [max_reports, report_period, 0x00]

ByteFieldNotes
0max_reportsNumber of LightMeasure reports to send. 0 cancels scheduling.
1report_periodInterval between reports in seconds. 0 cancels scheduling.
2Padding, always 0x00.

Response: acknowledged only; no response fields are read.

set_led (fn 1)

Request: [led, 0x00, 0x00]

ByteFieldNotes
0ledLedId as u8: Off=0, Red=1, Orange=2, Green=3.
1–2Padding, always 0x00.

Response: acknowledged only; no response fields are read.

Events (fn 0–2)

All three event variants share the same 16-byte payload layout decoded by SolarStatus::from_payload.

ByteFieldNotes
0battery_levelRemaining battery capacity as a percentage (u8).
1–2light_levelAmbient light in lux, big-endian u16 (0..=511).
3–15Unused.

Event sub-id (the function nibble on the broadcast message) selects the variant:

Sub-idVariant
0SolarEvent::Battery
1SolarEvent::LightMeasure
2SolarEvent::CheckLightButton

Usage (Rust)

use hidpp::{device::Device, feature::solar_dashboard::{LedId, SolarDashboardFeature, SolarEvent}};

// device: mut Device, already created via Device::new(channel, index).await?
device.enumerate_features().await?;
if let Some(feat) = device.get_feature::<SolarDashboardFeature>() {
    // Schedule 10 light-measure reports every 30 seconds.
    feat.set_light_measure(10, 30).await?;

    // Subscribe to broadcast events.
    let rx = feat.listen();
    while let Ok(event) = rx.recv().await {
        match event {
            SolarEvent::Battery(s) => println!("battery: {}%", s.battery_level),
            SolarEvent::LightMeasure(s) => println!("battery: {}%, lux: {}", s.battery_level, s.light_level),
            SolarEvent::CheckLightButton(s) => {
                println!("check-light pressed: battery {}%, lux {}", s.battery_level, s.light_level);
                // Override the firmware LED within the 250 ms window.
                feat.set_led(LedId::Green).await?;
            }
        }
    }
}

本页目录