Mercurial > templog
view rust/src/main.rs @ 622:5b456905eaac rust
use libc. update.
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 16 Apr 2017 22:50:05 +0800 |
parents | 8fda564cc46f |
children | 03167105f6de |
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; extern crate tokio_curl; extern crate curl; extern crate serde_json; #[macro_use] extern crate lazy_static; #[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; mod fridge; mod types; mod params; use types::*; use config::Config; fn run(config: &Config, nowait: bool, testmode: bool) { let mut core = Core::new().unwrap(); let handle = core.handle(); let params = params::Params::load(&config); let mut fridge = fridge::Fridge::new(&config, nowait, params, &handle); let sensor_stream = if testmode { sensor::TestSensor::new(config).stream(&handle) } else { sensor::OneWireSensor::new(config).stream(&handle) }; // Send the sensors of interest to the fridge (fridge_reading_s), // while streaming them all to the web sender. let (fridge_reading_s, fridge_reading_r) = mpsc::channel(1); let fridge_reading_r = fridge_reading_r.map_err(|e| TemplogError::new("Problem with fridge_reading_r channel")); let sensor_stream = sensor_stream.map(|r| { debug!("sensors {:?}", r); let msg = fridge::Message::Sensor { wort: r.get_temp(&config.WORT_NAME), fridge: r.get_temp(&config.FRIDGE_NAME) }; let t = fridge_reading_s.clone().send(msg) .map(|_| ()) .map_err(|e| { warn!("Send error in fridge_reading_s: {}", e.to_string()); () }); handle.spawn(t); r }); let param_stream = params::ParamWaiter::stream(config, &handle); let param_stream = param_stream.map(|p| { fridge::Message::Params(p) }); let timeouts = fridge.wakeups(); // forward all the different types of messages to the fridge let all_fridge = param_stream.select(timeouts).select(fridge_reading_r).forward(fridge) .map(|_| () ); let all_readings = sensor_stream.for_each(|_| Ok(())); // run forever 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 local.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 local.conf)", config::Config::default().to_toml_string()); std::process::exit(0); } args } fn load_config() -> Config { let nconfig = config::Config::default(); let conf_filename = "local.conf"; nconfig.merge_file(conf_filename) .unwrap_or_else(|e| { println!("Couldn't parse {}: {}", conf_filename, e); std::process::exit(1); }) } fn main() { let args = handle_args(); setup_log(args.flag_debug); //env_logger::init().unwrap(); info!("wort-templog"); debug!("debug mode"); let config = load_config(); 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); }