Skip to content

Commit

Permalink
Add toml
Browse files Browse the repository at this point in the history
  • Loading branch information
Eraden committed Apr 30, 2021
1 parent 91d2d82 commit 127d080
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 71 deletions.
49 changes: 40 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "argonfand"
version = "0.1.0"
version = "1.0.0"
authors = ["Adrian Woźniak <[email protected]>"]
edition = "2018"
license = "MIT OR Apache-2.0"
Expand All @@ -10,3 +10,5 @@ description = "Single threaded minimalistic ArgonOne case fan control"
rppal = { version = "0.11.3" }
gpio = { version = "0.4.1" }
gumdrop = { version = "0.8.0" }
serde = { version = "1.0.125", features = ["derive"] }
toml = { version = "0.5.8" }
66 changes: 53 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
# ArgonOne Fan Service

## Requirements


* Create:
`/etc/modules-load.d/raspi-conf.conf`

and fill it with `i2c-dev`

* Add to `/boot/config.txt`

must contain

```
dtparam=i2c_arm=on
dtparam=i2s=on
```

Example:

```
enable_gic=1
dtparam=i2c_arm=on
dtoverlay=vc4-kms-v3d,i2c-rtc,ds1307,pcf85063
initramfs initramfs-linux.img followkernel
enable_uart=1
```

Raspberry PI must be fully restarted after this so i2c module will be loaded.

## Run

ArgonOne case for Raspberry Pi 4B fan service.

```bash
Expand All @@ -24,23 +55,32 @@ systemctl enable argonfand.service

Config file must exists before starting application and is located:

`/etc/argonfand.conf`
`/etc/argonfand.toml`

Format:

```toml
# comments starts with "#"
# TEMP=SPEED
49=0
50=40
60=100
```
verbose = false
delay = 1000

My settings (not default)
[[values]]
temp = 45
speed = 0

```toml
54=0
55=55
65=80
80=100
[[values]]
temp = 54
speed = 10

[[values]]
temp = 55
speed = 50

[[values]]
temp = 65
speed = 80

[[values]]
temp = 80
speed = 100
```

45 changes: 21 additions & 24 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::str::FromStr;
use serde::{Serialize, Deserialize};

#[derive(Debug)]
pub enum ConfigError {
Expand All @@ -9,7 +10,9 @@ pub enum ConfigError {
MeasureTempOutput,
}

#[derive(Debug, Default, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
#[derive(Debug, Default, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
#[repr(transparent)]
#[serde(transparent)]
pub struct Temp(pub u8);

impl FromStr for Temp {
Expand All @@ -29,7 +32,9 @@ impl FromStr for Temp {
}
}

#[derive(Debug, Default, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
#[derive(Debug, Default, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
#[repr(transparent)]
#[serde(transparent)]
pub struct Speed(pub u8);

impl Speed {
Expand All @@ -48,10 +53,10 @@ impl FromStr for Speed {
}
}

#[derive(Default, Debug)]
#[derive(Default, Debug, Serialize, Deserialize)]
pub struct SpeedConfig {
temp: Temp,
speed: Speed,
pub temp: Temp,
pub speed: Speed,
}

impl FromStr for SpeedConfig {
Expand All @@ -66,16 +71,24 @@ impl FromStr for SpeedConfig {
}
}

#[derive(Default, Debug)]
#[derive(Default, Debug, Serialize, Deserialize)]
pub struct Config {
values: Vec<SpeedConfig>,
pub help: bool,
#[serde(default)]
pub verbose: bool,
#[serde(default = "Config::default_delay")]
pub delay: Option<u64>,
#[serde(skip_serializing, default)]
pub force_speed: Option<u8>,
#[serde(skip_serializing, default)]
pub help: bool,
pub values: Vec<SpeedConfig>,
}

impl Config {
pub fn default_delay() -> Option<u64> {
Some(1000)
}

pub fn push(&mut self, speed: SpeedConfig) {
self.values.push(speed);
self.values.sort_by(|a, b| a.temp.cmp(&b.temp))
Expand Down Expand Up @@ -104,19 +117,3 @@ impl Config {
}
}

impl FromStr for Config {
type Err = ConfigError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut config = Self::default();
for line in s
.lines()
.map(|s| s.trim())
.filter(|s| !s.starts_with('#'))
.filter(|s| s.contains("="))
{
config.push(line.parse()?);
}
Ok(config)
}
}
61 changes: 37 additions & 24 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use crate::config::{Config, ConfigError, Speed, Temp};
use crate::config::*;
use gumdrop::Options;
use std::process::Stdio;
use std::thread::sleep;

mod config;

static CONFIG_PATH: &str = "/etc/argonfand.toml";

#[derive(Options)]
pub struct AppOptions {
#[options(help = "print help message")]
Expand All @@ -21,6 +23,38 @@ pub struct AppOptions {

fn main() -> std::io::Result<()> {
let opts = AppOptions::parse_args_default_or_exit();

let mut config = if opts.generate {
println!("Writing {}", CONFIG_PATH);
let config = Config {
values: vec![
SpeedConfig { temp: Temp(45), speed: Speed(0) },
SpeedConfig { temp: Temp(54), speed: Speed(10) },
SpeedConfig { temp: Temp(55), speed: Speed(50) },
SpeedConfig { temp: Temp(65), speed: Speed(80) },
SpeedConfig { temp: Temp(80), speed: Speed(100) },
],
delay: Some(1000),
force_speed: None,
help: false,
verbose: false,
};
std::fs::write(
CONFIG_PATH,
toml::to_string_pretty(&config).unwrap()
)
.unwrap();
return Ok(());
} else {
read_config()?
};
config.help = opts.help;
config.verbose = opts.verbose;
if opts.delay.is_some() {
config.delay = opts.delay;
}
config.force_speed = opts.force_speed;
eprintln!("Loaded config: {:?}", config);
let mut bus = match rppal::i2c::I2c::with_bus(1) {
Ok(bus) => bus,
Err(e) => {
Expand All @@ -31,27 +65,6 @@ fn main() -> std::io::Result<()> {
if let Err(e) = bus.set_slave_address(0x1a) {
panic!("Failed to set I2c address {}", e);
};

let mut config = read_config()?;
if opts.generate {
println!("Writing /etc/argononed.conf");
std::fs::write(
"/etc/argononed.conf",
r#"45=0
54=1
55=55
65=80
80=100
"#,
)
.unwrap();
return Ok(());
}
config.help = opts.help;
config.verbose = opts.verbose;
config.delay = opts.delay;
config.force_speed = opts.force_speed;
eprintln!("Loaded config: {:?}", config);
set_speed(&mut bus, &config);
Ok(())
}
Expand Down Expand Up @@ -105,7 +118,7 @@ fn read_temp(verbose: bool) -> Result<Temp, ConfigError> {
}

fn read_config() -> std::io::Result<Config> {
let contents = std::fs::read_to_string("/etc/argononed.conf")?;
let config: Config = contents.parse().unwrap();
let contents = std::fs::read_to_string(CONFIG_PATH)?;
let config: Config = toml::from_str(&contents).unwrap();
Ok(config)
}

0 comments on commit 127d080

Please sign in to comment.