1#[cfg(feature = "serde")]
2use serde::{Deserialize, Serialize};
3
4pub trait PowerSwitch {
6 type Error;
7
8 fn switch_on(&mut self) -> Result<(), Self::Error>;
9 fn switch_off(&mut self) -> Result<(), Self::Error>;
10
11 fn is_switch_on(&self) -> bool {
12 self.switch_state() == SwitchState::On
13 }
14
15 fn switch_state(&self) -> SwitchState;
16}
17
18#[derive(Debug, Eq, PartialEq, Copy, Clone)]
19#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
20pub enum SwitchState {
21 Off = 0,
22 On = 1,
23 Unknown = 2,
24 Faulty = 3,
25}
26
27pub type SwitchId = u16;
28
29pub trait PowerSwitcherCommandSender {
31 type Error;
32
33 fn send_switch_on_cmd(&mut self, switch_id: SwitchId) -> Result<(), Self::Error>;
34 fn send_switch_off_cmd(&mut self, switch_id: SwitchId) -> Result<(), Self::Error>;
35}
36
37pub trait PowerSwitchInfo {
38 type Error;
39
40 fn get_switch_state(&mut self, switch_id: SwitchId) -> Result<SwitchState, Self::Error>;
42
43 fn get_is_switch_on(&mut self, switch_id: SwitchId) -> Result<bool, Self::Error> {
44 Ok(self.get_switch_state(switch_id)? == SwitchState::On)
45 }
46
47 fn switch_delay_ms(&self) -> u32;
52}
53
54#[cfg(test)]
55mod tests {
56 #![allow(dead_code)]
57 use super::*;
58 use std::boxed::Box;
59
60 struct Pcdu {
61 switch_rx: std::sync::mpsc::Receiver<(SwitchId, u16)>,
62 }
63
64 #[derive(Eq, PartialEq)]
65 enum DeviceState {
66 OFF,
67 SwitchingPower,
68 ON,
69 SETUP,
70 IDLE,
71 }
72 struct MyComplexDevice {
73 power_switcher: Box<dyn PowerSwitcherCommandSender<Error = ()>>,
74 power_info: Box<dyn PowerSwitchInfo<Error = ()>>,
75 switch_id: SwitchId,
76 some_state: u16,
77 dev_state: DeviceState,
78 mode: u32,
79 submode: u16,
80 }
81
82 impl MyComplexDevice {
83 pub fn periodic_op(&mut self) {
84 let mode = 1;
86 if mode == 1 {
87 if self.dev_state == DeviceState::OFF {
88 self.power_switcher
89 .send_switch_on_cmd(self.switch_id)
90 .expect("sending siwthc cmd failed");
91 self.dev_state = DeviceState::SwitchingPower;
92 }
93 if self.dev_state == DeviceState::SwitchingPower {
94 if self.power_info.get_is_switch_on(0).unwrap() {
95 self.dev_state = DeviceState::ON;
96 self.mode = 1;
97 }
98 }
99 }
100 }
101 }
102}