134 lines
4.1 KiB
Rust
134 lines
4.1 KiB
Rust
use chrono::Local;
|
|
use clap::Parser;
|
|
use nmea::Nmea;
|
|
use nmea::SentenceType;
|
|
use std::time::Duration;
|
|
|
|
/// 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<String>,
|
|
|
|
/// Format
|
|
#[arg(short = 'f', long, default_value = "csv")]
|
|
format: Option<String>,
|
|
}
|
|
|
|
// Function to get the location
|
|
fn get_loc(port: String, fmt: String) -> String {
|
|
let mut nmea = Nmea::default();
|
|
|
|
// Harcode port for dev
|
|
//let port_name = "/dev/tty.usbmodem1301";
|
|
let port_name = port;
|
|
|
|
//fn read_loc(com: &str) -> &str {
|
|
//println!("Reading from {port_name}");
|
|
|
|
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(_) => {
|
|
break;
|
|
}
|
|
};
|
|
|
|
// Only keep the GLL sentences
|
|
if sentence_type == SentenceType::GLL {
|
|
let lat = match nmea.latitude {
|
|
Some(lat) => lat,
|
|
None => -9999.25,
|
|
};
|
|
let lon = match nmea.longitude {
|
|
Some(lon) => lon,
|
|
None => -9999.25,
|
|
};
|
|
let date = Local::now();
|
|
//println!("{}, {lat}, {lon}", date.format("%Y-%m-%d %H:%M:%S"));
|
|
if fmt == "csv" {
|
|
return format!(
|
|
"{},{:.8},{:.8}",
|
|
date.format("%Y-%m-%d %H:%M:%S"),
|
|
lat,
|
|
lon
|
|
);
|
|
} else if fmt == "ssv" {
|
|
return format!(
|
|
"\"{}\" {:.8} {:.8}",
|
|
date.format("%Y-%m-%d %H:%M:%S"),
|
|
lat,
|
|
lon
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Err(_) => {} // lol that I can just not put a return in?
|
|
}
|
|
}
|
|
} else {
|
|
// 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);
|
|
}
|
|
|
|
return format!("\nCould not connect to port. Is it listed above?");
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
// Arguments
|
|
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!()
|
|
};
|
|
|
|
let fmt = match cli.format {
|
|
Some(fmt) => fmt,
|
|
None => {
|
|
return;
|
|
} //todo!()
|
|
};
|
|
|
|
// Run the function
|
|
// Max rate is about 1 measurement per second
|
|
//loop {
|
|
let result = get_loc(com.clone(), fmt.clone());
|
|
println!("{result}");
|
|
//}
|
|
|
|
}
|