Files
rpi-fan-control/src/main.rs
2025-05-25 22:03:00 +03:00

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");
}