pub mod curr;
pub mod energy;
pub mod fan;
pub mod humidity;
pub mod intrusion;
pub mod power;
pub mod pwm;
pub mod temp;
pub mod voltage;
#[cfg(feature = "virtual_sensors")]
pub mod virt;
use super::{
error::{Error, Result},
Sensor, SensorState,
};
use crate::hwmon::sync_hwmon::Hwmon;
use crate::sensors::SensorSubFunctionType;
use crate::units::Raw;
use std::{
fs::read_to_string,
path::{Path, PathBuf},
time::Duration,
};
pub trait SyncSensor: Sensor {
fn name(&self) -> String {
self.read_raw(SensorSubFunctionType::Label)
.unwrap_or_else(|_| format!("{}{}", self.base(), self.index()))
}
fn state(&self) -> Result<SensorState> {
let mut states = std::collections::HashMap::new();
for &sub_type in SensorSubFunctionType::read_write_list() {
match self.read_raw(sub_type) {
Ok(value) => states.insert(sub_type, value),
Err(e) => match e {
Error::SubtypeNotSupported { .. } => continue,
_ => return Err(e),
},
};
}
Ok(SensorState { states })
}
fn read_raw(&self, sub_type: SensorSubFunctionType) -> Result<String> {
let path = self.subfunction_path(sub_type);
match read_to_string(&path) {
Ok(s) => Ok(s.trim().to_string()),
Err(e) => match e.kind() {
std::io::ErrorKind::NotFound => Err(Error::subtype_not_supported(sub_type)),
std::io::ErrorKind::PermissionDenied => Err(Error::insufficient_rights(path)),
_ => Err(Error::read(e, path)),
},
}
}
}
#[cfg(feature = "writeable")]
pub trait WriteableSensor: Sensor {
fn supported_write_sub_functions(&self) -> Vec<SensorSubFunctionType> {
SensorSubFunctionType::write_list()
.filter(|&s| {
std::fs::OpenOptions::new()
.write(true)
.open(self.subfunction_path(s))
.is_ok()
})
.collect()
}
fn supported_read_write_sub_functions(&self) -> Vec<SensorSubFunctionType> {
SensorSubFunctionType::read_write_list()
.iter()
.copied()
.filter(|&s| {
std::fs::OpenOptions::new()
.read(true)
.write(true)
.open(self.subfunction_path(s))
.is_ok()
})
.collect()
}
fn write_raw(&self, sub_type: SensorSubFunctionType, raw_value: &str) -> Result<()> {
let path = self.subfunction_path(sub_type);
std::fs::write(&path, raw_value.as_bytes()).map_err(|e| match e.kind() {
std::io::ErrorKind::NotFound => Error::subtype_not_supported(sub_type),
std::io::ErrorKind::PermissionDenied => Error::insufficient_rights(path),
_ => Error::write(e, path),
})
}
fn reset_history(&self) -> Result<()> {
self.write_raw(SensorSubFunctionType::ResetHistory, &true.to_raw())
}
fn write_state(&self, state: &SensorState) -> Result<()> {
if let Some(&sub_type) = state
.states
.keys()
.find(|s| !self.supported_write_sub_functions().contains(s))
{
return Err(Error::subtype_not_supported(sub_type));
}
self.write_state_lossy(state)
}
fn write_state_lossy(&self, state: &SensorState) -> Result<()> {
for (&sub_type, raw_value) in &state.states {
if let Err(e) = self.write_raw(sub_type, raw_value) {
match e {
Error::SubtypeNotSupported { .. } => continue,
_ => return Err(e),
}
}
}
Ok(())
}
}
fn inspect_sensor<S: Sensor>(sensor: S, primary_subfunction: SensorSubFunctionType) -> Result<S> {
let primary_path = sensor.subfunction_path(primary_subfunction);
if let Err(e) = primary_path.metadata() {
return Err(Error::read(e, primary_path));
}
Ok(sensor)
}
pub(crate) trait SyncSensorExt: SyncSensor + Sized {
fn parse(hwmon: &crate::hwmon::sync_hwmon::Hwmon, index: u16) -> Result<Self>;
}
#[cfg(test)]
mod tests;