changeset 601:8c21df3711e2 rust

rigid_config more on sensors
author Matt Johnston <matt@ucc.asn.au>
date Wed, 15 Feb 2017 23:58:02 +0800
parents 9c76f3cf01ea
children 613f114feb4b
files rust/Cargo.lock rust/Cargo.toml rust/src/config.rs rust/src/fridge.rs rust/src/main.rs rust/src/sensor.rs
diffstat 6 files changed, 118 insertions(+), 83 deletions(-) [+]
line wrap: on
line diff
--- a/rust/Cargo.lock	Tue Feb 07 22:57:29 2017 +0800
+++ b/rust/Cargo.lock	Wed Feb 15 23:58:02 2017 +0800
@@ -5,11 +5,13 @@
  "docopt 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.2.1 (git+https://github.com/alexcrichton/toml-rs?branch=serde-upgrade)",
@@ -25,7 +27,7 @@
 
 [[package]]
 name = "aho-corasick"
-version = "0.6.1"
+version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -37,6 +39,11 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "crossbeam"
+version = "0.2.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "docopt"
 version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -65,6 +72,16 @@
 ]
 
 [[package]]
+name = "futures-cpupool"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "kernel32-sys"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -148,6 +165,14 @@
 ]
 
 [[package]]
+name = "num_cpus"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "quote"
 version = "0.3.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -182,7 +207,7 @@
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "aho-corasick 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_local 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -211,7 +236,7 @@
 
 [[package]]
 name = "serde"
-version = "0.9.6"
+version = "0.9.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -224,7 +249,7 @@
 
 [[package]]
 name = "serde_derive"
-version = "0.9.6"
+version = "0.9.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -314,7 +339,7 @@
 version = "0.2.1"
 source = "git+https://github.com/alexcrichton/toml-rs?branch=serde-upgrade#32a0a67b8de1d0b2a0dd98f1c96087fc9109fd00"
 dependencies = [
- "serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -366,11 +391,13 @@
 
 [metadata]
 "checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66"
-"checksum aho-corasick 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4f660b942762979b56c9f07b4b36bb559776fbad102f05d6771e1b629e8fd5bf"
+"checksum aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0638fd549427caa90c499814196d1b9e3725eb4d15d7339d6de073a680ed0ca2"
 "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
+"checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97"
 "checksum docopt 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab32ea6e284d87987066f21a9e809a73c14720571ef34516f0890b3d355ccfd8"
 "checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f"
 "checksum futures 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "c1913eb7083840b1bbcbf9631b7fda55eaf35fe7ead13cca034e8946f9e2bc41"
+"checksum futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bb982bb25cd8fa5da6a8eb3a460354c984ff1113da82bcb4f0b0862b5795db82"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
 "checksum lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6abe0ee2e758cd6bc8a2cd56726359007748fbf4128da998b65d0b70f881e19b"
 "checksum lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce12306c4739d86ee97c23139f3a34ddf0387bbf181bc7929d287025a8c3ef6b"
@@ -381,6 +408,7 @@
 "checksum mio 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "eecdbdd49a849336e77b453f021c89972a2cfb5b51931a0026ae0ac4602de681"
 "checksum miow 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3a78d2605eb97302c10cf944b8d96b0a2a890c52957caf92fcd1f24f69049579"
 "checksum net2 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)" = "5edf9cb6be97212423aed9413dd4729d62b370b5e1c571750e882cebbbc1e3e2"
+"checksum num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a225d1e2717567599c24f88e49f00856c6e825a12125181ee42c4257e3688d39"
 "checksum quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)" = "e7b44fd83db28b83c1c58187159934906e5e955c812e211df413b76b03c909a5"
 "checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
 "checksum redox_syscall 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd35cc9a8bdec562c757e3d43c1526b5c6d2653e23e2315065bc25556550753"
@@ -390,9 +418,9 @@
 "checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457"
 "checksum rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "237546c689f20bb44980270c73c3b9edd0891c1be49cc1274406134a66d3957b"
 "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
-"checksum serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0ae9a3c8b07c09dbe43022486d55a18c629a0618d2241e49829aaef9b6d862f9"
+"checksum serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1e0ed773960f90a78567fcfbe935284adf50c5d7cf119aa2cf43bb0b4afa69bb"
 "checksum serde_codegen_internals 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3172bf2940b975c0e4f6ab42a511c0a4407d4f46ccef87a9d3615db5c26fa96"
-"checksum serde_derive 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ecc6e0379ca933ece58302d2d3034443f06fbf38fd535857c1dc516195cbc3bf"
+"checksum serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6af30425c5161deb200aac4803c62b903eb3be7e889c5823d0e16c4ce0ce989c"
 "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
 "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
 "checksum syn 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f94368aae82bb29656c98443a7026ca931a659e8d19dcdc41d6e273054e820"
--- a/rust/Cargo.toml	Tue Feb 07 22:57:29 2017 +0800
+++ b/rust/Cargo.toml	Wed Feb 15 23:58:02 2017 +0800
@@ -5,6 +5,7 @@
 
 [dependencies]
 futures = "0.1"
+futures-cpupool = "0.1"
 tokio-core = "0.1"
 serde = "0.9"
 serde_derive = "0.9"
@@ -14,6 +15,7 @@
 docopt = "0.7"
 rustc-serialize = "0.3"
 time = "0.1"
+lazy_static = "0.2"
 
 [dependencies.toml]
 git = "https://github.com/alexcrichton/toml-rs"
--- a/rust/src/config.rs	Tue Feb 07 22:57:29 2017 +0800
+++ b/rust/src/config.rs	Wed Feb 15 23:58:02 2017 +0800
@@ -1,5 +1,6 @@
 extern crate toml;
 
+use std::error::Error;
 use std::fs::File;
 use std::io::Read;
 use serde::{Serialize,Deserialize,Deserializer,Serializer};
@@ -68,32 +69,22 @@
         toml::to_string(self).unwrap()
     }
 
