mirror of
https://github.com/italicsjenga/fh5-telemetry-watcher.git
synced 2024-12-23 14:11:33 +11:00
works way nicer
This commit is contained in:
parent
6561d70a38
commit
f47b37ac92
57
Cargo.lock
generated
57
Cargo.lock
generated
|
@ -46,12 +46,6 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-if"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.19"
|
version = "0.4.19"
|
||||||
|
@ -117,15 +111,6 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fastrand"
|
|
||||||
version = "1.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
|
|
||||||
dependencies = [
|
|
||||||
"instant",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fh5-common"
|
name = "fh5-common"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -165,15 +150,6 @@ dependencies = [
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "instant"
|
|
||||||
version = "0.1.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "0.4.8"
|
version = "0.4.8"
|
||||||
|
@ -268,30 +244,12 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "redox_syscall"
|
|
||||||
version = "0.2.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-automata"
|
name = "regex-automata"
|
||||||
version = "0.1.10"
|
version = "0.1.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "remove_dir_all"
|
|
||||||
version = "0.5.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
|
||||||
dependencies = [
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.9"
|
version = "1.0.9"
|
||||||
|
@ -345,21 +303,6 @@ dependencies = [
|
||||||
"csv",
|
"csv",
|
||||||
"fh5-common",
|
"fh5-common",
|
||||||
"serde",
|
"serde",
|
||||||
"tempfile",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tempfile"
|
|
||||||
version = "3.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"fastrand",
|
|
||||||
"libc",
|
|
||||||
"redox_syscall",
|
|
||||||
"remove_dir_all",
|
|
||||||
"winapi",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -11,5 +11,4 @@ serde = { version = "1.0", features = ["derive"] }
|
||||||
bincode = "1.3"
|
bincode = "1.3"
|
||||||
csv = "1.1"
|
csv = "1.1"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
tempfile = "3.3"
|
|
||||||
fh5-common = { path = "fh5-common", version="0.1" }
|
fh5-common = { path = "fh5-common", version="0.1" }
|
|
@ -1 +1 @@
|
||||||
Subproject commit eb2ee27c165ade2b356bb7e7edc225506b023b5e
|
Subproject commit d46772089f87b13268f1cf8da5bd61cad66eb7d9
|
136
src/main.rs
136
src/main.rs
|
@ -1,6 +1,7 @@
|
||||||
use fh5_common::{Filename, Telemetry};
|
use fh5_common::{Filename, Telemetry};
|
||||||
|
|
||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
|
use std::io::Write;
|
||||||
use std::net::UdpSocket;
|
use std::net::UdpSocket;
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
use std::os::unix::fs::OpenOptionsExt;
|
use std::os::unix::fs::OpenOptionsExt;
|
||||||
|
@ -10,7 +11,14 @@ use std::{fs, net};
|
||||||
use bincode;
|
use bincode;
|
||||||
use chrono::Local;
|
use chrono::Local;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use tempfile::tempfile;
|
|
||||||
|
macro_rules! verbose_print {
|
||||||
|
($args:expr, $($tts:tt)*) => {
|
||||||
|
if($args.verbose) {
|
||||||
|
println!($($tts)*);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[clap(author, version, about, long_about = None)]
|
#[clap(author, version, about, long_about = None)]
|
||||||
|
@ -26,10 +34,15 @@ struct Args {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Status {
|
struct Status {
|
||||||
inrace: bool,
|
next: Option<NextFile>,
|
||||||
position: u8,
|
position: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct NextFile {
|
||||||
|
writer: csv::Writer<Vec<u8>>,
|
||||||
|
name: Filename,
|
||||||
|
}
|
||||||
|
|
||||||
fn listen(socket: &net::UdpSocket, mut buffer: &mut [u8]) -> usize {
|
fn listen(socket: &net::UdpSocket, mut buffer: &mut [u8]) -> usize {
|
||||||
let number_of_bytes = match socket.recv_from(&mut buffer) {
|
let number_of_bytes = match socket.recv_from(&mut buffer) {
|
||||||
Ok((num, _)) => num,
|
Ok((num, _)) => num,
|
||||||
|
@ -45,7 +58,11 @@ fn listen(socket: &net::UdpSocket, mut buffer: &mut [u8]) -> usize {
|
||||||
fn main() {
|
fn main() {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
let ip = format!("0.0.0.0:{}", args.port.to_string());
|
let ip = format!("0.0.0.0:{}", args.port.to_string());
|
||||||
|
verbose_print!(
|
||||||
|
args,
|
||||||
|
"{}: Starting server",
|
||||||
|
&Local::now().format("%H:%M:%S").to_string()
|
||||||
|
);
|
||||||
if args.folder != "" {
|
if args.folder != "" {
|
||||||
println!("Saving logs to {}", args.folder);
|
println!("Saving logs to {}", args.folder);
|
||||||
} else {
|
} else {
|
||||||
|
@ -58,13 +75,11 @@ fn main() {
|
||||||
println!("Listening on port {}", args.port);
|
println!("Listening on port {}", args.port);
|
||||||
let mut buf = [0; 2048];
|
let mut buf = [0; 2048];
|
||||||
|
|
||||||
let mut writer = csv::Writer::from_writer(tempfile().expect("couldnt open tempfile"));
|
// let mut writer = csv::Writer::from_writer(tempfile().expect("couldnt open tempfile"));
|
||||||
|
|
||||||
let mut status = Status {
|
let mut status = Status {
|
||||||
inrace: false,
|
next: None,
|
||||||
position: 0,
|
position: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
'listener: while listen(&socket, &mut buf) != 0 {
|
'listener: while listen(&socket, &mut buf) != 0 {
|
||||||
let deserialised: Telemetry = bincode::deserialize(&buf).expect("error parsing packet");
|
let deserialised: Telemetry = bincode::deserialize(&buf).expect("error parsing packet");
|
||||||
if deserialised.is_race_on == 0 {
|
if deserialised.is_race_on == 0 {
|
||||||
|
@ -73,58 +88,63 @@ fn main() {
|
||||||
|
|
||||||
if status.position != deserialised.race_position {
|
if status.position != deserialised.race_position {
|
||||||
status.position = deserialised.race_position;
|
status.position = deserialised.race_position;
|
||||||
if args.verbose {
|
verbose_print!(args, "now position {}", status.position);
|
||||||
println!("now position {}", status.position);
|
}
|
||||||
|
// status.next.
|
||||||
|
if deserialised.race_position == 0 {
|
||||||
|
status.next.take().and_then(|next| -> Option<NextFile> {
|
||||||
|
verbose_print!(
|
||||||
|
args,
|
||||||
|
"{}: no longer in race",
|
||||||
|
&Local::now().format("%H:%M:%S").to_string()
|
||||||
|
);
|
||||||
|
finish_race(&args, next);
|
||||||
|
None
|
||||||
|
});
|
||||||
|
}
|
||||||
|
match status.next {
|
||||||
|
Some(ref mut next) => {
|
||||||
|
continue_race(&deserialised, &mut next.writer);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
if deserialised.race_position > 0 {
|
||||||
|
verbose_print!(
|
||||||
|
args,
|
||||||
|
"{}: entering race\ncar class: {}",
|
||||||
|
&Local::now().format("%H:%M:%S").to_string(),
|
||||||
|
deserialised.car_performance_index
|
||||||
|
);
|
||||||
|
let mut new_next = begin_race(&deserialised);
|
||||||
|
continue_race(&deserialised, &mut new_next.writer);
|
||||||
|
status.next = Some(new_next);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if status.inrace {
|
|
||||||
if deserialised.race_position == 0 {
|
|
||||||
// coming out of race
|
|
||||||
status.inrace = false;
|
|
||||||
writer.flush().expect("couldnt flush to file");
|
|
||||||
if args.verbose {
|
|
||||||
println!(
|
|
||||||
"{}: no longer in race",
|
|
||||||
&Local::now().format("%H:%M:%S").to_string()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
continue 'listener;
|
|
||||||
} else {
|
|
||||||
// still in race
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if deserialised.race_position > 0 {
|
|
||||||
// getting into race
|
|
||||||
status.inrace = true;
|
|
||||||
if args.verbose {
|
|
||||||
println!(
|
|
||||||
"{}: entering race",
|
|
||||||
&Local::now().format("%H:%M:%S").to_string()
|
|
||||||
);
|
|
||||||
println!("car class: {}", deserialised.car_performance_index);
|
|
||||||
}
|
|
||||||
let mut options = OpenOptions::new().write(true).create_new(true).clone();
|
|
||||||
// open file with wide open permissions on unix systems
|
|
||||||
if cfg!(target_family = "unix") {
|
|
||||||
options.mode(0o777);
|
|
||||||
}
|
|
||||||
// open file for this race
|
|
||||||
// filename format: timestamp _ car class _ car ordinal
|
|
||||||
let name = Filename::new_filename(
|
|
||||||
deserialised.car_performance_index,
|
|
||||||
deserialised.car_ordinal,
|
|
||||||
);
|
|
||||||
writer = csv::Writer::from_writer(
|
|
||||||
options
|
|
||||||
.open(folder_path.join(format!("{}{}", name.get_string(), ".csv",)))
|
|
||||||
.expect("couldnt open file"),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// still not in race
|
|
||||||
continue 'listener;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writer.serialize(deserialised).expect("couldnt serialise");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn begin_race(deserialised: &Telemetry) -> NextFile {
|
||||||
|
NextFile {
|
||||||
|
writer: csv::Writer::from_writer(vec![]),
|
||||||
|
name: Filename::new_filename(deserialised.car_performance_index, deserialised.car_ordinal),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn finish_race(args: &Args, next: NextFile) {
|
||||||
|
let mut options = OpenOptions::new().write(true).create_new(true).clone();
|
||||||
|
// open file with wide open permissions on unix systems
|
||||||
|
if cfg!(target_family = "unix") {
|
||||||
|
options.mode(0o777);
|
||||||
|
}
|
||||||
|
// open file for this race
|
||||||
|
let filename = format!("{}/{}.csv", args.folder, next.name.get_string());
|
||||||
|
verbose_print!(args, "Opening file {}", filename);
|
||||||
|
let mut filewriter = options.open(filename).expect("failed to open file");
|
||||||
|
let a = next.writer.into_inner().unwrap();
|
||||||
|
filewriter.write_all(&a).unwrap();
|
||||||
|
filewriter.flush().expect("could not flush file");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn continue_race(deserialised: &Telemetry, writer: &mut csv::Writer<Vec<u8>>) {
|
||||||
|
writer.serialize(deserialised).expect("couldnt serialise");
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue