ross_protocol/event/
relay.rs1use 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 RelayValue {
12 Single(bool),
13 DoubleExclusive(RelayDoubleExclusiveValue),
14}
15
16impl RelayValue {
17 fn serialize(self) -> Vec<u8> {
18 match self {
19 Self::Single(value) => vec![if value { 0x00 } else { 0x01 }],
20 Self::DoubleExclusive(RelayDoubleExclusiveValue::FirstChannelOn) => vec![0x02],
21 Self::DoubleExclusive(RelayDoubleExclusiveValue::SecondChannelOn) => vec![0x03],
22 Self::DoubleExclusive(RelayDoubleExclusiveValue::NoChannelOn) => vec![0x04],
23 }
24 }
25
26 fn deserialize(data: &[u8]) -> Result<Self, ConvertPacketError> {
27 if data.len() != 1 {
28 return Err(ConvertPacketError::WrongSize);
29 }
30
31 match data[0] {
32 0x00 => Ok(Self::Single(true)),
33 0x01 => Ok(Self::Single(false)),
34 0x02 => Ok(Self::DoubleExclusive(
35 RelayDoubleExclusiveValue::FirstChannelOn,
36 )),
37 0x03 => Ok(Self::DoubleExclusive(
38 RelayDoubleExclusiveValue::SecondChannelOn,
39 )),
40 0x04 => Ok(Self::DoubleExclusive(
41 RelayDoubleExclusiveValue::NoChannelOn,
42 )),
43 _ => Err(ConvertPacketError::UnknownEnumVariant),
44 }
45 }
46}
47
48#[repr(C)]
49#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
50pub enum RelayDoubleExclusiveValue {
51 FirstChannelOn,
52 SecondChannelOn,
53 NoChannelOn,
54}
55
56#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
57pub struct RelaySetValueEvent {
58 pub relay_address: u16,
59 pub transmitter_address: u16,
60 pub index: u8,
61 pub value: RelayValue,
62}
63
64impl ConvertPacket<RelaySetValueEvent> for RelaySetValueEvent {
65 fn try_from_packet(packet: &Packet) -> Result<Self, ConvertPacketError> {
66 if packet.data.len() != 6 {
67 return Err(ConvertPacketError::WrongSize);
68 }
69
70 if packet.is_error {
71 return Err(ConvertPacketError::WrongType);
72 }
73
74 if u16::from_be_bytes(packet.data[0..=1].try_into().unwrap()) != RELAY_SET_VALUE_EVENT_CODE
75 {
76 return Err(ConvertPacketError::Event(EventError::WrongEventType));
77 }
78
79 let relay_address = packet.device_address;
80 let transmitter_address = u16::from_be_bytes(packet.data[2..=3].try_into().unwrap());
81 let index = packet.data[4];
82 let value = RelayValue::deserialize(&packet.data[5..])?;
83
84 Ok(Self {
85 relay_address,
86 transmitter_address,
87 index,
88 value,
89 })
90 }
91
92 fn to_packet(&self) -> Packet {
93 let mut data = vec![];
94
95 for byte in u16::to_be_bytes(RELAY_SET_VALUE_EVENT_CODE).iter() {
96 data.push(*byte);
97 }
98
99 for byte in u16::to_be_bytes(self.transmitter_address).iter() {
100 data.push(*byte);
101 }
102
103 data.push(self.index);
104 data.append(&mut self.value.serialize());
105
106 Packet {
107 is_error: false,
108 device_address: self.relay_address,
109 data,
110 }
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117
118 const EVENT_PACKET: Packet = Packet {
119 is_error: false,
120 device_address: 0xabab,
121 data: vec![],
122 };
123
124 #[test]
125 fn set_state_try_from_packet_test() {
126 let mut packet = EVENT_PACKET;
127 packet.data = vec![
128 ((RELAY_SET_VALUE_EVENT_CODE >> 8) & 0xff) as u8, ((RELAY_SET_VALUE_EVENT_CODE >> 0) & 0xff) as u8, 0x01, 0x23, 0x45, 0x03, ];
135
136 let event = RelaySetValueEvent::try_from_packet(&packet).unwrap();
137
138 assert_eq!(event.relay_address, 0xabab);
139 assert_eq!(event.transmitter_address, 0x0123);
140 assert_eq!(event.index, 0x45);
141 assert_eq!(
142 event.value,
143 RelayValue::DoubleExclusive(RelayDoubleExclusiveValue::SecondChannelOn)
144 );
145 }
146
147 #[test]
148 fn set_state_to_packet_test() {
149 let event = RelaySetValueEvent {
150 relay_address: 0xabab,
151 transmitter_address: 0x0123,
152 index: 0x45,
153 value: RelayValue::DoubleExclusive(RelayDoubleExclusiveValue::SecondChannelOn),
154 };
155
156 let mut packet = EVENT_PACKET;
157 packet.data = vec![
158 ((RELAY_SET_VALUE_EVENT_CODE >> 8) & 0xff) as u8, ((RELAY_SET_VALUE_EVENT_CODE >> 0) & 0xff) as u8, 0x01, 0x23, 0x45, 0x03, ];
165
166 assert_eq!(event.to_packet(), packet);
167 }
168}