-    pub fn merge(&self, conf: &str) -> Result<Self, String>{
+    pub fn merge(&self, conf: &str) -> Result<Self, Box<Error>> {
         // convert existing and new toml into tables, combine them.
-        let mut new_toml = try!(toml::from_str(conf).map_err(|e| e.to_string()));
+        let mut new_toml = toml::from_str(conf)?;
         let mut ex_val = toml::Value::try_from(self).unwrap();
         let mut ex_toml = ex_val.as_table_mut().unwrap();
         ex_toml.append(&mut new_toml);
-        let ret: Self = toml::Value::Table(ex_toml.clone()).try_into().unwrap();
+        // TODO: wrap the error with a better message?
+        let ret = toml::Value::Table(ex_toml.clone()).try_into()?;
         Ok(ret)
     }
 
-    pub fn merge_file(&self, filename: &str) -> Result<Self, String>{
+    pub fn merge_file(&self, filename: &str) -> Result<Self, Box<Error>> {
 
-        let r = File::open(filename)
-            .and_then(|mut f| {
-                let mut s = String::new();
-                f.read_to_string(&mut s)
-                    .map(|_| s)
-            })
-            .map_err(|e| e.to_string());
+        let mut s = String::new();
+        File::open(filename)?.read_to_string(&mut s)?;
 
-        r.and_then(|s| {
-            self.merge(&s)
-        })
-        .map_err(|e| {
-            format!("Error loading config file {}: {}",
-                    filename, e)
-        })
+        self.merge(&s)
     }
 }
--- a/rust/src/fridge.rs	Tue Feb 07 22:57:29 2017 +0800
+++ b/rust/src/fridge.rs	Wed Feb 15 23:58:02 2017 +0800
@@ -10,9 +10,10 @@
 use tokio_core::reactor::{Timeout,Handle};
 use futures::sync::{mpsc};
 
-use config::Config;
 use types::*;
 
+use ::rigid_config;
+
 #[derive(Debug)]
 pub enum Message {
     Sensor {wort: Option<f32>, fridge: Option<f32>},
@@ -21,7 +22,6 @@
 }
 
 pub struct Fridge {
-    config: Config,
     params: Params,
     temp_wort: Option<f32>,
     temp_fridge: Option<f32>,
@@ -51,10 +51,9 @@
 }
 
 impl Fridge {
-    pub fn new(config: &Config, nowait: bool, p: Params, handle: &Handle) -> Fridge {
+    pub fn new(nowait: bool, p: Params, handle: &Handle) -> Fridge {
         let (s, r) = mpsc::channel(1);
         let mut f = Fridge { 
-            config: config.clone(),
             params: p,
             temp_wort: None,
             temp_fridge: None,
@@ -66,7 +65,7 @@
             last_off_time: Instant::now(),
         };
         if nowait {
-            f.last_off_time -= Duration::new(config.FRIDGE_DELAY, 100);
+            f.last_off_time -= Duration::new(rigid_config.FRIDGE_DELAY, 100);
         }
         f.tick();
         f
--- a/rust/src/main.rs	Tue Feb 07 22:57:29 2017 +0800
+++ b/rust/src/main.rs	Wed Feb 15 23:58:02 2017 +0800
@@ -7,6 +7,9 @@
 extern crate time;
 
 #[macro_use]
+extern crate lazy_static;
+
+#[macro_use]
 extern crate serde_derive;
 extern crate serde;
 
@@ -30,21 +33,21 @@
 use types::*;
 use config::Config;
 
-fn run(config: &Config, nowait: bool, testmode: bool) {
+fn run(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 mut fridge = fridge::Fridge::new(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)
+        sensor::TestSensor::stream(&handle)
     } else {
-        sensor::OneWireSensor::stream(&handle, config)
+        sensor::OneWireSensor::stream(&handle)
     };
 
     // Send the sensors of interest to the fridge (fridge_reading_s),
@@ -135,8 +138,22 @@
     args
 }
 
+fn load_config() -> Config {
+    let mut nconfig = config::Config::default();
+
+    let conf_filename = "tempserver.conf";
+    nconfig.merge_file(conf_filename)
+        .unwrap_or_else(|e| {
+            println!("Couldn't parse {}: {}", conf_filename, e);
+            std::process::exit(1);
+    })
+}
+
+lazy_static! {
+    static ref rigid_config: Config = load_config();
+}
+
 fn main() {
-    let mut config = config::Config::default();
 
     let args = handle_args();
     setup_log(args.flag_debug);
@@ -145,18 +162,14 @@
     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());
+            rigid_config.to_toml_string());
         std::process::exit(0);
     }
 
-    run(&config, args.flag_nowait, args.flag_test);
+
+
+    run(args.flag_nowait, args.flag_test);
 }
 
--- a/rust/src/sensor.rs	Tue Feb 07 22:57:29 2017 +0800
+++ b/rust/src/sensor.rs	Wed Feb 15 23:58:02 2017 +0800
@@ -1,68 +1,79 @@
 extern crate tokio_core;
 extern crate futures;
+extern crate futures_cpupool;
 
 use std::time::Duration;
 use std::io;
 use std::fs::File;
-use std::io::Read;
+use std::io::{Read,BufReader,BufRead};
+use std::path::PathBuf;
+use std::error::Error;
 
 use tokio_core::reactor::Interval;
 use tokio_core::reactor::Handle;
 use futures::Stream;
 use types::*;
-use config::Config;
+
+use ::rigid_config;
 
 pub trait Sensor {
-    fn stream(handle: &Handle, config: &Config)
+    fn stream(handle: &Handle)
         -> Box<Stream<Item=Readings, Error=io::Error>>;
 }
 
 pub struct OneWireSensor {
-    config: Config,
 }
 
 impl OneWireSensor {
-    fn new(config: &Config) -> OneWireSensor {
+    fn new() -> OneWireSensor {
         OneWireSensor {
-            config: config.clone(),
         }
     }
 
-    fn step(&mut self) -> Readings {
+    fn step() -> Readings {
         let mut r = Readings::new();
+
+
         r.add("ambient", Some(31.2));
         r.add("wort_todo", Some(8.0));
         debug!("sensor step {:?}", r);
         r
     }
 
-    fn sensor_names(&self) -> Vec<String> {
-        let mut names = vec![];
-        names
+    fn sensor_names(&self) -> Result<Vec<String>, Box<Error>> {
+        let mut path = PathBuf::from(&rigid_config.SENSOR_BASE_DIR);
+        path.push("w1_master_slaves");
+
+        let f = BufReader::new(File::open(path)?);
+        let s = f.lines().collect::<Result<Vec<String>, io::Error>>()?;
+        Ok(s)
     }
 }
 
+// does this need to be static?
+lazy_static! {
+    static ref thread_pool : futures_cpupool::CpuPool = futures_cpupool::CpuPool::new(3); // TODO: how many?
+}
+
 impl Sensor for OneWireSensor {
-    fn stream(handle: &Handle, config: &Config)
+    fn stream(handle: &Handle)
         -> Box<Stream<Item=Readings, Error=io::Error>> {
-        let mut s = OneWireSensor::new(config);
+        let mut s = OneWireSensor::new();
 
-        let dur = Duration::new(s.config.SENSOR_SLEEP,0);
-        Interval::new(dur, handle).unwrap().map(move |()| {
-            s.step()
-        }).boxed()
+        let dur = Duration::new(rigid_config.SENSOR_SLEEP,0);
+        Interval::new(dur, handle).unwrap()
+            .and_then(|()| {
+                thread_pool.spawn_fn(|| Ok(Self::step()))
+            }).boxed()
     }
 }
 
 pub struct TestSensor {
-    config: Config,
 }
 
 impl TestSensor {
-    pub fn new(config: &Config) -> Self {
-        TestSensor {
-            config: config.clone(),
-        }
+    pub fn new() -> Self {
+        TestSensor {}
     }
 
     fn step(&mut self) -> Readings {
@@ -73,28 +84,19 @@
         r
     }
 
-    fn try_read(filename: &str) -> Result<f32, String> {
-        File::open(filename)
-            .map_err(|e| e.to_string())
-            .and_then(|mut f| {
-                let mut s = String::new();
-                f.read_to_string(&mut s)
-                    .map_err(|e| e.to_string())
-                    .map(|_| s)
-            })
-            .and_then(|s| {
-                    s.trim().parse::<f32>()
-                        .map_err(|e| e.to_string())
-            })
+    fn try_read(filename: &str) -> Result<f32, Box<Error>> {
+        let mut s = String::new();
+        File::open(filename)?.read_to_string(&mut s)?;
+        Ok(s.trim().parse::<f32>()?)
     }
 }
 
 impl Sensor for TestSensor {
-    fn stream(handle: &Handle, config: &Config)
+    fn stream(handle: &Handle)
         -> Box<Stream<Item=Readings, Error=io::Error>> {
-        let mut s = TestSensor::new(config);
+        let mut s = TestSensor::new();
 
-        let dur = Duration::new(s.config.SENSOR_SLEEP,0);
+        let dur = Duration::new(rigid_config.SENSOR_SLEEP,0);
         Interval::new(dur, handle).unwrap().map(move |()| {
             s.step()
         }).boxed()