//! Code Name rama - Rede an mein Auto use std::io::{Write, Read}; use std::process::{Command, Stdio}; use std::collections::HashMap; use std::thread::sleep; use std::time::{Duration, Instant}; const NEW_TEXT: &str = "NEW"; const CHANGED_TEXT: &str = " * "; const OLD_TEXT: &str = " "; fn main() { sudo::escalate_if_needed().unwrap(); let user_message_timeout = Duration::from_secs(10); let cmd = "candump"; let args = ["can0"]; //let mut db: HashMap> = HashMap::new(); let mut db = HashMap::new(); let mut db_last = HashMap::new(); let command = Command::new(cmd) .args(args.iter()) .stdout(Stdio::piped()) .spawn(); let mut zero_read_count = 0usize; let mut last_user_message = Instant::now(); let mut last_can_data = Instant::now(); if let Ok(mut child) = command { let stdout = child.stdout.as_mut().expect("Failed to open stdout"); //let mut buf = String::new(); let mut i = 0usize; loop { //debug!("DBG start"); let mut buffer = [0; 1024]; let len = stdout.read(&mut buffer).expect("unable to read"); zero_read_count = if len == 0 { zero_read_count + 1 } else { last_can_data = Instant::now(); 0 }; //debug!("DBG read"); if zero_read_count > 50 { eprintln!("unable to read for {} cycles. Aborting!", zero_read_count); break; } let latest = String::from_utf8_lossy(&buffer[0..len]); //buf += latest; for line in latest.lines() { let mut parts = line.trim().split(" "); let (_dev, id, _len, data) = (parts.next().expect("no dev") , parts.next().expect("no id") , parts.next().expect("no len") , parts.next().expect("no data")); //db.entry(id.to_string()).or_insert(data.to_string()); db.insert(id.to_string(), data.to_string()); } if db_last != db { println!("{} (len: {}):", i, db.len()); let mut db_sorted = db.iter().collect::>(); db_sorted.sort(); for e in db_sorted { let new_text = if db_last.contains_key(e.0) { if db_last[e.0] == *e.1 { OLD_TEXT } else { CHANGED_TEXT } } else {NEW_TEXT}; println!("{} {}: {}", new_text, e.0, e.1); last_user_message = Instant::now(); } } i += 1; sleep(Duration::from_millis(50)); if last_user_message.elapsed() > user_message_timeout { println!("No new CAN data since {}", last_can_data.elapsed().as_secs()); last_user_message = Instant::now(); } db_last = db.clone(); } child.wait().expect("command wasn't running"); println!("Child has finished its execution!"); } else { println!("{:?} command didn't start", cmd); } } // 180 : Fernlicht: 00 68 = nomal; 00 78 = Fernlicht // 180 : [2] = 60 warnblinker; 04 = pipser // 180 : [2] = 40 blink link, 20 blink rechts // 2A0 : Geschwindigkeitsanzeige //: watch -n 0 cansend can0 '2A0#80FF8001' # Tempo & Kilometer ohne Pipsen (8) //: watch -n 0 cansend can0 '2A0#80FF0000' # Tempo // 380 : [0] = 2x = Handbremse // 380 : [0] = 4x = Bremsflüssigkeit // 380 : [0] = 8x = Bremsbeläge abgenutzt // 281 : Umdrehungen ///: Setzte ca. 2000 RPM: watch -n 0 cansend can0 '281#0000807C03BF3F00' ///: Ca. 900 rpm => 281: 00 00 40 73 02 04 1F 00 // 380 : [4] Nebelscheinwerfer // 38A : 1100 Lüftung & Pipsen // 545 : [3] Aktuelles Stück auf der CD // 683 : 12 07 26 06 /// Uhrzeit & Datum: Hour Min Day Month