longshot/protocol/request/
monitor.rs

1use super::PartialDecode;
2use crate::protocol::*;
3
4/// The response to a monitor inquiry sent by [`Request::MonitorV2`].
5///
6/// Some fields appear not to be used and always appear to be zero.
7#[derive(Clone, Debug, Default, Eq, PartialEq)]
8pub struct MonitorV2Response {
9    pub state: MachineEnum<EcamMachineState>,
10    pub accessory: MachineEnum<EcamAccessory>,
11    pub switches: SwitchSet<EcamMachineSwitch>,
12    pub alarms: SwitchSet<EcamMachineAlarm>,
13    pub progress: u8,
14    pub percentage: u8,
15    pub unknown0: u8,
16    pub unknown1: u8,
17    pub unknown2: u8,
18    pub unknown3: u8,
19    pub unknown4: u8,
20}
21
22impl<T: MachineEnumerable<T>> PartialDecode<SwitchSet<T>> for SwitchSet<T> {
23    fn partial_decode(input: &mut &[u8]) -> Option<SwitchSet<T>> {
24        let a = <u8>::partial_decode(input)? as u16;
25        let b = <u8>::partial_decode(input)? as u16;
26        // Note that this is inverted from <u16>::partial_decode
27        Some(SwitchSet::from_u16((b << 8) | a))
28    }
29}
30
31impl<T: MachineEnumerable<T>> PartialEncode for SwitchSet<T> {
32    fn partial_encode(&self, out: &mut Vec<u8>) {
33        self.value.partial_encode(out)
34    }
35}
36
37impl PartialDecode<MonitorV2Response> for MonitorV2Response {
38    fn partial_decode(input: &mut &[u8]) -> Option<MonitorV2Response> {
39        Some(MonitorV2Response {
40            accessory: <MachineEnum<EcamAccessory>>::partial_decode(input)?,
41            switches: <SwitchSet<EcamMachineSwitch>>::partial_decode(input)?,
42            alarms: <SwitchSet<EcamMachineAlarm>>::partial_decode(input)?,
43            state: <MachineEnum<EcamMachineState>>::partial_decode(input)?,
44            progress: <u8>::partial_decode(input)?,
45            percentage: <u8>::partial_decode(input)?,
46            unknown0: <u8>::partial_decode(input)?,
47            unknown1: <u8>::partial_decode(input)?,
48            unknown2: <u8>::partial_decode(input)?,
49            unknown3: <u8>::partial_decode(input)?,
50            unknown4: <u8>::partial_decode(input)?,
51        })
52    }
53}
54
55impl PartialEncode for MonitorV2Response {
56    fn partial_encode(&self, out: &mut Vec<u8>) {
57        out.push(self.accessory.into());
58        self.switches.partial_encode(out);
59        self.alarms.partial_encode(out);
60        out.push(self.state.into());
61        out.push(self.progress);
62        out.push(self.percentage);
63        out.push(self.unknown0);
64        out.push(self.unknown1);
65        out.push(self.unknown2);
66        out.push(self.unknown3);
67        out.push(self.unknown4);
68    }
69}
70
71#[cfg(test)]
72mod test {
73    use crate::protocol::EcamMachineSwitch;
74
75    use super::SwitchSet;
76
77    #[test]
78    fn switch_set_test() {
79        let switches = SwitchSet::<EcamMachineSwitch>::of(&[]);
80        assert_eq!("(empty)", format!("{:?}", switches));
81        let switches =
82            SwitchSet::of(&[EcamMachineSwitch::MotorDown, EcamMachineSwitch::WaterSpout]);
83        assert_eq!("WaterSpout | MotorDown", format!("{:?}", switches));
84    }
85}