More robust serial transfer and error handling

This commit is contained in:
Данила Горнушко 2024-06-06 17:11:13 +03:00
parent 633a493ab1
commit b2f3f482bb
3 changed files with 57 additions and 192 deletions

131
Cargo.lock generated
View file

@ -99,12 +99,6 @@ version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "bytemuck"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5"
[[package]]
name = "cc"
version = "1.0.98"
@ -134,7 +128,7 @@ dependencies = [
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-targets 0.52.5",
"windows-targets",
]
[[package]]
@ -183,16 +177,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
[[package]]
name = "colored"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8"
dependencies = [
"lazy_static",
"windows-sys 0.48.0",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.6"
@ -224,16 +208,6 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "drawille"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e64e461c3f1e69d99372620640b3fd5f0309eeda2e26e4af69f6760c0e1df845"
dependencies = [
"colored",
"fnv",
]
[[package]]
name = "enable-ansi-support"
version = "0.2.1"
@ -252,19 +226,12 @@ dependencies = [
"log",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "hailsens_logger"
version = "1.0.0"
dependencies = [
"chrono",
"clap",
"colored",
"crc",
"ctrlc",
"enable-ansi-support",
@ -273,7 +240,6 @@ dependencies = [
"log",
"owo-colors",
"serialport",
"textplots",
]
[[package]]
@ -336,12 +302,6 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.155"
@ -460,15 +420,6 @@ version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
[[package]]
name = "rgb"
version = "0.8.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8"
dependencies = [
"bytemuck",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
@ -510,16 +461,6 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "textplots"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f59b64803118dbff62f92842b3154a2c802dfd8e18660132bbcbfb141c637ae3"
dependencies = [
"drawille",
"rgb",
]
[[package]]
name = "thiserror"
version = "1.0.61"
@ -643,7 +584,7 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
"windows-targets 0.52.5",
"windows-targets",
]
[[package]]
@ -661,37 +602,13 @@ dependencies = [
"windows_x86_64_msvc 0.42.2",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets 0.48.5",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets 0.52.5",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
"windows-targets",
]
[[package]]
@ -716,12 +633,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.5"
@ -734,12 +645,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.5"
@ -752,12 +657,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.5"
@ -776,12 +675,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.5"
@ -794,12 +687,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.5"
@ -812,12 +699,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.5"
@ -830,12 +711,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.5"

View file

@ -4,9 +4,9 @@ version = "1.0.0"
edition = "2021"
[dependencies]
serialport = {version="4.3", default-features=false}
serialport = {version = "4.3", default-features = false}
log = "0.4"
fern = "0.6"
fern = {version = "0.6", default-features = false }
enable-ansi-support = "0.2"
owo-colors = "4.0"
chrono = "0.4"
@ -14,5 +14,3 @@ hound = "3.5"
clap = { version = "4.5", features = ["derive"] }
ctrlc = "3.4"
crc = "3.2"
textplots = "0.8"
colored = { version = "2.1", features = ["no-color"] }

View file

@ -14,7 +14,6 @@ use std::sync::Arc;
use std::time::Duration;
use std::time::{SystemTime, UNIX_EPOCH};
use std::{fmt, panic, slice};
use textplots::{Chart, Plot, Shape};
const MAX_DATA_LEN: usize = 1024 * 2 + 4 + 2;
@ -98,10 +97,7 @@ struct Args {
#[arg(long)]
winsize: Option<u32>,
#[arg(long = "plot", help = "Plot data")]
plot_data: bool,
#[arg(long, default_value_t = 10, help = "Value in Hz")]
#[arg(long, default_value_t = 5, help = "Value in Hz")]
request_rate: u32,
#[arg(short = 'f', long)]
@ -239,16 +235,6 @@ fn init_logger(
};
root_dispatch.apply()?;
// Set panic hook to log panic messages
panic::set_hook(Box::new(|panic_info| {
let panic_str = "Hailsens logger stopped with panic";
if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
error!("{panic_str}: {:?}", s);
} else {
error!("{panic_str}");
}
}));
Ok(())
}
@ -282,7 +268,7 @@ fn main() {
return;
}
};
port.set_timeout(Duration::from_millis(30))
port.set_timeout(Duration::from_millis(100))
.expect("Couldn't set serial port timeout!");
let command = format!("@{} name\n", args.device_id);
match process_command(&mut port, command) {
@ -353,7 +339,7 @@ fn main() {
let mut prev_stats: Option<StatsOnDetect> = None;
let mut err_cnt: u32 = 0;
let mut success_cnt: u32 = 0;
let samples_needed = args.wavs_path.is_some() || args.plot_data;
let samples_needed = args.wavs_path.is_some();
let mut needed_retry = false;
let mut last_hour_value = Local::now().hour();
@ -375,7 +361,7 @@ fn main() {
StatsOptions::Stats(val) => {
success_cnt = success_cnt.saturating_add(1);
info!(target: "stats10min", "{val}");
},
}
StatsOptions::DetectedNew(cur_stats) => {
success_cnt = success_cnt.saturating_add(1);
if prev_stats.map_or(true, |v| v != cur_stats) {
@ -416,17 +402,6 @@ fn main() {
Some(data) => {
debug!("Received new data with len: {}", data.len());
if args.plot_data {
let points: Vec<(f32, f32)> = data
.iter()
.enumerate()
.map(|(i, &x)| (i as f32, x as f32))
.collect();
Chart::new(280, 50, 0.0, 100.0)
.lineplot(&Shape::Lines(&points))
.display();
}
if let Some(wav_path) = args.wavs_path.as_deref() {
let path = Path::new(wav_path);
let filename =
@ -434,22 +409,25 @@ fn main() {
let path = path.join(filename);
// Create a new WAV file
let mut writer = WavWriter::create(&path, spec)
.expect("Can't create new WAV file!");
let mut i16_writer = writer.get_i16_writer(data.len() as u32);
for sample in data {
unsafe {
i16_writer.write_sample_unchecked(sample);
if let Ok(mut writer) = WavWriter::create(&path, spec) {
let mut i16_writer =
writer.get_i16_writer(data.len() as u32);
for sample in data {
unsafe {
i16_writer.write_sample_unchecked(sample);
}
}
if let Err(e) = i16_writer.flush() {
error!("Failed to write WAV file: {}", e);
}
info!(
"Sample: {}. WAV file {} has been written.",
cur_stats.hail_since_startup,
path.display()
);
} else {
error!("Can't create new WAV file!");
}
i16_writer
.flush()
.expect("Something went wrong while writing WAV file");
info!(
"Sample: {}. WAV file {} has been written.",
cur_stats.hail_since_startup,
path.display()
);
}
success_cnt = success_cnt.saturating_add(1);
@ -478,13 +456,13 @@ fn print_error_stats(error_counter: u32, success_counter: u32) {
match (success_counter == 0, error_counter == 0) {
(true, true) => {
warn!("No transfers in the last hour!");
},
}
(true, false) => {
warn!("No successful transfers in the last hour!");
},
}
(false, true) => {
info!("No errors in the last hour!");
},
}
(false, false) => {
let transfers = success_counter + error_counter;
let err_ratio = (error_counter as f64 / transfers as f64) * 100.0;
@ -507,16 +485,20 @@ fn get_stats(port: &mut Box<dyn SerialPort>, id: u32) -> StatsOptions {
None => return StatsOptions::None,
};
let split: Vec<&str> = response.split_whitespace().collect();
let split: Vec<&str> = response.trim_matches(char::from(0)).split_whitespace().collect();
let mut nums: Vec<u32> = Vec::with_capacity(5);
for i in split {
match i.parse() {
let num: Result<u32, _> = i.parse();
match num {
Ok(num) => nums.push(num),
Err(_) => return StatsOptions::None,
Err(_) => {
debug!("Can't parse '{i}' as u32");
return StatsOptions::None
}
}
}
match nums.len() {
2 => StatsOptions::Stats(Stats10Min {
hail: nums[0],
@ -631,15 +613,19 @@ fn get_sample_rate(port: &mut Box<dyn SerialPort>, id: u32) -> u32 {
fn process_command(port: &mut Box<dyn SerialPort>, command: String) -> Option<String> {
trace!("Writing command to the serial port: {}", command);
port.write_all(command.as_bytes())
.expect("Failed to write to serial port!");
port.flush().expect("Failed to flush serial port!");
if let Err(e) = port.write_all(command.as_bytes()) {
error!("Failed to write to serial port!: {}", e);
return None;
}
if let Err(e) = port.flush() {
error!("Failed to flush serial port!: {}", e);
}
trace!("Waiting for response from the serial port...");
let mut reader = BufReader::new(port);
let mut response = String::new();
match reader.read_line(&mut response) {
Ok(_) => {
trace!("Received response from the serial port");
trace!("Received response from the serial port: {response}");
Some(response)
}
Err(ref e) if e.kind() == std::io::ErrorKind::TimedOut => {
@ -647,7 +633,8 @@ fn process_command(port: &mut Box<dyn SerialPort>, command: String) -> Option<St
None
}
Err(e) => {
panic!("Failed to read from serial port: {}", e);
error!("Failed to read from serial port: {}", e);
None
}
}
}
@ -676,9 +663,13 @@ fn get_chunk(
) -> Option<Vec<i16>> {
let command = format!("@{} convbuf\n", id);
trace!("Writing convbuf to the serial port");
port.write_all(command.as_bytes())
.expect("Failed to write to serial port!");
port.flush().expect("Failed to flush serial port!");
if let Err(e) = port.write_all(command.as_bytes()) {
error!("Failed to write to serial port!: {}", e);
return None;
}
if let Err(e) = port.flush() {
error!("Failed to flush serial port!: {}", e);
}
trace!("Waiting for response from the serial port...");
let mut adc_buffer: Vec<u8> = vec![0; MAX_DATA_LEN];
std::thread::sleep(calculate_timeout(baud_rate, exp_buf_size(win_size)));
@ -695,7 +686,8 @@ fn get_chunk(
return None;
}
Err(e) => {
panic!("Failed to read from serial port: {}", e);
error!("Failed to read from serial port: {}", e);
return None;
}
}
trace!("Checking header...");