#[derive(Debug, Clone)] pub struct Config { pub status_pin: u8, pub fan_pin: u8, pub fan_on_temp_c: f64, pub fan_off_temp_c: f64, pub poll_interval_s: f64, pub thermal_alarm_temp_c: f64, pub influx: Option, pub renogy: RenogyConfig, } #[derive(Debug, Clone)] pub struct RenogyConfig { pub serial_path: Option, pub slave_address: u8, pub baud_rate: u32, pub poll_interval_s: f64, pub timeout_ms: u64, } #[derive(Debug, Clone)] pub struct InfluxConfig { pub url: String, pub org: String, pub bucket: String, pub token: String, pub host_tag: String, pub metrics_interval_s: f64, } impl Default for Config { fn default() -> Self { Self { status_pin: 4, fan_pin: 17, fan_on_temp_c: 35.0, fan_off_temp_c: 30.0, poll_interval_s: 2.0, thermal_alarm_temp_c: 80.0, influx: InfluxConfig::from_env(), renogy: RenogyConfig::from_env(), } } } impl RenogyConfig { pub fn from_env() -> Self { Self { serial_path: std::env::var("TOWERD_RENOGY_SERIAL").ok(), slave_address: std::env::var("TOWERD_RENOGY_SLAVE") .ok() .and_then(|s| s.parse().ok()) .unwrap_or(crate::renogy::registers::SLAVE_ADDRESS_DEFAULT), baud_rate: std::env::var("TOWERD_RENOGY_BAUD") .ok() .and_then(|s| s.parse().ok()) .unwrap_or(crate::renogy::registers::BAUD_RATE), poll_interval_s: std::env::var("TOWERD_RENOGY_INTERVAL_S") .ok() .and_then(|s| s.parse().ok()) .unwrap_or(10.0), timeout_ms: std::env::var("TOWERD_RENOGY_TIMEOUT_MS") .ok() .and_then(|s| s.parse().ok()) .unwrap_or(1000), } } } impl InfluxConfig { pub fn from_env() -> Option { let token = std::env::var("TOWERD_INFLUX_TOKEN").ok()?; let org = std::env::var("TOWERD_INFLUX_ORG").ok()?; let bucket = std::env::var("TOWERD_INFLUX_BUCKET").ok()?; Some(Self { url: std::env::var("TOWERD_INFLUX_URL") .unwrap_or_else(|_| "http://127.0.0.1:8086".into()), org, bucket, token, host_tag: std::env::var("TOWERD_INFLUX_HOST") .unwrap_or_else(|_| "kw1fox-1".into()), metrics_interval_s: std::env::var("TOWERD_INFLUX_INTERVAL_S") .ok() .and_then(|s| s.parse().ok()) .unwrap_or(30.0), }) } }