eurosim-obsw/src/pcdu.rs

170 lines
5.9 KiB
Rust
Raw Normal View History

2023-02-07 16:45:00 +01:00
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<PackageModel>,
device_state_map: HashMap<DeviceId, SwitchState>,
}
impl PCDU {
pub fn new(switch_rx: Receiver<(SwitchId, SwitchState)>, can_tx: CanTxHandler, can_rx: Receiver<PackageModel>) -> PCDU{
let mut device_state_map: HashMap<DeviceId, SwitchState> = 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<u16, ()>{
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<SwitchState, Self::Error> {
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<PackageModel>) {
let mut pcdu = PCDU::new(switch_rx, can_tx, can_rx);
loop{
pcdu.handle_power_requests().unwrap();
}
}