From 95b66ce8f75118871df6dd488fc2d63875b65795 Mon Sep 17 00:00:00 2001 From: wiiznokes <78230769+wiiznokes@users.noreply.github.com> Date: Mon, 13 Nov 2023 21:18:25 +0100 Subject: [PATCH 1/8] rename fake --- hardware/src/{hardware_test.rs => fake_hardware.rs} | 4 ++-- hardware/src/lib.rs | 2 +- src/integrated_test.rs | 4 ++-- src/main.rs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) rename hardware/src/{hardware_test.rs => fake_hardware.rs} (96%) diff --git a/hardware/src/hardware_test.rs b/hardware/src/fake_hardware.rs similarity index 96% rename from hardware/src/hardware_test.rs rename to hardware/src/fake_hardware.rs index 7ad975fc..8daaa4ea 100644 --- a/hardware/src/hardware_test.rs +++ b/hardware/src/fake_hardware.rs @@ -4,7 +4,7 @@ use rand::Rng; use crate::{ControlH, Hardware, HardwareBridge, HardwareError, HardwareItem, TempH, Value}; -pub struct TestBridge {} +pub struct FakeHardwareBridge {} #[derive(Debug)] struct InternalSensor {} @@ -12,7 +12,7 @@ struct InternalSensor {} #[derive(Debug)] struct InternalControl {} -impl HardwareBridge for TestBridge { +impl HardwareBridge for FakeHardwareBridge { fn generate_hardware() -> Hardware { let mut hardware = Hardware::default(); diff --git a/hardware/src/lib.rs b/hardware/src/lib.rs index 45a1db2a..ed6dfa7c 100644 --- a/hardware/src/lib.rs +++ b/hardware/src/lib.rs @@ -14,7 +14,7 @@ pub mod linux; pub mod windows; #[cfg(feature = "fake_hardware")] -pub mod hardware_test; +pub mod fake_hardware; #[derive(Debug, Clone)] pub enum HardwareError { diff --git a/src/integrated_test.rs b/src/integrated_test.rs index 92db6775..bf3f9fb7 100644 --- a/src/integrated_test.rs +++ b/src/integrated_test.rs @@ -5,7 +5,7 @@ use std::time::Duration; use data::directories::DirManager; use data::{config::Config, node::AppGraph, update::Update, AppState}; -use hardware::{hardware_test, HardwareBridge}; +use hardware::{fake_hardware, HardwareBridge}; #[test] fn test_config() { @@ -14,7 +14,7 @@ fn test_config() { let dir_manager = DirManager::new(Some(PathBuf::from("./.config"))); let settings = dir_manager.init_settings(); - let hardware = hardware_test::TestBridge::generate_hardware(); + let hardware = fake_hardware::FakeHardwareBridge::generate_hardware(); DirManager::serialize(&dir_manager.hardware_file_path(), &hardware).unwrap(); let config = DirManager::deserialize::( diff --git a/src/main.rs b/src/main.rs index afea8bf7..53c03424 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,7 +21,7 @@ fn main() { let settings = dir_manager.init_settings(); #[cfg(feature = "fake_hardware")] - let hardware = hardware::hardware_test::TestBridge::generate_hardware(); + let hardware = hardware::fake_hardware::FakeHardwareBridge::generate_hardware(); #[cfg(all(not(feature = "fake_hardware"), target_os = "linux"))] let hardware = hardware::linux::LinuxBridge::generate_hardware(); From 5b51b8892e77a91e5e5057b42faf1d1f862e533b Mon Sep 17 00:00:00 2001 From: wiiznokes <78230769+wiiznokes@users.noreply.github.com> Date: Mon, 13 Nov 2023 21:37:20 +0100 Subject: [PATCH 2/8] update windows --- hardware/Cargo.toml | 8 ++-- hardware/src/lib.rs | 4 +- hardware/src/linux.rs | 76 +++++++++++++++++----------------- hardware/src/windows.rs | 90 ++++++++++++++++++++++++++++++++++++++--- src/main.rs | 4 +- 5 files changed, 131 insertions(+), 51 deletions(-) diff --git a/hardware/Cargo.toml b/hardware/Cargo.toml index 501d38a8..f267703d 100644 --- a/hardware/Cargo.toml +++ b/hardware/Cargo.toml @@ -8,14 +8,14 @@ fake_hardware = ["rand"] [dependencies] -serde.workspace = true -serde_json.workspace = true log.workspace = true - - rand = {version = "0.8", optional = true} [target.'cfg(target_os = "linux")'.dependencies] lm-sensors = { git = "https://github.com/wiiznokes/lm-sensors.git", branch = "pwm" } +serde.workspace = true +serde_json.workspace = true + + [dev-dependencies] \ No newline at end of file diff --git a/hardware/src/lib.rs b/hardware/src/lib.rs index ed6dfa7c..ec59b919 100644 --- a/hardware/src/lib.rs +++ b/hardware/src/lib.rs @@ -7,10 +7,10 @@ use std::{fmt::Debug, rc::Rc}; #[macro_use] extern crate log; -#[cfg(all(not(feature = "fake_hardware"), target_os = "linux"))] +#[cfg(all(not(feature = "fake_hardware"), target_os = "windows"))] pub mod linux; -#[cfg(all(not(feature = "fake_hardware"), target_os = "windows"))] +#[cfg(all(not(feature = "fake_hardware"), target_os = "linux"))] pub mod windows; #[cfg(feature = "fake_hardware")] diff --git a/hardware/src/linux.rs b/hardware/src/linux.rs index 8e6a21c6..417a2b33 100644 --- a/hardware/src/linux.rs +++ b/hardware/src/linux.rs @@ -6,44 +6,6 @@ use crate::{ControlH, FanH, Hardware, HardwareBridge, HardwareError, HardwareIte pub struct LinuxBridge {} -#[derive(Debug, Clone, PartialEq, Eq)] -enum SubFeatureType { - PwmIo, - PwmEnable, - Fan, - Temp, -} - -struct InternalSubFeatureRef { - sub_feature_type: SubFeatureType, - sub_feature_ref: SubFeatureRef<'static>, -} - -impl Debug for InternalSubFeatureRef { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("InternalSubFeatureRef") - .field("sub_feature_type", &self.sub_feature_type) - .finish() - } -} -#[derive(Debug)] -struct InternalSensor { - sensor: InternalSubFeatureRef, -} - -#[derive(Debug)] -struct InternalControl { - io: InternalSubFeatureRef, - enable: InternalSubFeatureRef, -} - -impl Drop for InternalControl { - fn drop(&mut self) { - info!("pwm sould be set to auto"); - // TODO: set to auto - } -} - impl HardwareBridge for LinuxBridge { fn generate_hardware() -> Hardware { let mut hardware = Hardware::default(); @@ -196,6 +158,44 @@ fn generate_hardware(lib: &'static LMSensors, hardware: &mut Hardware) { } } +#[derive(Debug, Clone, PartialEq, Eq)] +enum SubFeatureType { + PwmIo, + PwmEnable, + Fan, + Temp, +} + +struct InternalSubFeatureRef { + sub_feature_type: SubFeatureType, + sub_feature_ref: SubFeatureRef<'static>, +} + +impl Debug for InternalSubFeatureRef { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("InternalSubFeatureRef") + .field("sub_feature_type", &self.sub_feature_type) + .finish() + } +} +#[derive(Debug)] +struct InternalSensor { + sensor: InternalSubFeatureRef, +} + +#[derive(Debug)] +struct InternalControl { + io: InternalSubFeatureRef, + enable: InternalSubFeatureRef, +} + +impl Drop for InternalControl { + fn drop(&mut self) { + info!("pwm sould be set to auto"); + // TODO: set to auto + } +} + impl HardwareItem for InternalSensor { fn get_value(&self) -> Result { match self.sensor.sub_feature_ref.raw_value() { diff --git a/hardware/src/windows.rs b/hardware/src/windows.rs index 9fe43953..5d34102f 100644 --- a/hardware/src/windows.rs +++ b/hardware/src/windows.rs @@ -1,8 +1,8 @@ -use std::{io::Read, net::TcpStream}; +use std::{io::Read, net::TcpStream, rc::Rc}; use serde::Deserialize; -use crate::{Hardware, HardwareBridge}; +use crate::{ControlH, Hardware, HardwareBridge, HardwareItem, Value, HardwareError}; pub struct WindowsBridge {} @@ -24,13 +24,15 @@ struct BaseHardware { name: String, #[serde(rename = "Index")] index: usize, + #[serde(rename = "Index2")] + index2: usize, #[serde(rename = "Type")] hardware_type: HardwareType, } impl HardwareBridge for WindowsBridge { fn generate_hardware() -> Hardware { - let hardware = Hardware::default(); + let mut hardware = Hardware::default(); let mut stream = try_connect(); println!("Connected to the server!"); @@ -38,8 +40,36 @@ impl HardwareBridge for WindowsBridge { let mut data = String::new(); stream.read_to_string(&mut data).unwrap(); let base_hardware_list = serde_json::from_str::>(&data).unwrap(); - - dbg!(&base_hardware_list); + + for base_hardware in base_hardware_list { + match base_hardware.hardware_type { + HardwareType::Control => hardware.controls.push(Rc::new(ControlH { + name: base_hardware.name, + hardware_id: base_hardware.id, + info: String::new(), + bridge: Box::new(InternalControl { + io: base_hardware.index, + enable: base_hardware.index2, + }), + })), + HardwareType::Fan => hardware.controls.push(Rc::new(ControlH { + name: base_hardware.name, + hardware_id: base_hardware.id, + info: String::new(), + bridge: Box::new(InternalSensor { + index: base_hardware.index, + }), + })), + HardwareType::Temp => hardware.controls.push(Rc::new(ControlH { + name: base_hardware.name, + hardware_id: base_hardware.id, + info: String::new(), + bridge: Box::new(InternalSensor { + index: base_hardware.index, + }), + })), + } + } hardware } @@ -54,3 +84,53 @@ fn try_connect() -> TcpStream { } panic!("can't find connection") } + + +#[derive(Debug)] +struct InternalSensor { + index: usize, +} + +#[derive(Debug)] +struct InternalControl { + io: usize, + enable: usize, +} + +impl Drop for InternalControl { + fn drop(&mut self) { + info!("pwm sould be set to auto"); + // TODO: set to auto + } +} + +impl HardwareItem for InternalSensor { + fn get_value(&self) -> Result { + println!("get value"); + return Ok(4); + } + + fn set_value(&self, value: Value) -> Result<(), crate::HardwareError> { + panic!("can't set the value of a sensor"); + } + + fn set_mode(&self, value: Value) -> Result<(), HardwareError> { + panic!("can't set the mode of a sensor"); + } +} + +impl HardwareItem for InternalControl { + fn get_value(&self) -> Result { + panic!("can't get the value of a control"); + } + + fn set_value(&self, value: Value) -> Result<(), crate::HardwareError> { + debug!("set value {} to a control", value); + Ok(()) + } + + fn set_mode(&self, value: Value) -> Result<(), HardwareError> { + debug!("set mode {} to a control", value); + Ok(()) + } +} diff --git a/src/main.rs b/src/main.rs index 53c03424..9c8bb2a3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,10 +23,10 @@ fn main() { #[cfg(feature = "fake_hardware")] let hardware = hardware::fake_hardware::FakeHardwareBridge::generate_hardware(); - #[cfg(all(not(feature = "fake_hardware"), target_os = "linux"))] + #[cfg(all(not(feature = "fake_hardware"), target_os = "windows"))] let hardware = hardware::linux::LinuxBridge::generate_hardware(); - #[cfg(all(not(feature = "fake_hardware"), target_os = "windows"))] + #[cfg(all(not(feature = "fake_hardware"), target_os = "linux"))] let hardware = hardware::windows::WindowsBridge::generate_hardware(); let hardware_file_path = dir_manager.hardware_file_path(); From 1235040e1998d8305594084e4adfdbbbb19fa447 Mon Sep 17 00:00:00 2001 From: wiiznokes <78230769+wiiznokes@users.noreply.github.com> Date: Mon, 13 Nov 2023 23:15:10 +0100 Subject: [PATCH 3/8] update windows code --- Makefile | 3 + .../Hardware/BaseHardware.cs | 23 ++++- .../Hardware/Control.cs | 3 +- .../Hardware/LHM.cs | 13 +-- .../Hardware/Sensor.cs | 3 +- .../LibreHardwareMonitorWrapper/Program.cs | 2 +- .../LibreHardwareMonitorWrapper/Server.cs | 84 ++++++++++++++++--- hardware/LibreHardwareMonitorWrapper/State.cs | 7 -- hardware/src/windows.rs | 50 +++++------ 9 files changed, 132 insertions(+), 56 deletions(-) diff --git a/Makefile b/Makefile index c9b4718c..f4238fad 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,9 @@ clean-libsensors: lhm: dotnet build ./hardware/LibreHardwareMonitorWrapper/ -c release +run-lhm: + dotnet run --project ./hardware/LibreHardwareMonitorWrapper/ -c release + test: cargo test --all --all-features diff --git a/hardware/LibreHardwareMonitorWrapper/Hardware/BaseHardware.cs b/hardware/LibreHardwareMonitorWrapper/Hardware/BaseHardware.cs index 39af82b3..287ce758 100644 --- a/hardware/LibreHardwareMonitorWrapper/Hardware/BaseHardware.cs +++ b/hardware/LibreHardwareMonitorWrapper/Hardware/BaseHardware.cs @@ -1,19 +1,36 @@ namespace LibreHardwareMonitorWrapper.Hardware; +public enum HardwareType +{ + Control = 1, + Fan = 2, + Temp = 3 +} + +public enum Command +{ + SetAuto = 1, + SetValue = 2, + + // command -> type -> index -> value + GetValue = 3, + Shutdown = 4 +} + public abstract class BaseHardware { - protected BaseHardware(string id, string name, int index, HardwareType type) + protected BaseHardware(string id, string name, string info, int index, HardwareType type) { Id = id; Name = name; Index = index; Type = type; + Info = info; } public string Id { get; } public string Name { get; } + public string Info { get; } public int Index { get; } - - public HardwareType Type { get; } } \ No newline at end of file diff --git a/hardware/LibreHardwareMonitorWrapper/Hardware/Control.cs b/hardware/LibreHardwareMonitorWrapper/Hardware/Control.cs index 5ee1f4d6..680f6941 100644 --- a/hardware/LibreHardwareMonitorWrapper/Hardware/Control.cs +++ b/hardware/LibreHardwareMonitorWrapper/Hardware/Control.cs @@ -7,7 +7,8 @@ public class Control : BaseHardware private readonly ISensor _mSensor; private bool _isSetSpeed; - public Control(string id, string name, ISensor sensor, int index) : base(id, name, index, HardwareType.Control) + public Control(string id, string name, string info, ISensor sensor, int index) : base(id, name, info, index, + HardwareType.Control) { _mSensor = sensor; } diff --git a/hardware/LibreHardwareMonitorWrapper/Hardware/LHM.cs b/hardware/LibreHardwareMonitorWrapper/Hardware/LHM.cs index 65114d49..40863f87 100644 --- a/hardware/LibreHardwareMonitorWrapper/Hardware/LHM.cs +++ b/hardware/LibreHardwareMonitorWrapper/Hardware/LHM.cs @@ -82,6 +82,9 @@ public void CreateHardware() } } + Console.WriteLine("nbControl: " + nbControl); + Console.WriteLine("nbFan: " + nbFan); + Console.WriteLine("nbTemp: " + nbTemp); return; void AddHardware(ISensor sensor) @@ -96,17 +99,17 @@ void AddHardware(ISensor sensor) { case SensorType.Control: id ??= SensorType.Control.ToString() + nbControl; - State.Controls.Add(new Control(id, name, sensor, nbControl)); + State.Controls.Add(new Control(id, name, name, sensor, nbControl)); nbControl += 1; break; case SensorType.Fan: - id ??= SensorType.Control.ToString() + nbFan; - State.Fans.Add(new Sensor(id, name, sensor, nbFan, HardwareType.Fan)); + id ??= SensorType.Fan.ToString() + nbFan; + State.Fans.Add(new Sensor(id, name, name, sensor, nbFan, HardwareType.Fan)); nbFan += 1; break; case SensorType.Temperature: - id ??= SensorType.Control.ToString() + nbTemp; - State.Temps.Add(new Sensor(id, name, sensor, nbTemp, HardwareType.Temp)); + id ??= SensorType.Temperature.ToString() + nbTemp; + State.Temps.Add(new Sensor(id, name, name, sensor, nbTemp, HardwareType.Temp)); nbTemp += 1; break; diff --git a/hardware/LibreHardwareMonitorWrapper/Hardware/Sensor.cs b/hardware/LibreHardwareMonitorWrapper/Hardware/Sensor.cs index 583e92fe..033c326a 100644 --- a/hardware/LibreHardwareMonitorWrapper/Hardware/Sensor.cs +++ b/hardware/LibreHardwareMonitorWrapper/Hardware/Sensor.cs @@ -6,7 +6,8 @@ public class Sensor : BaseHardware { private readonly ISensor _mSensor; - public Sensor(string id, string name, ISensor sensor, int index, HardwareType type) : base(id, name, index, type) + public Sensor(string id, string name, string info, ISensor sensor, int index, HardwareType type) : base(id, name, + info, index, type) { _mSensor = sensor; } diff --git a/hardware/LibreHardwareMonitorWrapper/Program.cs b/hardware/LibreHardwareMonitorWrapper/Program.cs index c42a7050..a1de21d6 100644 --- a/hardware/LibreHardwareMonitorWrapper/Program.cs +++ b/hardware/LibreHardwareMonitorWrapper/Program.cs @@ -17,10 +17,10 @@ var jsonText = JsonSerializer.Serialize(hardwareList, serializerOptions); - var server = new Server(); server.SendHardware(jsonText); +server.WaitForCommand(); server.Shutdown(); \ No newline at end of file diff --git a/hardware/LibreHardwareMonitorWrapper/Server.cs b/hardware/LibreHardwareMonitorWrapper/Server.cs index ef9553de..059977c4 100644 --- a/hardware/LibreHardwareMonitorWrapper/Server.cs +++ b/hardware/LibreHardwareMonitorWrapper/Server.cs @@ -1,6 +1,7 @@ using System.Net; using System.Net.Sockets; using System.Text; +using LibreHardwareMonitorWrapper.Hardware; namespace LibreHardwareMonitorWrapper; @@ -10,6 +11,7 @@ public class Server private readonly Socket _client; private readonly Socket _listener; private int _port = 55555; + private readonly byte[] _buffer = new byte[1024]; public Server() { @@ -25,31 +27,87 @@ public void SendHardware(string jsonText) { var stream = new NetworkStream(_client); var bytes = Encoding.UTF8.GetBytes(jsonText); + Console.WriteLine("Sending hardware" + jsonText); stream.Write(bytes); + Console.WriteLine("Hardware send"); } public void WaitForCommand() { - var buffer = new byte[1024]; - var bytesRead = _client.Receive(buffer); + while (true) + { + Console.WriteLine("waiting for commands"); + if (!block_read()) return; + var command = (Command)BitConverter.ToInt32(_buffer, 0); + Console.WriteLine("Receive command: " + command); + + int value; + int index; + switch (command) + { + case Command.SetAuto: + if (!block_read()) return; + index = BitConverter.ToInt32(_buffer, 0); + State.Controls[index].SetAuto(); + break; + case Command.SetValue: + if (!block_read()) return; + index = BitConverter.ToInt32(_buffer, 0); + if (!block_read()) return; + value = BitConverter.ToInt32(_buffer, 0); + State.Controls[index].SetSpeed(value); + break; + case Command.GetValue: + if (!block_read()) return; + index = BitConverter.ToInt32(_buffer, 0); + if (!block_read()) return; + var type = (HardwareType)BitConverter.ToInt32(_buffer, 0); - var message = Encoding.ASCII.GetString(buffer, 0, bytesRead); - Console.WriteLine("Received: " + message); + value = type switch + { + HardwareType.Fan => State.Fans[index].Value(), + HardwareType.Temp => State.Temps[index].Value(), + _ => throw new ArgumentOutOfRangeException() + }; - // var responseBuffer = Encoding.ASCII.GetBytes("Hello from C#"); - var responseBuffer = "Hello from C#"u8.ToArray(); - _client.Send(responseBuffer); + var bytes = BitConverter.GetBytes(value); + if (!block_send(bytes)) return; + break; + case Command.Shutdown: + return; + default: + throw new ArgumentOutOfRangeException(); + } + } } - public void JustWait() + private bool block_send(byte[] bytes) { - var buffer = new byte[1024]; - var bytesRead = _client.Receive(buffer); - - var message = Encoding.ASCII.GetString(buffer, 0, bytesRead); - Console.WriteLine("Received: " + message); + try + { + var bytesSend = _client.Send(bytes); + return bytesSend != 0; + } + catch (Exception e) + { + Console.WriteLine(e); + return false; + } } + private bool block_read() + { + try + { + var bytesRead = _client.Receive(_buffer); + return bytesRead != 0; + } + catch (Exception e) + { + Console.WriteLine(e); + return false; + } + } private void BindPort() { diff --git a/hardware/LibreHardwareMonitorWrapper/State.cs b/hardware/LibreHardwareMonitorWrapper/State.cs index 8af1a1a8..43bbd22c 100644 --- a/hardware/LibreHardwareMonitorWrapper/State.cs +++ b/hardware/LibreHardwareMonitorWrapper/State.cs @@ -2,13 +2,6 @@ namespace LibreHardwareMonitorWrapper; -public enum HardwareType -{ - Control, - Fan, - Temp -} - public static class State { public static readonly List Controls = new(); diff --git a/hardware/src/windows.rs b/hardware/src/windows.rs index 5d34102f..53bcc0f4 100644 --- a/hardware/src/windows.rs +++ b/hardware/src/windows.rs @@ -9,27 +9,6 @@ pub struct WindowsBridge {} const IP: &str = "127.0.0.1"; const DEFAULT_PORT: u16 = 55555; -#[derive(Deserialize, Debug, Clone)] -enum HardwareType { - Control, - Fan, - Temp, -} - -#[derive(Deserialize, Debug, Clone)] -struct BaseHardware { - #[serde(rename = "Id")] - id: String, - #[serde(rename = "Name")] - name: String, - #[serde(rename = "Index")] - index: usize, - #[serde(rename = "Index2")] - index2: usize, - #[serde(rename = "Type")] - hardware_type: HardwareType, -} - impl HardwareBridge for WindowsBridge { fn generate_hardware() -> Hardware { let mut hardware = Hardware::default(); @@ -48,8 +27,7 @@ impl HardwareBridge for WindowsBridge { hardware_id: base_hardware.id, info: String::new(), bridge: Box::new(InternalControl { - io: base_hardware.index, - enable: base_hardware.index2, + index: base_hardware.index, }), })), HardwareType::Fan => hardware.controls.push(Rc::new(ControlH { @@ -86,6 +64,26 @@ fn try_connect() -> TcpStream { } +#[derive(Deserialize, Debug, Clone)] +enum HardwareType { + Control = 1, + Fan = 2, + Temp = 3, +} + +#[derive(Deserialize, Debug, Clone)] +struct BaseHardware { + #[serde(rename = "Id")] + id: String, + #[serde(rename = "Name")] + name: String, + #[serde(rename = "Index")] + index: usize, + #[serde(rename = "Type")] + hardware_type: HardwareType, +} + + #[derive(Debug)] struct InternalSensor { index: usize, @@ -93,8 +91,7 @@ struct InternalSensor { #[derive(Debug)] struct InternalControl { - io: usize, - enable: usize, + index: usize, } impl Drop for InternalControl { @@ -134,3 +131,6 @@ impl HardwareItem for InternalControl { Ok(()) } } + + + From 868d8a83a36d648d273d3e16cd78c2def9f5b386 Mon Sep 17 00:00:00 2001 From: wiiznokes <78230769+wiiznokes@users.noreply.github.com> Date: Tue, 14 Nov 2023 00:01:37 +0100 Subject: [PATCH 4/8] fix eof --- .../LibreHardwareMonitorWrapper/Server.cs | 18 +++++--- hardware/src/windows.rs | 41 ++++++++++++------- 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/hardware/LibreHardwareMonitorWrapper/Server.cs b/hardware/LibreHardwareMonitorWrapper/Server.cs index 059977c4..30f6c628 100644 --- a/hardware/LibreHardwareMonitorWrapper/Server.cs +++ b/hardware/LibreHardwareMonitorWrapper/Server.cs @@ -8,10 +8,10 @@ namespace LibreHardwareMonitorWrapper; public class Server { private const string Address = "127.0.0.1"; + private readonly byte[] _buffer = new byte[1024]; private readonly Socket _client; private readonly Socket _listener; private int _port = 55555; - private readonly byte[] _buffer = new byte[1024]; public Server() { @@ -25,10 +25,16 @@ public Server() public void SendHardware(string jsonText) { + var stringBuilder = new StringBuilder(jsonText); + stringBuilder.Append('\n'); + + var jsonTextWithLineDelimiter = stringBuilder.ToString(); + var stream = new NetworkStream(_client); - var bytes = Encoding.UTF8.GetBytes(jsonText); - Console.WriteLine("Sending hardware" + jsonText); + var bytes = Encoding.UTF8.GetBytes(jsonTextWithLineDelimiter); + Console.WriteLine("Sending hardware" + jsonTextWithLineDelimiter); stream.Write(bytes); + stream.Close(); Console.WriteLine("Hardware send"); } @@ -40,7 +46,7 @@ public void WaitForCommand() if (!block_read()) return; var command = (Command)BitConverter.ToInt32(_buffer, 0); Console.WriteLine("Receive command: " + command); - + int value; int index; switch (command) @@ -100,7 +106,9 @@ private bool block_read() try { var bytesRead = _client.Receive(_buffer); - return bytesRead != 0; + if (bytesRead != 0) return true; + Console.WriteLine("byte read == 0"); + return false; } catch (Exception e) { diff --git a/hardware/src/windows.rs b/hardware/src/windows.rs index 53bcc0f4..4f43f218 100644 --- a/hardware/src/windows.rs +++ b/hardware/src/windows.rs @@ -1,8 +1,12 @@ -use std::{io::Read, net::TcpStream, rc::Rc}; +use std::{ + io::{BufRead, BufReader}, + net::TcpStream, + rc::Rc, +}; use serde::Deserialize; -use crate::{ControlH, Hardware, HardwareBridge, HardwareItem, Value, HardwareError}; +use crate::{ControlH, Hardware, HardwareBridge, HardwareError, HardwareItem, Value}; pub struct WindowsBridge {} @@ -13,13 +17,13 @@ impl HardwareBridge for WindowsBridge { fn generate_hardware() -> Hardware { let mut hardware = Hardware::default(); - let mut stream = try_connect(); - println!("Connected to the server!"); + let stream = try_connect(); let mut data = String::new(); - stream.read_to_string(&mut data).unwrap(); + let mut buff_reader = BufReader::new(&stream); + buff_reader.read_line(&mut data).unwrap(); let base_hardware_list = serde_json::from_str::>(&data).unwrap(); - + for base_hardware in base_hardware_list { match base_hardware.hardware_type { HardwareType::Control => hardware.controls.push(Rc::new(ControlH { @@ -56,14 +60,16 @@ impl HardwareBridge for WindowsBridge { fn try_connect() -> TcpStream { for port in DEFAULT_PORT..65535 { match TcpStream::connect((IP, port)) { - Ok(stream) => return stream, + Ok(stream) => { + info!("connected to {}:{}", IP, port); + return stream; + } Err(_) => continue, } } panic!("can't find connection") } - #[derive(Deserialize, Debug, Clone)] enum HardwareType { Control = 1, @@ -71,6 +77,16 @@ enum HardwareType { Temp = 3, } +#[derive(Debug, Clone)] +enum Command { + SetAuto = 1, + SetValue = 2, + + // command -> type -> index -> value + GetValue = 3, + Shutdown = 4, +} + #[derive(Deserialize, Debug, Clone)] struct BaseHardware { #[serde(rename = "Id")] @@ -83,7 +99,6 @@ struct BaseHardware { hardware_type: HardwareType, } - #[derive(Debug)] struct InternalSensor { index: usize, @@ -102,9 +117,8 @@ impl Drop for InternalControl { } impl HardwareItem for InternalSensor { - fn get_value(&self) -> Result { - println!("get value"); - return Ok(4); + fn get_value(&self) -> Result { + Ok(4) } fn set_value(&self, value: Value) -> Result<(), crate::HardwareError> { @@ -131,6 +145,3 @@ impl HardwareItem for InternalControl { Ok(()) } } - - - From 4d2324438be397f0941427f0ac0b7a7e11b573b0 Mon Sep 17 00:00:00 2001 From: wiiznokes <78230769+wiiznokes@users.noreply.github.com> Date: Tue, 14 Nov 2023 02:28:28 +0100 Subject: [PATCH 5/8] windows sould work (no process management) --- Cargo.lock | 59 +++++++++ data/src/config/control.rs | 26 ++-- data/src/config/fan.rs | 8 +- data/src/config/serde_test.rs | 25 +--- data/src/config/temp.rs | 8 +- data/src/lib.rs | 3 +- data/src/update.rs | 30 +++-- hardware/Cargo.toml | 1 + .../Hardware/BaseHardware.cs | 36 ------ .../HardwareManager.cs | 32 ++--- .../{Hardware => Lhm}/Control.cs | 0 .../LHM.cs => Lhm/HardwareResearcher.cs} | 14 ++- .../{Hardware => Lhm}/Sensor.cs | 2 +- .../LibreHardwareMonitorWrapper/Program.cs | 6 +- .../LibreHardwareMonitorWrapper/Server.cs | 49 ++++---- hardware/LibreHardwareMonitorWrapper/State.cs | 44 +++++-- hardware/src/lib.rs | 24 ++-- hardware/src/windows.rs | 119 +++++++++++------- src/main.rs | 3 +- ui/src/lib.rs | 1 + 20 files changed, 285 insertions(+), 205 deletions(-) delete mode 100644 hardware/LibreHardwareMonitorWrapper/Hardware/BaseHardware.cs rename hardware/LibreHardwareMonitorWrapper/{Hardware => Lhm}/Control.cs (100%) rename hardware/LibreHardwareMonitorWrapper/{Hardware/LHM.cs => Lhm/HardwareResearcher.cs} (86%) rename hardware/LibreHardwareMonitorWrapper/{Hardware => Lhm}/Sensor.cs (89%) diff --git a/Cargo.lock b/Cargo.lock index d51b6dd2..26ade36e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1287,6 +1287,7 @@ version = "0.1.0" dependencies = [ "lm-sensors", "log", + "ouroboros", "rand", "serde", "serde_json", @@ -1575,6 +1576,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" @@ -2121,6 +2131,31 @@ dependencies = [ "libredox 0.0.2", ] +[[package]] +name = "ouroboros" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c86de06555b970aec45229b27291b53154f21a5743a163419f4e4c0b065dcde" +dependencies = [ + "aliasable", + "ouroboros_macro", + "static_assertions", +] + +[[package]] +name = "ouroboros_macro" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cad0c4b129e9696e37cb712b243777b90ef489a0bfaa0ac34e7d9b860e4f134" +dependencies = [ + "heck", + "itertools", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "owned_ttf_parser" version = "0.20.0" @@ -2368,6 +2403,30 @@ dependencies = [ "toml_edit 0.20.7", ] +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.69" diff --git a/data/src/config/control.rs b/data/src/config/control.rs index ac5b3f68..a049135f 100644 --- a/data/src/config/control.rs +++ b/data/src/config/control.rs @@ -1,6 +1,6 @@ use std::rc::Rc; -use hardware::{ControlH, Hardware, Value}; +use hardware::{ControlH, Hardware, HardwareBridgeT, Value}; use serde::{Deserialize, Serialize}; use crate::{ @@ -42,26 +42,32 @@ impl Control { } } - pub fn set_value(&mut self, value: Value) -> Result { + pub fn set_value( + &mut self, + value: Value, + bridge: &mut HardwareBridgeT, + ) -> Result { if !self.manual_has_been_set { - self.set_mode(false)?; + self.set_mode(false, bridge)?; } match &self.control_h { - Some(control_h) => control_h - .bridge - .set_value(value) + Some(control_h) => bridge + .set_value(&control_h.internal_index.io, value) .map(|_| value) .map_err(UpdateError::Hardware), None => Err(UpdateError::NodeIsInvalid), } } - pub fn set_mode(&mut self, auto: bool) -> Result<(), UpdateError> { + pub fn set_mode( + &mut self, + auto: bool, + bridge: &mut HardwareBridgeT, + ) -> Result<(), UpdateError> { let res = match &self.control_h { - Some(control_h) => control_h - .bridge - .set_mode(!auto as i32) + Some(control_h) => bridge + .set_mode(&control_h.internal_index.enable, !auto as i32) .map_err(UpdateError::Hardware), None => Err(UpdateError::NodeIsInvalid), }; diff --git a/data/src/config/fan.rs b/data/src/config/fan.rs index b1f89973..b9fd902d 100644 --- a/data/src/config/fan.rs +++ b/data/src/config/fan.rs @@ -1,6 +1,6 @@ use std::rc::Rc; -use hardware::{FanH, Hardware, Value}; +use hardware::{FanH, Hardware, HardwareBridgeT, Value}; use serde::{Deserialize, Serialize}; use crate::{ @@ -20,9 +20,11 @@ pub struct Fan { } impl Fan { - pub fn get_value(&self) -> Result { + pub fn get_value(&self, bridge: &mut HardwareBridgeT) -> Result { match &self.fan_h { - Some(fan_h) => fan_h.bridge.get_value().map_err(UpdateError::Hardware), + Some(fan_h) => bridge + .get_value(&fan_h.internal_index) + .map_err(UpdateError::Hardware), None => Err(UpdateError::NodeIsInvalid), } } diff --git a/data/src/config/serde_test.rs b/data/src/config/serde_test.rs index 800a232d..aa7defdb 100644 --- a/data/src/config/serde_test.rs +++ b/data/src/config/serde_test.rs @@ -1,5 +1,5 @@ use const_format::formatcp; -use hardware::{ControlH, FanH, Hardware, HardwareItem, TempH}; +use hardware::{ControlH, FanH, Hardware, InternalControlIndex, TempH}; use serial_test::serial; use std::fmt::Debug; use std::fs::{self, File}; @@ -95,44 +95,27 @@ fn write_file(path: &str, content_generation: impl Fn() -> Result Result { - todo!() - } - - fn set_value(&self, _value: hardware::Value) -> Result<(), hardware::HardwareError> { - todo!() - } - - fn set_mode(&self, _value: hardware::Value) -> Result<(), hardware::HardwareError> { - todo!() - } -} - fn hardware1() -> Hardware { Hardware { controls: vec![ControlH { name: "ControlH".into(), hardware_id: "ControlH".into(), info: "ControlH".into(), - bridge: Box::new(T {}), + internal_index: InternalControlIndex { io: 0, enable: 0 }, } .into()], temps: vec![TempH { name: "TempH".into(), hardware_id: "TempH".into(), info: "TempH".into(), - bridge: Box::new(T {}), + internal_index: 0, } .into()], fans: vec![FanH { name: "FanH".into(), hardware_id: "FanH".into(), info: "FanH".into(), - bridge: Box::new(T {}), + internal_index: 0, } .into()], } diff --git a/data/src/config/temp.rs b/data/src/config/temp.rs index 81d6af47..8e990d91 100644 --- a/data/src/config/temp.rs +++ b/data/src/config/temp.rs @@ -1,6 +1,6 @@ use std::rc::Rc; -use hardware::{Hardware, TempH, Value}; +use hardware::{Hardware, HardwareBridgeT, TempH, Value}; use serde::{Deserialize, Serialize}; use crate::{ @@ -20,9 +20,11 @@ pub struct Temp { } impl Temp { - pub fn get_value(&self) -> Result { + pub fn get_value(&self, bridge: &mut HardwareBridgeT) -> Result { match &self.temp_h { - Some(temp_h) => temp_h.bridge.get_value().map_err(UpdateError::Hardware), + Some(temp_h) => bridge + .get_value(&temp_h.internal_index) + .map_err(UpdateError::Hardware), None => Err(UpdateError::NodeIsInvalid), } } diff --git a/data/src/lib.rs b/data/src/lib.rs index 75147167..cca0c057 100644 --- a/data/src/lib.rs +++ b/data/src/lib.rs @@ -13,7 +13,7 @@ pub mod node; pub mod settings; pub mod update; -use hardware::{Hardware, HardwareBridge}; +use hardware::{Hardware, HardwareBridge, HardwareBridgeT}; use node::AppGraph; use update::Update; @@ -25,6 +25,7 @@ pub struct AppState { pub dir_manager: DirManager, pub settings: Settings, pub hardware: Hardware, + pub bridge: HardwareBridgeT, pub app_graph: AppGraph, pub update: Update, } diff --git a/data/src/update.rs b/data/src/update.rs index be32fe72..c8a9b9a8 100644 --- a/data/src/update.rs +++ b/data/src/update.rs @@ -1,6 +1,6 @@ use std::collections::HashSet; -use hardware::{HardwareError, Value}; +use hardware::{HardwareBridgeT, HardwareError, Value}; use crate::{ id::Id, @@ -30,11 +30,16 @@ impl Update { Self {} } - pub fn graph(&mut self, nodes: &mut Nodes, root_nodes: &RootNodes) -> Result<(), UpdateError> { + pub fn graph( + &mut self, + nodes: &mut Nodes, + root_nodes: &RootNodes, + bridge: &mut HardwareBridgeT, + ) -> Result<(), UpdateError> { let mut updated: HashSet = HashSet::new(); for node_id in root_nodes { - Self::update_rec(nodes, node_id, &mut updated)?; + Self::update_rec(nodes, node_id, &mut updated, bridge)?; } Ok(()) } @@ -45,6 +50,7 @@ impl Update { nodes: &mut Nodes, node_id: &Id, updated: &mut HashSet, + bridge: &mut HardwareBridgeT, ) -> Result, UpdateError> { if updated.contains(node_id) { return match nodes.get(node_id) { @@ -67,7 +73,7 @@ impl Update { } for id in &input_ids { - match Self::update_rec(nodes, id, updated)? { + match Self::update_rec(nodes, id, updated, bridge)? { Some(value) => input_values.push(value), None => return Ok(None), } @@ -77,7 +83,7 @@ impl Update { return Err(UpdateError::NodeNotFound); }; - node.update(&input_values)?; + node.update(&input_values, bridge)?; updated.insert(node.id); Ok(node.value) @@ -85,12 +91,18 @@ impl Update { } impl Node { - pub fn update(&mut self, input_values: &Vec) -> Result<(), UpdateError> { + pub fn update( + &mut self, + input_values: &Vec, + bridge: &mut HardwareBridgeT, + ) -> Result<(), UpdateError> { let value = match &mut self.node_type { - crate::node::NodeType::Control(control) => control.set_value(input_values[0])?, + crate::node::NodeType::Control(control) => { + control.set_value(input_values[0], bridge)? + } - crate::node::NodeType::Fan(fan) => fan.get_value()?, - crate::node::NodeType::Temp(temp) => temp.get_value()?, + crate::node::NodeType::Fan(fan) => fan.get_value(bridge)?, + crate::node::NodeType::Temp(temp) => temp.get_value(bridge)?, crate::node::NodeType::CustomTemp(custom_temp) => custom_temp.update(input_values)?, crate::node::NodeType::Graph(_) => todo!(), crate::node::NodeType::Flat(flat) => flat.value.into(), diff --git a/hardware/Cargo.toml b/hardware/Cargo.toml index f267703d..e204d18d 100644 --- a/hardware/Cargo.toml +++ b/hardware/Cargo.toml @@ -10,6 +10,7 @@ fake_hardware = ["rand"] [dependencies] log.workspace = true rand = {version = "0.8", optional = true} +ouroboros = "0.18" [target.'cfg(target_os = "linux")'.dependencies] lm-sensors = { git = "https://github.com/wiiznokes/lm-sensors.git", branch = "pwm" } diff --git a/hardware/LibreHardwareMonitorWrapper/Hardware/BaseHardware.cs b/hardware/LibreHardwareMonitorWrapper/Hardware/BaseHardware.cs deleted file mode 100644 index 287ce758..00000000 --- a/hardware/LibreHardwareMonitorWrapper/Hardware/BaseHardware.cs +++ /dev/null @@ -1,36 +0,0 @@ -namespace LibreHardwareMonitorWrapper.Hardware; - -public enum HardwareType -{ - Control = 1, - Fan = 2, - Temp = 3 -} - -public enum Command -{ - SetAuto = 1, - SetValue = 2, - - // command -> type -> index -> value - GetValue = 3, - Shutdown = 4 -} - -public abstract class BaseHardware -{ - protected BaseHardware(string id, string name, string info, int index, HardwareType type) - { - Id = id; - Name = name; - Index = index; - Type = type; - Info = info; - } - - public string Id { get; } - public string Name { get; } - public string Info { get; } - public int Index { get; } - public HardwareType Type { get; } -} \ No newline at end of file diff --git a/hardware/LibreHardwareMonitorWrapper/HardwareManager.cs b/hardware/LibreHardwareMonitorWrapper/HardwareManager.cs index 1b8d7118..cd713e14 100644 --- a/hardware/LibreHardwareMonitorWrapper/HardwareManager.cs +++ b/hardware/LibreHardwareMonitorWrapper/HardwareManager.cs @@ -1,48 +1,52 @@ using LibreHardwareMonitorWrapper.Hardware; +using LibreHardwareMonitorWrapper.Lhm; namespace LibreHardwareMonitorWrapper; public static class HardwareManager { - private static readonly Lhm Lhm = new(); + private static readonly HardwareResearcher HardwareResearcher = new(); public static void Start() { - Lhm.Start(); - Lhm.CreateHardware(); + HardwareResearcher.Start(); + HardwareResearcher.CreateHardware(); } - public static int GetValue(HardwareType type, int index) + public static int GetValue(int index) { - Lhm.Update(); - return type switch + HardwareResearcher.Update(); + var hardware = State.Hardwares[index]; + return hardware.Type switch { - HardwareType.Control => State.Controls[index].Value(), - HardwareType.Fan => State.Fans[index].Value(), - HardwareType.Temp => State.Temps[index].Value(), - _ => throw new ArgumentOutOfRangeException(nameof(type), type, null) + HardwareType.Control => (hardware as Control)!.Value(), + HardwareType.Fan => (hardware as Sensor)!.Value(), + HardwareType.Temp => (hardware as Sensor)!.Value(), + _ => throw new ArgumentOutOfRangeException() }; } public static void SetValue(int index, int value) { - State.Controls[index].SetSpeed(value); + var control = State.Hardwares[index] as Control; + control!.SetSpeed(value); } public static void SetAuto(int index) { - State.Controls[index].SetAuto(); + var control = State.Hardwares[index] as Control; + control!.SetAuto(); } public static void Stop() { - Lhm.Stop(); + HardwareResearcher.Stop(); } public static void Update() { - Lhm.Update(); + HardwareResearcher.Update(); } } \ No newline at end of file diff --git a/hardware/LibreHardwareMonitorWrapper/Hardware/Control.cs b/hardware/LibreHardwareMonitorWrapper/Lhm/Control.cs similarity index 100% rename from hardware/LibreHardwareMonitorWrapper/Hardware/Control.cs rename to hardware/LibreHardwareMonitorWrapper/Lhm/Control.cs diff --git a/hardware/LibreHardwareMonitorWrapper/Hardware/LHM.cs b/hardware/LibreHardwareMonitorWrapper/Lhm/HardwareResearcher.cs similarity index 86% rename from hardware/LibreHardwareMonitorWrapper/Hardware/LHM.cs rename to hardware/LibreHardwareMonitorWrapper/Lhm/HardwareResearcher.cs index 40863f87..bc53646c 100644 --- a/hardware/LibreHardwareMonitorWrapper/Hardware/LHM.cs +++ b/hardware/LibreHardwareMonitorWrapper/Lhm/HardwareResearcher.cs @@ -1,8 +1,9 @@ using LibreHardwareMonitor.Hardware; +using LibreHardwareMonitorWrapper.Hardware; -namespace LibreHardwareMonitorWrapper.Hardware; +namespace LibreHardwareMonitorWrapper.Lhm; -public class Lhm : IVisitor +public class HardwareResearcher : IVisitor { private readonly Computer _mComputer = new() { @@ -66,6 +67,7 @@ public void CreateHardware() var nbControl = 0; var nbFan = 0; var nbTemp = 0; + var nbTot = 0; var hardwareArray = _mComputer.Hardware; @@ -99,22 +101,24 @@ void AddHardware(ISensor sensor) { case SensorType.Control: id ??= SensorType.Control.ToString() + nbControl; - State.Controls.Add(new Control(id, name, name, sensor, nbControl)); + State.Hardwares.Add(new Control(id, name, name, sensor, nbTot)); nbControl += 1; break; case SensorType.Fan: id ??= SensorType.Fan.ToString() + nbFan; - State.Fans.Add(new Sensor(id, name, name, sensor, nbFan, HardwareType.Fan)); + State.Hardwares.Add(new Sensor(id, name, name, sensor, nbTot, HardwareType.Fan)); nbFan += 1; break; case SensorType.Temperature: id ??= SensorType.Temperature.ToString() + nbTemp; - State.Temps.Add(new Sensor(id, name, name, sensor, nbTemp, HardwareType.Temp)); + State.Hardwares.Add(new Sensor(id, name, name, sensor, nbTot, HardwareType.Temp)); nbTemp += 1; break; default: throw new Exception("wrong sensor type"); } + + nbTot += 1; } } diff --git a/hardware/LibreHardwareMonitorWrapper/Hardware/Sensor.cs b/hardware/LibreHardwareMonitorWrapper/Lhm/Sensor.cs similarity index 89% rename from hardware/LibreHardwareMonitorWrapper/Hardware/Sensor.cs rename to hardware/LibreHardwareMonitorWrapper/Lhm/Sensor.cs index 033c326a..46053412 100644 --- a/hardware/LibreHardwareMonitorWrapper/Hardware/Sensor.cs +++ b/hardware/LibreHardwareMonitorWrapper/Lhm/Sensor.cs @@ -1,6 +1,6 @@ using LibreHardwareMonitor.Hardware; -namespace LibreHardwareMonitorWrapper.Hardware; +namespace LibreHardwareMonitorWrapper.Lhm; public class Sensor : BaseHardware { diff --git a/hardware/LibreHardwareMonitorWrapper/Program.cs b/hardware/LibreHardwareMonitorWrapper/Program.cs index a1de21d6..91e13651 100644 --- a/hardware/LibreHardwareMonitorWrapper/Program.cs +++ b/hardware/LibreHardwareMonitorWrapper/Program.cs @@ -4,7 +4,6 @@ HardwareManager.Start(); -var hardwareList = State.GetHardwareData(); var serializerOptions = new JsonSerializerOptions { @@ -15,7 +14,7 @@ }; -var jsonText = JsonSerializer.Serialize(hardwareList, serializerOptions); +var jsonText = JsonSerializer.Serialize(State.Hardwares, serializerOptions); var server = new Server(); @@ -23,4 +22,5 @@ server.WaitForCommand(); -server.Shutdown(); \ No newline at end of file +server.Shutdown(); +HardwareManager.Stop(); \ No newline at end of file diff --git a/hardware/LibreHardwareMonitorWrapper/Server.cs b/hardware/LibreHardwareMonitorWrapper/Server.cs index 30f6c628..071e19e4 100644 --- a/hardware/LibreHardwareMonitorWrapper/Server.cs +++ b/hardware/LibreHardwareMonitorWrapper/Server.cs @@ -1,7 +1,6 @@ using System.Net; using System.Net.Sockets; using System.Text; -using LibreHardwareMonitorWrapper.Hardware; namespace LibreHardwareMonitorWrapper; @@ -32,7 +31,7 @@ public void SendHardware(string jsonText) var stream = new NetworkStream(_client); var bytes = Encoding.UTF8.GetBytes(jsonTextWithLineDelimiter); - Console.WriteLine("Sending hardware" + jsonTextWithLineDelimiter); + Console.WriteLine("Sending hardware"); stream.Write(bytes); stream.Close(); Console.WriteLine("Hardware send"); @@ -43,8 +42,10 @@ public void WaitForCommand() while (true) { Console.WriteLine("waiting for commands"); - if (!block_read()) return; - var command = (Command)BitConverter.ToInt32(_buffer, 0); + var res = block_read(); + if (res < 0) return; + + var command = (Command)res; Console.WriteLine("Receive command: " + command); int value; @@ -52,30 +53,21 @@ public void WaitForCommand() switch (command) { case Command.SetAuto: - if (!block_read()) return; - index = BitConverter.ToInt32(_buffer, 0); - State.Controls[index].SetAuto(); + index = block_read(); + if (index < 0) return; + HardwareManager.SetAuto(index); break; case Command.SetValue: - if (!block_read()) return; - index = BitConverter.ToInt32(_buffer, 0); - if (!block_read()) return; - value = BitConverter.ToInt32(_buffer, 0); - State.Controls[index].SetSpeed(value); + index = block_read(); + if (index < 0) return; + value = block_read(); + if (value < 0) return; + HardwareManager.SetValue(index, value); break; case Command.GetValue: - if (!block_read()) return; - index = BitConverter.ToInt32(_buffer, 0); - if (!block_read()) return; - var type = (HardwareType)BitConverter.ToInt32(_buffer, 0); - - value = type switch - { - HardwareType.Fan => State.Fans[index].Value(), - HardwareType.Temp => State.Temps[index].Value(), - _ => throw new ArgumentOutOfRangeException() - }; - + index = block_read(); + if (index < 0) return; + value = HardwareManager.GetValue(index); var bytes = BitConverter.GetBytes(value); if (!block_send(bytes)) return; break; @@ -101,19 +93,20 @@ private bool block_send(byte[] bytes) } } - private bool block_read() + // return -1 if error + private int block_read() { try { var bytesRead = _client.Receive(_buffer); - if (bytesRead != 0) return true; + if (bytesRead != 0) return BitConverter.ToInt32(_buffer, 0); Console.WriteLine("byte read == 0"); - return false; + return -1; } catch (Exception e) { Console.WriteLine(e); - return false; + return -1; } } diff --git a/hardware/LibreHardwareMonitorWrapper/State.cs b/hardware/LibreHardwareMonitorWrapper/State.cs index 43bbd22c..f1296ff2 100644 --- a/hardware/LibreHardwareMonitorWrapper/State.cs +++ b/hardware/LibreHardwareMonitorWrapper/State.cs @@ -1,21 +1,39 @@ -using LibreHardwareMonitorWrapper.Hardware; - -namespace LibreHardwareMonitorWrapper; +namespace LibreHardwareMonitorWrapper; public static class State { - public static readonly List Controls = new(); - public static readonly List Fans = new(); - public static readonly List Temps = new(); + public static readonly List Hardwares = new(); +} - public static List GetHardwareData() - { - var list = new List(); +public enum HardwareType +{ + Control = 1, + Fan = 2, + Temp = 3 +} - list.AddRange(Controls); - list.AddRange(Fans); - list.AddRange(Temps); +public enum Command +{ + SetAuto = 1, + SetValue = 2, + GetValue = 3, + Shutdown = 4 +} - return list; +public abstract class BaseHardware +{ + protected BaseHardware(string id, string name, string info, int index, HardwareType type) + { + Id = id; + Name = name; + Index = index; + Type = type; + Info = info; } + + public string Id { get; } + public string Name { get; } + public string Info { get; } + public int Index { get; } + public HardwareType Type { get; } } \ No newline at end of file diff --git a/hardware/src/lib.rs b/hardware/src/lib.rs index ec59b919..ad01b4f3 100644 --- a/hardware/src/lib.rs +++ b/hardware/src/lib.rs @@ -23,9 +23,15 @@ pub enum HardwareError { } pub type Value = i32; - +pub type HardwareBridgeT = Box; pub trait HardwareBridge { - fn generate_hardware() -> Hardware; + fn generate_hardware() -> (Hardware, HardwareBridgeT) + where + Self: Sized; + + fn get_value(&mut self, internal_index: &usize) -> Result; + fn set_value(&mut self, internal_index: &usize, value: Value) -> Result<(), HardwareError>; + fn set_mode(&mut self, internal_index: &usize, value: Value) -> Result<(), HardwareError>; } #[derive(Debug, Clone, PartialEq, Eq)] @@ -35,14 +41,6 @@ pub enum HardwareType { Temp, } -pub trait HardwareItem: Debug { - fn get_value(&self) -> Result; - - fn set_value(&self, value: Value) -> Result<(), HardwareError>; - - fn set_mode(&self, value: Value) -> Result<(), HardwareError>; -} - #[derive(Debug, Clone)] pub struct InternalControlIndex { pub io: usize, @@ -59,7 +57,7 @@ pub struct ControlH { pub info: String, #[serde(skip)] - pub bridge: Box, + pub internal_index: InternalControlIndex, } #[derive(Serialize, Debug)] @@ -72,7 +70,7 @@ pub struct FanH { pub info: String, #[serde(skip)] - pub bridge: Box, + pub internal_index: usize, } #[derive(Serialize, Debug)] @@ -84,7 +82,7 @@ pub struct TempH { pub info: String, #[serde(skip)] - pub bridge: Box, + pub internal_index: usize, } #[derive(Serialize, Debug, Clone, Default)] diff --git a/hardware/src/windows.rs b/hardware/src/windows.rs index 4f43f218..6501920a 100644 --- a/hardware/src/windows.rs +++ b/hardware/src/windows.rs @@ -1,27 +1,32 @@ use std::{ - io::{BufRead, BufReader}, + io::{BufRead, BufReader, Read, Write}, net::TcpStream, rc::Rc, }; use serde::Deserialize; -use crate::{ControlH, Hardware, HardwareBridge, HardwareError, HardwareItem, Value}; +use crate::{ + ControlH, FanH, Hardware, HardwareBridge, HardwareBridgeT, HardwareError, InternalControlIndex, + TempH, Value, +}; -pub struct WindowsBridge {} +pub struct WindowsBridge { + pub stream: TcpStream, +} const IP: &str = "127.0.0.1"; const DEFAULT_PORT: u16 = 55555; impl HardwareBridge for WindowsBridge { - fn generate_hardware() -> Hardware { + fn generate_hardware() -> (Hardware, HardwareBridgeT) { let mut hardware = Hardware::default(); let stream = try_connect(); let mut data = String::new(); - let mut buff_reader = BufReader::new(&stream); - buff_reader.read_line(&mut data).unwrap(); + let mut buf_reader = BufReader::new(&stream); + buf_reader.read_line(&mut data).unwrap(); let base_hardware_list = serde_json::from_str::>(&data).unwrap(); for base_hardware in base_hardware_list { @@ -30,30 +35,48 @@ impl HardwareBridge for WindowsBridge { name: base_hardware.name, hardware_id: base_hardware.id, info: String::new(), - bridge: Box::new(InternalControl { - index: base_hardware.index, - }), + internal_index: InternalControlIndex { + io: base_hardware.index, + enable: base_hardware.index, + }, })), - HardwareType::Fan => hardware.controls.push(Rc::new(ControlH { + HardwareType::Fan => hardware.fans.push(Rc::new(FanH { name: base_hardware.name, hardware_id: base_hardware.id, info: String::new(), - bridge: Box::new(InternalSensor { - index: base_hardware.index, - }), + internal_index: base_hardware.index, })), - HardwareType::Temp => hardware.controls.push(Rc::new(ControlH { + HardwareType::Temp => hardware.temps.push(Rc::new(TempH { name: base_hardware.name, hardware_id: base_hardware.id, info: String::new(), - bridge: Box::new(InternalSensor { - index: base_hardware.index, - }), + internal_index: base_hardware.index, })), } } - hardware + let windows_bridge = WindowsBridge { stream }; + + (hardware, Box::new(windows_bridge)) + } + + fn get_value(&mut self, internal_index: &usize) -> Result { + let command: &[u8; 4] = &From::from(Command::GetValue); + self.stream.write_all(command).unwrap(); + + let mut buf = [0u8; 4]; + self.stream.read_exact(&mut buf).unwrap(); + + let i32 = I32::from(buf); + Ok(i32.0) + } + + fn set_value(&mut self, internal_index: &usize, value: Value) -> Result<(), HardwareError> { + todo!() + } + + fn set_mode(&mut self, internal_index: &usize, value: Value) -> Result<(), HardwareError> { + todo!() } } @@ -78,6 +101,7 @@ enum HardwareType { } #[derive(Debug, Clone)] +#[repr(i32)] enum Command { SetAuto = 1, SetValue = 2, @@ -87,6 +111,31 @@ enum Command { Shutdown = 4, } +impl From for [u8; 4] { + #[inline] + fn from(command: Command) -> Self { + let command_value = command as u32; + if is_little_endian() { + command_value.to_le_bytes() + } else { + command_value.to_be_bytes() + } + } +} + +struct I32(i32); + +impl From<[u8; 4]> for I32 { + #[inline] + fn from(bytes: [u8; 4]) -> Self { + if is_little_endian() { + I32(i32::from_le_bytes(bytes)) + } else { + I32(i32::from_be_bytes(bytes)) + } + } +} + #[derive(Deserialize, Debug, Clone)] struct BaseHardware { #[serde(rename = "Id")] @@ -116,32 +165,14 @@ impl Drop for InternalControl { } } -impl HardwareItem for InternalSensor { - fn get_value(&self) -> Result { - Ok(4) - } +#[inline] +fn is_little_endian() -> bool { + let test_value: u16 = 1; + let test_ptr: *const u16 = &test_value; - fn set_value(&self, value: Value) -> Result<(), crate::HardwareError> { - panic!("can't set the value of a sensor"); - } + // Read the first byte of the u16 through the pointer + let byte = unsafe { *test_ptr as u8 }; - fn set_mode(&self, value: Value) -> Result<(), HardwareError> { - panic!("can't set the mode of a sensor"); - } -} - -impl HardwareItem for InternalControl { - fn get_value(&self) -> Result { - panic!("can't get the value of a control"); - } - - fn set_value(&self, value: Value) -> Result<(), crate::HardwareError> { - debug!("set value {} to a control", value); - Ok(()) - } - - fn set_mode(&self, value: Value) -> Result<(), HardwareError> { - debug!("set mode {} to a control", value); - Ok(()) - } + // If the byte is 1, the system is little-endian; otherwise, it's big-endian + byte == 1 } diff --git a/src/main.rs b/src/main.rs index 9c8bb2a3..ef0c985b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,7 +27,7 @@ fn main() { let hardware = hardware::linux::LinuxBridge::generate_hardware(); #[cfg(all(not(feature = "fake_hardware"), target_os = "linux"))] - let hardware = hardware::windows::WindowsBridge::generate_hardware(); + let (hardware, bridge) = hardware::windows::WindowsBridge::generate_hardware(); let hardware_file_path = dir_manager.hardware_file_path(); @@ -51,6 +51,7 @@ fn main() { dir_manager, settings, hardware, + bridge, app_graph, update: Update::new(), }; diff --git a/ui/src/lib.rs b/ui/src/lib.rs index a2b2c243..374ac462 100644 --- a/ui/src/lib.rs +++ b/ui/src/lib.rs @@ -70,6 +70,7 @@ impl Application for Ui { match self.app_state.update.graph( &mut self.app_state.app_graph.nodes, &self.app_state.app_graph.root_nodes, + &mut self.app_state.bridge, ) { Ok(_) => {} Err(e) => { From 001fd8335a3ecb2f63458959b61fefd98986592d Mon Sep 17 00:00:00 2001 From: wiiznokes <78230769+wiiznokes@users.noreply.github.com> Date: Tue, 14 Nov 2023 02:33:22 +0100 Subject: [PATCH 6/8] makefile --- .config/hardware.toml | 17 ----------------- .gitignore | 3 ++- Makefile | 2 +- 3 files changed, 3 insertions(+), 19 deletions(-) delete mode 100644 .config/hardware.toml diff --git a/.config/hardware.toml b/.config/hardware.toml deleted file mode 100644 index c82f900b..00000000 --- a/.config/hardware.toml +++ /dev/null @@ -1,17 +0,0 @@ -Fan = [] - -[[Control]] -name = "control1" -id = "control1" - -[[Control]] -name = "control2" -id = "control2" - -[[Temp]] -name = "temp1" -id = "temp1" - -[[Temp]] -name = "temp2" -id = "temp2" diff --git a/.gitignore b/.gitignore index 5f7a041f..aa7ead3f 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ target/ .vscode/* !.vscode/launch.json bin/ -obj/ \ No newline at end of file +obj/ +.config/hardware.toml diff --git a/Makefile b/Makefile index f4238fad..b4f04bfe 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ fix: cargo clippy --all --fix --allow-dirty --allow-staged cargo fmt --all -clean-git: +git-cache: git rm -rf --cached . git add . From b2ba480bbb279a222f2c9fda3d3c2bce02793159 Mon Sep 17 00:00:00 2001 From: wiiznokes <78230769+wiiznokes@users.noreply.github.com> Date: Tue, 14 Nov 2023 03:07:40 +0100 Subject: [PATCH 7/8] fixes --- .config/config3.toml | 32 +++++++++++++++++++ .config/settings.toml | 2 +- .../LibreHardwareMonitorWrapper/Server.cs | 9 ++++-- hardware/src/windows.rs | 25 +++++++++++++-- 4 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 .config/config3.toml diff --git a/.config/config3.toml b/.config/config3.toml new file mode 100644 index 00000000..8f384790 --- /dev/null +++ b/.config/config3.toml @@ -0,0 +1,32 @@ +[[Control]] +name = "control1" +input = "linear1" +auto = false + +[[Linear]] +name = "linear1" +minTemp = 10 +minSpeed = 10 +maxTemp = 70 +maxSpeed = 100 +input = "custom_temp" + +[[CustomTemp]] +name = "custom_temp" +kind = "Average" +input = [ + "temp1", + "temp2", +] + + + + + +[[Temp]] +name = "temp1" +id = "/intelcpu/0/temperature/1" + +[[Temp]] +name = "temp2" +id = "/intelcpu/0/temperature/2" \ No newline at end of file diff --git a/.config/settings.toml b/.config/settings.toml index e1bd9cc3..cceb8b64 100644 --- a/.config/settings.toml +++ b/.config/settings.toml @@ -1,4 +1,4 @@ unit = "Celsius" update_delay = 0 disable_pwm_value = 0 -current_config = "config2.toml" +current_config = "config3.toml" diff --git a/hardware/LibreHardwareMonitorWrapper/Server.cs b/hardware/LibreHardwareMonitorWrapper/Server.cs index 071e19e4..d9a5f3fb 100644 --- a/hardware/LibreHardwareMonitorWrapper/Server.cs +++ b/hardware/LibreHardwareMonitorWrapper/Server.cs @@ -7,7 +7,7 @@ namespace LibreHardwareMonitorWrapper; public class Server { private const string Address = "127.0.0.1"; - private readonly byte[] _buffer = new byte[1024]; + private readonly byte[] _buffer = new byte[4]; private readonly Socket _client; private readonly Socket _listener; private int _port = 55555; @@ -67,9 +67,12 @@ public void WaitForCommand() case Command.GetValue: index = block_read(); if (index < 0) return; + Console.WriteLine("Receive index: " + index); value = HardwareManager.GetValue(index); var bytes = BitConverter.GetBytes(value); + Console.WriteLine("sending value: " + value); if (!block_send(bytes)) return; + Console.WriteLine("value send"); break; case Command.Shutdown: return; @@ -99,8 +102,8 @@ private int block_read() try { var bytesRead = _client.Receive(_buffer); - if (bytesRead != 0) return BitConverter.ToInt32(_buffer, 0); - Console.WriteLine("byte read == 0"); + if (bytesRead == 4) return BitConverter.ToInt32(_buffer, 0); + Console.WriteLine("byte read = " + bytesRead); return -1; } catch (Exception e) diff --git a/hardware/src/windows.rs b/hardware/src/windows.rs index 6501920a..951122fe 100644 --- a/hardware/src/windows.rs +++ b/hardware/src/windows.rs @@ -61,11 +61,20 @@ impl HardwareBridge for WindowsBridge { } fn get_value(&mut self, internal_index: &usize) -> Result { + + info!("send command: {:?}", Command::GetValue); + let command: &[u8; 4] = &From::from(Command::GetValue); self.stream.write_all(command).unwrap(); + info!("send index: {}", internal_index); + let index: &[u8; 4] = &From::from(I32(*internal_index)); + self.stream.write_all(index).unwrap(); + + info!("read value ..."); let mut buf = [0u8; 4]; self.stream.read_exact(&mut buf).unwrap(); + info!("read value!"); let i32 = I32::from(buf); Ok(i32.0) @@ -123,9 +132,9 @@ impl From for [u8; 4] { } } -struct I32(i32); +struct I32(T); -impl From<[u8; 4]> for I32 { +impl From<[u8; 4]> for I32 { #[inline] fn from(bytes: [u8; 4]) -> Self { if is_little_endian() { @@ -136,6 +145,18 @@ impl From<[u8; 4]> for I32 { } } +impl From> for [u8; 4] { + #[inline] + fn from(number: I32) -> Self { + let index = number.0 as i32; + if is_little_endian() { + index.to_le_bytes() + } else { + index.to_be_bytes() + } + } +} + #[derive(Deserialize, Debug, Clone)] struct BaseHardware { #[serde(rename = "Id")] From 98a4cb508104fdacad9810fe911309dd2e8fc1a7 Mon Sep 17 00:00:00 2001 From: wiiznokes <78230769+wiiznokes@users.noreply.github.com> Date: Tue, 14 Nov 2023 03:47:41 +0100 Subject: [PATCH 8/8] linux --- .config/config4.toml | 28 +++++ .config/settings.toml | 2 +- data/src/config/control.rs | 4 +- data/src/config/serde_test.rs | 4 +- data/src/update.rs | 1 - hardware/Cargo.toml | 7 +- hardware/src/lib.rs | 12 +- hardware/src/linux.rs | 206 ++++++++++++++++------------------ hardware/src/windows.rs | 8 +- src/main.rs | 6 +- 10 files changed, 141 insertions(+), 137 deletions(-) create mode 100644 .config/config4.toml diff --git a/.config/config4.toml b/.config/config4.toml new file mode 100644 index 00000000..0df1c196 --- /dev/null +++ b/.config/config4.toml @@ -0,0 +1,28 @@ +[[Control]] +name = "control1" +input = "linear1" +auto = false + +[[Linear]] +name = "linear1" +minTemp = 10 +minSpeed = 10 +maxTemp = 70 +maxSpeed = 100 +input = "custom_temp" + +[[CustomTemp]] +name = "custom_temp" +kind = "Average" +input = [ + "temp1", + "temp2", +] + +[[Temp]] +name = "temp1" +id = "coretemp-isa-0000-temp3_input" + +[[Temp]] +name = "temp2" +id = "coretemp-isa-0000-temp2_input" \ No newline at end of file diff --git a/.config/settings.toml b/.config/settings.toml index cceb8b64..b014f806 100644 --- a/.config/settings.toml +++ b/.config/settings.toml @@ -1,4 +1,4 @@ unit = "Celsius" update_delay = 0 disable_pwm_value = 0 -current_config = "config3.toml" +current_config = "config4.toml" diff --git a/data/src/config/control.rs b/data/src/config/control.rs index a049135f..b12d414b 100644 --- a/data/src/config/control.rs +++ b/data/src/config/control.rs @@ -53,7 +53,7 @@ impl Control { match &self.control_h { Some(control_h) => bridge - .set_value(&control_h.internal_index.io, value) + .set_value(&control_h.internal_index, value) .map(|_| value) .map_err(UpdateError::Hardware), None => Err(UpdateError::NodeIsInvalid), @@ -67,7 +67,7 @@ impl Control { ) -> Result<(), UpdateError> { let res = match &self.control_h { Some(control_h) => bridge - .set_mode(&control_h.internal_index.enable, !auto as i32) + .set_mode(&control_h.internal_index, !auto as i32) .map_err(UpdateError::Hardware), None => Err(UpdateError::NodeIsInvalid), }; diff --git a/data/src/config/serde_test.rs b/data/src/config/serde_test.rs index aa7defdb..49eaa665 100644 --- a/data/src/config/serde_test.rs +++ b/data/src/config/serde_test.rs @@ -1,5 +1,5 @@ use const_format::formatcp; -use hardware::{ControlH, FanH, Hardware, InternalControlIndex, TempH}; +use hardware::{ControlH, FanH, Hardware, TempH}; use serial_test::serial; use std::fmt::Debug; use std::fs::{self, File}; @@ -101,7 +101,7 @@ fn hardware1() -> Hardware { name: "ControlH".into(), hardware_id: "ControlH".into(), info: "ControlH".into(), - internal_index: InternalControlIndex { io: 0, enable: 0 }, + internal_index: 0, } .into()], temps: vec![TempH { diff --git a/data/src/update.rs b/data/src/update.rs index c8a9b9a8..f520382e 100644 --- a/data/src/update.rs +++ b/data/src/update.rs @@ -100,7 +100,6 @@ impl Node { crate::node::NodeType::Control(control) => { control.set_value(input_values[0], bridge)? } - crate::node::NodeType::Fan(fan) => fan.get_value(bridge)?, crate::node::NodeType::Temp(temp) => temp.get_value(bridge)?, crate::node::NodeType::CustomTemp(custom_temp) => custom_temp.update(input_values)?, diff --git a/hardware/Cargo.toml b/hardware/Cargo.toml index e204d18d..4b85d48c 100644 --- a/hardware/Cargo.toml +++ b/hardware/Cargo.toml @@ -9,14 +9,15 @@ fake_hardware = ["rand"] [dependencies] log.workspace = true -rand = {version = "0.8", optional = true} +serde.workspace = true ouroboros = "0.18" +rand = {version = "0.8", optional = true} [target.'cfg(target_os = "linux")'.dependencies] lm-sensors = { git = "https://github.com/wiiznokes/lm-sensors.git", branch = "pwm" } -serde.workspace = true -serde_json.workspace = true +[target.'cfg(target_os = "windows")'.dependencies] +serde_json.workspace = true [dev-dependencies] \ No newline at end of file diff --git a/hardware/src/lib.rs b/hardware/src/lib.rs index ad01b4f3..c15f2584 100644 --- a/hardware/src/lib.rs +++ b/hardware/src/lib.rs @@ -7,10 +7,10 @@ use std::{fmt::Debug, rc::Rc}; #[macro_use] extern crate log; -#[cfg(all(not(feature = "fake_hardware"), target_os = "windows"))] +#[cfg(all(not(feature = "fake_hardware"), target_os = "linux"))] pub mod linux; -#[cfg(all(not(feature = "fake_hardware"), target_os = "linux"))] +#[cfg(all(not(feature = "fake_hardware"), target_os = "windows"))] pub mod windows; #[cfg(feature = "fake_hardware")] @@ -41,12 +41,6 @@ pub enum HardwareType { Temp, } -#[derive(Debug, Clone)] -pub struct InternalControlIndex { - pub io: usize, - pub enable: usize, -} - #[derive(Serialize, Debug)] pub struct ControlH { pub name: String, @@ -57,7 +51,7 @@ pub struct ControlH { pub info: String, #[serde(skip)] - pub internal_index: InternalControlIndex, + pub internal_index: usize, } #[derive(Serialize, Debug)] diff --git a/hardware/src/linux.rs b/hardware/src/linux.rs index 417a2b33..10ef735e 100644 --- a/hardware/src/linux.rs +++ b/hardware/src/linux.rs @@ -2,25 +2,58 @@ use std::fmt::Debug; use lm_sensors::{feature, value, ChipRef, FeatureRef, LMSensors, SubFeatureRef}; -use crate::{ControlH, FanH, Hardware, HardwareBridge, HardwareError, HardwareItem, TempH, Value}; - -pub struct LinuxBridge {} +use crate::{ + ControlH, FanH, Hardware, HardwareBridge, HardwareBridgeT, HardwareError, TempH, Value, +}; +use ouroboros::self_referencing; + +#[self_referencing] +pub struct LinuxBridge { + lib: LMSensors, + #[borrows(lib)] + #[not_covariant] + sensors: Vec>, +} impl HardwareBridge for LinuxBridge { - fn generate_hardware() -> Hardware { + fn generate_hardware() -> (Hardware, HardwareBridgeT) { let mut hardware = Hardware::default(); - let lib = lm_sensors::Initializer::default().initialize().unwrap(); - let boxed = Box::new(lib); - // yes we leak like never here but it's not that bad in fact - // is even safe Rust. The kernel will be in charge to release - // memory when the process terminate. - let leaked: &'static mut LMSensors = Box::leak(boxed); - info!("lmsensors just leaked"); + let bridge = LinuxBridgeBuilder { + lib: lm_sensors::Initializer::default().initialize().unwrap(), + sensors_builder: |lib: &LMSensors| generate_hardware(lib, &mut hardware), + } + .build(); + + (hardware, Box::new(bridge)) + } - generate_hardware(leaked, &mut hardware); + fn get_value(&mut self, internal_index: &usize) -> Result { + self.with_sensors(|sensors| match sensors.get(*internal_index) { + Some(sensor) => match sensor { + InternalSubFeatureRef::Pwm(_) => { + panic!("can't get the value of a control"); + } + InternalSubFeatureRef::Sensor(sensor_refs) => match sensor_refs.io.raw_value() { + Ok(value) => Ok(value as i32), + Err(e) => { + error!("{}", e); + Err(HardwareError::LmSensors) + } + }, + }, + None => Err(HardwareError::IdNotFound), + }) + } - hardware + fn set_value(&mut self, internal_index: &usize, value: Value) -> Result<(), HardwareError> { + debug!("set value {} to {}", value, internal_index); + Ok(()) + } + + fn set_mode(&mut self, internal_index: &usize, value: Value) -> Result<(), HardwareError> { + debug!("set mode {} to {}", value, internal_index); + Ok(()) } } @@ -61,7 +94,40 @@ fn generate_id_name_info( Some((id, name, info)) } -fn generate_hardware(lib: &'static LMSensors, hardware: &mut Hardware) { +#[derive(Debug, Clone, PartialEq, Eq)] +enum SubFeatureType { + PwmIo, + PwmEnable, + Fan, + Temp, +} + +enum InternalSubFeatureRef<'a> { + Pwm(PwmRefs<'a>), + Sensor(SensorRefs<'a>), +} + +struct PwmRefs<'a> { + io: SubFeatureRef<'a>, + enable: SubFeatureRef<'a>, +} +struct SensorRefs<'a> { + io: SubFeatureRef<'a>, +} + +impl Drop for PwmRefs<'_> { + fn drop(&mut self) { + info!("pwm sould be set to auto"); + // TODO: set to auto + } +} + +fn generate_hardware<'a>( + lib: &'a LMSensors, + hardware: &mut Hardware, +) -> Vec> { + let mut sensors = Vec::new(); + for chip_ref in lib.chip_iter(None) { for feature_ref in chip_ref.feature_iter() { match feature_ref.kind() { @@ -76,16 +142,16 @@ fn generate_hardware(lib: &'static LMSensors, hardware: &mut Hardware) { if let Some((id, name, info)) = generate_id_name_info(&chip_ref, &feature_ref, &sub_feature_ref) { - let sensor = InternalSubFeatureRef { - sub_feature_type: SubFeatureType::Fan, - sub_feature_ref, - }; + let sensor = InternalSubFeatureRef::Sensor(SensorRefs { + io: sub_feature_ref, + }); + sensors.push(sensor); let fan_h = FanH { name, hardware_id: id, info, - bridge: Box::new(InternalSensor { sensor }), + internal_index: sensors.len() - 1, }; hardware.fans.push(fan_h.into()); } @@ -100,16 +166,16 @@ fn generate_hardware(lib: &'static LMSensors, hardware: &mut Hardware) { if let Some((id, name, info)) = generate_id_name_info(&chip_ref, &feature_ref, &sub_feature_ref) { - let sensor = InternalSubFeatureRef { - sub_feature_type: SubFeatureType::Temp, - sub_feature_ref, - }; + let sensor = InternalSubFeatureRef::Sensor(SensorRefs { + io: sub_feature_ref, + }); + sensors.push(sensor); let temp_h = TempH { name, hardware_id: id, info, - bridge: Box::new(InternalSensor { sensor }), + internal_index: sensors.len() - 1, }; hardware.temps.push(temp_h.into()); } @@ -129,23 +195,18 @@ fn generate_hardware(lib: &'static LMSensors, hardware: &mut Hardware) { if let Some((id, name, info)) = generate_id_name_info(&chip_ref, &feature_ref, &sub_feature_ref_io) { - let io = InternalSubFeatureRef { - sub_feature_type: SubFeatureType::PwmIo, - sub_feature_ref: sub_feature_ref_io, - }; - - let enable = InternalSubFeatureRef { - sub_feature_type: SubFeatureType::PwmEnable, - sub_feature_ref: sub_feature_ref_enable, - }; + let sensor = InternalSubFeatureRef::Pwm(PwmRefs { + io: sub_feature_ref_io, + enable: sub_feature_ref_enable, + }); - let control = InternalControl { io, enable }; + sensors.push(sensor); let control_h = ControlH { name, hardware_id: id, info, - bridge: Box::new(control), + internal_index: sensors.len() - 1, }; hardware.controls.push(control_h.into()); } @@ -156,78 +217,5 @@ fn generate_hardware(lib: &'static LMSensors, hardware: &mut Hardware) { }; } } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -enum SubFeatureType { - PwmIo, - PwmEnable, - Fan, - Temp, -} - -struct InternalSubFeatureRef { - sub_feature_type: SubFeatureType, - sub_feature_ref: SubFeatureRef<'static>, -} - -impl Debug for InternalSubFeatureRef { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("InternalSubFeatureRef") - .field("sub_feature_type", &self.sub_feature_type) - .finish() - } -} -#[derive(Debug)] -struct InternalSensor { - sensor: InternalSubFeatureRef, -} - -#[derive(Debug)] -struct InternalControl { - io: InternalSubFeatureRef, - enable: InternalSubFeatureRef, -} - -impl Drop for InternalControl { - fn drop(&mut self) { - info!("pwm sould be set to auto"); - // TODO: set to auto - } -} - -impl HardwareItem for InternalSensor { - fn get_value(&self) -> Result { - match self.sensor.sub_feature_ref.raw_value() { - Ok(value) => Ok(value as i32), - Err(e) => { - error!("{}", e); - Err(HardwareError::LmSensors) - } - } - } - - fn set_value(&self, value: Value) -> Result<(), crate::HardwareError> { - panic!("can't set the value of a sensor"); - } - - fn set_mode(&self, value: Value) -> Result<(), HardwareError> { - panic!("can't set the mode of a sensor"); - } -} - -impl HardwareItem for InternalControl { - fn get_value(&self) -> Result { - panic!("can't get the value of a control"); - } - - fn set_value(&self, value: Value) -> Result<(), crate::HardwareError> { - debug!("set value {} to a control", value); - Ok(()) - } - - fn set_mode(&self, value: Value) -> Result<(), HardwareError> { - debug!("set mode {} to a control", value); - Ok(()) - } + sensors } diff --git a/hardware/src/windows.rs b/hardware/src/windows.rs index 951122fe..4d5d4562 100644 --- a/hardware/src/windows.rs +++ b/hardware/src/windows.rs @@ -35,10 +35,7 @@ impl HardwareBridge for WindowsBridge { name: base_hardware.name, hardware_id: base_hardware.id, info: String::new(), - internal_index: InternalControlIndex { - io: base_hardware.index, - enable: base_hardware.index, - }, + internal_index: base_hardware.index, })), HardwareType::Fan => hardware.fans.push(Rc::new(FanH { name: base_hardware.name, @@ -61,7 +58,6 @@ impl HardwareBridge for WindowsBridge { } fn get_value(&mut self, internal_index: &usize) -> Result { - info!("send command: {:?}", Command::GetValue); let command: &[u8; 4] = &From::from(Command::GetValue); @@ -114,8 +110,6 @@ enum HardwareType { enum Command { SetAuto = 1, SetValue = 2, - - // command -> type -> index -> value GetValue = 3, Shutdown = 4, } diff --git a/src/main.rs b/src/main.rs index ef0c985b..afab1863 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,10 +23,10 @@ fn main() { #[cfg(feature = "fake_hardware")] let hardware = hardware::fake_hardware::FakeHardwareBridge::generate_hardware(); - #[cfg(all(not(feature = "fake_hardware"), target_os = "windows"))] - let hardware = hardware::linux::LinuxBridge::generate_hardware(); - #[cfg(all(not(feature = "fake_hardware"), target_os = "linux"))] + let (hardware, bridge) = hardware::linux::LinuxBridge::generate_hardware(); + + #[cfg(all(not(feature = "fake_hardware"), target_os = "windows"))] let (hardware, bridge) = hardware::windows::WindowsBridge::generate_hardware(); let hardware_file_path = dir_manager.hardware_file_path();