0x4301 · solarKeyboardDashboard
太阳能键盘的电池与环境光监测——调度周期性光照报告、覆盖 CheckLight LED 颜色,并接收包含电量与勒克斯值的广播事件。
适用于 Logitech 太阳能键盘(如 K750)的电池与环境光监测功能。
set_light_measure 通过指定报告次数和间隔秒数来调度周期性光照报告;将任一参数设为 0 可取消正在进行的调度。
set_led 以指定颜色点亮 CheckLight LED 并持续固件定义的时长——应在 CheckLightButton 事件触发后 250 ms 窗口内调用,以抢在固件自行显示状态之前介入。
全部三种广播事件均携带 SolarStatus 载荷,包含 battery_level(百分比)和 light_level(勒克斯,0–511):
Battery—— 自发报告,约每 90 秒、上电及重连时触发;此事件的light_level始终为0。LightMeasure—— 按set_light_measure设定的周期,每期发送一次。CheckLightButton—— 用户按下 CheckLight 按钮时触发,携带最新的电池与光照读数。
set_led 接受 LedId 枚举值:Off、Red、Orange 或 Green。
规格: Logitech HID++ 2.0 —— solarKeyboardDashboard。用于:
openlogi-hidpp中的类型化封装。
Function reference
The SolarDashboardFeature wrapper (0x4301) exposes:
Methods
| Function | HID++ fn | Signature | Returns |
|---|---|---|---|
set_light_measure | 0 | (max_reports: u8, report_period: u8) | () |
set_led | 1 | (led: LedId) | () |
listen | event | () | 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.
| Variant | Value | Description |
|---|---|---|
Off | 0 | All LEDs off. |
Red | 1 | Red. |
Orange | 2 | Orange. |
Green | 3 | Green. |
SolarStatus
Battery and light readings shared by every solar-dashboard event.
| Field | Type | Description |
|---|---|---|
battery_level | u8 | Remaining battery capacity, as a percentage. |
light_level | u16 | Current light measure in lux (0..=511). |
Events
SolarDashboardFeature implements EmittingFeature<SolarEvent>; call listen() to subscribe. Each variant wraps a SolarStatus payload.
| Variant | Description |
|---|---|
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]
| Byte | Field | Notes |
|---|---|---|
| 0 | max_reports | Number of LightMeasure reports to send. 0 cancels scheduling. |
| 1 | report_period | Interval between reports in seconds. 0 cancels scheduling. |
| 2 | — | Padding, always 0x00. |
Response: acknowledged only; no response fields are read.
set_led (fn 1)
Request: [led, 0x00, 0x00]
| Byte | Field | Notes |
|---|---|---|
| 0 | led | LedId as u8: Off=0, Red=1, Orange=2, Green=3. |
| 1–2 | — | Padding, 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.
| Byte | Field | Notes |
|---|---|---|
| 0 | battery_level | Remaining battery capacity as a percentage (u8). |
| 1–2 | light_level | Ambient light in lux, big-endian u16 (0..=511). |
| 3–15 | — | Unused. |
Event sub-id (the function nibble on the broadcast message) selects the variant:
| Sub-id | Variant |
|---|---|
| 0 | SolarEvent::Battery |
| 1 | SolarEvent::LightMeasure |
| 2 | SolarEvent::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?;
}
}
}
}