cpu_temp/temperature/
hwmon.rs1use std::fs;
5use std::path::PathBuf;
6
7#[derive(Clone)]
9pub struct HwmonSensor {
10 pub path: PathBuf,
12 pub name: String,
14}
15
16pub fn find_cpu_hwmon_sensors() -> anyhow::Result<Vec<HwmonSensor>> {
18 let mut sensors = Vec::new();
19
20 for entry in fs::read_dir("/sys/class/hwmon")? {
21 let entry = entry?;
22 let path = entry.path();
23
24 if !path.is_dir() {
25 continue;
26 }
27
28 let name = path.file_name().and_then(|n| n.to_str()).unwrap_or("");
29
30 let hwmon_name_path = path.join("name");
32 let hwmon_name = fs::read_to_string(&hwmon_name_path).ok();
33
34 if let Some(ref name_str) = hwmon_name {
36 if name_str.contains("coretemp") || name_str.contains("cpu") {
37 let sensor = HwmonSensor {
38 path: path.clone(),
39 name: name_str.clone(),
40 };
41 sensors.push(sensor);
42 continue;
43 }
44 }
45
46 let temp_input_path = path.join("temp1_input");
48 if temp_input_path.exists() {
49 let sensor = HwmonSensor {
50 path: path.clone(),
51 name: hwmon_name.unwrap_or_else(|| name.to_string()),
52 };
53 sensors.push(sensor);
54 }
55 }
56
57 sensors.sort_by(|a, b| {
59 if a.name.contains("coretemp") {
60 std::cmp::Ordering::Less
61 } else if b.name.contains("coretemp") {
62 std::cmp::Ordering::Greater
63 } else {
64 a.name.cmp(&b.name)
65 }
66 });
67
68 Ok(sensors)
69}
70
71#[derive(Debug, Clone)]
73pub struct HwmonTempData {
74 pub id: u32,
75 pub name: String,
76 pub temperature: f32,
77}
78
79pub fn read_hwmon_temperatures(sensor: &HwmonSensor) -> anyhow::Result<Vec<HwmonTempData>> {
81 let mut temps = Vec::new();
82 let mut id = 1;
83
84 loop {
85 let temp_label = sensor.path.join(format!("temp{}_label", id));
86 let temp_input = sensor.path.join(format!("temp{}_input", id));
87
88 if !temp_input.exists() {
89 break;
90 }
91
92 let temp_name = if temp_label.exists() {
93 fs::read_to_string(&temp_label)
94 .ok()
95 .and_then(|s| {
96 let s = s.trim().to_string();
97 if s.is_empty() { None } else { Some(s) }
98 })
99 .unwrap_or(format!("temp{}", id))
100 } else {
101 format!("temp{}", id)
102 };
103
104 let value = fs::read_to_string(&temp_input)?;
105 let temperature = value.trim().parse::<f32>()? / 1000.0;
106
107 temps.push(HwmonTempData {
108 id,
109 name: temp_name,
110 temperature,
111 });
112
113 id += 1;
114 }
115
116 Ok(temps)
117}
118
119pub fn get_tj_max() -> f32 {
122 let cpuinfo_path = "/proc/cpuinfo";
124 if let Ok(content) = fs::read_to_string(cpuinfo_path) {
125 for line in content.lines() {
126 if line.starts_with("cpu M") && line.contains("TjMax") {
127 if let Some(value_str) = line.split(':').nth(1) {
128 if let Ok(value) = value_str.trim().parse::<f32>() {
129 return value;
130 }
131 }
132 }
133 }
134 }
135
136 100.0
139}