# HG changeset patch # User Matt Johnston # Date 1492270763 -28800 # Node ID 8136a6b99866a849d7db21487085823f51b8f16e # Parent 8fda564cc46f2d7965acbe5d67d329e0aade4eea make it compile again diff -r 8fda564cc46f -r 8136a6b99866 rust/Cargo.toml --- a/rust/Cargo.toml Thu Mar 23 00:20:22 2017 +0800 +++ b/rust/Cargo.toml Sat Apr 15 23:39:23 2017 +0800 @@ -24,4 +24,5 @@ base64 = "0.4" # linux only +[target.linux.dependencies] sysfs_gpio = "0.5" diff -r 8fda564cc46f -r 8136a6b99866 rust/src/fridge.rs --- a/rust/src/fridge.rs Thu Mar 23 00:20:22 2017 +0800 +++ b/rust/src/fridge.rs Sat Apr 15 23:39:23 2017 +0800 @@ -1,5 +1,6 @@ extern crate futures; extern crate tokio_core; +#[cfg(linux)] extern crate sysfs_gpio; use std; @@ -11,6 +12,8 @@ use futures::{Future,future,Sink,Stream}; use tokio_core::reactor::{Timeout,Handle}; use futures::sync::{mpsc}; + +#[cfg(target_os = "linux")] use sysfs_gpio::{Direction, Pin}; use config::Config; @@ -34,7 +37,7 @@ last_off_time: Instant, wort_valid_time: Instant, integrator: StepIntegrator, - gpio: Pin, + control: FridgeControl, // Timeouts to wake ourselves up again handle: Handle, @@ -59,10 +62,18 @@ } } +enum FridgeControl { +#[cfg(target_os = "linux")] + Gpio(Pin), + Fake, +} + +struct TestControl {} + impl Drop for Fridge { fn drop(&mut self) { // safety fridge off - self.gpio.set_state(0); + self.turn(false); } } @@ -77,8 +88,8 @@ temp_fridge: None, last_off_time: Instant::now(), wort_valid_time: Instant::now() - Duration::new(config.FRIDGE_WORT_INVALID_TIME, 100), - integrator: StepIntegrator::new(p.overshoot_delay), - gpio: Pin::new(config.FRIDGE_GPIO_PIN), + integrator: StepIntegrator::new(Duration::new(p.overshoot_delay, 0)), + control: Self::make_control(config), handle: handle.clone(), timeout_s: s, @@ -90,15 +101,27 @@ f.last_off_time -= Duration::new(config.FRIDGE_DELAY, 1); } - // XXX better error handling? - f.gpio.export().expect("Exporting fridge gpio failed"); - f.gpio.set_direction(Direction::Low).expect("Fridge gpio direction failed"); - f.tick(); f } +#[cfg(target_os = "linux")] + fn make_control(config: &Config) -> FridgeControl { + let mut pin = Pin(config.FRIDGE_GPIO_PIN); + // XXX better error handling? + pin.export().expect("Exporting fridge gpio failed"); + pin.set_direction(Direction::Low).expect("Fridge gpio direction failed"); + FridgeControl::Gpio(pin) + } + +#[cfg(not(target_os = "linux"))] + fn make_control(config: &Config) -> FridgeControl { + FridgeControl::Fake + } + + + fn next_wakeup(&self) -> Duration { let millis = 400; let dur = Duration::from_millis(millis); @@ -123,18 +146,22 @@ } fn turn_off(&mut self) { - log!("Turning fridge off"); + info!("Turning fridge off"); self.turn(false); } fn turn_on(&mut self) { - log!("Turning fridge on"); + info!("Turning fridge on"); self.turn(true); } fn turn(&mut self, on: bool) { + match self.control { +#[cfg(target_os = "linux")] + Gpio(pin) => pin.set_value(on as u8), + FridgeControl::Fake => debug!("fridge turns {}", if on {"on"} else {"off"}), + } self.on = on; - self.gpio.set_value(on as u8) } /// Turns the fridge off and on @@ -145,18 +172,18 @@ let off_time = Instant::now() - self.last_off_time; // Or elsewhere? - self.integrator.set_limit(self.params.overshoot_delay); + self.integrator.set_limit(Duration::new(self.params.overshoot_delay, 0)); // Safety to avoid bad things happening to the fridge motor (?) // When it turns off don't start up again for at least FRIDGE_DELAY - if !self.on && off_time < self.config.FRIDGE_DELAY { - log!("fridge skipping, too early"); + if !self.on && off_time < Duration::new(self.config.FRIDGE_DELAY, 0) { + info!("fridge skipping, too early"); return; } if self.params.disabled { if self.on { - log!("Disabled, turning fridge off"); + info!("Disabled, turning fridge off"); self.turn_off(); } return; @@ -166,7 +193,7 @@ if self.temp_wort.is_none() { let invalid_time = Instant::now() - self.wort_valid_time; warn!("Invalid wort sensor for {:?} secs", invalid_time); - if invalid_time < self.config.FRIDGE_WORT_INVALID_TIME { + if invalid_time < Duration::new(self.config.FRIDGE_WORT_INVALID_TIME, 0) { warn!("Has only been invalid for {:?}, waiting", invalid_time); return; } @@ -179,27 +206,28 @@ if self.on { debug!("fridge is on"); let on_time = self.integrator.integrate().as_secs() as f32; - let on_ratio = on_time / params.overshoot_delay as f32; + let on_ratio = on_time / self.params.overshoot_delay as f32; - overshoot = params.overshoot_factor as f32 * on_ratio; - debug!("on_time {}, overshoot {}", on_percent, overshoot); + let overshoot = self.params.overshoot_factor as f32 * on_ratio; + debug!("on_percent {}, overshoot {}", on_ratio * 100.0, overshoot); let mut turn_off = false; - if let Some(t) = self.temp_wort && !params.nowort { + if self.temp_wort.is_some() && !self.params.nowort { + let t = self.temp_wort.unwrap(); // use the wort temperature - if t - overshoot < params.fridge_setpoint { - log!("wort has cooled enough, {temp}º (overshoot {overshoot}º = {factor} × {percent}%)", + if t - overshoot < self.params.fridge_setpoint { + info!("wort has cooled enough, {temp}º (overshoot {overshoot}º = {factor} × {percent}%)", temp = t, overshoot = overshoot, - factor = params.overshoot_factor, - percent = on_ratio*100); + factor = self.params.overshoot_factor, + percent = on_ratio*100.0); turn_off = true; } - } else let if Some(t) = self.temp_fridge { + } else if let Some(t) = self.temp_fridge { // use the fridge temperature if t < fridge_min { warn!("fridge off fallback, fridge {}, min {}", t, fridge_min); if self.temp_wort.is_none() { - W("wort has been invalid for {:?}", Instant::now() - self.wort_valid_time); + warn!("wort has been invalid for {:?}", Instant::now() - self.wort_valid_time); } turn_off = true; } @@ -211,17 +239,18 @@ debug!("fridge is off. fridge {:?} max {:?}. wort {:?} max {:?}", self.temp_fridge, fridge_max, self.temp_wort, wort_max); let mut turn_on = false; - if let Some(t) = self.temp_wort && !params.nowort { + if self.temp_wort.is_some() && !self.params.nowort { // use the wort temperature + let t = self.temp_wort.unwrap(); if t >= wort_max { - log!("Wort is too hot {}°, max {}°", t, wort_max); + info!("Wort is too hot {}°, max {}°", t, wort_max); turn_on = true; } } if let Some(t) = self.temp_fridge { if t >= fridge_max { - warn!("fridge too hot fallback, fridge {}°, max {}°", t, fridge_max) + warn!("fridge too hot fallback, fridge {}°, max {}°", t, fridge_max); turn_on = true; } } @@ -237,7 +266,7 @@ fn tick(&mut self) { debug!("tick"); - self.compare_temperatures() + self.compare_temperatures(); self.send_next_timeout(); } diff -r 8fda564cc46f -r 8136a6b99866 rust/src/params.rs --- a/rust/src/params.rs Thu Mar 23 00:20:22 2017 +0800 +++ b/rust/src/params.rs Sat Apr 15 23:39:23 2017 +0800 @@ -27,7 +27,7 @@ pub struct Params { pub fridge_setpoint: f32, pub fridge_difference: f32, - pub overshoot_delay: u32, + pub overshoot_delay: u64, pub overshoot_factor: f32, pub disabled: bool, pub nowort: bool, diff -r 8fda564cc46f -r 8136a6b99866 rust/src/types.rs --- a/rust/src/types.rs Thu Mar 23 00:20:22 2017 +0800 +++ b/rust/src/types.rs Sat Apr 15 23:39:23 2017 +0800 @@ -238,7 +238,7 @@ self.trim(); } - fn integrate(&self) -> Duration { + pub fn integrate(&self) -> Duration { let durs = self.on_periods.iter().map(|p| { let end = p.end.unwrap_or_else(|| Instant::now()); end - p.start