diff --git a/.github/ISSUE_TEMPLATE/blank_issue.md b/.github/ISSUE_TEMPLATE/blank_issue.md new file mode 100644 index 00000000..e7ec9a2b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/blank_issue.md @@ -0,0 +1,4 @@ +--- +name: Blank Issue (do not use this for bug reports or feature requests) +about: Create an issue with a blank template. +--- diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..72c45efe --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,21 @@ +--- +name: Bug Report +about: Report a correctness issue or violated expectation +labels: bug +--- + +#### Bug Description: + +#### Expected Result: + +#### Steps to Reproduce: + +#### Possible Solutions: + +#### Possible Additional Information: + +#### Operating system + +#### fan-control version + +#### Logs, Panic Messages, Stack Traces: diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..0086358d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..cc2f9eaf --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,13 @@ +--- +name: Feature Request +about: Request a feature +labels: enhancement +--- + +#### Use Case: + +#### Proposed Change: + +#### Who Benefits From The Change(s)?: + +#### Alternative Approaches: diff --git a/.github/_ISSUE_TEMPLATE/bug_report.yml b/.github/_ISSUE_TEMPLATE/bug_report.yml deleted file mode 100644 index c983cec1..00000000 --- a/.github/_ISSUE_TEMPLATE/bug_report.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Bug Report -description: Create a bug report -labels: ["bug"] -body: - - type: markdown - attributes: - value: Thanks for filing a bug report 😄! - - type: textarea - id: problem - attributes: - label: Problem - description: > - Please provide a clear and concise description of what the bug is, - including what currently happens and what you expected to happen. - validations: - required: true - - type: textarea - id: steps - attributes: - label: Steps - description: Please list the steps to reproduce the bug. - placeholder: | - 1. - 2. - 3. - - type: textarea - id: possible-solutions - attributes: - label: Possible Solution(s) - description: > - Not obligatory, but suggest a fix/reason for the bug, - or ideas how to implement the addition or change. - - type: textarea - id: notes - attributes: - label: Notes - description: Provide any additional notes that might be helpful. - - type: dropdown - id: os - attributes: - label: Operative System - description: Which operative system are you using? - options: - - Windows - - Linux - - Both - validations: - required: false - - type: textarea - id: version - attributes: - label: Version - description: Please paste the version you're running - render: text diff --git a/.github/_ISSUE_TEMPLATE/feature_request.yml b/.github/_ISSUE_TEMPLATE/feature_request.yml deleted file mode 100644 index a92ce8aa..00000000 --- a/.github/_ISSUE_TEMPLATE/feature_request.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Feature Request -description: Suggest an idea for enhancing fan-control -labels: ["enhancement"] -body: - - type: textarea - id: problem - attributes: - label: Problem - description: > - Please provide a clear description of your use case and the problem - this feature request is trying to solve. - validations: - required: true - - type: textarea - id: solution - attributes: - label: Proposed Solution - description: > - Please provide a clear and concise description of what you want to happen. - - type: textarea - id: notes - attributes: - label: Notes - description: Provide any additional context or information that might be helpful. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1ce4056e..691bcb74 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,8 @@ on: paths-ignore: - "**.md" + - "**.txt" + - "**.log" concurrency: group: ${{ github.ref }}-${{ github.workflow }} diff --git a/.github/workflows/upload_artifacts.yml b/.github/workflows/upload_artifacts.yml index 99b91162..002668c6 100644 --- a/.github/workflows/upload_artifacts.yml +++ b/.github/workflows/upload_artifacts.yml @@ -8,28 +8,6 @@ env: CARGO_TERM_COLOR: always jobs: - linux: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - run: rustup update - - uses: taiki-e/install-action@just - - uses: Swatinem/rust-cache@v2 - - run: | - cargo install cargo-packager - - - name: Build libsensors - run: just libsensors - - name: Package deb - run: just deb - - - run: echo "DEB_NAME=$(basename ./packages/fan-control*.deb)" >> $GITHUB_ENV - - uses: actions/upload-artifact@v4 - with: - name: ${{ env.DEB_NAME }} - path: | - ./packages/${{ env.DEB_NAME }} - windows: runs-on: windows-latest steps: diff --git a/.gitignore b/.gitignore index 86c242b3..1c148233 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,6 @@ rustc-ice* # IDE .idea/ .vscode/* -!.vscode/launch.json !.vscode/settings.json !.vscode/extensions.json @@ -28,3 +27,8 @@ LibreHardwareMonitorWrapper.sln.DotSettings.user # Lmsensors build/ + +/.flatpak-builder +/vendor +/repo +/flatpak-out \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 292ca8a7..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "lldb", - "request": "launch", - "name": "Debug 'fan-control'", - "cargo": { - "args": ["build", "--bin=fan-control", "--package=fan-control"], - "filter": { - "name": "fan-control", - "kind": "bin" - } - }, - "args": ["-p", "./.test"], - "cwd": "${workspaceFolder}" - }, - { - "type": "lldb", - "request": "launch", - "name": "Debug 'fan-control': fake hardware", - "cargo": { - "args": [ - "build", - "--bin=fan-control", - "--package=fan-control", - "--features=fake_hardware" - ], - "filter": { - "name": "fan-control", - "kind": "bin" - } - }, - "args": ["-p", "./.test", "-c", "test"], - "cwd": "${workspaceFolder}" - }, - { - "type": "lldb", - "request": "launch", - "name": "Debug unit tests in library 'data'", - "cargo": { - "args": ["test", "--no-run", "--lib", "--package=data"], - "filter": { - "name": "data", - "kind": "lib" - } - }, - "args": [], - "cwd": "${workspaceFolder}" - }, - { - "type": "lldb", - "request": "launch", - "name": "Debug unit tests in library 'hardware'", - "cargo": { - "args": ["test", "--no-run", "--lib", "--package=hardware"], - "filter": { - "name": "hardware", - "kind": "lib" - } - }, - "args": [], - "cwd": "${workspaceFolder}" - }, - { - "type": "lldb", - "request": "launch", - "name": "Debug unit tests in library 'ui'", - "cargo": { - "args": ["test", "--no-run", "--lib", "--package=ui"], - "filter": { - "name": "ui", - "kind": "lib" - } - }, - "args": [], - "cwd": "${workspaceFolder}" - }, - { - "type": "lldb", - "request": "launch", - "name": "Debug unit tests in executable 'fan-control'", - "cargo": { - "args": [ - "test", - "--no-run", - "--bin=fan-control", - "--package=fan-control" - ], - "filter": { - "name": "fan-control", - "kind": "bin" - } - }, - "args": [], - "cwd": "${workspaceFolder}" - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json index 69ae6071..7d3d1f7f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,15 @@ { "rust-analyzer.showUnlinkedFileNotification": false, - "rust-analyzer.cargo.features": "all" -} + "rust-analyzer.cargo.features": "all", + "rust-analyzer.server.extraEnv": { + "CARGO_TARGET_DIR": "target/analyzer" + }, + "rust-analyzer.linkedProjects": [ + "Cargo.toml", + ], + "rust-analyzer.files.excludeDirs": [ + ".flatpak-builder", + "flatpak-out", + "packages" + ] +} \ No newline at end of file diff --git a/BUILD.md b/BUILD.md index a6c74d6e..242e9977 100644 --- a/BUILD.md +++ b/BUILD.md @@ -11,7 +11,7 @@ git clone https://github.com/wiiznokes/fan-control.git cd fan-control sudo apt install make bison flex clang -y just libsensors -cargo run --release # or just deb for building a deb package +cargo run --release ``` ### Windows diff --git a/Cargo.lock b/Cargo.lock index 1efb9f4f..2faa68e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -774,6 +774,39 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +[[package]] +name = "cached" +version = "0.49.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e8e463fceca5674287f32d252fb1d94083758b8709c160efae66d263e5f4eba" +dependencies = [ + "ahash", + "cached_proc_macro", + "cached_proc_macro_types", + "hashbrown", + "instant", + "once_cell", + "thiserror", +] + +[[package]] +name = "cached_proc_macro" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad9f16c0d84de31a2ab7fdf5f7783c14631f7075cf464eb3bb43119f61c9cb2a" +dependencies = [ + "darling 0.14.4", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cached_proc_macro_types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0" + [[package]] name = "cairo-sys-rs" version = "0.18.2" @@ -1376,14 +1409,38 @@ dependencies = [ "winapi", ] +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core 0.14.4", + "darling_macro 0.14.4", +] + [[package]] name = "darling" version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.20.8", + "darling_macro 0.20.8", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 1.0.109", ] [[package]] @@ -1400,13 +1457,24 @@ dependencies = [ "syn 2.0.55", ] +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core 0.14.4", + "quote", + "syn 1.0.109", +] + [[package]] name = "darling_macro" version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ - "darling_core", + "darling_core 0.20.8", "quote", "syn 2.0.55", ] @@ -1445,6 +1513,7 @@ dependencies = [ "serial_test", "thiserror", "toml 0.8.12", + "utils", ] [[package]] @@ -1492,7 +1561,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e8ef033054e131169b8f0f9a7af8f5533a9436fadf3c500ed547f730f07090d" dependencies = [ - "darling", + "darling 0.20.8", "proc-macro2", "quote", "syn 2.0.55", @@ -1792,7 +1861,7 @@ dependencies = [ [[package]] name = "fan-control" -version = "0.1.2" +version = "0.1.3" dependencies = [ "clap", "crossterm", @@ -2428,7 +2497,6 @@ dependencies = [ name = "hardware" version = "0.1.0" dependencies = [ - "cargo-packager-resource-resolver", "derive_more", "env_logger", "lm-sensors", @@ -2438,6 +2506,7 @@ dependencies = [ "serde", "serde_json", "thiserror", + "utils", ] [[package]] @@ -3096,7 +3165,6 @@ dependencies = [ "iced_runtime", "iced_style", "iced_tiny_skia", - "iced_wgpu", "iced_widget", "iced_winit", "lazy_static", @@ -5208,7 +5276,6 @@ dependencies = [ name = "ui" version = "0.1.0" dependencies = [ - "cargo-packager-resource-resolver", "data", "derive_more", "hardware", @@ -5220,6 +5287,7 @@ dependencies = [ "once_cell", "rust-embed", "tokio", + "utils", ] [[package]] @@ -5395,6 +5463,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "utils" +version = "0.1.0" +dependencies = [ + "cached", + "cargo-packager-resource-resolver", + "log", +] + [[package]] name = "version-compare" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index 981254af..05d32aca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["data", "hardware", "ui"] +members = ["data", "hardware", "ui", "utils"] resolver = "2" [workspace.package] @@ -8,17 +8,14 @@ edition = "2021" license = "MIT" homepage = "https://github.com/wiiznokes/fan-control/" repository = "https://github.com/wiiznokes/fan-control.git" -rust-version = "1.76" keywords = ["fan-control", "lhm", "lmsensors", "sensors", "iced-app"] [package] name = "fan-control" -version = "0.1.2" +version = "0.1.3" description = "Control your fans with different behaviors" exclude = ["/.*", "justfile", "LICENCE"] -categories = ["command-line-utilities"] -rust-version.workspace = true authors.workspace = true edition.workspace = true license.workspace = true @@ -28,9 +25,9 @@ keywords.workspace = true [package.metadata.packager] before-each-package-command = "cargo build --release" -identifier = "com.wiiznokes.fan-control" -icons = ["resource/app_icon/*"] -resources = ["resource/icons", "resource/windows"] +identifier = "io.github.wiiznokes.fan-control" +icons = ["resource/windows/app_icon.ico"] +resources = ["resource/icons", "resource/windows/lhmbuild"] category = "Utility" [package.metadata.packager.windows] @@ -58,6 +55,7 @@ winres = "0.1" hardware = { path = "hardware" } data = { path = "data" } ui = { path = "ui" } +utils = { path = "utils" } clap = { version = "4.3", features = ["derive"] } serde = { version = "1.0", features = ["derive", "rc"] } serde_json = "1.0" diff --git a/README.md b/README.md index 1d906cce..d44681de 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,11 @@ -# Features +

