use nmea::Nmea; use nmea::SentenceType; use std::thread; use std::time::Duration; use clap::Parser; use chrono::Local; /// Command-line arguments using Clap. #[derive(Parser, Debug)] #[command(author, version, about = "A tool for echoing latitude and longitude from a GPS USB dongle.")] struct Cli { /// COM port #[arg(short = 'c', long)] com: Option, } fn main() { let cli = Cli::parse(); let com = match cli.com { Some(com) => com, None => { // https://github.com/serialport/serialport-rs#listing-available-ports let ports = serialport::available_ports().expect("No ports found!"); println!("Available Ports:"); for p in ports { println!("{}", p.port_name); } println!("\nMissing `-c` port argument, use one listed above."); return; } //todo!() } ; println!("Reading from {com:?}"); // Inifnite loop until I add controls while 1 == 1 { let mut nmea = Nmea::default(); // Harcode port for dev //let port_name = "/dev/tty.usbmodem1301"; let port_name = com.clone(); // Thread for GPS streaming thread::spawn(move || { let port = serialport::new(port_name, 9600) .timeout(Duration::from_millis(1000)) .open(); if let Ok(mut serial) = port { let mut buf = [0u8; 1024]; loop { match serial.read(&mut buf) { Ok(n) => { let data = String::from_utf8_lossy(&buf[..n]); for line in data.lines() { // Check sentence type let sentence_type = match nmea.parse(line) { Ok(sentence_type) => sentence_type, Err(_) => { return; } }; // Only keep the GLL sentences if sentence_type == SentenceType::GLL { let lat = match nmea.latitude { Some(lat) => lat, None => todo!() } ; let lon = match nmea.longitude { Some(lon) => lon, None => todo!() } ; let date = Local::now(); println!("{}, {lat}, {lon}", date.format("%Y-%m-%d %H:%M:%S")); } } } Err(_) => break, } } } }); } }