josie / alder-tools

//! adlermon — Alder Lake monitor.
//!
//! Currently a dump tool: prints a one-shot sensor snapshot to stdout. The
//! TUI consumes the same `sensors` layer once the vCore source spike is done.

mod sensors;

use std::thread::sleep;
use std::time::{Duration, Instant};

use sensors::{cpu_frequencies, discover_chips, rapl_domains, rapl_energy_uj};

fn main() {
    println!("== hwmon ==");
    for chip in discover_chips() {
        println!("[{}] {}", chip.name, chip.path.display());
        for (label, volts) in sensors::voltages(&chip) {
            println!("  {:>18}: {:8.3} V", label, volts);
        }
        for (label, temp) in sensors::temperatures(&chip) {
            println!("  {:>18}: {:7.1} °C", label, temp);
        }
        for (label, rpm) in sensors::fans(&chip) {
            println!("  {:>18}: {:7.0} RPM", label, rpm);
        }
    }

    println!("\n== cpu frequency (MHz) ==");
    for (cpu, khz) in cpu_frequencies() {
        println!("  cpu{:>2}: {:8.1} MHz", cpu, khz as f64 / 1000.0);
    }

    println!("\n== RAPL power (sampled over 500 ms) ==");
    let domains = rapl_domains();
    let first: Vec<Option<u64>> = domains.iter().map(|d| rapl_energy_uj(&d.id)).collect();
    let start = Instant::now();
    sleep(Duration::from_millis(500));
    let elapsed = start.elapsed().as_secs_f64();
    for (domain, first) in domains.iter().zip(first) {
        match (first, rapl_energy_uj(&domain.id)) {
            (Some(a), Some(b)) if b >= a => {
                let watts = (b - a) as f64 / 1_000_000.0 / elapsed;
                println!("  {:>18} ({}): {:6.2} W", domain.name, domain.id, watts);
            }
            _ => println!("  {:>18} ({}): unreadable", domain.name, domain.id),
        }
    }
}