use crate::sensor_names::{CPU_NAMES, DISK_NAMES, TEMP_NAMES};
use anyhow::{anyhow, Result};
use core::f64;
use serde::Deserialize;
use std::{collections::BTreeMap, process::Command};
#[derive(Debug)]
pub struct SensorData {
chips: BTreeMap<String, Sensor>,
}
impl SensorData {
pub fn cpu_chip(&self) -> Option<&Sensor> {
for cpu_name in CPU_NAMES {
if let Some(chip) = self.chips.get(cpu_name) {
return Some(chip);
}
}
None
}
pub fn disk_chip(&self) -> Option<&Sensor> {
for disk_name in DISK_NAMES {
if let Some(chip) = self.chips.get(disk_name) {
return Some(chip);
}
}
None
}
}
#[derive(Debug, Deserialize)]
pub struct Sensor {
#[serde(rename = "Adapter")]
_adapter: String,
#[serde(rename = "Tctl", skip_serializing_if = "Option::is_none")]
tctl: Option<BTreeMap<String, f64>>,
#[serde(rename = "Tccd1", skip_serializing_if = "Option::is_none")]
tccd1: Option<BTreeMap<String, f64>>,
#[serde(skip_serializing_if = "Option::is_none")]
temp1: Option<BTreeMap<String, f64>>,
#[serde(skip_serializing_if = "Option::is_none")]
temp2: Option<BTreeMap<String, f64>>,
#[serde(rename = "Package id 0", skip_serializing_if = "Option::is_none")]
package_id_0: Option<BTreeMap<String, f64>>,
#[serde(rename = "Composite", skip_serializing_if = "Option::is_none")]
composite: Option<BTreeMap<String, f64>>,
}
impl Sensor {
pub fn temp(&self) -> Option<f64> {
let temperatures = self.actual_sector()?;
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.temp2.is_some() {
return self.temp2.clone();
}
if self.package_id_0.is_some() {
return self.package_id_0.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 sensors_data: Result<BTreeMap<String, Sensor>, serde_json::Error> =
serde_json::from_str(&json_output);
match sensors_data {
Ok(chips) => Ok(SensorData { chips }),
Err(err) => Err(anyhow!(err)),
}
} else {
Err(anyhow!(String::from_utf8_lossy(&output.stderr).to_string()))
}
}