tweaking to fix misc. fake pic errors

This commit is contained in:
2024-11-03 15:29:40 -05:00
parent 045237d44f
commit 26cd5584e9
5 changed files with 223 additions and 75 deletions

View File

@ -26,6 +26,7 @@ pub enum Commands {
FPicLockout,
FPicFault {data: Arc<String>}, // String is cause. Send empty string to clear fault.
FPicLimit {data: Limits},
FPicOutput,
// TODO: real hardware buttons - consider re-sending occasionally when pressed, so that transitions like holding up -> stopping -> holding down -> stopped -> (should go down but gets no new notice) work.

View File

@ -49,6 +49,7 @@ impl FakePic {
Commands::PairTimerExpired,
Commands::StopTimerExpired,
Commands::ButtonTimerExpired,
Commands::FPicOutput,
];
FakePic {
motor_state: Motors{
@ -99,11 +100,11 @@ impl FakePic {
Ok(())
}
pub async fn press_up(&mut self) -> Result<()> {
if self.status_state.union(Statuses::PANIC).is_empty() || self.status_state.union(Statuses::LOCKOUT).is_empty(){
if !self.status_state.intersection(Statuses::PANIC| Statuses::LOCKOUT).is_empty() {
warn!("Ignoring commands while in panic or lockout mode!")
}
if self.motor_state.are_cooldown() {
info!("Ignoring commands while motors cool down")
else if self.motor_state.are_cooldown() {
warn!("Ignoring commands while motors cool down")
}
else if self.motor_state.going_down() {
warn!("Reversing from down to up; entering cooldown!");
@ -120,11 +121,11 @@ impl FakePic {
Ok(())
}
pub async fn press_down(&mut self) -> Result<()> {
if self.status_state.union(Statuses::PANIC).is_empty() || self.status_state.union(Statuses::LOCKOUT).is_empty() {
if !self.status_state.intersection(Statuses::PANIC| Statuses::LOCKOUT).is_empty() {
warn!("Ignoring commands while in panic or lockout mode!")
}
else if self.motor_state.are_cooldown() {
info!("Ignoring commands while motors cool down")
warn!("Ignoring commands while motors cool down")
}
else if self.motor_state.going_up() {
warn!("Reversing from up to down; entering cooldown!");
@ -143,18 +144,25 @@ impl FakePic {
pub async fn press_stop(&mut self) -> Result<()> {
self.motor_state.stop();
self.send_q.send(Commands::BluetoothStatusMotor { data: self.motor_state }).await?;
//self.send_q.send(Commands::ButtonTimerClear).await?; // Stop waiting on button timeouts
Ok(())
}
pub async fn toggle_panic(&mut self) -> Result<()> {
self.status_state ^= Statuses::PANIC;
self.status_state = self.status_state.symmetric_difference(Statuses::PANIC);
if self.status_state.intersection(Statuses::PANIC).is_empty(){
warn!("Clearing Panic status")
} else {
warn!("Entering panic status")
}
self.motor_state.stop();
self.send_q.send(Commands::BluetoothStatusStatus { data: self.status_state }).await?;
self.send_q.send(Commands::BluetoothStatusMotor { data: self.motor_state }).await?;
//self.send_q.send(Commands::BluetoothStatusMotor { data: self.motor_state }).await?;
Ok(())
}
pub async fn lockout(&mut self) -> Result<()> {
self.status_state &= Statuses::LOCKOUT; // No toggle; lockout can only be cleared by reboot per spec
self.motor_state.stop();
warn!("Locking out all movement controls until device is reset!");
self.send_q.send(Commands::BluetoothStatusStatus { data: self.status_state }).await?;
self.send_q.send(Commands::BluetoothStatusMotor { data: self.motor_state }).await?;
Ok(())
@ -167,6 +175,7 @@ impl FakePic {
}
self.fault_cause = cause;
self.send_q.send(Commands::BluetoothStatusStatus { data: self.status_state }).await?;
self.send_q.send(Commands::BluetoothStatusReason { data: Arc::new(self.fault_cause.clone())}).await?;
Ok(())
}
pub async fn change_limit(&mut self, limits: Limits) -> Result<()> {
@ -182,55 +191,91 @@ impl FakePic {
// === Handle events from event manager =====================================================
pub async fn run(&mut self) -> Result<()> {
let cmd = self.recv_q.recv().await.expect("PIC simulator failed waiting for messages");
match cmd {
// Commands from testing and user
Commands::FPicToggleAux => {self.toggle_aux().await}
Commands::FPicToggleAuto => {self.toggle_auto().await}
Commands::FPicPressLearn => {self.press_learn().await}
Commands::FPicPressUp => {self.press_up().await}
Commands::FPicPressDown => {self.press_down().await}
Commands::FPicPressStop => {self.press_stop().await}
Commands::FPicTogglePanic => {self.toggle_panic().await}
Commands::FPicLockout => {self.lockout().await}
Commands::FPicFault{data} => {self.fault(data.to_string()).await}
Commands::FPicLimit { data } => {self.change_limit(data).await}
// Commands from bluetooth
Commands::BluetoothAuto { data } => {
if data.is_pressed() {
self.toggle_auto().await?;
} Ok(())
loop {
let cmd = self.recv_q.recv().await.expect("PIC simulator failed waiting for messages");
match cmd {
// Commands from testing and user
Commands::FPicToggleAux => {self.toggle_aux().await?}
Commands::FPicToggleAuto => {self.toggle_auto().await?}
Commands::FPicPressLearn => {self.press_learn().await?}
Commands::FPicPressUp => {self.press_up().await?}
Commands::FPicPressDown => {self.press_down().await?}
Commands::FPicPressStop => {self.press_stop().await?}
Commands::FPicTogglePanic => {self.toggle_panic().await?}
Commands::FPicLockout => {self.lockout().await?}
Commands::FPicFault{data} => {self.fault(data.to_string()).await?}
Commands::FPicLimit { data } => {self.change_limit(data).await?}
// Commands from bluetooth
Commands::BluetoothAuto { data } => {
if data.is_pressed() {
self.toggle_auto().await?;
}
}
Commands::BluetoothAux { data } => {
if data.is_pressed() {
self.toggle_aux().await?;
}
}
Commands::BluetoothLearn { data } => {
if data.is_pressed() {
self.press_learn().await?;
}
}
Commands::BluetoothUp { data } => {
if data.is_pressed() {
self.press_up().await?;
} else {
self.press_stop().await?; // Releasing up is equivalent to stop
}
}
Commands::BluetoothDown { data } => {
if data.is_pressed() {
self.press_down().await?;
} else {
self.press_stop().await?; // Releasing down is equivalent to stop
}
}
Commands::BluetoothStop { .. } => {self.press_stop().await?} // Stopping on release of stop button is a noop but safe.
// Commands from timers
Commands::PairTimerExpired => {self.exit_learn().await?}
Commands::StopTimerExpired => {self.exit_cooldown().await?}
Commands::ButtonTimerExpired => {self.press_stop().await?}
Commands::FPicOutput => {
warn!("== Fake PIC internal state ==---------------");
if self.status_state.intersection(Statuses::LOCKOUT).is_empty() {
info!("Lockout flag: Off");
} else {
error!("Lockout flag: On");
}
if self.status_state.intersection(Statuses::PANIC).is_empty() {
info!("Panic flag: Off");
} else {
warn!("Panic flag: On");
}
if self.status_state.intersection(Statuses::FAULT).is_empty() {
info!("Fault flag: Off");
} else {
warn!("Fault flag: On");
}
if self.status_state.intersection(Statuses::LEARN).is_empty() {
info!("Learn flag: Off");
} else {
info!("Learn flag: On");
}
if self.status_state.intersection(Statuses::AUTO).is_empty() {
info!("Auto flag: Off");
} else {
info!("Auto flag: On");
}
if self.status_state.intersection(Statuses::AUX).is_empty() {
info!("Aux flag: Off");
} else {
warn!("Aux flag: On");
}
warn!("==------------------------------------------");
}
_ => {warn!("Unknown command received by Fake PIC simulator!");}
}
Commands::BluetoothAux { data } => {
if data.is_pressed() {
self.toggle_aux().await?;
} Ok(())
}
Commands::BluetoothLearn { data } => {
if data.is_pressed() {
self.press_learn().await?;
} Ok(())
}
Commands::BluetoothUp { data } => {
if data.is_pressed() {
self.press_up().await?;
} else {
self.press_stop().await?; // Releasing up is equivalent to stop
} Ok(())
}
Commands::BluetoothDown { data } => {
if data.is_pressed() {
self.press_down().await?;
} else {
self.press_stop().await?; // Releasing down is equivalent to stop
} Ok(())
}
Commands::BluetoothStop { .. } => {self.press_stop().await} // Stopping on release of stop button is a noop but safe.
// Commands from timers
Commands::PairTimerExpired => {self.exit_learn().await}
Commands::StopTimerExpired => {self.exit_cooldown().await}
Commands::ButtonTimerExpired => {self.press_stop().await}
_ => {warn!("Unknown command received by Fake PIC simulator!"); Ok(())}
}
}