use std::collections::HashMap; use std::sync::mpsc::Receiver; use satrs_core::power::{PowerSwitch, PowerSwitcher, SwitchId, SwitchState}; use crate::can::{CanRxHandler, CanTxHandler}; use crate::can_ids::{DeviceId, PackageId, PackageModel}; use std::convert::TryFrom; use std::ops::Deref; use std::time::Duration; use log::warn; pub use strum::IntoEnumIterator; // 0.17.1 pub use strum_macros::EnumIter; // 0.17.1 #[derive(Copy, Clone, Debug, PartialEq, EnumIter)] pub enum DeviceState { On, Off, SwitchingPower, Setup, Idle, } pub struct PCDU { switch_rx: Receiver<(SwitchId, SwitchState)>, can_tx: CanTxHandler, can_rx: Receiver, device_state_map: HashMap, } impl PCDU { pub fn new(switch_rx: Receiver<(SwitchId, SwitchState)>, can_tx: CanTxHandler, can_rx: Receiver) -> PCDU{ let mut device_state_map: HashMap = HashMap::new(); for id in DeviceId::iter() { device_state_map.insert(id, SwitchState::Off); } PCDU{switch_rx, can_tx, can_rx, device_state_map} } pub fn handle_power_requests(&mut self) -> Result{ let mut i = 0; while let Ok((switch_id, switch_state)) = self.switch_rx.recv() { match switch_state { SwitchState::Off => { match self.send_switch_off_cmd(switch_id) { Ok(_) => { i = i + 1; } Err(_) => { return Err(()); } } } SwitchState::On => { match self.send_switch_on_cmd(switch_id) { Ok(_) => { i = i + 1; } Err(_) => { return Err(()); } } } _ => {} } } return Ok(i); } } impl PowerSwitcher for PCDU { type Error = (); fn send_switch_on_cmd(&mut self, switch_id: SwitchId) -> Result<(), Self::Error> { return match DeviceId::try_from(switch_id) { Ok(device_id) => { let buf: &[u8] = &switch_id.to_be_bytes(); if buf.len() == 1 { self.can_tx.tx_socket(PackageId::DevicePowerOnRequest, buf); let mut i = 0; while i < 10 { match self.can_rx.recv() { Ok(msg) => { if msg.package_id() == PackageId::DevicePowerOnConfirmation { return if msg.data()[0] == device_id as u8 && msg.data()[1] == 1 { *self.device_state_map.get_mut(&(device_id)).unwrap() = SwitchState::On; Ok(()) } else { Err(()) } } } Err(_) => { warn!("Error receiving Can Bus Message."); } } i = i + 1; } Err(()) } else { Err(()) } } Err(_) => { Err(()) } } } fn send_switch_off_cmd(&mut self, switch_id: SwitchId) -> Result<(), Self::Error> { return match DeviceId::try_from(switch_id) { Ok(device_id) => { let buf: &[u8] = &switch_id.to_be_bytes(); if buf.len() == 1 { self.can_tx.tx_socket(PackageId::DevicePowerOffRequest, buf); let mut i = 0; while i < 10 { match self.can_rx.recv() { Ok(msg) => { if msg.package_id() == PackageId::DevicePowerOffConfirmation { return if msg.data()[0] == device_id as u8 && msg.data()[1] == 1 { *self.device_state_map.get_mut(&(device_id)).unwrap() = SwitchState::Off; Ok(()) } else { Err(()) } } } Err(_) => { warn!("Error receiving Can Bus Message."); } } i = i + 1; } Err(()) } else { Err(()) } } Err(_) => { Err(()) } } } fn get_switch_state(&mut self, switch_id: SwitchId) -> Result { if let Ok(device_id) = DeviceId::try_from(switch_id) { return match self.device_state_map.get_mut(&device_id) { None => { Err(()) } Some(state) => { let return_state = state.clone(); Ok(return_state) } } } else { Err(()) } } fn switch_delay_ms(&self) -> u32 { return 0; } } pub fn core_power_task(switch_rx: Receiver<(SwitchId, SwitchState)>, can_tx: CanTxHandler, can_rx: Receiver) { let mut pcdu = PCDU::new(switch_rx, can_tx, can_rx); loop{ pcdu.handle_power_requests().unwrap(); } }