use log::{error, info}; use tokio::select; use tokio::sync::mpsc::Receiver; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; use crate::icd; use crate::client::WorkbookClient; use crate::plot::TimeSeriesPlot; use crate::signals::FrequencySignal; pub async fn communicate_with_hardware( mut run_impedancemeter_rx: Receiver, magnitude: Arc>, phase: Arc>, magnitude_series: Arc>, phase_series: Arc>, connected: Arc, ) { loop { let workbook_client = match WorkbookClient::new() { Ok(client) => { info!("Connected to hardware successfully."); connected.store(true, Ordering::Relaxed); client }, Err(e) => { error!("Failed to connect to hardware: {:?}", e); tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; continue; } }; let mut sub = workbook_client .client .subscribe_multi::(8) .await .unwrap(); let data = (magnitude_series.clone(), phase_series.clone(), magnitude.clone(), phase.clone()); tokio::spawn(async move { while let Ok(val) = sub.recv().await { let mut mag_plot = data.0.lock().unwrap(); let mut phase_plot = data.1.lock().unwrap(); let mut mag_val = data.2.lock().unwrap(); let mut phase_val = data.3.lock().unwrap(); *mag_val = val.magnitude; *phase_val = val.phase; mag_plot.add(val.magnitude as f64); phase_plot.add(val.phase as f64); } info!("ImpedanceTopic subscription ended."); }); loop { select! { Some(frequency) = run_impedancemeter_rx.recv() => { match frequency { FrequencySignal::Start(freq) => { if let Err(e) = workbook_client.start_impedancemeter(freq).await { error!("Failed to start impedancemeter: {:?}", e); } else { info!("Impedancemeter started at frequency: {}", freq); } }, FrequencySignal::Stop => { if let Err(e) = workbook_client.stop_impedancemeter().await { error!("Failed to stop impedancemeter: {:?}", e); } else { info!("Impedancemeter stopped."); } }, } } _ = workbook_client.wait_closed() => { // Handle client closure info!("Client connection closed."); break; } else => { // All channels closed break; } } } info!("Communication with hardware ended."); connected.store(false, Ordering::Relaxed); tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; } }