Skip to content

Commit a1b5a25

Browse files
Added quiet option to mute stdout
1 parent d983e92 commit a1b5a25

File tree

2 files changed

+24
-34
lines changed

2 files changed

+24
-34
lines changed

src/args.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,20 +78,25 @@ pub struct Args {
7878
#[clap(short, long, default_value_t = 120, value_parser = parse_interval)]
7979
pub interval: u64,
8080

81-
/// Print output as <hum,temp> to stdout (for use in unix pipeline).
81+
/// Print output as `<hum,temp>` to stdout (for use in unix pipeline).
8282
#[clap(short = 'P', long, action = SetTrue)]
8383
pub pipe: bool,
8484

8585
/// Output CSV directory.
86-
#[clap(short, long, default_value = "~", value_parser = parse_directory, requires = "csv")]
86+
#[clap(short, long, default_value = "~", value_parser = parse_directory)]
8787
pub directory: PathBuf,
8888

8989
/// Output CSV filename format (see
9090
/// https://docs.rs/chrono/latest/chrono/format/strftime/index.html for valid specifiers).
9191
#[clap(short, long, default_value = "%Y%m%d")]
9292
pub format: String,
9393

94-
/// Dumps data to CSV file.
94+
/// Dumps data to CSV file (can be swapped at runtime signalling `datalogger` process with
95+
/// SIGUSR1).
9596
#[clap(long, action = SetTrue)]
9697
pub csv: bool,
98+
99+
/// Mute standard output.
100+
#[clap(short, long, action = SetTrue)]
101+
pub quiet: bool,
97102
}

src/main.rs

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use chrono::{DateTime, Local};
2222
use dht22_pi::{self, Reading, ReadingError};
2323
use error::ErrorKind;
2424
use signal_hook::{
25-
consts::{SIGINT, SIGUSR1},
25+
consts::SIGUSR1,
2626
flag::register,
2727
};
2828
use std::{
@@ -76,7 +76,7 @@ impl Display for Measure {
7676
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
7777
write!(
7878
f,
79-
"{} {} -> Humidity: {}%, Temperature: {}°C",
79+
"Date: {}, Time: {}, Humidity: {}%, Temperature: {}°C",
8080
self.datetime.date().format("%Y-%m-%d"),
8181
self.datetime.time().format("%H:%M:%S"),
8282
self.reading.humidity,
@@ -102,7 +102,7 @@ fn run(args: Args) -> Result<(), ErrorKind> {
102102
let (tx, rx) = mpsc::channel::<Measure>();
103103

104104
// Output thread.
105-
let output_thread = thread::spawn(move || -> Result<(), ErrorKind> {
105+
thread::spawn(move || -> Result<(), ErrorKind> {
106106
// Register signal hook for SIGUSR1 events: such events swap the current args.csv value
107107
// (this is used to enable/disable writing of measures to output file at runtime).
108108
let sig = Arc::new(AtomicBool::new(false));
@@ -115,23 +115,18 @@ fn run(args: Args) -> Result<(), ErrorKind> {
115115
let mut csv = args.csv;
116116

117117
for measure in rx {
118-
// If SIGUSR1 received (so set to true), swap csv and restore sig to false.
118+
// If SIGUSR1 received (hence sig is true), swap csv and restore sig to false.
119119
if sig.load(Ordering::Relaxed) {
120120
csv = !csv;
121121
sig.store(false, Ordering::Relaxed);
122122
}
123123

124124
if csv {
125-
// If `pipe` options is passed, print with "<hum>,<temp>" format to stdout.
126-
if args.pipe {
127-
println!("{}", measure.to_pipe());
128-
}
129-
130125
let filename = Local::now().format(&args.format).to_string();
131126
let csv_file = &args.directory.join(filename).with_extension("csv");
132127
match OpenOptions::new().create(true).append(true).open(csv_file) {
133128
Ok(mut file) => {
134-
// If file is empty write headers.
129+
// If file is empty, then write headers.
135130
if file
136131
.metadata()
137132
.expect("unable to get output file metadata")
@@ -146,27 +141,24 @@ fn run(args: Args) -> Result<(), ErrorKind> {
146141
}
147142
Err(e) => return Err(ErrorKind::FileError(e.to_string())),
148143
}
149-
} else if args.pipe {
150-
println!("{}", measure.to_pipe());
151-
} else if args.csv == csv && !args.csv {
152-
// Print human readable output to stdout only if args.csv is left unchanged and it
153-
// was set to false at launch (this means the user is intentionally trying to print
154-
// human readable to stdout).
155-
println!("{measure}");
144+
}
145+
146+
if !args.quiet {
147+
// If `pipe` options is passed, print with "<hum>,<temp>" format to stdout, else
148+
// print human readable values.
149+
if args.pipe {
150+
println!("{}", measure.to_pipe());
151+
} else {
152+
println!("{}", measure);
153+
}
156154
}
157155
}
158156

159157
Ok(())
160158
});
161159

162-
// Register signal hook for SIGINT events: in this case error is unrecoverable, so it's fine to
163-
// panic.
164-
let int = Arc::new(AtomicBool::new(false));
165-
// Set `int` to true when the program receives a SIGTERM kill signal.
166-
register(SIGINT, Arc::clone(&int)).expect("unable to register SIGTERM event handler");
167-
168160
// Start main loop: loop guard is 'received SIGINT'.
169-
while !int.load(Ordering::Relaxed) {
161+
loop {
170162
let start_measuring = Instant::now();
171163
let mut retries = 0;
172164
tx.send(Measure::new(
@@ -198,13 +190,6 @@ fn run(args: Args) -> Result<(), ErrorKind> {
198190
// Sleep for `args.interval` corrected by the time spent measuring.
199191
thread::sleep(Duration::from_secs(args.interval) - start_measuring.elapsed());
200192
}
201-
202-
drop(tx);
203-
output_thread
204-
.join()
205-
.expect("unable to join 'output_thread'")?;
206-
207-
Ok(())
208193
}
209194

210195
fn main() {

0 commit comments

Comments
 (0)