mirror of
https://codeberg.org/icewind/palantir.git
synced 2026-06-03 10:14:09 +02:00
hwmon abstraction wip
This commit is contained in:
parent
553c16f225
commit
197f19d3a1
3 changed files with 124 additions and 33 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
|
use crate::hwmon::FileSource;
|
||||||
use crate::sensors::Memory;
|
use crate::sensors::Memory;
|
||||||
use crate::FileSource;
|
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::fs::read_to_string;
|
use std::fs::read_to_string;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
|
||||||
122
src/hwmon.rs
Normal file
122
src/hwmon.rs
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
use std::fs::{read_dir, read_to_string, File};
|
||||||
|
use std::io;
|
||||||
|
use std::io::{ErrorKind, Read, Seek};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
fn read_to_string_trimmed(path: &Path) -> io::Result<String> {
|
||||||
|
let mut s = read_to_string(path)?;
|
||||||
|
let len = s.trim().len();
|
||||||
|
s.truncate(len);
|
||||||
|
Ok(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FileSource {
|
||||||
|
buff: String,
|
||||||
|
file: File,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FileSource {
|
||||||
|
pub fn open<P: AsRef<Path>>(path: P) -> io::Result<FileSource> {
|
||||||
|
Ok(FileSource {
|
||||||
|
buff: String::with_capacity(32),
|
||||||
|
file: File::open(path)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read<T>(&mut self) -> io::Result<T>
|
||||||
|
where
|
||||||
|
T: FromStr,
|
||||||
|
<T as FromStr>::Err: std::error::Error + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
self.buff.clear();
|
||||||
|
self.file.rewind()?;
|
||||||
|
self.file.read_to_string(&mut self.buff)?;
|
||||||
|
self.buff
|
||||||
|
.trim()
|
||||||
|
.parse()
|
||||||
|
.map_err(|e| io::Error::new(ErrorKind::InvalidData, e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Device {
|
||||||
|
base_path: PathBuf,
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Device {
|
||||||
|
pub fn new(path: PathBuf) -> io::Result<Device> {
|
||||||
|
let name = read_to_string_trimmed(&path.join("name"))?;
|
||||||
|
Ok(Device {
|
||||||
|
base_path: path,
|
||||||
|
name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list() -> impl Iterator<Item = io::Result<Device>> {
|
||||||
|
let sensors = read_dir("/sys/class/hwmon").into_iter().flatten();
|
||||||
|
sensors.map(|device| device.and_then(|device| Device::new(device.path())))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sensors(&self) -> impl Iterator<Item = io::Result<Sensor>> {
|
||||||
|
// determine early to avoid borrowing &self in iterator
|
||||||
|
let is_cpu_thermal = self.name == "cpu_thermal";
|
||||||
|
|
||||||
|
let sensors = read_dir(&self.base_path).into_iter().flatten();
|
||||||
|
sensors
|
||||||
|
.filter_map(|sensor| {
|
||||||
|
let sensor = match sensor {
|
||||||
|
Ok(sensor) => sensor,
|
||||||
|
Err(e) => return Some(Err(e)),
|
||||||
|
};
|
||||||
|
|
||||||
|
if sensor.file_name().to_str()?.ends_with("_input") {
|
||||||
|
Some(Ok(sensor.path()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map(move |path| {
|
||||||
|
let path = path?;
|
||||||
|
|
||||||
|
let input_name = path.file_name().unwrap().to_str().unwrap();
|
||||||
|
|
||||||
|
// rpi cpu_thermal doesn't have labels, so we hardcode one
|
||||||
|
if is_cpu_thermal && input_name == "temp1_input" {
|
||||||
|
return Ok(Sensor {
|
||||||
|
input_path: path,
|
||||||
|
name: "Tdie".into(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let base_name = input_name.trim_end_matches("_input");
|
||||||
|
|
||||||
|
let label_name = path.with_file_name(format!("{base_name}_label"));
|
||||||
|
let name = read_to_string_trimmed(&label_name)?;
|
||||||
|
|
||||||
|
Ok(Sensor {
|
||||||
|
input_path: path,
|
||||||
|
name,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Sensor {
|
||||||
|
input_path: PathBuf,
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sensor {
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reader(&self) -> io::Result<FileSource> {
|
||||||
|
FileSource::open(&self.input_path)
|
||||||
|
}
|
||||||
|
}
|
||||||
33
src/lib.rs
33
src/lib.rs
|
|
@ -1,6 +1,7 @@
|
||||||
pub mod disk;
|
pub mod disk;
|
||||||
pub mod docker;
|
pub mod docker;
|
||||||
pub mod gpu;
|
pub mod gpu;
|
||||||
|
pub mod hwmon;
|
||||||
pub mod power;
|
pub mod power;
|
||||||
pub mod sensors;
|
pub mod sensors;
|
||||||
|
|
||||||
|
|
@ -10,10 +11,6 @@ use crate::disk::*;
|
||||||
use crate::sensors::*;
|
use crate::sensors::*;
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::fs::File;
|
|
||||||
use std::io::{ErrorKind, Read, Seek};
|
|
||||||
use std::path::Path;
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
pub fn get_metrics() -> Result<String> {
|
pub fn get_metrics() -> Result<String> {
|
||||||
let disk_usage = disk_usage()?;
|
let disk_usage = disk_usage()?;
|
||||||
|
|
@ -119,31 +116,3 @@ pub fn get_metrics() -> Result<String> {
|
||||||
}
|
}
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FileSource {
|
|
||||||
buff: String,
|
|
||||||
file: File,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FileSource {
|
|
||||||
pub fn open<P: AsRef<Path>>(path: P) -> std::io::Result<FileSource> {
|
|
||||||
Ok(FileSource {
|
|
||||||
buff: String::with_capacity(32),
|
|
||||||
file: File::open(path)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read<T>(&mut self) -> std::io::Result<T>
|
|
||||||
where
|
|
||||||
T: FromStr,
|
|
||||||
<T as FromStr>::Err: std::error::Error + Send + Sync + 'static,
|
|
||||||
{
|
|
||||||
self.buff.clear();
|
|
||||||
self.file.rewind()?;
|
|
||||||
self.file.read_to_string(&mut self.buff)?;
|
|
||||||
self.buff
|
|
||||||
.trim()
|
|
||||||
.parse()
|
|
||||||
.map_err(|e| std::io::Error::new(ErrorKind::InvalidData, e))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue