mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2025-02-25 18:55:26 -06:00
Added pci.ids path for ubuntu and fixed crash for GPUs without hwmon interface
This commit is contained in:
parent
55bc2ee468
commit
d5d0829e4e
@ -1,7 +1,7 @@
|
||||
use crate::config::Config;
|
||||
use crate::hw_mon::{HWMon, HWMonError};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{collections::BTreeMap, fs};
|
||||
use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice};
|
||||
|
||||
@ -27,7 +27,7 @@ pub struct FanControlInfo {
|
||||
#[derive(Clone)]
|
||||
pub struct GpuController {
|
||||
hw_path: PathBuf,
|
||||
hw_mon: HWMon,
|
||||
hw_mon: Option<HWMon>,
|
||||
pub gpu_info: GpuInfo,
|
||||
config: Config,
|
||||
config_path: PathBuf,
|
||||
@ -58,18 +58,19 @@ pub struct GpuInfo {
|
||||
|
||||
impl GpuController {
|
||||
pub fn new(hw_path: PathBuf, config: Config, config_path: PathBuf) -> Self {
|
||||
let hwmon_path = fs::read_dir(&hw_path.join("hwmon"))
|
||||
.unwrap()
|
||||
.next()
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
.path();
|
||||
|
||||
let hw_mon = match fs::read_dir(&hw_path.join("hwmon")) {
|
||||
Ok(mut path) => {
|
||||
let path = path.next().unwrap().unwrap().path();
|
||||
let hw_mon = HWMon::new(
|
||||
&hwmon_path,
|
||||
&path,
|
||||
config.fan_control_enabled,
|
||||
config.fan_curve.clone(),
|
||||
);
|
||||
Some(hw_mon)
|
||||
},
|
||||
_ => None,
|
||||
};
|
||||
|
||||
|
||||
let mut controller = GpuController {
|
||||
hw_path: hw_path.clone(),
|
||||
@ -95,17 +96,17 @@ impl GpuController {
|
||||
|
||||
for line in uevent.split('\n') {
|
||||
let split = line.split('=').collect::<Vec<&str>>();
|
||||
match split[0] {
|
||||
"DRIVER" => driver = split[1].to_string(),
|
||||
"PCI_ID" => {
|
||||
let ids = split[1].split(':').collect::<Vec<&str>>();
|
||||
vendor_id = ids[0].to_string();
|
||||
model_id = ids[1].to_string();
|
||||
match split.get(0).unwrap() {
|
||||
&"DRIVER" => driver = split.get(1).unwrap().to_string(),
|
||||
&"PCI_ID" => {
|
||||
let ids = split.last().expect("failed to get split").split(':').collect::<Vec<&str>>();
|
||||
vendor_id = ids.get(0).unwrap().to_string();
|
||||
model_id = ids.get(0).unwrap().to_string();
|
||||
}
|
||||
"PCI_SUBSYS_ID" => {
|
||||
let ids = split[1].split(':').collect::<Vec<&str>>();
|
||||
card_vendor_id = ids[0].to_string();
|
||||
card_model_id = ids[1].to_string();
|
||||
&"PCI_SUBSYS_ID" => {
|
||||
let ids = split.last().expect("failed to get split").split(':').collect::<Vec<&str>>();
|
||||
card_vendor_id = ids.get(0).unwrap().to_string();
|
||||
card_model_id = ids.get(1).unwrap().to_string();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
@ -116,9 +117,14 @@ impl GpuController {
|
||||
let mut card_vendor = String::new();
|
||||
let mut card_model = String::new();
|
||||
|
||||
let full_hwid_list = fs::read_to_string("/usr/share/hwdata/pci.ids")
|
||||
.expect("Could not read pci.ids. Perhaps the \"hwids\" package is not installed?");
|
||||
let mut full_hwid_list = String::new();
|
||||
if Path::exists(&PathBuf::from("/usr/share/hwdata/pci.ids")) {
|
||||
full_hwid_list = fs::read_to_string("/usr/share/hwdata/pci.ids").unwrap();
|
||||
} else if Path::exists(&PathBuf::from("/usr/share/misc/pci.ids")) {
|
||||
full_hwid_list = fs::read_to_string("/usr/share/misc/pci.ids").unwrap();
|
||||
}
|
||||
|
||||
if !full_hwid_list.is_empty() {
|
||||
//some weird space character, don't touch
|
||||
let pci_id_line = format!(" {}", model_id.to_lowercase());
|
||||
let card_ids_line = format!(
|
||||
@ -135,7 +141,7 @@ impl GpuController {
|
||||
|
||||
if line.len() > card_vendor_id.len() {
|
||||
if line[0..card_vendor_id.len()] == card_vendor_id.to_lowercase() {
|
||||
card_vendor = line.splitn(2, ' ').collect::<Vec<&str>>()[1]
|
||||
card_vendor = line.splitn(2, ' ').collect::<Vec<&str>>().last().unwrap()
|
||||
.trim_start()
|
||||
.to_string();
|
||||
}
|
||||
@ -147,6 +153,9 @@ impl GpuController {
|
||||
card_model = line[card_ids_line.len()..].trim_start().to_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
let vbios_version = match fs::read_to_string(self.hw_path.join("vbios_version")) {
|
||||
Ok(v) => v,
|
||||
@ -199,11 +208,10 @@ impl GpuController {
|
||||
Err(_) => 0,
|
||||
};
|
||||
|
||||
let (mem_freq, gpu_freq) = (self.hw_mon.get_mem_freq(), self.hw_mon.get_gpu_freq());
|
||||
let gpu_temp = self.hw_mon.get_gpu_temp();
|
||||
let (power_avg, power_max) = (self.hw_mon.get_power_avg(), self.hw_mon.get_power_cap());
|
||||
let fan_speed = self.hw_mon.get_fan_speed();
|
||||
let max_fan_speed = self.hw_mon.fan_max_speed;
|
||||
let (mem_freq, gpu_freq, gpu_temp, power_avg, power_max, fan_speed, max_fan_speed) = match &self.hw_mon {
|
||||
Some(hw_mon) => (hw_mon.get_mem_freq(), hw_mon.get_gpu_freq(), hw_mon.get_gpu_temp(), hw_mon.get_power_avg(), hw_mon.get_power_cap(), hw_mon.get_fan_speed(), hw_mon.fan_max_speed),
|
||||
None => (0, 0, 0, 0, 0, 0, 0),
|
||||
};
|
||||
|
||||
GpuStats {
|
||||
mem_total,
|
||||
@ -219,7 +227,10 @@ impl GpuController {
|
||||
}
|
||||
|
||||
pub fn start_fan_control(&mut self) -> Result<(), HWMonError> {
|
||||
match self.hw_mon.start_fan_control() {
|
||||
match &self.hw_mon {
|
||||
Some(hw_mon) => {
|
||||
|
||||
match hw_mon.start_fan_control() {
|
||||
Ok(_) => {
|
||||
self.config.fan_control_enabled = true;
|
||||
self.config
|
||||
@ -229,10 +240,15 @@ impl GpuController {
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
},
|
||||
None => Err(HWMonError::NoHWMon),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stop_fan_control(&mut self) -> Result<(), HWMonError> {
|
||||
match self.hw_mon.stop_fan_control() {
|
||||
match &self.hw_mon {
|
||||
Some(hw_mon) => {
|
||||
match hw_mon.stop_fan_control() {
|
||||
Ok(_) => {
|
||||
self.config.fan_control_enabled = false;
|
||||
self.config
|
||||
@ -242,23 +258,37 @@ impl GpuController {
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
},
|
||||
None => Err(HWMonError::NoHWMon),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_fan_control(&self) -> FanControlInfo {
|
||||
let control = self.hw_mon.get_fan_control();
|
||||
|
||||
FanControlInfo {
|
||||
pub fn get_fan_control(&self) -> Result<FanControlInfo, HWMonError> {
|
||||
match &self.hw_mon {
|
||||
Some(hw_mon) => {
|
||||
let control = hw_mon.get_fan_control();
|
||||
Ok(FanControlInfo {
|
||||
enabled: control.0,
|
||||
curve: control.1,
|
||||
}
|
||||
})
|
||||
},
|
||||
None => Err(HWMonError::NoHWMon),
|
||||
}
|
||||
|
||||
pub fn set_fan_curve(&mut self, curve: BTreeMap<i32, f64>) {
|
||||
self.hw_mon.set_fan_curve(curve.clone());
|
||||
}
|
||||
|
||||
pub fn set_fan_curve(&mut self, curve: BTreeMap<i32, f64>) -> Result<(), HWMonError> {
|
||||
match &self.hw_mon {
|
||||
Some(hw_mon) => {
|
||||
hw_mon.set_fan_curve(curve.clone());
|
||||
self.config.fan_curve = curve;
|
||||
self.config
|
||||
.save(&self.config_path)
|
||||
.expect("Failed to save config");
|
||||
Ok(())
|
||||
},
|
||||
None => Err(HWMonError::NoHWMon),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_vulkan_info(pci_id: &str) -> VulkanInfo {
|
||||
|
@ -15,6 +15,7 @@ use serde::{Deserialize, Serialize};
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub enum HWMonError {
|
||||
PermissionDenied,
|
||||
NoHWMon,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -150,7 +150,10 @@ impl Daemon {
|
||||
None => Err(DaemonError::InvalidID),
|
||||
},
|
||||
Action::GetFanControl(i) => match gpu_controllers.get(&i) {
|
||||
Some(controller) => Ok(DaemonResponse::FanControlInfo(controller.get_fan_control())),
|
||||
Some(controller) => match controller.get_fan_control() {
|
||||
Ok(info) => Ok(DaemonResponse::FanControlInfo(info)),
|
||||
Err(_) => Err(DaemonError::HWMonError),
|
||||
}
|
||||
None => Err(DaemonError::InvalidID),
|
||||
}
|
||||
Action::SetFanCurve(i, curve) => match gpu_controllers.get_mut(&i) {
|
||||
@ -159,9 +162,11 @@ impl Daemon {
|
||||
let mut buffer = Vec::new();
|
||||
stream.read_to_end(&mut buffer).unwrap();
|
||||
|
||||
controller.set_fan_curve(curve);
|
||||
match controller.set_fan_curve(curve) {
|
||||
Ok(_) => Ok(DaemonResponse::OK),
|
||||
Err(_) => Err(DaemonError::HWMonError),
|
||||
}
|
||||
|
||||
Ok(DaemonResponse::OK)
|
||||
},
|
||||
None => Err(DaemonError::InvalidID),
|
||||
}
|
||||
|
@ -146,8 +146,10 @@ fn build_ui(application: >k::Application) {
|
||||
glib::Continue(true)
|
||||
});
|
||||
|
||||
let fan_control = d.get_fan_control(current_gpu_id).unwrap();
|
||||
let fan_control = d.get_fan_control(current_gpu_id);
|
||||
|
||||
match fan_control {
|
||||
Ok(ref fan_control) => {
|
||||
if fan_control.enabled {
|
||||
println!("Automatic fan control disabled!");
|
||||
automatic_fan_control_switch.set_active(false);
|
||||
@ -156,6 +158,15 @@ fn build_ui(application: >k::Application) {
|
||||
println!("Automatic fan control enabled");
|
||||
fan_curve_frame.set_visible(false);
|
||||
}
|
||||
},
|
||||
Err(_) => {
|
||||
automatic_fan_control_switch.set_sensitive(false);
|
||||
automatic_fan_control_switch.set_tooltip_text(Some("Unavailable"));
|
||||
|
||||
fan_curve_frame.set_visible(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let b = apply_button.clone();
|
||||
|
||||
@ -173,6 +184,9 @@ fn build_ui(application: >k::Application) {
|
||||
b.set_sensitive(true);
|
||||
});
|
||||
|
||||
match fan_control {
|
||||
Ok(fan_control) => {
|
||||
|
||||
let curve: Arc<RwLock<BTreeMap<i32, f64>>> = Arc::new(RwLock::new(fan_control.curve));
|
||||
|
||||
for i in 1..6 {
|
||||
@ -222,6 +236,10 @@ fn build_ui(application: >k::Application) {
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
Err(_) => (),
|
||||
}
|
||||
|
||||
|
||||
main_window.set_application(Some(application));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user