hidpp/feature/
illumination.rs1pub mod event;
13pub mod types;
14
15#[cfg(test)]
16mod tests;
17
18use openlogi_hidpp_derive::Feature;
19
20pub use event::IlluminationEvent;
21pub use types::{
22 BrightnessClampedSource, ControlCapabilities, ControlInfo, IlluminationState, LevelConfig,
23 SetLevels,
24};
25
26use self::types::{be16, illumination_state};
27use crate::{
28 feature::{EventSource, FeatureEndpoint},
29 protocol::v20::{ErrorType, Hidpp20Error},
30};
31
32const FN_GET_ILLUMINATION: u8 = 0;
35const FN_SET_ILLUMINATION: u8 = 1;
36const FN_GET_BRIGHTNESS_INFO: u8 = 2;
37const FN_GET_BRIGHTNESS: u8 = 3;
38const FN_SET_BRIGHTNESS: u8 = 4;
39const FN_GET_BRIGHTNESS_LEVELS: u8 = 5;
40const FN_SET_BRIGHTNESS_LEVELS: u8 = 6;
41const FN_GET_COLOR_TEMPERATURE_INFO: u8 = 7;
42const FN_GET_COLOR_TEMPERATURE: u8 = 8;
43const FN_SET_COLOR_TEMPERATURE: u8 = 9;
44const FN_GET_COLOR_TEMPERATURE_LEVELS: u8 = 10;
45const FN_SET_COLOR_TEMPERATURE_LEVELS: u8 = 11;
46const FN_GET_BRIGHTNESS_EFFECTIVE_MAX: u8 = 12;
47
48#[derive(Feature)]
50#[creatable(id = 0x1990, version = 0)]
51pub struct IlluminationFeature {
52 endpoint: FeatureEndpoint,
54
55 events: EventSource<IlluminationEvent>,
57}
58
59impl IlluminationFeature {
60 pub async fn get_illumination(&self) -> Result<IlluminationState, Hidpp20Error> {
62 let payload = self
63 .endpoint
64 .call(FN_GET_ILLUMINATION, [0; 3])
65 .await?
66 .extend_payload();
67 illumination_state(payload[0])
68 }
69
70 pub async fn set_illumination(&self, state: IlluminationState) -> Result<(), Hidpp20Error> {
72 self.endpoint
73 .call(FN_SET_ILLUMINATION, [u8::from(state), 0, 0])
74 .await?;
75 Ok(())
76 }
77
78 pub async fn get_brightness_info(&self) -> Result<ControlInfo, Hidpp20Error> {
80 self.read_info(FN_GET_BRIGHTNESS_INFO).await
81 }
82
83 pub async fn get_brightness(&self) -> Result<u16, Hidpp20Error> {
85 self.read_value(FN_GET_BRIGHTNESS).await
86 }
87
88 pub async fn set_brightness(&self, brightness: u16) -> Result<(), Hidpp20Error> {
95 self.write_value(FN_SET_BRIGHTNESS, brightness).await
96 }
97
98 pub async fn get_brightness_levels(
101 &self,
102 start_index: u8,
103 ) -> Result<LevelConfig, Hidpp20Error> {
104 self.read_levels(FN_GET_BRIGHTNESS_LEVELS, start_index)
105 .await
106 }
107
108 pub async fn set_brightness_levels(&self, levels: &SetLevels) -> Result<(), Hidpp20Error> {
110 self.write_levels(FN_SET_BRIGHTNESS_LEVELS, levels).await
111 }
112
113 pub async fn get_brightness_effective_max(&self) -> Result<u16, Hidpp20Error> {
116 self.read_value(FN_GET_BRIGHTNESS_EFFECTIVE_MAX).await
117 }
118
119 pub async fn get_color_temperature_info(&self) -> Result<ControlInfo, Hidpp20Error> {
121 self.read_info(FN_GET_COLOR_TEMPERATURE_INFO).await
122 }
123
124 pub async fn get_color_temperature(&self) -> Result<u16, Hidpp20Error> {
126 self.read_value(FN_GET_COLOR_TEMPERATURE).await
127 }
128
129 pub async fn set_color_temperature(&self, color_temperature: u16) -> Result<(), Hidpp20Error> {
134 self.write_value(FN_SET_COLOR_TEMPERATURE, color_temperature)
135 .await
136 }
137
138 pub async fn get_color_temperature_levels(
141 &self,
142 start_index: u8,
143 ) -> Result<LevelConfig, Hidpp20Error> {
144 self.read_levels(FN_GET_COLOR_TEMPERATURE_LEVELS, start_index)
145 .await
146 }
147
148 pub async fn set_color_temperature_levels(
150 &self,
151 levels: &SetLevels,
152 ) -> Result<(), Hidpp20Error> {
153 self.write_levels(FN_SET_COLOR_TEMPERATURE_LEVELS, levels)
154 .await
155 }
156
157 async fn read_info(&self, function: u8) -> Result<ControlInfo, Hidpp20Error> {
159 let payload = self.endpoint.call(function, [0; 3]).await?.extend_payload();
160 Ok(ControlInfo::from_payload(&payload))
161 }
162
163 async fn read_value(&self, function: u8) -> Result<u16, Hidpp20Error> {
165 let payload = self.endpoint.call(function, [0; 3]).await?.extend_payload();
166 Ok(be16(&payload, 0))
167 }
168
169 async fn write_value(&self, function: u8, value: u16) -> Result<(), Hidpp20Error> {
171 let [hi, lo] = value.to_be_bytes();
172 self.endpoint.call(function, [hi, lo, 0]).await?;
173 Ok(())
174 }
175
176 async fn read_levels(
178 &self,
179 function: u8,
180 start_index: u8,
181 ) -> Result<LevelConfig, Hidpp20Error> {
182 if start_index > 0x0f {
183 return Err(Hidpp20Error::Feature(ErrorType::InvalidArgument));
184 }
185 let payload = self
187 .endpoint
188 .call(function, [start_index << 4, 0, 0])
189 .await?
190 .extend_payload();
191 Ok(LevelConfig::from_payload(&payload))
192 }
193
194 async fn write_levels(&self, function: u8, levels: &SetLevels) -> Result<(), Hidpp20Error> {
196 self.endpoint
197 .call_long(function, levels.to_payload()?)
198 .await?;
199 Ok(())
200 }
201}