0x4301 · solarKeyboardDashboard
Battery and ambient-light monitoring for solar keyboards — schedule periodic light-measure reports, override the CheckLight LED color, and receive battery and lux broadcast events.
Battery and ambient-light monitoring for Logitech solar keyboards such as the K750.
set_light_measure schedules periodic light reports by specifying the number of
reports and their interval in seconds; passing 0 for either value cancels an
in-progress schedule. set_led overrides the firmware's CheckLight LED to a chosen
color for a firmware-defined duration; call it within the 250 ms window after a
CheckLightButton event to intercept before the firmware renders its own status.
All three broadcast events carry a SolarStatus payload with battery_level
(percentage) and light_level (lux, 0–511):
Battery— spontaneous report fired roughly every 90 s, at power-up, and on reconnect;light_levelis always0.LightMeasure— one report per period set byset_light_measure.CheckLightButton— fired when the user presses the CheckLight button, carrying the latest battery and light readings.
set_led accepts a LedId variant: Off, Red, Orange, or Green.
Spec: Logitech HID++ 2.0 — solarKeyboardDashboard. Used by: Typed wrapper in
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?;
}
}
}
}