eurosim-obsw/src/pcdu.rs

225 lines
7.3 KiB
Rust
Raw Normal View History

2023-02-07 16:45:00 +01:00
use std::collections::HashMap;
2023-02-09 15:38:32 +01:00
use std::sync::mpsc::{Receiver, Sender};
use satrs_core::power::{PowerSwitcherCommandSender, PowerSwitchInfo, PowerSwitchProvider, SwitchId, SwitchState};
use crate::can::{CanTxHandler};
2023-02-07 16:45:00 +01:00
use crate::can_ids::{DeviceId, PackageId, PackageModel};
use std::convert::TryFrom;
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;
use log::info;
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)]
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: CanTxHandler,
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}
}
}
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-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
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-07 16:45:00 +01:00
}
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
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: CanTxHandler, can_rx: Receiver<PackageModel>, device_state_map: Arc<Mutex<HashMap<DeviceId, SwitchState>>>) -> PCDU{
PCDU{switch_rx, can_tx, can_rx, device_state_map}
}
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();
self.can_tx.tx_socket(PackageId::DevicePowerOnRequest, buf);
let mut map_lock = self.device_state_map.lock().unwrap();
*map_lock.get_mut(&dev_id).unwrap() = SwitchState::Unknown;
self.can_rx.recv();
self.can_rx.recv();
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();
self.can_tx.tx_socket(PackageId::DevicePowerOffRequest, buf);
let mut map_lock = self.device_state_map.lock().unwrap();
*map_lock.get_mut(&dev_id).unwrap() = SwitchState::Unknown;
self.can_rx.recv();
self.can_rx.recv();
Ok(())
} else {
Err(())
}
}
pub fn update_states_helper(&mut self, dev_id: &DeviceId) -> Result<(), ()> {
let switch_id: SwitchId = *dev_id as u16;
let dev_id_bytes = *dev_id as u8;
let buf: &[u8] = &dev_id_bytes.to_be_bytes();
self.can_tx.tx_socket(PackageId::DevicePowerStatusRequest, buf);
match self.can_rx.recv_timeout(Duration::from_secs(10)) {
Ok(msg) => {
if msg.package_id() == PackageId::DevicePowerStatusResponse && msg.data()[0] == dev_id_bytes{
info!("received power status response");
let mut map_lock = self.device_state_map.lock().unwrap();
let mut state: SwitchState;
match msg.data()[1] {
0 => {
state = SwitchState::Off
},
1 => {
state = SwitchState::On
},
2 => {
state = SwitchState::Faulty
},
_ => {
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;
info!("{:?}", map_lock);
Ok(())
2023-02-07 16:45:00 +01:00
} else {
Err(())
}
}
2023-02-09 15:38:32 +01:00
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
pub fn update_all_states_helper(&mut self) -> Result<(), ()> {
let mut map_lock = self.device_state_map.lock().unwrap();
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-09 15:38:32 +01:00
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_power_off(switch_id) {
Ok(_) => {
i = i + 1;
}
Err(_) => {
return Err(());
}
}
}
SwitchState::On => {
match self.send_power_on(switch_id) {
Ok(_) => {
i = i + 1;
}
Err(_) => {
return Err(());
}
}
}
_ => {}
}
self.update_switch_states(switch_id);
}
return Ok(i);
2023-02-07 16:45:00 +01:00
}
}
2023-02-09 15:38:32 +01:00
pub fn core_power_task(switch_rx: Receiver<(SwitchId, SwitchState)>, can_tx: CanTxHandler, can_rx: Receiver<PackageModel>, device_state_map: Arc<Mutex<HashMap<DeviceId, SwitchState>>>) {
let mut pcdu = PCDU::new(switch_rx, can_tx, can_rx, device_state_map);
2023-02-07 16:45:00 +01:00
loop{
pcdu.handle_power_requests().unwrap();
}
}