eurosim-obsw/src/power_handler.rs

233 lines
7.4 KiB
Rust
Raw Normal View History

2023-02-07 16:45:00 +01:00
use crate::can_ids::{DeviceId, PackageId, PackageModel};
2023-02-15 14:57:43 +01:00
use log::{debug};
use satrs_core::power::{
PowerSwitchInfo, PowerSwitchProvider, PowerSwitcherCommandSender, SwitchId, SwitchState,
};
use std::collections::HashMap;
2023-02-07 16:45:00 +01:00
use std::convert::TryFrom;
use std::sync::mpsc::{Receiver, Sender};
2023-02-09 15:38:32 +01:00
use std::sync::{Arc, Mutex};
2023-02-07 16:45:00 +01:00
use std::time::Duration;
2023-02-09 15:38:32 +01:00
use std::vec;
2023-02-07 16:45:00 +01:00
pub use strum::IntoEnumIterator; // 0.17.1
pub use strum_macros::EnumIter; // 0.17.1
#[derive(Copy, Clone, Debug, PartialEq, EnumIter)]
2023-02-07 16:45:00 +01:00
pub enum DeviceState {
On,
Off,
SwitchingPower,
Setup,
Idle,
}
2023-02-09 15:38:32 +01:00
#[derive(Clone)]
pub struct PowerSwitcher {
switch_tx: Sender<(SwitchId, SwitchState)>,
device_state_map: Arc<Mutex<HashMap<DeviceId, SwitchState>>>,
}
2023-02-07 16:45:00 +01:00
pub struct PCDU {
switch_rx: Receiver<(SwitchId, SwitchState)>,
can_tx: Sender<PackageModel>,
2023-02-07 16:45:00 +01:00
can_rx: Receiver<PackageModel>,
2023-02-09 15:38:32 +01:00
device_state_map: Arc<Mutex<HashMap<DeviceId, SwitchState>>>,
2023-02-07 16:45:00 +01:00
}
2023-02-09 15:38:32 +01:00
impl PowerSwitcher {
pub fn new(
switch_tx: Sender<(SwitchId, SwitchState)>,
device_state_map: Arc<Mutex<HashMap<DeviceId, SwitchState>>>,
) -> PowerSwitcher {
PowerSwitcher {
switch_tx,
device_state_map,
}
2023-02-09 15:38:32 +01:00
}
}
impl PowerSwitcherCommandSender for PowerSwitcher {
type Error = ();
fn send_switch_on_cmd(&mut self, switch_id: SwitchId) -> Result<(), Self::Error> {
return match self.switch_tx.send((switch_id, SwitchState::On)) {
Ok(_) => Ok(()),
Err(_) => Err(()),
};
2023-02-09 15:38:32 +01:00
}
2023-02-07 16:45:00 +01:00
2023-02-09 15:38:32 +01:00
fn send_switch_off_cmd(&mut self, switch_id: SwitchId) -> Result<(), Self::Error> {
return match self.switch_tx.send((switch_id, SwitchState::Off)) {
Ok(_) => Ok(()),
Err(_) => Err(()),
};
2023-02-07 16:45:00 +01:00
}
2023-02-09 15:38:32 +01:00
}
2023-02-07 16:45:00 +01:00
2023-02-09 15:38:32 +01:00
impl PowerSwitchInfo for PowerSwitcher {
type Error = ();
fn get_switch_state(&mut self, switch_id: SwitchId) -> Result<SwitchState, Self::Error> {
let map_locked = self.device_state_map.lock().unwrap();
if let Ok(dev_id) = DeviceId::try_from(switch_id) {
return if let Some(state) = map_locked.get(&dev_id) {
Ok(*state)
} else {
Err(())
};
2023-02-09 15:38:32 +01:00
} else {
Err(())
2023-02-07 16:45:00 +01:00
}
}
2023-02-09 15:38:32 +01:00
fn switch_delay_ms(&self) -> u32 {
0
}
2023-02-07 16:45:00 +01:00
}
2023-02-09 15:38:32 +01:00
impl PowerSwitchProvider for PowerSwitcher {
2023-02-07 16:45:00 +01:00
type Error = ();
2023-02-09 15:38:32 +01:00
}
2023-02-07 16:45:00 +01:00
2023-02-09 15:38:32 +01:00
impl PCDU {
pub fn new(
switch_rx: Receiver<(SwitchId, SwitchState)>,
can_tx: Sender<PackageModel>,
can_rx: Receiver<PackageModel>,
device_state_map: Arc<Mutex<HashMap<DeviceId, SwitchState>>>,
) -> PCDU {
PCDU {
switch_rx,
can_tx,
can_rx,
device_state_map,
}
2023-02-09 15:38:32 +01:00
}
pub fn send_power_on(&mut self, switch_id: SwitchId) -> Result<(), ()> {
return if let Ok(dev_id) = DeviceId::try_from(switch_id) {
let dev_id_bytes = dev_id as u8;
let buf: &[u8] = &dev_id_bytes.to_be_bytes();
2023-02-15 14:02:05 +01:00
self.can_tx.send(PackageModel::new(PackageId::DevicePowerOnRequest, buf).unwrap()).unwrap();
2023-02-09 15:38:32 +01:00
let mut map_lock = self.device_state_map.lock().unwrap();
*map_lock.get_mut(&dev_id).unwrap() = SwitchState::Unknown;
// TODO: potentially change bus logic -> remove acceptance and verification of power off/on, since status is simply called in next step anyway
2023-02-15 14:02:05 +01:00
self.can_rx.recv().unwrap();
self.can_rx.recv().unwrap();
2023-02-09 15:38:32 +01:00
Ok(())
} else {
Err(())
};
2023-02-07 16:45:00 +01:00
}
2023-02-09 15:38:32 +01:00
pub fn send_power_off(&mut self, switch_id: SwitchId) -> Result<(), ()> {
return if let Ok(dev_id) = DeviceId::try_from(switch_id) {
let dev_id_bytes = dev_id as u8;
let buf: &[u8] = &dev_id_bytes.to_be_bytes();
2023-02-15 14:02:05 +01:00
self.can_tx.send(PackageModel::new(PackageId::DevicePowerOffRequest, buf).unwrap()).unwrap();
2023-02-09 15:38:32 +01:00
let mut map_lock = self.device_state_map.lock().unwrap();
*map_lock.get_mut(&dev_id).unwrap() = SwitchState::Unknown;
2023-02-15 14:02:05 +01:00
self.can_rx.recv().unwrap();
self.can_rx.recv().unwrap();
2023-02-09 15:38:32 +01:00
Ok(())
} else {
Err(())
};
2023-02-09 15:38:32 +01:00
}
pub fn update_states_helper(&mut self, dev_id: &DeviceId) -> Result<(), ()> {
2023-02-15 14:02:05 +01:00
let _switch_id: SwitchId = *dev_id as u16;
2023-02-09 15:38:32 +01:00
let dev_id_bytes = *dev_id as u8;
let buf: &[u8] = &dev_id_bytes.to_be_bytes();
2023-02-15 14:02:05 +01:00
self.can_tx.send(PackageModel::new(PackageId::DevicePowerStatusRequest, buf).unwrap()).unwrap();
2023-02-09 15:38:32 +01:00
match self.can_rx.recv_timeout(Duration::from_secs(10)) {
Ok(msg) => {
if msg.package_id() == PackageId::DevicePowerStatusResponse
&& msg.data()[0] == dev_id_bytes
{
2023-02-15 14:57:43 +01:00
debug!("received power status response");
2023-02-09 15:38:32 +01:00
let mut map_lock = self.device_state_map.lock().unwrap();
2023-02-15 14:02:05 +01:00
let state: SwitchState;
2023-02-09 15:38:32 +01:00
match msg.data()[1] {
0 => state = SwitchState::Off,
1 => state = SwitchState::On,
2 => state = SwitchState::Faulty,
2023-02-09 15:38:32 +01:00
_ => {
return Err(());
2023-02-07 16:45:00 +01:00
}
}
2023-02-09 15:38:32 +01:00
*map_lock.get_mut(&dev_id).unwrap() = state;
2023-02-15 14:57:43 +01:00
debug!("{:?}", map_lock);
2023-02-09 15:38:32 +01:00
Ok(())
2023-02-07 16:45:00 +01:00
} else {
Err(())
}
}
Err(_) => Err(()),
2023-02-07 16:45:00 +01:00
}
}
2023-02-09 15:38:32 +01:00
pub fn update_all_states_helper(&mut self) -> Result<(), ()> {
2023-02-15 14:02:05 +01:00
let map_lock = self.device_state_map.lock().unwrap();
2023-02-09 15:38:32 +01:00
let mut device_list = vec::Vec::new();
for key in map_lock.keys() {
device_list.push(key.clone());
}
drop(map_lock);
for dev_id in device_list {
self.update_states_helper(&dev_id)?;
}
Ok(())
}
pub fn update_switch_states(&mut self, switch_id: SwitchId) -> Result<(), ()> {
return if let Ok(dev_id) = DeviceId::try_from(switch_id) {
match dev_id {
DeviceId::All => self.update_all_states_helper(),
_ => self.update_states_helper(&dev_id),
2023-02-07 16:45:00 +01:00
}
} else {
Err(())
};
2023-02-07 16:45:00 +01:00
}
pub fn handle_power_requests(&mut self) -> Result<u16, ()> {
2023-02-09 15:38:32 +01:00
let mut i = 0;
while let Ok((switch_id, switch_state)) = self.switch_rx.recv() {
match switch_state {
SwitchState::Off => match self.send_power_off(switch_id) {
Ok(_) => {
i = i + 1;
2023-02-09 15:38:32 +01:00
}
Err(_) => {
return Err(());
2023-02-09 15:38:32 +01:00
}
},
SwitchState::On => match self.send_power_on(switch_id) {
Ok(_) => {
i = i + 1;
}
Err(_) => {
return Err(());
}
},
2023-02-09 15:38:32 +01:00
_ => {}
}
2023-02-15 14:02:05 +01:00
self.update_switch_states(switch_id).unwrap();
2023-02-09 15:38:32 +01:00
}
return Ok(i);
2023-02-07 16:45:00 +01:00
}
}
pub fn core_power_task(
switch_rx: Receiver<(SwitchId, SwitchState)>,
can_tx: Sender<PackageModel>,
can_rx: Receiver<PackageModel>,
device_state_map: Arc<Mutex<HashMap<DeviceId, SwitchState>>>,
) {
2023-02-09 15:38:32 +01:00
let mut pcdu = PCDU::new(switch_rx, can_tx, can_rx, device_state_map);
loop {
2023-02-07 16:45:00 +01:00
pcdu.handle_power_requests().unwrap();
}
}