Mercurial > templog
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 } |