diff --git a/Cargo.lock b/Cargo.lock index d1f4d2a..e8b91bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,77 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "backtrace" +version = "0.3.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e692897359247cc6bb902933361652380af0f1b7651ae5c5013407f30e109e" +dependencies = [ + "backtrace-sys", + "cfg-if", + "libc", + "rustc-demangle", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7de8aba10a69c8e8d7622c5710229485ec32e9d55fdad160ea559c086fdcd118" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "cc" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "confy" +version = "0.3.2-alpha.0" +source = "git+https://github.com/GoWebProd/confy#7e9dac7c54ad3f123a196b1565cf08efb68241e1" +dependencies = [ + "failure", + "serde", + "serde_yaml", +] + +[[package]] +name = "dtoa" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4358a9e11b9a09cf52383b451b49a169e8d797b68aa02301ff586d70d9661ea3" + +[[package]] +name = "failure" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8529c2421efa3066a5cbd8063d2244603824daccb6936b079010bb2aa89464b" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "030a733c8287d6213886dd487564ff5c8f6aae10278b3588ed177f9d18f8d231" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -12,6 +84,30 @@ version = "0.2.67" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018" +[[package]] +name = "linked-hash-map" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" + +[[package]] +name = "proc-macro2" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" +dependencies = [ + "proc-macro2", +] + [[package]] name = "rppal" version = "0.11.3" @@ -22,9 +118,87 @@ dependencies = [ "libc", ] +[[package]] +name = "rustc-demangle" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" + +[[package]] +name = "serde" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_yaml" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" +dependencies = [ + "dtoa", + "linked-hash-map", + "serde", + "yaml-rust", +] + +[[package]] +name = "syn" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + [[package]] name = "tempi" version = "0.1.0" dependencies = [ + "confy", "rppal", + "serde", +] + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" + +[[package]] +name = "yaml-rust" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d" +dependencies = [ + "linked-hash-map", ] diff --git a/Cargo.toml b/Cargo.toml index b9e6373..176d7c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,5 +7,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +confy = { git = "https://github.com/GoWebProd/confy" } #"0.4.0" # Will need something more than this version to have yaml support rppal = "0.11.3" - +#serde_derive = "1.0.104" +serde = { version = "1.0.104", features = ["derive"] } diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..6efb606 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,36 @@ +use crate::fan::hysteresis::HysteresisConfig; +use crate::fan::pwm::PwmConfig; + +use serde::{Deserialize, Serialize}; +use std::time::Duration; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Config { + pub check_interval: Duration, + pub mode: FanMode, + pub verbosity_mode: VerbosityMode, +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum FanMode { + Hysteresis(HysteresisConfig), + Pwm(PwmConfig), +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum VerbosityMode { + Human, + Machine, + Quiet, +} + +impl Default for Config { + fn default() -> Self { + Config { + check_interval: Duration::from_secs(10), + mode: FanMode::Hysteresis(HysteresisConfig::default()), + //mode: FanMode::Pwm(PwmConfig::default()), + verbosity_mode: VerbosityMode::Human, + } + } +} diff --git a/src/fan/hysteresis.rs b/src/fan/hysteresis.rs index d782729..7f97a83 100644 --- a/src/fan/hysteresis.rs +++ b/src/fan/hysteresis.rs @@ -1,23 +1,41 @@ use crate::fan::Fan; use rppal::gpio::{Gpio, OutputPin}; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct HysteresisConfig { + max_temperature: f64, + hysteresis: f64, + bcm_pin: u8, +} + +impl Default for HysteresisConfig { + fn default() -> Self { + HysteresisConfig { + max_temperature: 70_f64, + hysteresis: 10_f64, + bcm_pin: 18, + } + } +} pub struct Hysteresis { - pub max_temperature: f64, - pub hysteresis: f64, + max_temperature: f64, + hysteresis: f64, pin: OutputPin, } impl Hysteresis { - pub fn new(max_temperature: f64, hysteresis: f64, bcm_pin: u8) -> Hysteresis { + pub fn new(config: HysteresisConfig) -> Self { let gpio = Gpio::new().unwrap(); - let mut pin = gpio.get(bcm_pin).unwrap().into_output(); + let mut pin = gpio.get(config.bcm_pin).unwrap().into_output(); pin.set_low(); Hysteresis { - max_temperature, - hysteresis, + max_temperature: config.max_temperature, + hysteresis: config.hysteresis, pin, } } diff --git a/src/fan/pwm.rs b/src/fan/pwm.rs index c28f98f..2b05880 100644 --- a/src/fan/pwm.rs +++ b/src/fan/pwm.rs @@ -1,21 +1,56 @@ use crate::fan::Fan; use rppal::pwm::{Channel, Polarity, Pwm as Pwm_rpi}; +use serde::{Deserialize, Serialize}; + +// See: https://serde/rs/remote-derive.html +#[derive(Serialize, Deserialize)] +#[serde(remote = "Channel")] +pub enum ChannelDef { + Pwm0, + Pwm1, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct PwmConfig { + max_temperature: f64, + min_temperature: f64, + frequency: f64, + #[serde(with = "ChannelDef")] + channel: Channel, +} + +impl Default for PwmConfig { + fn default() -> Self { + PwmConfig { + max_temperature: 70_f64, + min_temperature: 60_f64, + frequency: 0.1_f64, + channel: Channel::Pwm0, + } + } +} pub struct Pwm { - pub max_temperature: f64, - pub min_temperature: f64, + max_temperature: f64, + min_temperature: f64, pwm: Pwm_rpi, } impl Pwm { - pub fn new(max_temperature: f64, min_temperature: f64, bcm_pin: Channel) -> Pwm { - let pwm = - Pwm_rpi::with_frequency(bcm_pin, 0.1_f64, 0_f64, Polarity::Normal, false).unwrap(); + pub fn new(config: PwmConfig) -> Self { + let pwm = Pwm_rpi::with_frequency( + config.channel, + config.frequency, + 0_f64, + Polarity::Normal, + false, + ) + .unwrap(); Pwm { - max_temperature, - min_temperature, + max_temperature: config.max_temperature, + min_temperature: config.min_temperature, pwm, } } diff --git a/src/main.rs b/src/main.rs index a003618..089d615 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,22 +1,26 @@ +mod config; mod fan; mod temperatures; +use config::{Config, FanMode::*, VerbosityMode::*}; use fan::hysteresis::Hysteresis; use fan::pwm::Pwm; use fan::Fan; +use temperatures::Temperatures; -use rppal::pwm::Channel; use std::error::Error; use std::thread; -use std::time::Duration; fn main() -> Result<(), Box> { - let mut temps = temperatures::Temperatures::new()?; + let mut temps = Temperatures::new()?; + let config: Config = confy::load("tempi").unwrap(); - let mut fan: Box = if true { - Box::new(Hysteresis::new(52.0, 5.0, 18)) - } else { - Box::new(Pwm::new(52.0, 42.0, Channel::Pwm0)) + // Can be used to check configuration and/or save default one. + //confy::store("tempi", dbg!(&config)).unwrap(); + + let mut fan: Box = match config.mode { + Hysteresis(h) => Box::new(Hysteresis::new(h)), + Pwm(p) => Box::new(Pwm::new(p)), }; loop { @@ -26,17 +30,21 @@ fn main() -> Result<(), Box> { Some(t) => { fan.update_temperature(t); - println!( - "CPU: {:.1}°C, fan is at {:.1}%", - t, - fan.percentage() * 100_f64 - ); + match config.verbosity_mode { + Human => println!( + "CPU: {:.1}°C, fan is at {:.1}%", + t, + fan.percentage() * 100_f64 + ), + Machine => println!("{} | {}", t, fan.percentage()), + Quiet => (), + } } None => { eprintln!("Recuring problem while getting the temperature"); } } - thread::sleep(Duration::from_secs(5)); + thread::sleep(config.check_interval); } }