comparison rust/src/main.rs @ 634:a5721c02d3ee rust

build succeeds
author Matt Johnston <matt@ucc.asn.au>
date Sun, 22 Sep 2019 20:35:40 +0800
parents 490e9e15b98c
children 4424a8b30f9c
comparison
equal deleted inserted replaced
633:490e9e15b98c 634:a5721c02d3ee
1 #![feature(async_closure)]
1 #[macro_use] extern crate log; 2 #[macro_use] extern crate log;
2 // riker has its own logging? 3 // riker has its own logging?
3 //extern crate env_logger; 4 //extern crate env_logger;
4 5
5 #[macro_use] extern crate lazy_static; 6 #[macro_use] extern crate lazy_static;
6 7
7 use sensor::Sensor;
8 8
9 mod config; 9 mod config;
10 mod sensor; 10 mod sensor;
11 mod fridge; 11 mod fridge;
12 mod types; 12 mod types;
13 mod params; 13 mod params;
14 14
15 use types::*; 15 use crate::config::Config;
16 use config::Config;
17 16
18 fn run(config: &Config, nowait: bool, testmode: bool) { 17 use riker::actors::*;
19 18
20 let mut core = Core::new().unwrap(); 19 use structopt::StructOpt;
21 let handle = core.handle();
22 20
23 let params = params::Params::load(&config); 21 fn run(cf: Config, nowait: bool, testmode: bool) {
24 let mut fridge = fridge::Fridge::new(&config, nowait, params, &handle);
25 22
26 let sensor_stream = if testmode { 23 let sys = ActorSystem::new().unwrap();
27 sensor::TestSensor::new(config).stream(&handle) 24 let props = Props::new_args(params::ParamWaiter::new, cf.clone());
25 sys.actor_of(props, "paramwaiter").unwrap();
26
27 if testmode {
28 let props = Props::new_args(sensor::TestSensor::new, cf.clone());
29 sys.actor_of(props, "sensor").unwrap()
28 } else { 30 } else {
29 sensor::OneWireSensor::new(config).stream(&handle) 31 let props = Props::new_args(sensor::OneWireSensor::new, cf.clone());
32 sys.actor_of(props, "sensor").unwrap()
30 }; 33 };
31 34
32 // Send the sensors of interest to the fridge (fridge_reading_s), 35 let props = Props::new_args(fridge::Fridge::new_actor, (cf.clone(), nowait));
33 // while streaming them all to the web sender. 36 sys.actor_of(props, "fridge").unwrap();
34 let (fridge_reading_s, fridge_reading_r) = mpsc::channel(1);
35 let fridge_reading_r = fridge_reading_r.map_err(|e| TemplogError::new("Problem with fridge_reading_r channel"));
36 let sensor_stream = sensor_stream.map(|r| {
37 debug!("sensors {:?}", r);
38 let msg = fridge::Message::Sensor {
39 wort: r.get_temp(&config.WORT_NAME),
40 fridge: r.get_temp(&config.FRIDGE_NAME)
41 };
42 let t = fridge_reading_s.clone().send(msg)
43 .map(|_| ())
44 .map_err(|e| {
45 warn!("Send error in fridge_reading_s: {}", e.to_string());
46 ()
47 });
48 handle.spawn(t);
49 r
50 });
51
52 let param_stream = params::ParamWaiter::stream(config.clone(), handle.clone());
53 let param_stream = param_stream.map(|p| {
54 fridge::Message::Params(p)
55 });
56
57 let timeouts = fridge.wakeups();
58
59 // forward all the different types of messages to the fridge
60 let all_fridge = param_stream.select(timeouts).select(fridge_reading_r).forward(fridge) .map(|_| () );
61
62 let all_readings = sensor_stream.for_each(|_| Ok(()));
63
64 // run forever
65 let all = all_fridge.select(all_readings);
66 core.run(all).ok();
67 } 37 }
68 38
69 const USAGE: &'static str = "\ 39 #[derive(Debug, StructOpt)]
70 Wort Temperature 40 #[structopt(name = "Wort Temperature", about = "Matt Johnston 2019 [email protected]")]
71 Matt Johnston 2017 [email protected] 41 struct Opt {
72 Usage: wort-templog [--help] [--new] [--daemon] [--debug] [--test] [--defconf] [--thisconf] [--nowait] 42 /// Replace existing running instance
43 #[structopt(long)]
44 new: bool,
73 45
74 Options: 46 /// Run in background
75 -h, --help 47 #[structopt(short = "D", long)]
76 --new Replace existing running instance 48 daemon: bool,
77 -D, --daemon Run in background
78 -d, --debug
79 -t, --test Use fake sensors etc
80 --nowait Skip initial fridge wait
81 --defconf Print default config (customise in local.conf)
82 --thisconf Print used config
83 ";
84 49
85 #[derive(RustcDecodable)] 50 #[structopt(short, long)]
86 struct Args { 51 debug: bool,
87 flag_new: bool, 52
88 flag_daemon: bool, 53 /// Use fake sensors etc
89 flag_debug: bool, 54 #[structopt(long)]
90 flag_test: bool, 55 test: bool,
91 flag_defconf: bool, 56
92 flag_thisconf: bool, 57 /// Skip initial fridge wait
93 flag_nowait: bool, 58 #[structopt(long)]
59 nowait: bool,
60
61 /// Print default config (customise in local.conf)
62 #[structopt(long)]
63 defconf: bool,
94 } 64 }
95 65
96 fn handle_args() -> Args { 66 fn handle_args() -> Opt {
97 let args: Args = docopt::Docopt::new(USAGE).and_then(|d| d.decode()).unwrap_or_else(|e| e.exit()); 67 let args = Opt::from_args();
98 68
99 if args.flag_defconf { 69 if args.defconf {
100 println!("Default configuration:\n{}\n\n{}", 70 println!("Default configuration:\n{}\n\n{}",
101 "(custom options go in local.conf)", 71 "(custom options go in local.conf)",
102 config::Config::default().to_toml_string()); 72 config::Config::default_toml());
103 std::process::exit(0); 73 std::process::exit(0);
104 } 74 }
105 args 75 args
106 } 76 }
107 77
108 fn setup_log(debug: bool) { 78 // fn setup_log(debug: bool) {
109 let loglevel = if debug { 79 // let loglevel = if debug {
110 log::LogLevelFilter::Debug 80 // log::LevelFilter::Debug
111 } else { 81 // } else {
112 log::LogLevelFilter::Info 82 // log::LevelFilter::Info
113 }; 83 // };
114 84
115 let format = |record: &log::LogRecord| { 85 // let format = |record: &log::Record| {
116 let datefmt = "%Y-%m-%d %I:%M:%S %p"; 86 // let datefmt = "%Y-%m-%d %I:%M:%S %p";
117 let ts = time::strftime(datefmt, &time::now()).unwrap(); 87 // let ts = chrono::Local::now().format(datefmt);
118 format!("{}: {} - {}", ts, record.level(), record.args()) 88 // format!("{}: {} - {}", ts, record.level(), record.args())
119 }; 89 // };
120 90
121 91
122 let mut builder = env_logger::LogBuilder::new(); 92 // let mut builder = env_logger::Builder::new();
123 builder.format(format).filter(Some("wort_templog"), loglevel); 93 // builder.format(format).filter(Some("wort_templog"), loglevel);
124 builder.init().unwrap(); 94 // builder.init().unwrap();
125 } 95 // }
126
127 fn load_config() -> Config {
128 let nconfig = config::Config::default();
129
130 let conf_filename = "local.conf";
131 nconfig.merge_file(conf_filename)
132 .unwrap_or_else(|e| {
133 if let TemplogErrorKind::Io(ref ioe) = *e.kind() {
134 if let Some(errno) = ioe.raw_os_error() {
135 if errno == libc::ENOENT {
136 return nconfig;
137 }
138 }
139 }
140
141 println!("Couldn't parse {}: {}", conf_filename, e);
142 std::process::exit(1);
143 })
144 }
145 96
146 fn main() { 97 fn main() {
147 98
148 let args = handle_args(); 99 let args = handle_args();
149 setup_log(args.flag_debug); 100 // setup_log(args.debug);
150 //env_logger::init().unwrap(); 101 //env_logger::init().unwrap();
151 102
152 info!("wort-templog"); 103 info!("wort-templog");
153 debug!("debug mode"); 104 debug!("debug mode");
154 105
155 let config = load_config(); 106 let config = config::Config::load().unwrap();
156 107
157 if args.flag_thisconf { 108 run(config, args.nowait, args.test);
158 println!("Current configuration:\n\n{}",
159 config.to_toml_string());
160 std::process::exit(0);
161 }
162
163 run(&config, args.flag_nowait, args.flag_test);
164 } 109 }