1use alloc::vec;
2use alloc::vec::Vec;
3use core::convert::TryInto;
4
5use crate::convert_packet::{ConvertPacket, ConvertPacketError};
6use crate::event::event_code::*;
7use crate::event::EventError;
8use crate::packet::Packet;
9
10#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
11pub enum PwmValue {
12 Binary(bool),
13 Single(u8),
14 Rgb(u8, u8, u8),
15 RgbB(u8, u8, u8, u8),
16 Rgbw(u8, u8, u8, u8),
17 RgbwB(u8, u8, u8, u8, u8),
18}
19
20impl PwmValue {
21 fn serialize(self) -> Vec<u8> {
22 match self {
23 Self::Binary(value) => vec![0x00, if value { 0x01 } else { 0x00 }],
24 Self::Single(value) => vec![0x01, value],
25 Self::Rgb(red, green, blue) => vec![0x02, red, green, blue],
26 Self::RgbB(red, green, blue, brightness) => vec![0x03, red, green, blue, brightness],
27 Self::Rgbw(red, green, blue, white) => {
28 vec![0x04, red, green, blue, white]
29 }
30 Self::RgbwB(red, green, blue, white, brightness) => {
31 vec![0x05, red, green, blue, white, brightness]
32 }
33 }
34 }
35
36 fn deserialize(data: &[u8]) -> Result<Self, ConvertPacketError> {
37 if data.len() < 2 {
38 return Err(ConvertPacketError::WrongSize);
39 }
40
41 match data[0] {
42 0x00 => {
43 if data.len() != 2 {
44 return Err(ConvertPacketError::WrongSize);
45 }
46
47 Ok(Self::Binary(data[1] != 0x00))
48 }
49 0x01 => {
50 if data.len() != 2 {
51 return Err(ConvertPacketError::WrongSize);
52 }
53
54 Ok(Self::Single(data[1]))
55 }
56 0x02 => {
57 if data.len() != 4 {
58 return Err(ConvertPacketError::WrongSize);
59 }
60
61 Ok(Self::Rgb(data[1], data[2], data[3]))
62 }
63 0x03 => {
64 if data.len() != 5 {
65 return Err(ConvertPacketError::WrongSize);
66 }
67
68 Ok(Self::RgbB(data[1], data[2], data[3], data[4]))
69 }
70 0x04 => {
71 if data.len() != 5 {
72 return Err(ConvertPacketError::WrongSize);
73 }
74
75 Ok(Self::Rgbw(data[1], data[2], data[3], data[4]))
76 }
77 0x05 => {
78 if data.len() != 6 {
79 return Err(ConvertPacketError::WrongSize);
80 }
81
82 Ok(Self::RgbwB(data[1], data[2], data[3], data[4], data[5]))
83 }
84 _ => Err(ConvertPacketError::UnknownEnumVariant),
85 }
86 }
87}
88
89#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
90pub struct PwmChangeBrightnessEvent {
91 pub pwm_address: u16,
92 pub transmitter_address: u16,
93 pub index: u8,
94 pub value: PwmValue,
95}
96
97impl ConvertPacket<PwmChangeBrightnessEvent> for PwmChangeBrightnessEvent {
98 fn try_from_packet(packet: &Packet) -> Result<Self, ConvertPacketError> {
99 if packet.data.len() < 7 {
100 return Err(ConvertPacketError::WrongSize);
101 }
102
103 if packet.is_error {
104 return Err(ConvertPacketError::WrongType);
105 }
106
107 if u16::from_be_bytes(packet.data[0..=1].try_into().unwrap())
108 != PWM_CHANGE_BRIGHTNESS_EVENT_CODE
109 {
110 return Err(ConvertPacketError::Event(EventError::WrongEventType));
111 }
112
113 let pwm_address = packet.device_address;
114 let transmitter_address = u16::from_be_bytes(packet.data[2..=3].try_into().unwrap());
115 let index = packet.data[4];
116 let value = PwmValue::deserialize(&packet.data[5..])?;
117
118 Ok(PwmChangeBrightnessEvent {
119 pwm_address,
120 transmitter_address,
121 index,
122 value,
123 })
124 }
125
126 fn to_packet(&self) -> Packet {
127 let mut data = vec![];
128
129 for byte in u16::to_be_bytes(PWM_CHANGE_BRIGHTNESS_EVENT_CODE).iter() {
130 data.push(*byte);
131 }
132
133 for byte in u16::to_be_bytes(self.transmitter_address).iter() {
134 data.push(*byte);
135 }
136
137 data.push(self.index);
138 data.append(&mut self.value.serialize());
139
140 Packet {
141 is_error: false,
142 device_address: self.pwm_address,
143 data,
144 }
145 }
146}
147
148#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
149pub struct PwmAnimateBrightnessEvent {
150 pub pwm_address: u16,
151 pub transmitter_address: u16,
152 pub index: u8,
153 pub duration: u32,
154 pub target_value: PwmValue,
155}
156
157impl ConvertPacket<PwmAnimateBrightnessEvent> for PwmAnimateBrightnessEvent {
158 fn try_from_packet(packet: &Packet) -> Result<Self, ConvertPacketError> {
159 if packet.data.len() < 11 {
160 return Err(ConvertPacketError::WrongSize);
161 }
162
163 if packet.is_error {
164 return Err(ConvertPacketError::WrongType);
165 }
166
167 if u16::from_be_bytes(packet.data[0..=1].try_into().unwrap())
168 != PWM_ANIMATE_BRIGHTNESS_EVENT_CODE
169 {
170 return Err(ConvertPacketError::Event(EventError::WrongEventType));
171 }
172
173 let pwm_address = packet.device_address;
174 let transmitter_address = u16::from_be_bytes(packet.data[2..=3].try_into().unwrap());
175 let index = packet.data[4];
176 let duration = u32::from_be_bytes(packet.data[5..=8].try_into().unwrap());
177 let target_value = PwmValue::deserialize(&packet.data[9..])?;
178
179 Ok(Self {
180 pwm_address,
181 transmitter_address,
182 index,
183 duration,
184 target_value,
185 })
186 }
187
188 fn to_packet(&self) -> Packet {
189 let mut data = vec![];
190
191 for byte in u16::to_be_bytes(PWM_ANIMATE_BRIGHTNESS_EVENT_CODE).iter() {
192 data.push(*byte);
193 }
194
195 for byte in u16::to_be_bytes(self.transmitter_address).iter() {
196 data.push(*byte);
197 }
198
199 data.push(self.index);
200
201 for byte in u32::to_be_bytes(self.duration).iter() {
202 data.push(*byte);
203 }
204
205 data.append(&mut self.target_value.serialize());
206
207 Packet {
208 is_error: false,
209 device_address: self.pwm_address,
210 data,
211 }
212 }
213}
214
215#[cfg(test)]
216mod tests {
217 use super::*;
218
219 const EVENT_PACKET: Packet = Packet {
220 is_error: false,
221 device_address: 0xabab,
222 data: vec![],
223 };
224
225 #[test]
226 fn change_brightness_try_from_packet_test() {
227 let mut packet = EVENT_PACKET;
228 packet.data = vec![
229 ((PWM_CHANGE_BRIGHTNESS_EVENT_CODE >> 8) & 0xff) as u8, ((PWM_CHANGE_BRIGHTNESS_EVENT_CODE >> 0) & 0xff) as u8, 0x00, 0x00, 0x01, 0x02, 0x23, 0x45, 0x67, ];
239
240 let event = PwmChangeBrightnessEvent::try_from_packet(&packet).unwrap();
241
242 assert_eq!(event.pwm_address, 0xabab);
243 assert_eq!(event.transmitter_address, 0x0000);
244 assert_eq!(event.index, 0x01);
245 assert_eq!(event.value, PwmValue::Rgb(0x23, 0x45, 0x67));
246 }
247
248 #[test]
249 fn change_brightness_to_packet_test() {
250 let event = PwmChangeBrightnessEvent {
251 pwm_address: 0xabab,
252 transmitter_address: 0x0000,
253 index: 0x01,
254 value: PwmValue::Rgb(0x23, 0x45, 0x67),
255 };
256
257 let mut packet = EVENT_PACKET;
258 packet.data = vec![
259 ((PWM_CHANGE_BRIGHTNESS_EVENT_CODE >> 8) & 0xff) as u8, ((PWM_CHANGE_BRIGHTNESS_EVENT_CODE >> 0) & 0xff) as u8, 0x00, 0x00, 0x01, 0x02, 0x23, 0x45, 0x67, ];
269
270 assert_eq!(event.to_packet(), packet);
271 }
272
273 #[test]
274 fn animate_brightness_try_from_packet_test() {
275 let mut packet = EVENT_PACKET;
276 packet.data = vec![
277 ((PWM_ANIMATE_BRIGHTNESS_EVENT_CODE >> 8) & 0xff) as u8, ((PWM_ANIMATE_BRIGHTNESS_EVENT_CODE >> 0) & 0xff) as u8, 0x00, 0x00, 0x01, 0xab, 0xab, 0xab, 0xab, 0x02, 0x23, 0x45, 0x67, ];
291
292 let event = PwmAnimateBrightnessEvent::try_from_packet(&packet).unwrap();
293
294 assert_eq!(event.pwm_address, 0xabab);
295 assert_eq!(event.transmitter_address, 0x0000);
296 assert_eq!(event.index, 0x01);
297 assert_eq!(event.duration, 0xabab_abab);
298 assert_eq!(event.target_value, PwmValue::Rgb(0x23, 0x45, 0x67));
299 }
300
301 #[test]
302 fn animate_brightness_to_packet_test() {
303 let event = PwmAnimateBrightnessEvent {
304 pwm_address: 0xabab,
305 transmitter_address: 0x0000,
306 index: 0x01,
307 duration: 0xabab_abab,
308 target_value: PwmValue::Rgb(0x23, 0x45, 0x67),
309 };
310
311 let mut packet = EVENT_PACKET;
312 packet.data = vec![
313 ((PWM_ANIMATE_BRIGHTNESS_EVENT_CODE >> 8) & 0xff) as u8, ((PWM_ANIMATE_BRIGHTNESS_EVENT_CODE >> 0) & 0xff) as u8, 0x00, 0x00, 0x01, 0xab, 0xab, 0xab, 0xab, 0x02, 0x23, 0x45, 0x67, ];
327
328 assert_eq!(event.to_packet(), packet);
329 }
330}