Mercurial > templog
view rust/src/main.rs @ 600:9c76f3cf01ea rust
slightly less ugly
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Tue, 07 Feb 2017 22:57:29 +0800 |
parents | f71cf1ad745f |
children | 8c21df3711e2 |
line wrap: on
line source
extern crate tokio_core; extern crate futures; #[macro_use] extern crate log; extern crate env_logger; extern crate rustc_serialize; extern crate time; #[macro_use] extern crate serde_derive; extern crate serde; extern crate toml; extern crate docopt; use std::io; use tokio_core::reactor::Core; use futures::{Stream,Sink,Future}; use futures::sync::{mpsc}; use sensor::Sensor; mod config; mod sensor; pub mod fridge; mod types; mod paramwaiter; use types::*; use config::Config; fn run(config: &Config, nowait: bool, testmode: bool) { let mut core = Core::new().unwrap(); let handle = core.handle(); let mut paramh = ParamHolder::new(); let mut fridge = fridge::Fridge::new(config, nowait, paramh.p, &handle); let (fridge_reading_s, fridge_reading_r) = mpsc::channel(1); let fridge_reading_r = fridge_reading_r.map_err(|_| io::Error::new(io::ErrorKind::Other, "Problem with fridge_reading_r channel")); let sensor_stream = if testmode { sensor::TestSensor::stream(&handle, config) } else { sensor::OneWireSensor::stream(&handle, config) }; // Send the sensors of interest to the fridge (fridge_reading_s), // while streaming them all to the web sender. let s = sensor_stream.map(|r| { debug!("sensors {:?}", r); let t = fridge_reading_s.clone().send(fridge::Message::Sensor{wort: r.wort(), fridge: r.fridge()}) .map(|_| ()) .map_err(|e| { warn!("Send error in fridge_reading_s: {}", e.to_string()); () }); handle.spawn(t); r }); let param_stream = paramwaiter::ParamWaiter::stream(&handle); let p = param_stream.map(|p| { fridge::Message::Params(p) }); let timeouts = fridge.wakeups(); let all_readings = s.for_each(|_| Ok(())); let all_fridge = p.select(timeouts).select(fridge_reading_r).forward(fridge) .map(|_| () ); let all = all_fridge.select(all_readings); core.run(all).ok(); } const USAGE: &'static str = "\ Wort Temperature Matt Johnston 2017 [email protected] Usage: wort-templog [--help] [--new] [--daemon] [--debug] [--test] [--defconf] [--thisconf] [--nowait] Options: -h, --help --new Replace existing running instance -D, --daemon Run in background -d, --debug -t, --test Use fake sensors etc --nowait Skip initial fridge wait --defconf Print default config (customise in tempserver.conf) --thisconf Print used config "; #[derive(RustcDecodable)] struct Args { flag_new: bool, flag_daemon: bool, flag_debug: bool, flag_test: bool, flag_defconf: bool, flag_thisconf: bool, flag_nowait: bool, } fn setup_log(debug: bool) { let loglevel = if debug { log::LogLevelFilter::Debug } else { log::LogLevelFilter::Info }; let format = |record: &log::LogRecord| { let datefmt = "%Y-%m-%d %I:%M:%S %p"; let ts = time::strftime(datefmt, &time::now()).unwrap(); format!("{}: {} - {}", ts, record.level(), record.args()) }; let mut builder = env_logger::LogBuilder::new(); builder.format(format).filter(Some("wort_templog"), loglevel); builder.init().unwrap(); } fn handle_args() -> Args { let args: Args = docopt::Docopt::new(USAGE).and_then(|d| d.decode()).unwrap_or_else(|e| e.exit()); if args.flag_defconf { println!("Default configuration:\n{}\n\n{}", "(custom options go in tempserver.conf)", config::Config::default().to_toml_string()); std::process::exit(0); } args } fn main() { let mut config = config::Config::default(); let args = handle_args(); setup_log(args.flag_debug); //env_logger::init().unwrap(); info!("wort-templog"); debug!("debug mode"); let conf_filename = "tempserver.conf"; config = config.merge_file(conf_filename) .unwrap_or_else(|e| { panic!("Couldn't parse {}: {}", conf_filename, e); }); if args.flag_thisconf { println!("Current configuration:\n\n{}", config.to_toml_string()); std::process::exit(0); } run(&config, args.flag_nowait, args.flag_test); }