bobview_probe/
bobview-probe.rs1use std::time::{Duration, Instant};
6
7fn main() {
8 let mut seconds = 5.0;
9 let mut puts = Vec::new();
10 let mut names = Vec::new();
11 let mut args = std::env::args().skip(1);
12 while let Some(arg) = args.next() {
13 match arg.as_str() {
14 "--seconds" => seconds = args.next().and_then(|s| s.parse().ok()).unwrap_or(seconds),
15 "--put" => puts.extend(args.next()),
16 "-h" | "--help" => {
17 println!("usage: bobview-probe [--seconds N] [--put NAME=VALUE]... NAME...");
18 return;
19 }
20 _ => names.push(arg),
21 }
22 }
23
24 let manager = pv::PvManager::new();
25 let mut pvs: Vec<_> = names
26 .iter()
27 .map(|n| (manager.subscribe(n), String::new()))
28 .collect();
29 let writers: Vec<_> = puts
30 .iter()
31 .filter_map(|p| {
32 let pair = p.split_once('=');
33 if pair.is_none() {
34 eprintln!("ignoring --put {p}: expected NAME=VALUE");
35 }
36 pair
37 })
38 .map(|(n, v)| (manager.subscribe(n), v.to_string()))
39 .collect();
40 let mut written = false;
41
42 let end = Instant::now() + Duration::from_secs_f64(seconds);
43 while Instant::now() < end {
44 if !written && writers.iter().all(|(pv, _)| pv.state().connected) {
45 for (pv, value) in &writers {
46 pv.write(value.clone());
47 }
48 written = true;
49 }
50 for (pv, last) in &mut pvs {
51 let s = pv.state();
52 let line = if let Some(e) = &s.error {
53 format!("error: {e}")
54 } else if !s.connected {
55 "disconnected".to_string()
56 } else {
57 format!("{} {:?}", s.format(None, true), s.severity)
58 };
59 if line != *last {
60 println!("{:<30} {line}", pv.name().to_string());
61 *last = line;
62 }
63 }
64 std::thread::sleep(Duration::from_millis(50));
65 }
66}