fan-control

+ +
+ Download on Flathub   +Download on Github release   +
+ +## Features - Display sensors data on real time - Control fans based on custom behaviors @@ -7,13 +14,13 @@ ![screenshot of fan-control](https://media.githubusercontent.com/media/wiiznokes/fan-control/master/resource/screenshots/app.png) -# Usage +## Usage - You can add items with the buttons on the right of the app. - To save a configuration, write a name in the "Configuration name" field, and click on the `+`. - To modify the value of a fan, you must select it in a `Control` item (the left column), select a `Behavior`, and activate the swtich. -# Installation +## Installation
Linux @@ -24,10 +31,10 @@ To have the maximum number of sensors detected by the application, you must - Debian: `sudo apt install lm-sensors` - Fedora: `sudo dnf install lm_sensors` 2. run the hardware detection script: `sudo sensors-detect` +3. [install udev rules](./resource/linux/udev_rules.md) +4. install the app from [flathub](io.github.wiiznokes.fan-control) -Also, make sure to run the application with sudo. (running in user mode is [planned](https://wiki.archlinux.org/title/udev)) - -The configuration file will be in [`~/.config/fan-control`](file://~/.config/fan-control) or [`/root/.config/fan-control`](file:///root/.config/fan-control). +The configuration file will be in [`~/.var/app/io.github.wiiznokes.fan-control/config/fan-control/`](file://~/.var/app/io.github.wiiznokes.fan-control/config/fan-control/).
diff --git a/build.rs b/build.rs index 06798ec7..143411e7 100644 --- a/build.rs +++ b/build.rs @@ -6,7 +6,7 @@ fn main() -> io::Result<()> { if env::var_os("CARGO_CFG_WINDOWS").is_some() && std::env::var("PROFILE").unwrap() == "release" { winres::WindowsResource::new() - .set_icon("resource/app_icon/app_icon150.ico") + .set_icon("resource/windows/app_icon.ico") .set_manifest_file("resource/windows/manifest.xml") .compile()?; } diff --git a/data/Cargo.toml b/data/Cargo.toml index 1a4fa5c7..5ba31807 100644 --- a/data/Cargo.toml +++ b/data/Cargo.toml @@ -2,7 +2,6 @@ name = "data" version = "0.1.0" description = "Data struct used by fan-control" -rust-version.workspace = true authors.workspace = true edition.workspace = true license.workspace = true @@ -25,6 +24,7 @@ rust-embed.workspace = true lazy_static.workspace = true derive_more.workspace = true thiserror.workspace = true +utils.workspace = true lexical-sort = "0.3" [dev-dependencies] diff --git a/data/src/config/graph.rs b/data/src/config/graph.rs index a9c1f924..1c1e67c0 100644 --- a/data/src/config/graph.rs +++ b/data/src/config/graph.rs @@ -5,12 +5,13 @@ use serde::{Deserialize, Deserializer, Serialize}; use crate::{ app_graph::Nodes, - config::graph::affine::Affine, id::IdGenerator, node::{IsValid, Node, NodeType, ToNode}, update::UpdateError, }; +use super::utils::affine::Affine; + #[derive(Serialize, Deserialize, Debug, Clone, Eq)] pub struct Coord { pub temp: u8, @@ -57,7 +58,6 @@ impl Coord { } } -// todo: better default + UI #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Graph { pub name: String, @@ -92,6 +92,10 @@ impl ToNode for Graph { } impl IsValid for Graph { + // todo: we can filter wrong Coord when launching + // and only autorize good coord to be added so we don't need this + // kind on verification + // so only check if !empty fn is_valid(&self) -> bool { #[derive(PartialEq)] enum DupState { @@ -168,72 +172,55 @@ impl Graph { } } -// todo: use it in linear -mod affine { - use hardware::Value; - - #[derive(Debug)] - pub struct Affine { - pub xa: f32, - pub ya: f32, - pub xb: f32, - pub yb: f32, - } - - impl Affine { - pub fn calcule(&self, value: Value) -> f32 { - let a = (self.yb - self.ya) / (self.xb - self.xa); - let b = self.ya - a * self.xa; +#[cfg(test)] +mod test { + use crate::config::graph::{Coord, Coords}; - a * value as f32 + b - } - } -} - -#[test] -fn test() { - let coord1 = Coord { - temp: 10, - percent: 10, - }; + #[test] + fn test() { + let coord1 = Coord { + temp: 10, + percent: 10, + }; - let coord2 = Coord { - temp: 20, - percent: 20, - }; + let coord2 = Coord { + temp: 20, + percent: 20, + }; - let coord3 = Coord { - temp: 30, - percent: 30, - }; + let coord3 = Coord { + temp: 30, + percent: 30, + }; - let coord4 = Coord { - temp: 40, - percent: 40, - }; + let coord4 = Coord { + temp: 40, + percent: 40, + }; - let coords = Coords(vec![coord1, coord2, coord3, coord4]); + let coords = Coords(vec![coord1, coord2, coord3, coord4]); - let dummy_coord = Coord { - temp: 50, - percent: 0, - }; + let dummy_coord = Coord { + temp: 50, + percent: 0, + }; - let res = coords.0.binary_search(&dummy_coord); + let res = coords.0.binary_search(&dummy_coord); - match res { - Ok(index) => { - println!("use {}", index); - } - Err(index) => { - if index == 0 { + match res { + Ok(index) => { println!("use {}", index); - } else if index == coords.0.len() { - println!("use {}", index - 1); - } else { - println!("use {} and {}", index - 1, index); + } + Err(index) => { + if index == 0 { + println!("use {}", index); + } else if index == coords.0.len() { + println!("use {}", index - 1); + } else { + println!("use {} and {}", index - 1, index); + } } } + dbg!(&res); } - dbg!(&res); } diff --git a/data/src/config/linear.rs b/data/src/config/linear.rs index e5617b88..a97df2ea 100644 --- a/data/src/config/linear.rs +++ b/data/src/config/linear.rs @@ -7,6 +7,8 @@ use crate::{ use hardware::{Hardware, Value}; use serde::{Deserialize, Serialize}; +use super::utils::affine::Affine; + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Linear { pub name: String, @@ -27,12 +29,6 @@ impl IsValid for Linear { } } -#[derive(Debug)] -struct Affine { - a: f32, - b: f32, -} - impl Linear { pub fn get_value(&self, value: Value) -> Result { if value <= self.min_temp.into() { @@ -43,21 +39,15 @@ impl Linear { return Ok(self.max_speed.into()); } - let affine = self.calcule_affine(); - - let final_value: f32 = affine.a * value as f32 + affine.b; - Ok(final_value as Value) - } - - fn calcule_affine(&self) -> Affine { - let xa: f32 = self.min_temp.into(); - let ya: f32 = self.min_speed.into(); - let xb: f32 = self.max_temp.into(); - let yb: f32 = self.max_speed.into(); - - let a = (yb - ya) / (xb - xa); + let res = Affine { + xa: self.min_temp.into(), + ya: self.min_speed.into(), + xb: self.max_temp.into(), + yb: self.max_speed.into(), + } + .calcule(value) as Value; - Affine { a, b: ya - a * xa } + Ok(res) } } diff --git a/data/src/config/mod.rs b/data/src/config/mod.rs index e37c4797..784f44c2 100644 --- a/data/src/config/mod.rs +++ b/data/src/config/mod.rs @@ -7,6 +7,8 @@ pub mod linear; pub mod target; pub mod temp; +mod utils; + #[cfg(test)] mod serde_test; diff --git a/data/src/config/utils/affine.rs b/data/src/config/utils/affine.rs new file mode 100644 index 00000000..5090e949 --- /dev/null +++ b/data/src/config/utils/affine.rs @@ -0,0 +1,18 @@ +use hardware::Value; + +#[derive(Debug)] +pub struct Affine { + pub xa: f32, + pub ya: f32, + pub xb: f32, + pub yb: f32, +} + +impl Affine { + pub fn calcule(&self, value: Value) -> f32 { + let a = (self.yb - self.ya) / (self.xb - self.xa); + let b = self.ya - a * self.xa; + + a * value as f32 + b + } +} diff --git a/data/src/config/utils/mod.rs b/data/src/config/utils/mod.rs new file mode 100644 index 00000000..e176016f --- /dev/null +++ b/data/src/config/utils/mod.rs @@ -0,0 +1 @@ +pub mod affine; diff --git a/data/src/dir_manager.rs b/data/src/dir_manager.rs index 3273da23..20241835 100644 --- a/data/src/dir_manager.rs +++ b/data/src/dir_manager.rs @@ -7,6 +7,7 @@ use directories::ProjectDirs; use hardware::Hardware; use thiserror::Error; +use utils::{APP, ORG, QUALIFIER}; use crate::{config::Config, settings::Settings, utils::RemoveElem}; @@ -44,10 +45,6 @@ static HARDWARE_FILENAME: &str = "hardware.toml"; impl DirManager { pub fn new(config_dir_path: &Option, config_name: &Option) -> DirManager { fn default_config_dir_path() -> PathBuf { - static QUALIFIER: &str = "com"; - static ORG: &str = "wiiznokes"; - static APP: &str = "fan-control"; - ProjectDirs::from(QUALIFIER, ORG, APP) .unwrap() .config_dir() diff --git a/data/src/settings.rs b/data/src/settings.rs index ea063e5b..a970a25c 100644 --- a/data/src/settings.rs +++ b/data/src/settings.rs @@ -16,9 +16,10 @@ pub struct Settings { #[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize, Default, Values)] pub enum AppTheme { - #[default] System, Dark, + // todo: change default to system when dark mode is fixed + #[default] Light, } diff --git a/hardware/Cargo.toml b/hardware/Cargo.toml index ba50d54b..53073fb8 100644 --- a/hardware/Cargo.toml +++ b/hardware/Cargo.toml @@ -3,7 +3,6 @@ name = "hardware" version = "0.1.0" description = "hardware abstraction used by fan-control" categories = ["hardware-support"] -rust-version.workspace = true authors.workspace = true edition.workspace = true license.workspace = true @@ -19,17 +18,17 @@ fake_hardware = ["rand"] thiserror.workspace = true log.workspace = true serde.workspace = true -ouroboros = "0.18" rand = { version = "0.8", optional = true } derive_more.workspace = true [target.'cfg(target_os = "windows")'.dependencies] serde_json.workspace = true -cargo-packager-resource-resolver.workspace = true +utils.workspace = true #num_enum = "0.7" [target.'cfg(target_os = "linux")'.dependencies] lm-sensors = { git = "https://github.com/wiiznokes/lm-sensors.git", branch = "pwm" } +ouroboros = "0.18" [dev-dependencies] env_logger.workspace = true \ No newline at end of file diff --git a/hardware/LibreHardwareMonitorWrapper/LibreHardwareMonitorWrapper.csproj b/hardware/LibreHardwareMonitorWrapper/LibreHardwareMonitorWrapper.csproj index fc0804b3..56a9dfac 100644 --- a/hardware/LibreHardwareMonitorWrapper/LibreHardwareMonitorWrapper.csproj +++ b/hardware/LibreHardwareMonitorWrapper/LibreHardwareMonitorWrapper.csproj @@ -11,7 +11,7 @@ win-x64 false false - .\..\..\resource\windows\build + .\..\..\resource\windows\lhmbuild diff --git a/hardware/src/linux.rs b/hardware/src/linux.rs index 6ee27d40..dc1e8d98 100644 --- a/hardware/src/linux.rs +++ b/hardware/src/linux.rs @@ -12,14 +12,6 @@ use ouroboros::self_referencing; static DEFAULT_PWM_ENABLE: f64 = 5.0; static MANUAL_MODE: f64 = 1.0; -#[self_referencing] -struct LinuxBridgeSelfRef { - lib: LMSensors, - #[borrows(lib)] - #[not_covariant] - sensors: Vec>, -} - pub struct LinuxBridge { lm_sensor: LinuxBridgeSelfRef, hardware: Hardware, @@ -31,6 +23,26 @@ pub enum LinuxError { LmSensors(String, lm_sensors::errors::Error), } +#[self_referencing] +struct LinuxBridgeSelfRef { + lib: LMSensors, + + // ouroboros doesn't provide any documentation on the droping order + // https://github.com/someguynamedjosh/ouroboros/issues/82 + // but this structure that store references should be dropped first + #[borrows(lib)] + #[not_covariant] + sensors: Vec>, +} + +impl Drop for PwmRefs<'_> { + fn drop(&mut self) { + if let Err(e) = self.enable.set_raw_value(self.default_enable_cached) { + error!("can't set auto to a pwm sensor when quitting: {}", e) + } + } +} + struct PwmRefs<'a> { io: SubFeatureRef<'a>, enable: SubFeatureRef<'a>, @@ -318,11 +330,3 @@ impl HardwareBridge for LinuxBridge { }) } } - -impl Drop for PwmRefs<'_> { - fn drop(&mut self) { - if let Err(e) = self.enable.set_raw_value(self.default_enable_cached) { - error!("can't set auto to a pwn in his drop function: {}", e) - } - } -} diff --git a/hardware/src/windows.rs b/hardware/src/windows.rs index 4dd78907..848bd2cd 100644 --- a/hardware/src/windows.rs +++ b/hardware/src/windows.rs @@ -12,8 +12,6 @@ use thiserror::Error; use crate::{HControl, HSensor, Hardware, HardwareBridge, Mode, Value}; -use cargo_packager_resource_resolver as resource_resolver; - use self::packet::{command::Command, i32::I32, Packet}; pub struct WindowsBridge { @@ -30,8 +28,6 @@ pub enum WindowsError { SpawnServer(std::io::Error), #[error("No connection was found")] NoConnectionFound, - #[error(transparent)] - Resource(#[from] resource_resolver::Error), #[error("Failed to parse hardware struct: {0}")] JSONConfigParseError(#[from] serde_json::Error), } @@ -39,31 +35,13 @@ pub enum WindowsError { type Result = std::result::Result; fn spawn_windows_server() -> Result { - let resource_path = { - let resource_suffix = "resource"; - #[cfg(test)] - { - std::path::PathBuf::from(format!("../{resource_suffix}")) - } - #[cfg(not(test))] - { - match resource_resolver::current_format() { - Ok(package_format) => match resource_resolver::resources_dir(package_format) { - Ok(path) => path, - Err(e) => { - error!("Can't find resource path: {e}. Fall back to current dir."); - match std::env::current_dir() { - Ok(current_dir) => current_dir.join(resource_suffix), - Err(e) => return Err(WindowsError::SpawnServer(e)), - } - } - }, - Err(_) => std::path::PathBuf::from(resource_suffix), - } - } + let resource_path = if cfg!(test) { + std::path::PathBuf::from("../resource".to_string()) + } else { + utils::resource_dir() }; - let exe_path = resource_path.join("windows/build/LibreHardwareMonitorWrapper"); + let exe_path = resource_path.join("lhmbuild/LibreHardwareMonitorWrapper"); let mut command = process::Command::new(exe_path); diff --git a/i18n/en/ui.ftl b/i18n/en/ui.ftl index eff90d57..12ff8a04 100644 --- a/i18n/en/ui.ftl +++ b/i18n/en/ui.ftl @@ -37,7 +37,7 @@ add_target = Take 5 variables: - a sensor value If the sensor > trigger temperature, trigger speed is set until this sensor is < ideal temperature -add_graph = A graph +add_graph = Graph # Config config_name = Configuration name diff --git a/i18n/fr/ui.ftl b/i18n/fr/ui.ftl index 12e1e20d..88694ef1 100644 --- a/i18n/fr/ui.ftl +++ b/i18n/fr/ui.ftl @@ -24,20 +24,20 @@ add_temp = Monitore un capteur de temperature add_custom_temp = Defini une logique entre des valeurs (Max, Moyenne, ...) add_control = Applique un certain comportement a un ventilateur add_flat = Retourne une valeur fixe -add_linear = Prendre 5 variables : +add_linear = Prend 5 variables : - une température minimale et maximale - une vitesse minimale et maximale - une valeur de capteur Si le capteur < température minimale -> vitesse minimale Si le capteur > température maximale -> vitesse maximale Sinon, une moyenne est calculée (voir icÎne) -add_target = Prendre 5 variables : +add_target = Prend 5 variables : - une température idéale et une température de déclenchement - une vitesse idéale et une vitesse de déclenchement - une valeur de capteur Si le capteur > température de déclenchement, la vitesse de déclenchement est définie jusqu'à ce que ce capteur < température idéale -add_graph = Un graph +add_graph = Graphe # Config config_name = Nom de la configuration diff --git a/justfile b/justfile index e872020d..80fd1727 100644 --- a/justfile +++ b/justfile @@ -17,11 +17,6 @@ lhm: ################### Packaging -deb: - cargo packager --release --formats deb --verbose - mkdir -p packages - cp ./target/release/fan-control*.deb ./packages/ - nsis: cargo packager --release --formats nsis --verbose New-Item -Path .\packages -ItemType Directory -Force > $null @@ -51,10 +46,11 @@ fmt-lhm: ################### Clean clean-libsensors: - make -C ./hardware/libsensors/ clean uninstall PREFIX=./../../build/libsensors ETCDIR=./../../build/libsensors/etc - + make -C ./hardware/libsensors/ clean uninstall PREFIX=./../../build/libsensors ETCDIR=./../../build/libsensors/etc || true + rm -r build/libsensors || true + clean-lhm: - dotnet clean ./hardware/LibreHardwareMonitorWrapper/ + dotnet clean ./hardware/LibreHardwareMonitorWrapper/ || true @@ -89,23 +85,8 @@ expand: +## TEMP -## Debug - -debll: - dpkg-deb -c ./packages/fan-control*.deb | grep -v usr/lib/fan-control/icons/ - -debi: deb debll - sudo apt-get remove fan-control -y || true > /dev/null - sudo apt-get install ./packages/fan-control_0.1.0_amd64.deb > /dev/null - fan-control - -debinfo: - dpkg-query -s fan-control - -debl: - dpkg-query -L fan-control | grep -v /usr/lib/fan-control/ressource/ - -package-msi: - cargo bundle --release --format msi - +# todo: Add to CI +metainfo-check: + appstreamcli validate --pedantic --explain --strict resource/linux/metainfo.xml diff --git a/resource/app_icon/app_icon128.png b/resource/app_icon/app_icon128.png deleted file mode 100644 index abf1315f..00000000 --- a/resource/app_icon/app_icon128.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b90533f75a219274ef306cb37941680ec68ac655abdac164437f776d8bdada62 -size 2360 diff --git a/resource/app_icon/app_icon16.png b/resource/app_icon/app_icon16.png deleted file mode 100644 index f7ecec66..00000000 --- a/resource/app_icon/app_icon16.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4e6bcd4d333f2e8b456ae83b9af65bedcac59e9ca1d149140f0ba6c03fc4cef3 -size 410 diff --git a/resource/app_icon/app_icon24.png b/resource/app_icon/app_icon24.png deleted file mode 100644 index 42aacdcb..00000000 --- a/resource/app_icon/app_icon24.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0cf1d3c290e43cbfd583daf34dcd9ae8cde23d18bf53794ebac2d29641202673 -size 552 diff --git a/resource/app_icon/app_icon256.png b/resource/app_icon/app_icon256.png deleted file mode 100644 index c5c3e90e..00000000 --- a/resource/app_icon/app_icon256.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f94296df40b9ee3fac6df1c37d96d61abe4499510c771ca8b2383038dab7237e -size 4594 diff --git a/resource/app_icon/app_icon32.png b/resource/app_icon/app_icon32.png deleted file mode 100644 index 3dc52a30..00000000 --- a/resource/app_icon/app_icon32.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:990f3c64b56a230c1792b80380c1ea8f42af1730392b467aae7a8aeb3f7b6aeb -size 704 diff --git a/resource/app_icon/app_icon48.png b/resource/app_icon/app_icon48.png deleted file mode 100644 index b3d1f150..00000000 --- a/resource/app_icon/app_icon48.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e8d337009541545300e0158ff5fdb89898e348b31212c190e084205de26fea49 -size 792 diff --git a/resource/app_icon/app_icon512.png b/resource/app_icon/app_icon512.png deleted file mode 100644 index 18da9497..00000000 --- a/resource/app_icon/app_icon512.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:feb1d7fb0cde1e8554eab9cd7782f52fdec4fce4f43f77706dfac588c5a5cc14 -size 9161 diff --git a/resource/app_icon/app_icon64.png b/resource/app_icon/app_icon64.png deleted file mode 100644 index e5deac43..00000000 --- a/resource/app_icon/app_icon64.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:48f8766744d99287e8d9b587dce8e2c74685152d1bc819afe3260b830d18c969 -size 1297 diff --git a/resource/linux/60-fan-control.rules b/resource/linux/60-fan-control.rules new file mode 100644 index 00000000..15b7adff --- /dev/null +++ b/resource/linux/60-fan-control.rules @@ -0,0 +1,2 @@ + +KERNEL=="hwmon7", SUBSYSTEM=="hwmon", TAG+="uaccess" \ No newline at end of file diff --git a/resource/linux/app_icon.svg b/resource/linux/app_icon.svg new file mode 100644 index 00000000..1ee6445d --- /dev/null +++ b/resource/linux/app_icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resource/linux/desktop_entry.desktop b/resource/linux/desktop_entry.desktop new file mode 100644 index 00000000..b3a6434e --- /dev/null +++ b/resource/linux/desktop_entry.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Name=fan-control +Comment=Control your fans with different behaviors +Type=Application +Keywords=fan;control;temp;sensor; +Categories=System;Utility; +Exec=fan-control +Icon=io.github.wiiznokes.fan-control +StartupWMClass=io.github.wiiznokes.fan-control +Terminal=false \ No newline at end of file diff --git a/resource/linux/install_udev_rules.sh b/resource/linux/install_udev_rules.sh new file mode 100755 index 00000000..a3f821a7 --- /dev/null +++ b/resource/linux/install_udev_rules.sh @@ -0,0 +1,35 @@ +#! /bin/bash + +STEAMOS=0 +STEAMOS_READONLY=0 + +# Test for SteamOS and disable readonly mode if we're running on it +if command -v steamos-readonly >& /dev/null +then + # Test if SteamOS readonly mode is enabled + if sudo steamos-readonly status | grep 'enabled' + then + echo "steamos readonly mode is true" + STEAMOS_READONLY=1 + fi + + STEAMOS=1 + sudo steamos-readonly disable +fi + +# Download udev rules file +#wget https://raw.githubusercontent.com/wiiznokes/fan-control/flatpak/resource/linux/60-fan-control.rules + +# Move udev rules file to udev rules directory +sudo mv 60-fan-control.rules /usr/lib/udev/rules.d +#sudo install -m644 90-fan-control.rules /usr/lib/udev/rules.d + +# Reload the rules +sudo udevadm control --reload-rules && sudo udevadm trigger + + +if [ "$STEAMOS" = 1 ] ; then + if [ "$STEAMOS_READONLY" = 1 ] ; then + sudo steamos-readonly enable + fi +fi diff --git a/resource/linux/metainfo.xml b/resource/linux/metainfo.xml new file mode 100644 index 00000000..174ace1e --- /dev/null +++ b/resource/linux/metainfo.xml @@ -0,0 +1,70 @@ + + + + + + io.github.wiiznokes.fan-control + + fan-control + Control your fans with different behaviors + + MIT + MIT + + + wiiznokes + + + https://github.com/wiiznokes/fan-control + https://github.com/wiiznokes/fan-control/issues + https://www.paypal.com/donate/?hosted_button_id=HV84HZ4G63HQ6 + https://github.com/wiiznokes/fan-control + + + + +

You can add items with the buttons on the right of the app. + To save a configuration, write a name in the "Configuration name" field, and click on the +. + To modify the value of a fan, you must select it in a Control item (the left column), select a + Behavior, and activate the swtich. +

+
    +
  • Display sensors data on real time
  • +
  • Control fans based on custom behaviors
  • +
  • Save configuration
  • +
+
+ + io.github.wiiznokes.fan-control.desktop + + + fan-control screenshot + + https://media.githubusercontent.com/media/wiiznokes/fan-control/master/resource/screenshots/app.png + + + + + + +

First release on Flathub

+
    +
  • Flatpak support
  • +
  • Initial graph support
  • +
+
+
+ + + + +

Initial release

+
    +
  • UI
  • +
  • Windows + Linux support
  • +
+
+
+
+ +
\ No newline at end of file diff --git a/resource/linux/rules.txt b/resource/linux/rules.txt new file mode 100644 index 00000000..4d4ff4fc --- /dev/null +++ b/resource/linux/rules.txt @@ -0,0 +1,47 @@ + +# The kernel name is assigned to devices by the kernel. It is unique. + +# uaccess add user access to the device. It will be able to interact with +# the way the device was configured + +KERNEL=="i2c-[0-99]*", TAG+="uaccess" + + + +# Action add: this rule will be triggered when a device is added to the system +# SUBSYSTEM=="platform": In Linux, the "platform" subsystem typically represents +# hardware devices integrated into the system's motherboard or platform. +# RUN ...: add write permission to all user to the file. %k get replaced by the kernel name (so faustus) + + +ACTION=="add", SUBSYSTEM=="platform", KERNEL=="faustus", RUN+="/bin/chmod a+w /sys/bus/platform/devices/%k/kbbl/kbbl_speed" + + + + + + + +SUBSYSTEMS=="usb|hidraw", ATTRS{idVendor}=="3061", ATTRS{idProduct}=="4772", TAG+="uaccess", TAG+="GaiZhongGai_20_PRO" + + + +use udevadm monitor -u | grep hwmon to see what rules get triggered + + + + +We need to check if uaccess is enough or we need to change ownership +Is it always in hwmon7 ? + + +https://github.com/lm-sensors/lm-sensors/issues/426 + +find . -name "pwm2*" -exec sudo chmod a+w {} \; + +# KERNEL=="hwmon[0-99]*" + +# RUN+="/bin/chmod -R a+w /sys/class/hwmon/hwmon7" + + +https://gitlab.com/CalcProgrammer1/OpenRGB/ \ No newline at end of file diff --git a/resource/linux/udev_rules.md b/resource/linux/udev_rules.md new file mode 100644 index 00000000..5284eecc --- /dev/null +++ b/resource/linux/udev_rules.md @@ -0,0 +1,30 @@ +# Install udev rules on Linux + +## Info + +fan-control is distributed with flatpak on Linux, which allows containerization. But fan-control need to access your sensors to work. +This is why we use [udev](https://en.wikipedia.org/wiki/Udev), which allows normal user to access devices, without giving them sudo permission. [This is](./60-fan-control.rules) the rule that you need for fan-control. + +# Commands to install the rules + +```sh +wget https://raw.githubusercontent.com/wiiznokes/fan-control/resource/linux/60-fan-control.rules +sudo mv 60-fan-control.rules /usr/lib/udev/rules.d +sudo udevadm control --reload-rules && sudo udevadm trigger +``` + +#### _Info_ + +- _wget_: download the rule in your current directory +- _sudo mv_: move the rule where it need to be +- _udevadm_: reload the rules + +### Steam Os + +You need to disable read the read only mode temporarily + +```sh +sudo steamos-readonly disable +... commands +sudo steamos-readonly enable +``` diff --git a/resource/app_icon/app_icon150.ico b/resource/windows/app_icon.ico similarity index 100% rename from resource/app_icon/app_icon150.ico rename to resource/windows/app_icon.ico diff --git a/ui/Cargo.toml b/ui/Cargo.toml index 7e1cd69d..7443a645 100644 --- a/ui/Cargo.toml +++ b/ui/Cargo.toml @@ -2,7 +2,6 @@ name = "ui" version = "0.1.0" description = "Ui implementation of fan-control" -rust-version.workspace = true authors.workspace = true edition.workspace = true license.workspace = true @@ -20,7 +19,7 @@ i18n-embed-fl.workspace = true rust-embed.workspace = true lazy_static.workspace = true once_cell.workspace = true -cargo-packager-resource-resolver.workspace = true +utils.workspace = true derive_more.workspace = true tokio = { version = "1.35", features = ["time"] } [dependencies.libcosmic] @@ -31,7 +30,8 @@ branch = "master" default-features = false features = [ "smol", - "wgpu", + # disable because cause seg fault when quitting the app on flatpak + #"wgpu", "winit", "tokio", "multi-window" diff --git a/ui/src/icon.rs b/ui/src/icon.rs index a9b29527..c7144eda 100644 --- a/ui/src/icon.rs +++ b/ui/src/icon.rs @@ -7,17 +7,8 @@ use cosmic::{ use data::node::NodeTypeLight; use once_cell::sync::Lazy; -use cargo_packager_resource_resolver as resource_resolver; - lazy_static::lazy_static! { - static ref ICONS_DIR: PathBuf = { - resource_resolver::current_format() - .map_or(PathBuf::from("resource/icons"), |package_format| { - resource_resolver::resources_dir(package_format) - .unwrap_or(PathBuf::from("resource")) - .join("icons/") - }) - }; + static ref ICONS_DIR: PathBuf = utils::resource_dir().join("icons/"); } static EXTENSION: &str = "px.svg"; diff --git a/ui/src/lib.rs b/ui/src/lib.rs index 674b17a5..ac675fc6 100644 --- a/ui/src/lib.rs +++ b/ui/src/lib.rs @@ -72,7 +72,7 @@ impl cosmic::Application for Ui { type Message = AppMsg; type Flags = AppState; - const APP_ID: &'static str = "com.wiiznokes.fan-control"; + const APP_ID: &'static str = utils::APP_ID; fn core(&self) -> &Core { &self.core diff --git a/utils/Cargo.toml b/utils/Cargo.toml new file mode 100644 index 00000000..64970423 --- /dev/null +++ b/utils/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "utils" +version = "0.1.0" +description = "Utils for fan-control" + +authors.workspace = true +edition.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +keywords.workspace = true + + +[dependencies] +cached = "0.49" +cargo-packager-resource-resolver.workspace = true +log.workspace = true diff --git a/utils/build.rs b/utils/build.rs new file mode 100644 index 00000000..f9583aea --- /dev/null +++ b/utils/build.rs @@ -0,0 +1,9 @@ +use std::env; + +fn main() { + println!("cargo:rerun-if-env-changed=FAN_CONTROL_FORMAT"); + + if let Ok(var) = env::var("FAN_CONTROL_FORMAT") { + println!("cargo:rustc-cfg=FAN_CONTROL_FORMAT=\"{}\"", var); + } +} diff --git a/utils/src/lib.rs b/utils/src/lib.rs new file mode 100644 index 00000000..c4b016ff --- /dev/null +++ b/utils/src/lib.rs @@ -0,0 +1,33 @@ +use std::path::PathBuf; + +use cargo_packager_resource_resolver as resource_resolver; +use log::error; + +use cached::proc_macro::cached; + +// https://github.com/rust-lang/rust/issues/31383 + +pub const APP_ID: &str = "io.github.wiiznokes.fan-control"; + +pub const QUALIFIER: &str = "io.github"; +pub const ORG: &str = "wiiznokes"; +pub const APP: &str = "fan-control"; + +#[cached] +pub fn resource_dir() -> PathBuf { + if cfg!(FAN_CONTROL_FORMAT = "flatpak") { + PathBuf::from(format!("/app/share/{APP_ID}/resource")) + } else { + match resource_resolver::current_format() { + Ok(format) => resource_resolver::resources_dir(format).unwrap(), + Err(e) => { + if matches!(e, resource_resolver::Error::UnkownPackageFormat) { + PathBuf::from("resource") + } else { + error!("{e}"); + panic!() + } + } + } + } +}