hidpp/feature/solar_dashboard/
mod.rs1pub mod event;
6
7#[cfg(test)]
8mod tests;
9
10use std::sync::Arc;
11
12use num_enum::{IntoPrimitive, TryFromPrimitive};
13
14pub use event::{SolarEvent, SolarStatus};
15
16use crate::{
17 channel::{HidppChannel, MessageListenerGuard},
18 event::EventEmitter,
19 feature::{CreatableFeature, EmittingFeature, Feature, FeatureEndpoint, event_payload},
20 protocol::v20::Hidpp20Error,
21};
22
23#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
25#[cfg_attr(feature = "serde", derive(serde::Serialize))]
26#[non_exhaustive]
27#[repr(u8)]
28pub enum LedId {
29 Off = 0,
31 Red = 1,
33 Orange = 2,
35 Green = 3,
37}
38
39pub struct SolarDashboardFeature {
41 endpoint: FeatureEndpoint,
43
44 emitter: Arc<EventEmitter<SolarEvent>>,
46
47 _msg_listener: MessageListenerGuard,
49}
50
51impl CreatableFeature for SolarDashboardFeature {
52 const ID: u16 = 0x4301;
53 const STARTING_VERSION: u8 = 0;
54
55 fn new(chan: Arc<HidppChannel>, device_index: u8, feature_index: u8) -> Self {
56 let emitter = Arc::new(EventEmitter::new());
57
58 let listener = chan.add_msg_listener_guarded({
59 let emitter = Arc::clone(&emitter);
60
61 move |raw, matched| {
62 let Some((func, payload)) =
63 event_payload(raw, matched, device_index, feature_index)
64 else {
65 return;
66 };
67 if let Some(event) = event::decode_event(func.to_lo(), &payload) {
68 emitter.emit(event);
69 }
70 }
71 });
72
73 Self {
74 endpoint: FeatureEndpoint::new(chan, device_index, feature_index),
75 emitter,
76 _msg_listener: listener,
77 }
78 }
79}
80
81impl Feature for SolarDashboardFeature {}
82
83impl EmittingFeature<SolarEvent> for SolarDashboardFeature {
84 fn listen(&self) -> async_channel::Receiver<SolarEvent> {
85 self.emitter.create_receiver()
86 }
87}
88
89impl SolarDashboardFeature {
90 pub async fn set_light_measure(
95 &self,
96 max_reports: u8,
97 report_period: u8,
98 ) -> Result<(), Hidpp20Error> {
99 self.endpoint
100 .call(0, [max_reports, report_period, 0])
101 .await?;
102 Ok(())
103 }
104
105 pub async fn set_led(&self, led: LedId) -> Result<(), Hidpp20Error> {
112 self.endpoint.call(1, [led.into(), 0, 0]).await?;
113 Ok(())
114 }
115}