use std::fs;
use std::fs::{File, OpenOptions};
use std::io::Write;
use std::path::{Path, PathBuf};
use temp_dir::TempDir;
pub struct VirtualHwmonBuilder {
root: PathBuf,
index: u16,
}
#[allow(dead_code)]
impl VirtualHwmonBuilder {
pub fn create(
root: impl AsRef<Path>,
index: u16,
name: &str,
label: Option<&str>,
) -> VirtualHwmonBuilder {
let path = root.as_ref().join(format!("hwmon{}", index));
fs::create_dir_all(&path).unwrap();
File::create(path.join("name"))
.unwrap()
.write(name.as_ref())
.unwrap();
File::create(path.join("update_interval"))
.unwrap()
.write("1000".as_bytes())
.unwrap();
if let Some(label) = label {
File::create(path.join("label"))
.unwrap()
.write(label.as_ref())
.unwrap();
}
VirtualHwmonBuilder {
root: root.as_ref().to_path_buf(),
index,
}
}
pub fn add_temp(self, index: u16, functions: &[(&str, &str)]) -> VirtualHwmonBuilder {
for (function, value) in functions {
OpenOptions::new()
.read(true)
.write(true)
.create(true)
.truncate(true)
.open(self.path().join(format!("temp{}{}", index, function)))
.unwrap()
.write(value.as_bytes())
.unwrap();
}
self
}
pub fn add_fan(self, index: u16, functions: &[(&str, &str)]) -> VirtualHwmonBuilder {
for (function, value) in functions {
OpenOptions::new()
.read(true)
.write(true)
.create(true)
.truncate(true)
.open(self.path().join(format!("fan{}{}", index, function)))
.unwrap()
.write(value.as_bytes())
.unwrap();
}
self
}
pub fn add_pwm(self, index: u16, functions: &[(&str, &str)]) -> VirtualHwmonBuilder {
for (function, value) in functions {
OpenOptions::new()
.read(true)
.write(true)
.create(true)
.truncate(true)
.open(self.path().join(format!("pwm{}{}", index, function)))
.unwrap()
.write(value.as_bytes())
.unwrap();
}
self
}
pub fn path(&self) -> PathBuf {
self.root.join(format!("hwmon{}", self.index))
}
}
#[cfg(feature = "virtual_sensors")]
pub struct VirtualSensorBuilder {
path: PathBuf,
}
#[cfg(feature = "virtual_sensors")]
#[allow(dead_code)]
impl VirtualSensorBuilder {
pub fn create(path: impl AsRef<Path>, value: Option<&str>) -> VirtualSensorBuilder {
let path = path.as_ref();
fs::create_dir_all(path.parent().unwrap()).unwrap();
File::create(path)
.unwrap()
.write(value.unwrap_or_default().as_bytes())
.unwrap();
VirtualSensorBuilder {
path: path.to_path_buf(),
}
}
pub fn path(&self) -> PathBuf {
self.path.to_path_buf()
}
}
#[test]
#[cfg(feature = "sync")]
fn test_parse() {
use crate::sensors::sync_sensors::{temp::TempSensor, SyncSensor};
use crate::units::{Raw, Temperature};
let test_dir = TempDir::new().unwrap();
VirtualHwmonBuilder::create(test_dir.path(), 0, "system", None)
.add_fan(1, &[("_input", "1000")])
.add_fan(2, &[("_input", "1000")])
.add_pwm(1, &[("_enable", "1"), ("_mode", "1"), ("", "255")])
.add_pwm(2, &[("_enable", "1"), ("_mode", "1"), ("", "255")])
.add_temp(1, &[("_input", "40000"), ("_label", "temp1")])
.add_temp(2, &[("_input", "60000"), ("_label", "temp2")]);
VirtualHwmonBuilder::create(test_dir.path(), 1, "other", None)
.add_fan(1, &[("_input", "1000")])
.add_fan(2, &[("_input", "1000")])
.add_pwm(1, &[("_enable", "1"), ("_mode", "1"), ("", "255")])
.add_temp(1, &[("_input", "40000"), ("_label", "temp1")]);
let hwmons = crate::hwmon::sync_hwmon::Hwmons::parse_path(test_dir.path()).unwrap();
let hwmon0 = hwmons.hwmons_by_name("system").next().unwrap();
let hwmon1 = hwmons.hwmons_by_name("other").next().unwrap();
assert_eq!(hwmon0.name(), hwmons.hwmon_by_index(0).unwrap().name());
assert_eq!(hwmon1.name(), hwmons.hwmon_by_index(1).unwrap().name());
assert_eq!(hwmons.hwmon_by_index(2).is_none(), true);
assert_eq!(hwmons.hwmons_by_name("alias").next().is_none(), true);
assert_eq!(hwmon0.temps().len(), 2);
assert_eq!(hwmon1.temps().len(), 1);
assert_eq!(hwmon0.pwms().len(), 2);
assert_eq!(hwmon1.pwms().len(), 1);
hwmon0.pwms().get(&1u16).unwrap();
hwmon0.pwms().get(&2u16).unwrap();
hwmon1.pwms().get(&1u16).unwrap();
assert_eq!(
hwmon0.temps().get(&1u16).unwrap().read_input().unwrap(),
Temperature::from_raw("40000").unwrap()
);
assert_eq!(
hwmon0.temps().get(&2u16).unwrap().read_input().unwrap(),
Temperature::from_raw("60000").unwrap()
);
assert_eq!(
hwmon1.temps().get(&1u16).unwrap().read_input().unwrap(),
Temperature::from_raw("40000").unwrap()
);
assert_eq!(hwmon0.temps().get(&1u16).unwrap().name(), "temp1");
assert_eq!(hwmon0.temps().get(&2u16).unwrap().name(), "temp2");
assert_eq!(hwmon1.temps().get(&1u16).unwrap().name(), "temp1");
}
#[tokio::test]
#[cfg(feature = "async")]
async fn async_test_parse() {
use crate::sensors::async_sensors::{temp::AsyncTempSensor, AsyncSensor};
use crate::units::{Raw, Temperature};
let test_dir = TempDir::new().unwrap();
VirtualHwmonBuilder::create(test_dir.path(), 0, "system", None)
.add_fan(1, &[("_input", "1000")])
.add_fan(2, &[("_input", "1000")])
.add_pwm(1, &[("_enable", "1"), ("_mode", "1"), ("", "255")])
.add_pwm(2, &[("_enable", "1"), ("_mode", "1"), ("", "255")])
.add_temp(1, &[("_input", "40000"), ("_label", "temp1")])
.add_temp(2, &[("_input", "60000"), ("_label", "temp2")]);
VirtualHwmonBuilder::create(test_dir.path(), 1, "other", None)
.add_fan(1, &[("_input", "1000")])
.add_fan(2, &[("_input", "1000")])
.add_pwm(1, &[("_enable", "1"), ("_mode", "1"), ("", "255")])
.add_temp(1, &[("_input", "40000"), ("_label", "temp1")]);
let hwmons = crate::hwmon::async_hwmon::Hwmons::parse_path(test_dir.path())
.await
.unwrap();
let hwmon0 = hwmons.hwmons_by_name("system").next().unwrap();
let hwmon1 = hwmons.hwmons_by_name("other").next().unwrap();
assert_eq!(hwmon0.name(), hwmons.hwmon_by_index(0).unwrap().name());
assert_eq!(hwmon1.name(), hwmons.hwmon_by_index(1).unwrap().name());
assert_eq!(hwmons.hwmon_by_index(2).is_none(), true);
assert_eq!(hwmons.hwmons_by_name("alias").next().is_none(), true);
assert_eq!(hwmon0.temps().len(), 2);
assert_eq!(hwmon1.temps().len(), 1);
assert_eq!(hwmon0.pwms().len(), 2);
assert_eq!(hwmon1.pwms().len(), 1);
hwmon0.pwms().get(&1u16).unwrap();
hwmon0.pwms().get(&2u16).unwrap();
hwmon1.pwms().get(&1u16).unwrap();
assert_eq!(
hwmon0
.temps()
.get(&1u16)
.unwrap()
.read_input()
.await
.unwrap(),
Temperature::from_raw("40000").unwrap()
);
assert_eq!(
hwmon0
.temps()
.get(&2u16)
.unwrap()
.read_input()
.await
.unwrap(),
Temperature::from_raw("60000").unwrap()
);
assert_eq!(
hwmon1
.temps()
.get(&1u16)
.unwrap()
.read_input()
.await
.unwrap(),
Temperature::from_raw("40000").unwrap()
);
assert_eq!(hwmon0.temps().get(&1u16).unwrap().name().await, "temp1");
assert_eq!(hwmon0.temps().get(&2u16).unwrap().name().await, "temp2");
assert_eq!(hwmon1.temps().get(&1u16).unwrap().name().await, "temp1");
}