first commit
This commit is contained in:
13
src/cli.rs
Normal file
13
src/cli.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use structopt::StructOpt;
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
#[structopt(
|
||||
name = "temp",
|
||||
about = "Simple personal CLI to gather machine temperatures."
|
||||
)]
|
||||
pub enum Arguments {
|
||||
#[structopt(about = "Temperature in Celsius, ONLY AMD")]
|
||||
CPU,
|
||||
#[structopt(about = "Temperature in Celsius, ONLY NVIDIA")]
|
||||
GPU,
|
||||
}
|
92
src/lm_sensors.rs
Normal file
92
src/lm_sensors.rs
Normal file
@ -0,0 +1,92 @@
|
||||
use anyhow::anyhow;
|
||||
use anyhow::Result;
|
||||
use core::f64;
|
||||
use serde::Deserialize;
|
||||
use std::collections::BTreeMap;
|
||||
use std::process::Command;
|
||||
|
||||
pub struct SensorData {
|
||||
chips: BTreeMap<String, Sensor>,
|
||||
}
|
||||
|
||||
impl SensorData {
|
||||
pub fn cpu_chip(&self) -> Option<&Sensor> {
|
||||
let cpu_names = vec!["k10temp-pci-00c3"];
|
||||
for cpu_name in cpu_names {
|
||||
if let Some(chip) = self.chips.get(cpu_name) {
|
||||
return Some(chip);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Sensor {
|
||||
#[serde(rename = "Adapter")]
|
||||
_adapter: String,
|
||||
|
||||
#[serde(rename = "Tctl")]
|
||||
tctl: Option<BTreeMap<String, f64>>,
|
||||
|
||||
#[serde(rename = "Tccd1")]
|
||||
tccd1: Option<BTreeMap<String, f64>>,
|
||||
temp1: Option<BTreeMap<String, f64>>,
|
||||
|
||||
#[serde(rename = "Composite")]
|
||||
composite: Option<BTreeMap<String, f64>>,
|
||||
}
|
||||
|
||||
impl Sensor {
|
||||
pub fn temp(&self) -> Option<f64> {
|
||||
let sensor = self.actual_sector();
|
||||
match sensor {
|
||||
None => return None,
|
||||
Some(temperatures) => {
|
||||
let temp_names = vec!["temp1_input"];
|
||||
for temp_name in temp_names {
|
||||
if let Some(temp) = temperatures.get(temp_name) {
|
||||
return Some(*temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn actual_sector(&self) -> Option<BTreeMap<String, f64>> {
|
||||
if self.tctl.is_some() {
|
||||
return self.tctl.clone();
|
||||
}
|
||||
|
||||
if self.tccd1.is_some() {
|
||||
return self.tccd1.clone();
|
||||
}
|
||||
|
||||
if self.temp1.is_some() {
|
||||
return self.temp1.clone();
|
||||
}
|
||||
|
||||
if self.composite.is_some() {
|
||||
return self.composite.clone();
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sensors_data() -> Result<SensorData> {
|
||||
let output = Command::new("sensors").arg("-j").output()?;
|
||||
|
||||
if output.status.success() {
|
||||
let json_output = String::from_utf8_lossy(&output.stdout).to_string();
|
||||
let sensor_data: Result<BTreeMap<String, Sensor>, serde_json::Error> =
|
||||
serde_json::from_str(&json_output);
|
||||
match sensor_data {
|
||||
Ok(data) => Ok(SensorData { chips: data }),
|
||||
Err(err) => Err(anyhow!(err)),
|
||||
}
|
||||
} else {
|
||||
Err(anyhow!(String::from_utf8_lossy(&output.stderr).to_string()))
|
||||
}
|
||||
}
|
38
src/main.rs
Normal file
38
src/main.rs
Normal file
@ -0,0 +1,38 @@
|
||||
mod cli;
|
||||
mod lm_sensors;
|
||||
mod nvidia_smi;
|
||||
use cli::Arguments;
|
||||
use lm_sensors::sensors_data;
|
||||
use nvidia_smi::temperature;
|
||||
use structopt::StructOpt;
|
||||
|
||||
fn main() {
|
||||
let opts = Arguments::from_args();
|
||||
match opts {
|
||||
Arguments::CPU => print_cpu_temp(),
|
||||
Arguments::GPU => print_gpu_temp(),
|
||||
}
|
||||
}
|
||||
|
||||
fn print_cpu_temp() {
|
||||
let sensors_data = sensors_data();
|
||||
match sensors_data {
|
||||
Ok(sensors) => {
|
||||
let cpu_chip = sensors.cpu_chip();
|
||||
if let Some(chip) = cpu_chip {
|
||||
if let Some(temp) = chip.temp() {
|
||||
println!("{}", temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn print_gpu_temp() {
|
||||
let gpu_temp_data = temperature();
|
||||
match gpu_temp_data {
|
||||
Ok(temp) => println!("{}", temp),
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
21
src/nvidia_smi.rs
Normal file
21
src/nvidia_smi.rs
Normal file
@ -0,0 +1,21 @@
|
||||
use anyhow::anyhow;
|
||||
use anyhow::Result;
|
||||
use std::process::Command;
|
||||
use std::result::Result::Ok;
|
||||
|
||||
pub fn temperature() -> Result<f64> {
|
||||
let output = Command::new("nvidia-smi")
|
||||
.arg("--query-gpu=temperature.gpu")
|
||||
.arg("--format=csv,noheader")
|
||||
.output()?;
|
||||
if output.status.success() {
|
||||
let string_temp = String::from_utf8_lossy(&output.stdout).to_string();
|
||||
let clean_temp = string_temp.trim();
|
||||
match &clean_temp.parse::<f64>() {
|
||||
Ok(temp) => Ok(*temp),
|
||||
Err(err) => Err(anyhow!(err.to_string())),
|
||||
}
|
||||
} else {
|
||||
Err(anyhow!(String::from_utf8_lossy(&output.stderr).to_string()))
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user