1use crate::Error;
32
33#[cfg(feature = "serde")]
34use serde::{Deserialize, Serialize};
35
36#[cfg(feature = "serde")]
37mod util {
38 use serde::{ser::SerializeSeq, Serializer};
39
40 pub fn f32_1_digits<S>(x: &f32, s: S) -> Result<S::Ok, S::Error>
41 where
42 S: Serializer,
43 {
44 s.serialize_f64((*x as f64 * 10.0).round() / 10.0)
45 }
46
47 pub fn f32_3_digits<S>(x: &f32, s: S) -> Result<S::Ok, S::Error>
48 where
49 S: Serializer,
50 {
51 s.serialize_f64((*x as f64 * 1000.0).round() / 1000.0)
52 }
53
54 pub fn vec_f32_3_digits<S>(vec: &Vec<f32>, s: S) -> Result<S::Ok, S::Error>
55 where
56 S: Serializer,
57 {
58 let mut seq = s.serialize_seq(Some(vec.len()))?;
59 for e in vec {
60 let val = (*e as f64 * 1000.0).round() / 1000.0;
61 seq.serialize_element(&val)?;
62 }
63 seq.end()
64 }
65}
66
67#[derive(Debug)]
70#[repr(u8)]
71pub enum Address {
72 Host = 0x40,
74 }
78
79pub const MINIMUM_DELAY: std::time::Duration = std::time::Duration::from_millis(4);
84
85const TX_BUFFER_LENGTH: usize = 13;
87const RX_BUFFER_LENGTH: usize = 13;
89const START_BYTE: u8 = 0xa5;
91const DATA_LENGTH: u8 = 0x08;
93
94fn create_request_header(address: Address, command: u8) -> Vec<u8> {
109 let mut tx_buffer = vec![0; TX_BUFFER_LENGTH];
110 tx_buffer[0] = START_BYTE;
111 tx_buffer[1] = address as u8;
112 tx_buffer[2] = command;
113 tx_buffer[3] = DATA_LENGTH;
114 tx_buffer
115}
116
117fn calc_crc(buffer: &[u8]) -> u8 {
121 let mut checksum: u8 = 0;
122 let slice = &buffer[0..buffer.len() - 1];
123 for b in slice {
124 checksum = checksum.wrapping_add(*b);
125 }
126 checksum
127}
128
129fn calc_crc_and_set(buffer: &mut [u8]) {
131 let len = buffer.len();
132 buffer[len - 1] = calc_crc(buffer)
133}
134
135macro_rules! read_bit {
138 ($byte:expr,$position:expr) => {
139 ($byte >> $position) & 1 != 0
140 };
141}
142
143fn validate_len(buffer: &[u8], expected_size: usize) -> std::result::Result<(), Error> {
154 if buffer.len() < expected_size {
155 log::warn!(
156 "Invalid buffer size - required={} received={}",
157 expected_size,
158 buffer.len()
159 );
160 return Err(Error::ReplySizeError);
161 }
162 Ok(())
163}
164
165fn validate_checksum(buffer: &[u8]) -> std::result::Result<(), Error> {
175 let checksum = calc_crc(buffer);
176 if buffer[buffer.len() - 1] != checksum {
177 log::warn!(
178 "Invalid checksum - calculated={:02X?} received={:02X?} buffer={:?}",
179 checksum,
180 buffer[buffer.len() - 1],
181 buffer
182 );
183 return Err(Error::CheckSumError);
184 }
185 Ok(())
186}
187
188#[derive(Debug, Clone)]
190#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
191pub struct Soc {
192 #[cfg_attr(feature = "serde", serde(serialize_with = "util::f32_3_digits"))]
194 pub total_voltage: f32,
195 #[cfg_attr(feature = "serde", serde(serialize_with = "util::f32_3_digits"))]
198 pub current: f32,
199 #[cfg_attr(feature = "serde", serde(serialize_with = "util::f32_1_digits"))]
201 pub soc_percent: f32,
202}
203
204impl Soc {
205 pub fn request(address: Address) -> Vec<u8> {
217 let mut tx_buffer = create_request_header(address, 0x90);
218 calc_crc_and_set(&mut tx_buffer);
219 tx_buffer
220 }
221
222 pub fn reply_size() -> usize {
224 RX_BUFFER_LENGTH
225 }
226
227 pub fn decode(rx_buffer: &[u8]) -> std::result::Result<Self, Error> {
239 validate_len(rx_buffer, Self::reply_size())?;
240 validate_checksum(rx_buffer)?;
241 Ok(Self {
242 total_voltage: u16::from_be_bytes([rx_buffer[4], rx_buffer[5]]) as f32 / 10.0,
243 current: (((u16::from_be_bytes([rx_buffer[8], rx_buffer[9]]) as i32) - 30000) as f32)
245 / 10.0,
246 soc_percent: u16::from_be_bytes([rx_buffer[10], rx_buffer[11]]) as f32 / 10.0,
247 })
248 }
249}
250
251#[derive(Debug, Clone)]
253#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
254pub struct CellVoltageRange {
255 #[cfg_attr(feature = "serde", serde(serialize_with = "util::f32_3_digits"))]
257 pub highest_voltage: f32,
258 pub highest_cell: u8,
260 #[cfg_attr(feature = "serde", serde(serialize_with = "util::f32_3_digits"))]
262 pub lowest_voltage: f32,
263 pub lowest_cell: u8,
265}
266
267impl CellVoltageRange {
268 pub fn request(address: Address) -> Vec<u8> {
280 let mut tx_buffer = create_request_header(address, 0x91);
281 calc_crc_and_set(&mut tx_buffer);
282 tx_buffer
283 }
284
285 pub fn reply_size() -> usize {
287 RX_BUFFER_LENGTH
288 }
289
290 pub fn decode(rx_buffer: &[u8]) -> std::result::Result<Self, Error> {
302 validate_len(rx_buffer, Self::reply_size())?;
303 validate_checksum(rx_buffer)?;
304 Ok(Self {
305 highest_voltage: u16::from_be_bytes([rx_buffer[4], rx_buffer[5]]) as f32 / 1000.0,
306 highest_cell: rx_buffer[6],
307 lowest_voltage: u16::from_be_bytes([rx_buffer[7], rx_buffer[8]]) as f32 / 1000.0,
308 lowest_cell: rx_buffer[9],
309 })
310 }
311}
312
313#[derive(Debug, Clone)]
315#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
316pub struct TemperatureRange {
317 pub highest_temperature: i8,
319 pub highest_sensor: u8,
321 pub lowest_temperature: i8,
323 pub lowest_sensor: u8,
325}
326
327impl TemperatureRange {
328 pub fn request(address: Address) -> Vec<u8> {
340 let mut tx_buffer = create_request_header(address, 0x92);
341 calc_crc_and_set(&mut tx_buffer);
342 tx_buffer
343 }
344
345 pub fn reply_size() -> usize {
347 RX_BUFFER_LENGTH
348 }
349
350 pub fn decode(rx_buffer: &[u8]) -> std::result::Result<Self, Error> {
362 validate_len(rx_buffer, Self::reply_size())?;
363 validate_checksum(rx_buffer)?;
364 Ok(Self {
366 highest_temperature: ((rx_buffer[4] as i16) - 40) as i8,
367 highest_sensor: rx_buffer[5],
368 lowest_temperature: ((rx_buffer[6] as i16) - 40) as i8,
369 lowest_sensor: rx_buffer[7],
370 })
371 }
372}
373
374#[derive(Debug, Clone)]
376#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
377pub enum MosfetMode {
378 Stationary,
380 Charging,
382 Discharging,
384}
385
386#[derive(Debug, Clone)]
388#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
389pub struct MosfetStatus {
390 pub mode: MosfetMode,
392 pub charging_mosfet: bool,
394 pub discharging_mosfet: bool,
396 pub bms_cycles: u8,
398 #[cfg_attr(feature = "serde", serde(serialize_with = "util::f32_3_digits"))]
400 pub capacity_ah: f32,
401}
402
403impl MosfetStatus {
404 pub fn request(address: Address) -> Vec<u8> {
416 let mut tx_buffer = create_request_header(address, 0x93);
417 calc_crc_and_set(&mut tx_buffer);
418 tx_buffer
419 }
420
421 pub fn reply_size() -> usize {
423 RX_BUFFER_LENGTH
424 }
425
426 pub fn decode(rx_buffer: &[u8]) -> std::result::Result<Self, Error> {
438 validate_len(rx_buffer, Self::reply_size())?;
439 validate_checksum(rx_buffer)?;
440 let mode = match rx_buffer[4] {
441 0 => MosfetMode::Stationary,
442 1 => MosfetMode::Charging,
443 2 => MosfetMode::Discharging,
444 _ => unreachable!(),
445 };
446 Ok(Self {
447 mode,
448 charging_mosfet: rx_buffer[5] != 0,
449 discharging_mosfet: rx_buffer[6] != 0,
450 bms_cycles: rx_buffer[7],
451 capacity_ah: u32::from_be_bytes([
452 rx_buffer[8],
453 rx_buffer[9],
454 rx_buffer[10],
455 rx_buffer[11],
456 ]) as f32
457 / 1000.0,
458 })
459 }
460}
461
462#[derive(Debug, Clone)]
464#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
465pub struct IOState {
466 pub di1: bool,
468 pub di2: bool,
470 pub di3: bool,
472 pub di4: bool,
474 pub do1: bool,
476 pub do2: bool,
478 pub do3: bool,
480 pub do4: bool,
482}
483
484#[derive(Debug, Clone)]
486#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
487pub struct Status {
488 pub cells: u8,
490 pub temperature_sensors: u8,
492 pub charger_running: bool,
494 pub load_running: bool,
496 pub states: IOState,
498 pub cycles: u16,
500}
501
502impl Status {
503 pub fn request(address: Address) -> Vec<u8> {
515 let mut tx_buffer = create_request_header(address, 0x94);
516 calc_crc_and_set(&mut tx_buffer);
517 tx_buffer
518 }
519
520 pub fn reply_size() -> usize {
522 RX_BUFFER_LENGTH
523 }
524
525 pub fn decode(rx_buffer: &[u8]) -> std::result::Result<Self, Error> {
537 validate_len(rx_buffer, Self::reply_size())?;
538 validate_checksum(rx_buffer)?;
539 Ok(Self {
540 cells: rx_buffer[4],
541 temperature_sensors: rx_buffer[5],
542 charger_running: rx_buffer[6] != 0,
543 load_running: rx_buffer[7] != 0,
544 states: IOState {
545 di1: read_bit!(rx_buffer[8], 0),
546 di2: read_bit!(rx_buffer[8], 1),
547 di3: read_bit!(rx_buffer[8], 2),
548 di4: read_bit!(rx_buffer[8], 3),
549 do1: read_bit!(rx_buffer[8], 4),
550 do2: read_bit!(rx_buffer[8], 5),
551 do3: read_bit!(rx_buffer[8], 6),
552 do4: read_bit!(rx_buffer[8], 7),
553 },
554 cycles: u16::from_be_bytes([rx_buffer[9], rx_buffer[10]]),
555 })
556 }
557}
558
559#[derive(Debug, Clone)]
562#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
563pub struct CellVoltages(
564 #[cfg_attr(feature = "serde", serde(serialize_with = "util::vec_f32_3_digits"))] Vec<f32>,
565);
566
567impl CellVoltages {
568 pub fn request(address: Address) -> Vec<u8> {
580 let mut tx_buffer = create_request_header(address, 0x95);
581 calc_crc_and_set(&mut tx_buffer);
582 tx_buffer
583 }
584
585 fn n_frames(n_cells: u8) -> usize {
587 (n_cells as f32 / 3.0).ceil() as usize
588 }
589
590 pub fn reply_size(n_cells: u8) -> usize {
596 Self::n_frames(n_cells) * RX_BUFFER_LENGTH
597 }
598
599 pub fn decode(rx_buffer: &[u8], n_cells: u8) -> std::result::Result<Self, Error> {
612 validate_len(rx_buffer, Self::reply_size(n_cells))?;
613 let mut voltages = Vec::with_capacity(n_cells as usize);
614 let mut n_cell = 1;
615
616 for n_frame in 1..=Self::n_frames(n_cells) {
617 let part =
618 &rx_buffer[((n_frame - 1) * RX_BUFFER_LENGTH)..((n_frame) * RX_BUFFER_LENGTH)];
619 if n_frame != usize::from(part[4]) {
620 log::warn!(
621 "Frame out of order - expected={} received={}",
622 n_frame,
623 part[4]
624 );
625 return Err(Error::FrameNoError);
626 }
627 validate_checksum(part)?;
628 for i in 0..3 {
629 let volt = u16::from_be_bytes([part[5 + i + i], part[6 + i + i]]) as f32 / 1000.0;
630 log::trace!("Frame #{n_frame} cell #{n_cell} volt={volt}");
631 voltages.push(volt);
632 n_cell += 1;
633 if n_cell > n_cells {
634 break;
635 }
636 }
637 }
638 Ok(Self(voltages))
639 }
640}
641
642impl std::ops::Deref for CellVoltages {
643 type Target = [f32];
644
645 fn deref(&self) -> &[f32] {
646 &self.0
647 }
648}
649
650pub struct CellTemperatures;
653
654impl CellTemperatures {
655 pub fn request(address: Address) -> Vec<u8> {
667 let mut tx_buffer = create_request_header(address, 0x96);
668 calc_crc_and_set(&mut tx_buffer);
669 tx_buffer
670 }
671
672 fn n_frames(n_sensors: u8) -> usize {
674 (n_sensors as f32 / 7.0).ceil() as usize
675 }
676
677 pub fn reply_size(n_sensors: u8) -> usize {
683 Self::n_frames(n_sensors) * RX_BUFFER_LENGTH
684 }
685
686 pub fn decode(rx_buffer: &[u8], n_sensors: u8) -> std::result::Result<Vec<i32>, Error> {
700 validate_len(rx_buffer, Self::reply_size(n_sensors))?;
701 let mut result = Vec::with_capacity(n_sensors as usize);
702 let mut n_sensor = 1;
703
704 for n_frame in 1..=Self::n_frames(n_sensors) {
705 let part =
706 &rx_buffer[((n_frame - 1) * RX_BUFFER_LENGTH)..((n_frame) * RX_BUFFER_LENGTH)];
707 if n_frame != usize::from(part[4]) {
708 log::warn!(
709 "Frame out of order - expected={} received={}",
710 n_frame,
711 part[4]
712 );
713 return Err(Error::FrameNoError);
714 }
715 validate_checksum(part)?;
716 for i in 0..7 {
717 let temperature = part[5 + i] as i32 - 40;
718 log::trace!("Frame #{n_frame} sensor #{n_sensor} °C={temperature}");
719 result.push(temperature);
720 n_sensor += 1;
721 if n_sensor > n_sensors {
722 break;
723 }
724 }
725 }
726 Ok(result)
727 }
728}
729
730pub struct CellBalanceState;
732
733impl CellBalanceState {
734 pub fn request(address: Address) -> Vec<u8> {
746 let mut tx_buffer = create_request_header(address, 0x97);
747 calc_crc_and_set(&mut tx_buffer);
748 tx_buffer
749 }
750
751 pub fn reply_size() -> usize {
753 RX_BUFFER_LENGTH
754 }
755
756 pub fn decode(rx_buffer: &[u8], n_cells: u8) -> std::result::Result<Vec<bool>, Error> {
770 validate_len(rx_buffer, Self::reply_size())?;
771 validate_checksum(rx_buffer)?;
772 let mut result = Vec::with_capacity(n_cells as usize);
773 let mut n_cell = 0;
774 for i in 0..6 {
776 for j in 0..8 {
778 result.push(read_bit!(rx_buffer[4 + i], j));
779 n_cell += 1;
780 if n_cell >= n_cells {
781 return Ok(result);
782 }
783 }
784 }
785 Ok(result)
786 }
787}
788
789#[derive(Debug, Clone, thiserror::Error, PartialEq)]
791#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
792pub enum ErrorCode {
793 #[error("Cell voltage is too high (Level 1)")]
795 CellVoltHighLevel1,
796 #[error("Cell voltage is too high (Level 2)")]
798 CellVoltHighLevel2,
799 #[error("Cell voltage is too low (Level 1)")]
801 CellVoltLowLevel1,
802 #[error("Cell voltage is too low (Level 2)")]
804 CellVoltLowLevel2,
805 #[error("Total voltage is too high (Level 1)")]
807 SumVoltHighLevel1,
808 #[error("Total voltage is too high (Level 2)")]
810 SumVoltHighLevel2,
811 #[error("Total voltage is too low (Level 1)")]
813 SumVoltLowLevel1,
814 #[error("Total voltage is too low (Level 2)")]
816 SumVoltLowLevel2,
817 #[error("Charging temperature too high (Level 1)")]
819 ChargeTempHighLevel1,
820 #[error("Charging temperature too high (Level 2)")]
822 ChargeTempHighLevel2,
823 #[error("Charging temperature too low (Level 1)")]
825 ChargeTempLowLevel1,
826 #[error("Charging temperature too low (Level 2)")]
828 ChargeTempLowLevel2,
829 #[error("Discharging temperature too high (Level 1)")]
831 DischargeTempHighLevel1,
832 #[error("Discharging temperature too high (Level 2)")]
834 DischargeTempHighLevel2,
835 #[error("Discharging temperature too low (Level 1)")]
837 DischargeTempLowLevel1,
838 #[error("Discharging temperature too low (Level 2)")]
840 DischargeTempLowLevel2,
841 #[error("Charge overcurrent (Level 1)")]
843 ChargeOvercurrentLevel1,
844 #[error("Charge overcurrent (Level 2)")]
846 ChargeOvercurrentLevel2,
847 #[error("Discharge overcurrent (Level 1)")]
849 DischargeOvercurrentLevel1,
850 #[error("Discharge overcurrent (Level 2)")]
852 DischargeOvercurrentLevel2,
853 #[error("SOC too high (Level 1)")]
855 SocHighLevel1,
856 #[error("SOC too high (Level 2)")]
858 SocHighLevel2,
859 #[error("SOC too low (Level 1)")]
861 SocLowLevel1,
862 #[error("SOC too low (Level 2)")]
864 SocLowLevel2,
865 #[error("Excessive voltage difference between cells (Level 1)")]
867 DiffVoltLevel1,
868 #[error("Excessive voltage difference between cells (Level 2)")]
870 DiffVoltLevel2,
871 #[error("Excessive temperature difference between sensors (Level 1)")]
873 DiffTempLevel1,
874 #[error("Excessive temperature difference between sensors (Level 2)")]
876 DiffTempLevel2,
877 #[error("Charging MOSFET temperature too high")]
879 ChargeMosTempHighAlarm,
880 #[error("Discharging MOSFET temperature too high")]
882 DischargeMosTempHighAlarm,
883 #[error("Charging MOSFET temperature sensor failure")]
885 ChargeMosTempSensorErr,
886 #[error("Discharging MOSFET temperature sensor failure")]
888 DischargeMosTempSensorErr,
889 #[error("Charging MOSFET adhesion failure")]
891 ChargeMosAdhesionErr,
892 #[error("Discharging MOSFET adhesion failure")]
894 DischargeMosAdhesionErr,
895 #[error("Charging MOSFET open circuit failure")]
897 ChargeMosOpenCircuitErr,
898 #[error("Discharging MOSFET open circuit failure")]
900 DischargeMosOpenCircuitErr,
901 #[error("AFE acquisition chip failure")]
903 AfeCollectChipErr,
904 #[error("Cell voltage collection circuit failure")]
906 VoltageCollectDropped,
907 #[error("Cell temperature sensor failure")]
909 CellTempSensorErr,
910 #[error("EEPROM storage failure")]
912 EepromErr,
913 #[error("RTC clock failure")]
915 RtcErr,
916 #[error("Pre-charge failure")]
918 PrechangeFailure,
919 #[error("Communication failure")]
921 CommunicationFailure,
922 #[error("Internal communication failure")]
924 InternalCommunicationFailure,
925 #[error("Current detection module failure")]
927 CurrentModuleFault,
928 #[error("Total voltage detection module failure")]
930 SumVoltageDetectFault,
931 #[error("Short circuit protection failure")]
933 ShortCircuitProtectFault,
934 #[error("Low voltage forbids charging")]
936 LowVoltForbiddenChargeFault,
937}
938
939impl ErrorCode {
940 pub fn request(address: Address) -> Vec<u8> {
952 let mut tx_buffer = create_request_header(address, 0x98);
953 calc_crc_and_set(&mut tx_buffer);
954 tx_buffer
955 }
956
957 pub fn reply_size() -> usize {
959 RX_BUFFER_LENGTH
960 }
961
962 pub fn decode(rx_buffer: &[u8]) -> std::result::Result<Vec<Self>, Error> {
976 validate_len(rx_buffer, Self::reply_size())?;
977 validate_checksum(rx_buffer)?;
978 let mut result = Vec::new();
979
980 macro_rules! ck_and_add {
981 ($byte:expr,$position:expr,$enum_type:expr) => {
982 if read_bit!(rx_buffer[$byte], $position) {
983 result.push($enum_type);
984 }
985 };
986 }
987
988 ck_and_add!(4, 0, ErrorCode::CellVoltHighLevel1);
989 ck_and_add!(4, 1, ErrorCode::CellVoltHighLevel2);
990 ck_and_add!(4, 2, ErrorCode::CellVoltLowLevel1);
991 ck_and_add!(4, 3, ErrorCode::CellVoltLowLevel2);
992 ck_and_add!(4, 4, ErrorCode::SumVoltHighLevel1);
993 ck_and_add!(4, 5, ErrorCode::SumVoltHighLevel2);
994 ck_and_add!(4, 6, ErrorCode::SumVoltLowLevel1);
995 ck_and_add!(4, 7, ErrorCode::SumVoltLowLevel2);
996
997 ck_and_add!(5, 0, ErrorCode::ChargeTempHighLevel1);
998 ck_and_add!(5, 1, ErrorCode::ChargeTempHighLevel2);
999 ck_and_add!(5, 2, ErrorCode::ChargeTempLowLevel1);
1000 ck_and_add!(5, 3, ErrorCode::ChargeTempLowLevel2);
1001 ck_and_add!(5, 4, ErrorCode::DischargeTempHighLevel1);
1002 ck_and_add!(5, 5, ErrorCode::DischargeTempHighLevel2);
1003 ck_and_add!(5, 6, ErrorCode::DischargeTempLowLevel1);
1004 ck_and_add!(5, 7, ErrorCode::DischargeTempLowLevel2);
1005
1006 ck_and_add!(6, 1, ErrorCode::ChargeOvercurrentLevel2);
1007 ck_and_add!(6, 0, ErrorCode::ChargeOvercurrentLevel1);
1008 ck_and_add!(6, 2, ErrorCode::DischargeOvercurrentLevel1);
1009 ck_and_add!(6, 3, ErrorCode::DischargeOvercurrentLevel2);
1010 ck_and_add!(6, 4, ErrorCode::SocHighLevel1);
1011 ck_and_add!(6, 5, ErrorCode::SocHighLevel2);
1012 ck_and_add!(6, 6, ErrorCode::SocLowLevel1);
1013 ck_and_add!(6, 7, ErrorCode::SocLowLevel2);
1014
1015 ck_and_add!(7, 0, ErrorCode::DiffVoltLevel1);
1016 ck_and_add!(7, 1, ErrorCode::DiffVoltLevel2);
1017 ck_and_add!(7, 2, ErrorCode::DiffTempLevel1);
1018 ck_and_add!(7, 3, ErrorCode::DiffTempLevel2);
1019
1020 ck_and_add!(8, 0, ErrorCode::ChargeMosTempHighAlarm);
1021 ck_and_add!(8, 1, ErrorCode::DischargeMosTempHighAlarm);
1022 ck_and_add!(8, 2, ErrorCode::ChargeMosTempSensorErr);
1023 ck_and_add!(8, 3, ErrorCode::DischargeMosTempSensorErr);
1024 ck_and_add!(8, 4, ErrorCode::ChargeMosAdhesionErr);
1025 ck_and_add!(8, 5, ErrorCode::DischargeMosAdhesionErr);
1026 ck_and_add!(8, 6, ErrorCode::ChargeMosOpenCircuitErr);
1027 ck_and_add!(8, 7, ErrorCode::DischargeMosOpenCircuitErr);
1028
1029 ck_and_add!(9, 0, ErrorCode::AfeCollectChipErr);
1030 ck_and_add!(9, 1, ErrorCode::VoltageCollectDropped);
1031 ck_and_add!(9, 2, ErrorCode::CellTempSensorErr);
1032 ck_and_add!(9, 3, ErrorCode::EepromErr);
1033 ck_and_add!(9, 4, ErrorCode::RtcErr);
1034 ck_and_add!(9, 5, ErrorCode::PrechangeFailure);
1035 ck_and_add!(9, 6, ErrorCode::CommunicationFailure);
1036 ck_and_add!(9, 7, ErrorCode::InternalCommunicationFailure);
1037
1038 ck_and_add!(10, 0, ErrorCode::CurrentModuleFault);
1039 ck_and_add!(10, 1, ErrorCode::SumVoltageDetectFault);
1040 ck_and_add!(10, 2, ErrorCode::ShortCircuitProtectFault);
1041 ck_and_add!(10, 3, ErrorCode::LowVoltForbiddenChargeFault);
1042
1043 Ok(result)
1044 }
1045}
1046
1047pub struct SetDischargeMosfet;
1049
1050impl SetDischargeMosfet {
1051 pub fn request(address: Address, enable: bool) -> Vec<u8> {
1064 let mut tx_buffer = create_request_header(address, 0xD9);
1065 if enable {
1066 tx_buffer[4] = 0x01;
1067 }
1068 calc_crc_and_set(&mut tx_buffer);
1069 tx_buffer
1070 }
1071
1072 pub fn reply_size() -> usize {
1075 RX_BUFFER_LENGTH
1076 }
1077
1078 pub fn decode(rx_buffer: &[u8]) -> std::result::Result<(), Error> {
1091 validate_len(rx_buffer, Self::reply_size())?;
1092 validate_checksum(rx_buffer)
1093 }
1094}
1095
1096pub struct SetChargeMosfet;
1098
1099impl SetChargeMosfet {
1100 pub fn request(address: Address, enable: bool) -> Vec<u8> {
1113 let mut tx_buffer = create_request_header(address, 0xDA);
1114 if enable {
1115 tx_buffer[4] = 0x01;
1116 }
1117 calc_crc_and_set(&mut tx_buffer);
1118 tx_buffer
1119 }
1120
1121 pub fn reply_size() -> usize {
1123 RX_BUFFER_LENGTH
1124 }
1125
1126 pub fn decode(rx_buffer: &[u8]) -> std::result::Result<(), Error> {
1139 validate_len(rx_buffer, Self::reply_size())?;
1140 validate_checksum(rx_buffer)
1141 }
1142}
1143
1144pub struct SetSoc;
1146
1147impl SetSoc {
1148 pub fn request(address: Address, soc_percent: f32) -> Vec<u8> {
1161 let mut tx_buffer = create_request_header(address, 0x21);
1162 let value = {
1163 let val = (soc_percent * 10.0).round();
1164 if val > 1000.0 {
1165 1000
1167 } else if val < 0.0 {
1168 0
1169 } else {
1170 val as u16
1171 }
1172 }
1173 .to_be_bytes();
1174 tx_buffer[10] = value[0]; tx_buffer[11] = value[1]; calc_crc_and_set(&mut tx_buffer);
1177 tx_buffer
1178 }
1179
1180 pub fn reply_size() -> usize {
1182 RX_BUFFER_LENGTH
1183 }
1184
1185 pub fn decode(rx_buffer: &[u8]) -> std::result::Result<(), Error> {
1198 validate_len(rx_buffer, Self::reply_size())?;
1199 validate_checksum(rx_buffer)
1200 }
1201}
1202
1203pub struct BmsReset;
1205
1206impl BmsReset {
1207 pub fn request(address: Address) -> Vec<u8> {
1219 let mut tx_buffer = create_request_header(address, 0x00);
1220 calc_crc_and_set(&mut tx_buffer);
1221 tx_buffer
1222 }
1223
1224 pub fn reply_size() -> usize {
1226 RX_BUFFER_LENGTH
1227 }
1228
1229 pub fn decode(rx_buffer: &[u8]) -> std::result::Result<(), Error> {
1242 validate_len(rx_buffer, Self::reply_size())?;
1243 validate_checksum(rx_buffer)
1244 }
1245}
1246
1247#[cfg(test)]
1248mod tests {
1249 use super::*;
1250
1251 fn calculate_test_checksum(data: &[u8]) -> u8 {
1253 let mut checksum: u8 = 0;
1254 for byte in data.iter().take(data.len() - 1) {
1255 checksum = checksum.wrapping_add(*byte);
1256 }
1257 checksum
1258 }
1259
1260 #[test]
1261 fn test_calc_crc_valid() {
1262 let data1: [u8; 13] = [
1263 0xA5, 0x40, 0x90, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1264 ]; let expected_crc1 = calculate_test_checksum(&data1);
1266 assert_eq!(calc_crc(&data1), expected_crc1);
1267
1268 let data2: [u8; 13] = [
1269 0xA5, 0x40, 0x90, 0x08, 0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xBA, 0xBE, 0x00,
1270 ]; let expected_crc2 = calculate_test_checksum(&data2);
1272 assert_eq!(calc_crc(&data2), expected_crc2);
1273
1274 let data3: [u8; 13] = [
1275 0xA5, 0x01, 0x02, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
1276 ];
1277 let expected_crc3 = calculate_test_checksum(&data3);
1278 assert_eq!(calc_crc(&data3), expected_crc3);
1279 }
1280
1281 #[test]
1282 fn test_validate_checksum_valid() {
1283 let mut data: [u8; 13] = [
1284 0xA5, 0x40, 0x90, 0x08, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x00,
1285 ];
1286 data[12] = calc_crc(&data); assert!(validate_checksum(&data).is_ok());
1288 }
1289
1290 #[test]
1291 fn test_validate_checksum_invalid() {
1292 let mut data: [u8; 13] = [
1293 0xA5, 0x40, 0x90, 0x08, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x00,
1294 ];
1295 data[12] = calc_crc(&data).wrapping_add(1); let result = validate_checksum(&data);
1297 assert!(result.is_err());
1298 match result.err().unwrap() {
1299 Error::CheckSumError => {} _ => panic!("Unexpected error type"),
1301 }
1302 }
1303
1304 #[test]
1305 fn test_status_decode_valid() {
1306 let bytes: [u8; 13] = [
1311 0xA5, 0x40, 0x94, 0x08, 0x10, 0x04, 0x01, 0x00, 0xAA, 0x04, 0xD2, 0x00, 0x16,
1312 ];
1313 let expected_status = Status {
1314 cells: 16,
1315 temperature_sensors: 4,
1316 charger_running: true,
1317 load_running: false,
1318 states: IOState {
1319 di1: false, di2: true, di3: false, di4: true, do1: false, do2: true, do3: false, do4: true, },
1328 cycles: 1234,
1329 };
1330 match Status::decode(&bytes) {
1331 Ok(decoded) => {
1332 assert_eq!(decoded.cells, expected_status.cells);
1333 assert_eq!(
1334 decoded.temperature_sensors,
1335 expected_status.temperature_sensors
1336 );
1337 assert_eq!(decoded.charger_running, expected_status.charger_running);
1338 assert_eq!(decoded.load_running, expected_status.load_running);
1339 assert_eq!(decoded.states.di1, expected_status.states.di1);
1340 assert_eq!(decoded.states.di2, expected_status.states.di2);
1341 assert_eq!(decoded.states.di3, expected_status.states.di3);
1342 assert_eq!(decoded.states.di4, expected_status.states.di4);
1343 assert_eq!(decoded.states.do1, expected_status.states.do1);
1344 assert_eq!(decoded.states.do2, expected_status.states.do2);
1345 assert_eq!(decoded.states.do3, expected_status.states.do3);
1346 assert_eq!(decoded.states.do4, expected_status.states.do4);
1347 assert_eq!(decoded.cycles, expected_status.cycles);
1348 }
1349 Err(e) => panic!("Decoding failed: {:?}", e),
1350 }
1351 }
1352
1353 #[test]
1354 fn test_mosfet_status_decode_valid() {
1355 let bytes: [u8; 13] = [
1358 0xA5, 0x40, 0x93, 0x08, 0x01, 0x01, 0x00, 0x96, 0x00, 0x00, 0xC3, 0xCB, 0xA6,
1359 ];
1360 let expected_status = MosfetStatus {
1361 mode: MosfetMode::Charging,
1362 charging_mosfet: true,
1363 discharging_mosfet: false,
1364 bms_cycles: 150,
1365 capacity_ah: 50.123,
1366 };
1367 match MosfetStatus::decode(&bytes) {
1368 Ok(decoded) => {
1369 assert!(matches!(decoded.mode, MosfetMode::Charging));
1370 assert_eq!(decoded.charging_mosfet, expected_status.charging_mosfet);
1371 assert_eq!(
1372 decoded.discharging_mosfet,
1373 expected_status.discharging_mosfet
1374 );
1375 assert_eq!(decoded.bms_cycles, expected_status.bms_cycles);
1376 assert!((decoded.capacity_ah - expected_status.capacity_ah).abs() < f32::EPSILON);
1377 }
1378 Err(e) => panic!("Decoding failed: {:?}", e),
1379 }
1380 }
1381
1382 #[test]
1383 fn test_temperature_range_decode_valid() {
1384 let bytes: [u8; 13] = [
1387 0xA5, 0x40, 0x92, 0x08, 0x41, 0x01, 0x32, 0x02, 0x00, 0x00, 0x00, 0x00, 0xF5,
1388 ];
1389 let expected_range = TemperatureRange {
1390 highest_temperature: 25,
1391 highest_sensor: 1,
1392 lowest_temperature: 10,
1393 lowest_sensor: 2,
1394 };
1395 match TemperatureRange::decode(&bytes) {
1396 Ok(decoded) => {
1397 assert_eq!(
1398 decoded.highest_temperature,
1399 expected_range.highest_temperature
1400 );
1401 assert_eq!(decoded.highest_sensor, expected_range.highest_sensor);
1402 assert_eq!(
1403 decoded.lowest_temperature,
1404 expected_range.lowest_temperature
1405 );
1406 assert_eq!(decoded.lowest_sensor, expected_range.lowest_sensor);
1407 }
1408 Err(e) => panic!("Decoding failed: {:?}", e),
1409 }
1410 }
1411
1412 #[test]
1413 fn test_cell_voltage_range_decode_valid() {
1414 let bytes: [u8; 13] = [
1417 0xA5, 0x40, 0x91, 0x08, 0x0D, 0x80, 0x01, 0x0C, 0x33, 0x05, 0x00, 0x00, 0x50,
1418 ];
1419 let expected_range = CellVoltageRange {
1420 highest_voltage: 3.456,
1421 highest_cell: 1,
1422 lowest_voltage: 3.123,
1423 lowest_cell: 5,
1424 };
1425 match CellVoltageRange::decode(&bytes) {
1426 Ok(decoded) => {
1427 assert!(
1428 (decoded.highest_voltage - expected_range.highest_voltage).abs() < f32::EPSILON
1429 );
1430 assert_eq!(decoded.highest_cell, expected_range.highest_cell);
1431 assert!(
1432 (decoded.lowest_voltage - expected_range.lowest_voltage).abs() < f32::EPSILON
1433 );
1434 assert_eq!(decoded.lowest_cell, expected_range.lowest_cell);
1435 }
1436 Err(e) => panic!("Decoding failed: {:?}", e),
1437 }
1438 }
1439
1440 #[test]
1441 fn test_validate_len_valid() {
1442 let data: [u8; 13] = [0; 13];
1443 assert!(validate_len(&data, 13).is_ok());
1444 }
1445
1446 #[test]
1447 fn test_validate_len_valid_larger_buffer() {
1448 let data: [u8; 15] = [0; 15]; assert!(validate_len(&data, 13).is_ok());
1450 }
1451
1452 #[test]
1453 fn test_validate_len_invalid() {
1454 let data: [u8; 12] = [0; 12];
1455 let result = validate_len(&data, 13);
1456 assert!(result.is_err());
1457 match result.err().unwrap() {
1458 Error::ReplySizeError => {} _ => panic!("Unexpected error type"),
1460 }
1461 }
1462
1463 #[test]
1464 fn test_validate_len_empty() {
1465 let data: [u8; 0] = [];
1466 let result = validate_len(&data, 13);
1467 assert!(result.is_err());
1468 match result.err().unwrap() {
1469 Error::ReplySizeError => {} _ => panic!("Unexpected error type"),
1471 }
1472 }
1473
1474 #[test]
1476 fn test_soc_decode_valid() {
1477 let bytes: [u8; 13] = [
1480 0xA5, 0x40, 0x90, 0x08, 0x02, 0x1F, 0x00, 0x00, 0x75, 0x49, 0x02, 0xF3, 0x51,
1481 ];
1482 let expected_soc = Soc {
1483 total_voltage: 54.3,
1484 current: 2.5,
1485 soc_percent: 75.5,
1486 };
1487 match Soc::decode(&bytes) {
1488 Ok(decoded) => {
1489 assert!((decoded.total_voltage - expected_soc.total_voltage).abs() < f32::EPSILON);
1490 assert!((decoded.current - expected_soc.current).abs() < f32::EPSILON);
1491 assert!((decoded.soc_percent - expected_soc.soc_percent).abs() < f32::EPSILON);
1492 }
1493 Err(e) => panic!("Decoding failed: {:?}", e),
1494 }
1495 }
1496
1497 #[test]
1498 fn test_soc_decode_negative_current() {
1499 let bytes: [u8; 13] = [
1502 0xA5, 0x40, 0x90, 0x08, 0x01, 0xF4, 0x00, 0x00, 0x74, 0xCC, 0x01, 0xF4, 0xA7,
1503 ];
1504 let expected_soc = Soc {
1505 total_voltage: 50.0,
1506 current: -10.0,
1507 soc_percent: 50.0,
1508 };
1509 match Soc::decode(&bytes) {
1510 Ok(decoded) => {
1511 assert!((decoded.total_voltage - expected_soc.total_voltage).abs() < f32::EPSILON);
1512 assert!((decoded.current - expected_soc.current).abs() < f32::EPSILON);
1513 assert!((decoded.soc_percent - expected_soc.soc_percent).abs() < f32::EPSILON);
1514 }
1515 Err(e) => panic!("Decoding failed: {:?}", e),
1516 }
1517 }
1518
1519 #[test]
1520 fn test_soc_decode_invalid_checksum() {
1521 let bytes: [u8; 13] = [
1522 0xA5, 0x40, 0x90, 0x08, 0x02, 0x1F, 0x00, 0x00, 0x75, 0x49, 0x02, 0xF3, 0x52,
1523 ]; let result = Soc::decode(&bytes);
1525 assert!(result.is_err());
1526 match result.err().unwrap() {
1527 Error::CheckSumError => {} e => panic!("Unexpected error type: {:?}", e),
1529 }
1530 }
1531
1532 #[test]
1533 fn test_soc_decode_invalid_len() {
1534 let bytes: [u8; 12] = [
1535 0xA5, 0x40, 0x90, 0x08, 0x02, 0x1F, 0x00, 0x00, 0x75, 0x49, 0x02, 0xF3,
1536 ]; let result = Soc::decode(&bytes);
1538 assert!(result.is_err());
1539 match result.err().unwrap() {
1540 Error::ReplySizeError => {} e => panic!("Unexpected error type: {:?}", e),
1542 }
1543 }
1544
1545 #[test]
1546 fn test_cell_voltages_decode_valid_multi_frame() {
1547 let frame1: [u8; 13] = [
1552 0xA5, 0x40, 0x95, 0x08, 0x01, 0x0C, 0xE4, 0x0C, 0xE5, 0x0C, 0xE6, 0x00, 0x56,
1553 ];
1554
1555 let frame2: [u8; 13] = [
1559 0xA5, 0x40, 0x95, 0x08, 0x02, 0x0C, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
1560 ];
1561
1562 let mut combined_bytes = Vec::new();
1563 combined_bytes.extend_from_slice(&frame1);
1564 combined_bytes.extend_from_slice(&frame2);
1565
1566 let expected_voltages = vec![3.300, 3.301, 3.302, 3.303];
1567
1568 match CellVoltages::decode(&combined_bytes, 4) {
1569 Ok(decoded) => {
1570 assert_eq!((*decoded).len(), expected_voltages.len());
1571 for (d, e) in (*decoded).iter().zip(expected_voltages.iter()) {
1572 assert!((d - e).abs() < f32::EPSILON);
1573 }
1574 }
1575 Err(e) => panic!("Decoding failed: {:?}", e),
1576 }
1577 }
1578
1579 #[test]
1580 fn test_cell_voltages_decode_frame_out_of_order() {
1581 let frame1: [u8; 13] = [
1582 0xA5, 0x40, 0x95, 0x08, 0x01, 0x0C, 0xE4, 0x0C, 0xE5, 0x0C, 0xE6, 0x00, 0x56,
1583 ];
1584 let frame2_wrong_order: [u8; 13] = [
1585 0xA5, 0x40, 0x95, 0x08, 0x01, 0x0C, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75,
1586 ]; let mut combined_bytes = Vec::new();
1589 combined_bytes.extend_from_slice(&frame1);
1590 combined_bytes.extend_from_slice(&frame2_wrong_order);
1591
1592 let result = CellVoltages::decode(&combined_bytes, 4);
1593 assert!(result.is_err());
1594 match result.err().unwrap() {
1595 Error::FrameNoError => {} e => panic!("Unexpected error type: {:?}", e),
1597 }
1598 }
1599
1600 #[test]
1601 fn test_cell_temperatures_decode_valid_multi_frame() {
1602 let frame1: [u8; 13] = [
1607 0xA5, 0x40, 0x96, 0x08, 0x01, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x3D,
1608 ];
1609
1610 let frame2: [u8; 13] = [
1614 0xA5, 0x40, 0x96, 0x08, 0x02, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8,
1615 ];
1616
1617 let mut combined_bytes = Vec::new();
1618 combined_bytes.extend_from_slice(&frame1);
1619 combined_bytes.extend_from_slice(&frame2);
1620
1621 let expected_temperatures = vec![20, 21, 22, 23, 24, 25, 26, 27];
1622
1623 match CellTemperatures::decode(&combined_bytes, 8) {
1624 Ok(decoded) => {
1625 assert_eq!(decoded, expected_temperatures);
1626 }
1627 Err(e) => panic!("Decoding failed: {:?}", e),
1628 }
1629 }
1630
1631 #[test]
1632 fn test_cell_balance_state_decode_valid() {
1633 let bytes: [u8; 13] = [
1638 0xA5, 0x40, 0x97, 0x08, 0x01, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
1639 ];
1640
1641 let mut expected_state = vec![false; 16];
1642 expected_state[0] = true; expected_state[8] = true; expected_state[15] = true; match CellBalanceState::decode(&bytes, 16) {
1647 Ok(decoded) => {
1648 assert_eq!(decoded, expected_state);
1649 }
1650 Err(e) => panic!("Decoding failed: {:?}", e),
1651 }
1652 }
1653
1654 #[test]
1655 fn test_cell_balance_state_decode_n_cells_less_than_byte_boundary() {
1656 let bytes: [u8; 13] = [
1661 0xA5, 0x40, 0x97, 0x08, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95,
1662 ];
1663
1664 let mut expected_state = vec![false; 5];
1665 expected_state[0] = true; expected_state[4] = true; match CellBalanceState::decode(&bytes, 5) {
1669 Ok(decoded) => {
1670 assert_eq!(decoded, expected_state);
1671 }
1672 Err(e) => panic!("Decoding failed: {:?}", e),
1673 }
1674 }
1675
1676 #[test]
1677 fn test_error_code_decode_valid() {
1678 let bytes: [u8; 13] = [
1690 0xA5, 0x40, 0x98, 0x08, 0x01, 0x08, 0x10, 0x08, 0x00, 0x01, 0x00, 0x00, 0xA7,
1691 ];
1692
1693 let expected_errors = vec![
1694 ErrorCode::CellVoltHighLevel1,
1695 ErrorCode::ChargeTempLowLevel2,
1696 ErrorCode::SocHighLevel1,
1697 ErrorCode::DiffTempLevel2,
1698 ErrorCode::AfeCollectChipErr,
1699 ];
1700
1701 match ErrorCode::decode(&bytes) {
1702 Ok(decoded) => {
1703 assert_eq!(decoded.len(), expected_errors.len());
1704 for err in expected_errors {
1705 assert!(decoded.contains(&err), "Missing error: {:?}", err);
1706 }
1707 }
1708 Err(e) => panic!("Decoding failed: {:?}", e),
1709 }
1710 }
1711
1712 #[test]
1713 fn test_error_code_decode_no_errors() {
1714 let bytes: [u8; 13] = [
1717 0xA5, 0x40, 0x98, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85,
1718 ];
1719
1720 match ErrorCode::decode(&bytes) {
1721 Ok(decoded) => {
1722 assert!(decoded.is_empty());
1723 }
1724 Err(e) => panic!("Decoding failed: {:?}", e),
1725 }
1726 }
1727
1728 #[test]
1730 fn test_soc_request() {
1731 let expected_frame: [u8; 13] = [
1732 0xA5, 0x40, 0x90, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7D,
1733 ];
1734 assert_eq!(Soc::request(Address::Host), expected_frame);
1735 }
1736
1737 #[test]
1738 fn test_cell_voltage_range_request() {
1739 let expected_frame: [u8; 13] = [
1742 0xA5, 0x40, 0x91, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E,
1743 ];
1744 assert_eq!(CellVoltageRange::request(Address::Host), expected_frame);
1745 }
1746
1747 #[test]
1748 fn test_temperature_range_request() {
1749 let expected_frame: [u8; 13] = [
1752 0xA5, 0x40, 0x92, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
1753 ];
1754 assert_eq!(TemperatureRange::request(Address::Host), expected_frame);
1755 }
1756
1757 #[test]
1758 fn test_mosfet_status_request() {
1759 let expected_frame: [u8; 13] = [
1762 0xA5, 0x40, 0x93, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
1763 ];
1764 assert_eq!(MosfetStatus::request(Address::Host), expected_frame);
1765 }
1766
1767 #[test]
1768 fn test_status_request() {
1769 let expected_frame: [u8; 13] = [
1772 0xA5, 0x40, 0x94, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
1773 ];
1774 assert_eq!(Status::request(Address::Host), expected_frame);
1775 }
1776
1777 #[test]
1778 fn test_cell_voltages_request() {
1779 let expected_frame: [u8; 13] = [
1782 0xA5, 0x40, 0x95, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82,
1783 ];
1784 assert_eq!(CellVoltages::request(Address::Host), expected_frame);
1785 }
1786
1787 #[test]
1788 fn test_cell_temperatures_request() {
1789 let expected_frame: [u8; 13] = [
1792 0xA5, 0x40, 0x96, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83,
1793 ];
1794 assert_eq!(CellTemperatures::request(Address::Host), expected_frame);
1795 }
1796
1797 #[test]
1798 fn test_cell_balance_state_request() {
1799 let expected_frame: [u8; 13] = [
1802 0xA5, 0x40, 0x97, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84,
1803 ];
1804 assert_eq!(CellBalanceState::request(Address::Host), expected_frame);
1805 }
1806
1807 #[test]
1808 fn test_error_code_request() {
1809 let expected_frame: [u8; 13] = [
1812 0xA5, 0x40, 0x98, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85,
1813 ];
1814 assert_eq!(ErrorCode::request(Address::Host), expected_frame);
1815 }
1816
1817 #[test]
1818 fn test_set_discharge_mosfet_request_enable() {
1819 let expected_frame: [u8; 13] = [
1822 0xA5, 0x40, 0xD9, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7,
1823 ];
1824 assert_eq!(
1825 SetDischargeMosfet::request(Address::Host, true),
1826 expected_frame
1827 );
1828 }
1829
1830 #[test]
1831 fn test_set_discharge_mosfet_request_disable() {
1832 let expected_frame: [u8; 13] = [
1835 0xA5, 0x40, 0xD9, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6,
1836 ];
1837 assert_eq!(
1838 SetDischargeMosfet::request(Address::Host, false),
1839 expected_frame
1840 );
1841 }
1842
1843 #[test]
1844 fn test_set_charge_mosfet_request_enable() {
1845 let expected_frame: [u8; 13] = [
1848 0xA5, 0x40, 0xDA, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8,
1849 ];
1850 assert_eq!(
1851 SetChargeMosfet::request(Address::Host, true),
1852 expected_frame
1853 );
1854 }
1855
1856 #[test]
1857 fn test_set_soc_request() {
1858 let expected_frame: [u8; 13] = [
1862 0xA5, 0x40, 0x21, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x25, 0x36,
1863 ];
1864 assert_eq!(SetSoc::request(Address::Host, 80.5), expected_frame);
1865 }
1866
1867 #[test]
1868 fn test_bms_reset_request() {
1869 let expected_frame: [u8; 13] = [
1872 0xA5, 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xED,
1873 ];
1874 assert_eq!(BmsReset::request(Address::Host), expected_frame);
1875 }
1876}