84 lines
2.7 KiB
Rust
84 lines
2.7 KiB
Rust
mod config;
|
|
mod temperature;
|
|
mod fan;
|
|
|
|
use config::Config;
|
|
use temperature::TemperatureMonitor;
|
|
use fan::FanController;
|
|
use log::{info, error, LevelFilter};
|
|
use simplelog::{WriteLogger, Config as LogConfig};
|
|
use std::{fs::File, thread, time::Duration};
|
|
use std::process;
|
|
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
|
|
|
|
fn main() {
|
|
// Set up signal handling for clean shutdown
|
|
let running = Arc::new(AtomicBool::new(true));
|
|
let r = running.clone();
|
|
|
|
ctrlc::set_handler(move || {
|
|
info!("Received shutdown signal, exiting...");
|
|
r.store(false, Ordering::SeqCst);
|
|
}).expect("Error setting Ctrl-C handler");
|
|
|
|
// Load configuration
|
|
let config_path = "/var/fan_control/config.toml";
|
|
let config = match Config::load(config_path) {
|
|
Ok(config) => config,
|
|
Err(e) => {
|
|
eprintln!("Error loading configuration: {}", e);
|
|
process::exit(1);
|
|
}
|
|
};
|
|
|
|
// Initialize logging
|
|
if let Err(e) = WriteLogger::init(
|
|
LevelFilter::Info,
|
|
LogConfig::default(),
|
|
File::create(&config.log_path).unwrap_or_else(|_| {
|
|
eprintln!("Failed to open log file, logging to stdout");
|
|
process::exit(1);
|
|
}),
|
|
) {
|
|
eprintln!("Failed to initialize logger: {}", e);
|
|
process::exit(1);
|
|
}
|
|
|
|
info!("Fan control daemon starting");
|
|
info!("Configuration: temperature path={}, GPIO chip={}, GPIO line={}, threshold={}°C, variance={}°C",
|
|
config.temp_path, config.gpio_chip, config.gpio_line, config.threshold, config.variance);
|
|
|
|
// Initialize temperature monitor
|
|
let temp_monitor = TemperatureMonitor::new(config.temp_path);
|
|
|
|
// Initialize fan controller
|
|
let mut fan_controller = match FanController::new(config.gpio_chip, config.gpio_line) {
|
|
Ok(controller) => controller,
|
|
Err(e) => {
|
|
error!("Failed to initialize fan controller: {}", e);
|
|
process::exit(1);
|
|
}
|
|
};
|
|
|
|
// Main loop
|
|
info!("Entering main control loop");
|
|
while running.load(Ordering::SeqCst) {
|
|
// Read temperature
|
|
match temp_monitor.read_celsius() {
|
|
Ok(temperature) => {
|
|
// Update fan state based on temperature
|
|
if let Err(e) = fan_controller.update(temperature, config.threshold, config.variance) {
|
|
error!("Failed to update fan state: {}", e);
|
|
}
|
|
},
|
|
Err(e) => {
|
|
error!("Failed to read temperature: {}", e);
|
|
}
|
|
}
|
|
|
|
// Sleep for the configured interval
|
|
thread::sleep(Duration::from_millis(config.interval_ms));
|
|
}
|
|
|
|
info!("Fan control daemon shutting down");
|
|
} |