use std::{
fs,
path::PathBuf,
sync::{
atomic::{AtomicBool, Ordering},
Arc, Mutex,
},
time::Duration,
};
use chrono::Utc;
use log::info;
use rusty_tip::{ActionDriver, Job, Logger, SignalIndex, TipController};
fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
let driver = ActionDriver::new("127.0.0.1", 6501)?;
let mut custom_controller = TipController::new(driver, SignalIndex(76), 2.0, (-2.0, 0.0));
let file_path = create_log_file_path()?;
println!("{file_path:?}");
custom_controller
.set_pulse_stepping_fixed(1.5, 2.0, 4, 10.0)
.set_stability_threshold(5)
.with_logger(Logger::new(file_path, 5));
let running = Arc::new(AtomicBool::new(true));
let running_clone = Arc::clone(&running);
let controller = Arc::new(Mutex::new(custom_controller));
let controller_clone = Arc::clone(&controller);
ctrlc::set_handler(move || {
info!("Received Ctrl-C, signaling stop and flushing logger...");
running_clone.store(false, Ordering::SeqCst);
if let Ok(mut ctrl) = controller_clone.lock() {
match ctrl.flush_logger() {
Ok(()) => info!("Logger flushed successfully on exit"),
Err(e) => info!("Failed to flush logger on exit: {}", e),
}
}
})?;
let result: Result<(), Box<dyn std::error::Error>> = {
let mut ctrl = controller.lock().unwrap();
let mut total_elapsed = Duration::from_secs(0);
let max_duration = Duration::from_secs(1000);
let check_interval = Duration::from_secs(5);
while total_elapsed < max_duration && running.load(Ordering::SeqCst) {
let remaining = max_duration - total_elapsed;
let run_duration = check_interval.min(remaining);
match ctrl.run(run_duration) {
Ok(final_state) => {
info!("Controller finished with state: {:?}", final_state);
break;
}
Err(e) if e.to_string().contains("Loop timeout") => {
total_elapsed += run_duration;
if !running.load(Ordering::SeqCst) {
info!("Stop signal received, exiting gracefully");
break;
}
}
Err(e) => {
info!("Controller failed: {}", e);
break;
}
}
}
Ok(())
};
match result {
Ok(()) => {
info!("Controller loop completed");
}
Err(e) => {
info!("Controller loop failed: {}", e);
}
}
Ok(())
}
fn create_log_file_path() -> Result<PathBuf, Box<dyn std::error::Error>> {
let root_dir = std::env::current_dir()?;
let history_dir = root_dir.join("examples").join("history");
fs::create_dir_all(&history_dir)?;
let filename = format!("log_{}.jsonl", Utc::now().format("%Y%m%d_%H%M%S"));
let file_path = history_dir.join(filename);
Ok(file_path)
}