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();
|
|
|
|
}
|
|
|
|
}
|