mirror of
https://github.com/AdnanHodzic/auto-cpufreq.git
synced 2025-04-08 17:05:56 +02:00
Compare commits
196 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
3898246f4b | ||
|
00be2a5d91 | ||
|
c6ba839f93 | ||
|
dc385dd6a2 | ||
|
1d3593d162 | ||
|
af5fb382e1 | ||
|
8f026ac649 | ||
|
f2c4a2d763 | ||
|
6be1547243 | ||
|
beafca250f | ||
|
ffb56de246 | ||
|
081dbda79c | ||
|
e6bbd2c833 | ||
|
4cee388c1b | ||
|
cef9bfec79 | ||
|
436022b69e | ||
|
9ead67d44f | ||
|
d1892ba727 | ||
|
f08f9c66ac | ||
|
d9cde7a6f2 | ||
|
db54ea39e6 | ||
|
c0d9ec565a | ||
|
96fcf631ee | ||
|
3e4d8947d9 | ||
|
4dae1d4b59 | ||
|
19e57bde02 | ||
|
18a3a93f62 | ||
|
d45a31853c | ||
|
41081a5bdf | ||
|
6a13948458 | ||
|
7b03630a5e | ||
|
3e52842022 | ||
|
08d95b6bec | ||
|
a42e8fb51e | ||
|
163a1f9399 | ||
|
927ff7281a | ||
|
1c11ca3139 | ||
|
429bf7672f | ||
|
64af2b4ec6 | ||
|
7925c21023 | ||
|
e2d605085c | ||
|
1122c907a8 | ||
|
484742a683 | ||
|
27f0690564 | ||
|
c6a4580e85 | ||
|
a1ac308be7 | ||
|
7ac55199f2 | ||
|
42a1239068 | ||
|
a14d06ce94 | ||
|
c7bab0e36f | ||
|
4ef561eccf | ||
|
910aef9072 | ||
|
6f7e469e66 | ||
|
34ebd04df0 | ||
|
432883acee | ||
|
f300d31e0f | ||
|
d09063f116 | ||
|
2fdb703b96 | ||
|
f1c812cf56 | ||
|
a7df94d832 | ||
|
1e44c8031c | ||
|
7313ec9b8c | ||
|
3f6d7a3e77 | ||
|
487c344da3 | ||
|
a5ffa5730b | ||
|
e878dd51fe | ||
|
420648f5f1 | ||
|
2b09bf7543 | ||
|
1f911b534c | ||
|
cc6d98d8b1 | ||
|
a79ec81709 | ||
|
14e1d2785d | ||
|
eb0ba8aa7e | ||
|
b8f864e87e | ||
|
281a7adc34 | ||
|
78c3f71438 | ||
|
95ba1f42bd | ||
|
f1c1dc6b10 | ||
|
0815e7eb96 | ||
|
8bb7478e38 | ||
|
5e17ee31b1 | ||
|
2df634b09c | ||
|
215026ad43 | ||
|
971f40f0ca | ||
|
de12f9f708 | ||
|
0354775b72 | ||
|
ab32952737 | ||
|
166cd065a2 | ||
|
0354ff6cc4 | ||
|
b4c5276feb | ||
|
13e9009d5c | ||
|
6ff1b89e22 | ||
|
ba5b5fb032 | ||
|
7afd192ff9 | ||
|
9b8e873145 | ||
|
1d7f12e846 | ||
|
539914a545 | ||
|
005b4aa178 | ||
|
3e8ee20117 | ||
|
1abad4da7b | ||
|
68dec52bce | ||
|
e71edd8c30 | ||
|
27ca776029 | ||
|
d2cb5a3761 | ||
|
fe29620646 | ||
|
8938cc92d7 | ||
|
242cb0cb58 | ||
|
c523f51fd1 | ||
|
cad325f265 | ||
|
4dbad5539a | ||
|
0d1178cba0 | ||
|
8b4ff4b443 | ||
|
35a08192da | ||
|
15c17fc52c | ||
|
4ddff1f702 | ||
|
2e47f47b21 | ||
|
929fdf6020 | ||
|
34f3d23aa0 | ||
|
d3760eaf37 | ||
|
98cd5dd31f | ||
|
6dde7441ee | ||
|
3414f4878a | ||
|
5bf295d86a | ||
|
5d4ba17d69 | ||
|
964f2f5efe | ||
|
78a86a1126 | ||
|
a79b3be822 | ||
|
4165f9483b | ||
|
d710518c61 | ||
|
37e12a4266 | ||
|
c3e2f83d7b | ||
|
0f14a6a252 | ||
|
64b11ab089 | ||
|
7f9ced7bfd | ||
|
0c03b004bb | ||
|
1b229891bc | ||
|
fdb20f5ea2 | ||
|
cc410dad1c | ||
|
7f3b3e1fc1 | ||
|
4defdacb2c | ||
|
fecec333e8 | ||
|
7e02a0769d | ||
|
20a1a9d3a6 | ||
|
5b01ce4d97 | ||
|
f0de797485 | ||
|
257d6e9532 | ||
|
3e2b779406 | ||
|
4628b5d1e1 | ||
|
9f132bdc81 | ||
|
e173723f24 | ||
|
674b3c4ae0 | ||
|
ee888d4729 | ||
|
71ebc3e80e | ||
|
0925b5d542 | ||
|
b0f84726d7 | ||
|
8fbb9480f0 | ||
|
d47453c050 | ||
|
3dffa23e00 | ||
|
faf7134cb6 | ||
|
c67e290cc0 | ||
|
c34e3e7fbd | ||
|
486a9a6dc2 | ||
|
d593e3e839 | ||
|
3dcf2fd837 | ||
|
9a935ebd5b | ||
|
de37962dc7 | ||
|
b1758ba74b | ||
|
717ab2d462 | ||
|
fe7eab8576 | ||
|
9912f9d809 | ||
|
c65eac3472 | ||
|
8f343df8b8 | ||
|
b38919f56b | ||
|
dadfae087f | ||
|
471611de7d | ||
|
f574257dc4 | ||
|
04b878360c | ||
|
fe21ddf245 | ||
|
69ef913c1b | ||
|
2bfe71e8d8 | ||
|
f66df2a8e8 | ||
|
1c9ff32a33 | ||
|
d04438ee81 | ||
|
9a1c0ad44a | ||
|
13edca0a61 | ||
|
70c58fba3a | ||
|
122dd0f96c | ||
|
d77c1de6d6 | ||
|
d26ec98837 | ||
|
d60642720a | ||
|
2ae8ed4be2 | ||
|
6e74a95f10 | ||
|
3e28e79e28 | ||
|
ff72e1e0f3 | ||
|
e813301aa8 | ||
|
43b33be51c |
@ -1,4 +1,15 @@
|
||||
### Fill out informtion requested in this template, without doing so issue will be ignored & closed!
|
||||
---
|
||||
name: Bug report or feature request
|
||||
about: Report an issue or request a feature request
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### Fill out information requested in this template, without doing so issue will be ignored & closed!
|
||||
|
||||
#### Before submitting an issue, it is strongly recommended to use the **[auto-cpufreq-genAI-chatbot](https://foolcontrol.org/?p=4903)** to get an immediate answer to your question.
|
||||
|
||||
### Have you tried?
|
||||
|
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1 @@
|
||||
blank_issues_enabled: false
|
28
.github/workflows/build-linux.yml
vendored
Normal file
28
.github/workflows/build-linux.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
name: Linux Build
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- "README.md"
|
||||
- ".gitignore"
|
||||
- "LICENSE"
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build_linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.1
|
||||
|
||||
- name: Install poetry
|
||||
run: pipx install poetry
|
||||
|
||||
- name: "Setup Python"
|
||||
uses: actions/setup-python@v5.0.0
|
||||
with:
|
||||
python-version: 3.12
|
||||
cache: "poetry"
|
||||
|
||||
- name: "Install auto-cpufreq"
|
||||
run: sudo ./auto-cpufreq-installer --install
|
||||
|
26
.github/workflows/build-nix.yaml
vendored
Normal file
26
.github/workflows/build-nix.yaml
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
name: Nix Flake
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- "README.md"
|
||||
- ".gitignore"
|
||||
- "LICENSE"
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build-nix:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: "Install Nix ❄️"
|
||||
uses: cachix/install-nix-action@v25
|
||||
|
||||
- name: "Nix Cache"
|
||||
uses: DeterminateSystems/magic-nix-cache-action@v3
|
||||
|
||||
- name: "Build Nix Flake ❄️"
|
||||
run: nix build
|
||||
|
||||
|
7
.gitignore
vendored
7
.gitignore
vendored
@ -110,6 +110,7 @@ venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
.direnv
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
@ -138,3 +139,9 @@ dmypy.json
|
||||
|
||||
# pycharm
|
||||
.idea/
|
||||
|
||||
# nix build
|
||||
/result
|
||||
|
||||
# vs code
|
||||
.vscode/
|
||||
|
619
README.md
619
README.md
@ -1,123 +1,353 @@
|
||||
# auto-cpufreq
|
||||
[](https://github.com/AdnanHodzic/auto-cpufreq/actions/workflows/build-linux.yml)
|
||||
[](https://github.com/AdnanHodzic/auto-cpufreq/actions/workflows/build-nix.yaml)
|
||||
|
||||
Automatic CPU speed & power optimizer for Linux based on active monitoring of laptop's battery state, CPU usage, CPU temperature and system load. Ultimately allowing you to improve battery life without making any compromises.
|
||||
Automatic CPU speed & power optimizer for Linux. Actively monitors laptop battery state, CPU usage, CPU temperature, and system load, ultimately allowing you to improve battery life without making any compromises.
|
||||
|
||||
For tl;dr folks there's a: [Youtube: auto-cpufreq - tool demo](https://www.youtube.com/watch?v=QkYRpVEEIlg)
|
||||
For tl;dr folks:
|
||||
|
||||
[](http://www.youtube.com/watch?v=QkYRpVEEIlg)
|
||||
[Youtube: auto-cpufreq v2.0 release & demo of all available features and options](https://www.youtube.com/watch?v=SPGpkZ0AZVU)
|
||||
|
||||
[](https://www.youtube.com/watch?v=QkYRpVEEIlg)
|
||||
|
||||
[Youtube: auto-cpufreq - tool demo](https://www.youtube.com/watch?v=QkYRpVEEIlg)
|
||||
|
||||
[](https://www.youtube.com/watch?v=QkYRpVEEIlg)
|
||||
|
||||
|
||||
If you're having a problem with auto-cpufreq, before ([submitting an issue](https://github.com/AdnanHodzic/auto-cpufreq/issues)), it is strongly recommended to use the **[auto-cpufreq-genAI-chatbot](https://foolcontrol.org/?p=4903)** to get an immediate answer to your question.
|
||||
|
||||
[](https://www.youtube.com/watch?v=a-UcwAAXOoc)
|
||||
|
||||
Example of auto-cpufreq GUI (available >= v2.0)
|
||||
|
||||
<img src="https://github.com/user-attachments/assets/9c7715c4-16b7-4a5c-86be-4c390276d9e8" width="480" alt="Example of auto-cpufreq desktop entry (icon)" />
|
||||
|
||||
Example of `auto-cpufreq --stats` CLI output
|
||||
|
||||
<img src="https://github.com/user-attachments/assets/9c7715c4-16b7-4a5c-86be-4c390276d9e8" width="480" alt="Example of auto-cpufreq desktop entry (icon)"/>
|
||||
|
||||
## Looking for developers and co-maintainers
|
||||
|
||||
auto-cpufreq is looking for [co-maintainers & open source developers to help shape future of the project!](https://github.com/AdnanHodzic/auto-cpufreq/discussions/312)
|
||||
- If you would like to discuss anything regarding auto-cpufreq or its development, please join the [auto-cpufreq Discord server!](https://discord.gg/Sjauxtj6kH)
|
||||
- auto-cpufreq is looking for [co-maintainers & open source developers to help shape the future of the project!](https://github.com/AdnanHodzic/auto-cpufreq/discussions/312)
|
||||
|
||||
## Index
|
||||
|
||||
- [Why do I need auto-cpufreq?](#why-do-i-need-auto-cpufreq)
|
||||
- [Supported architectures and devices](#supported-architectures-and-devices)
|
||||
- [Features](#features)
|
||||
- [Installing auto-cpufreq](#installing-auto-cpufreq)
|
||||
- [auto-cpufreq-installer](#auto-cpufreq-installer)
|
||||
- [Snap Store](#snap-store)
|
||||
- [AUR package (Arch based distributions)](#aur-package-arch-based-distributions)
|
||||
- [NixOS](#nixos)
|
||||
- [For developers](#installation-development-mode-only)
|
||||
- [Post-installation](#post-installation)
|
||||
- [Configuring auto-cpufreq](#configuring-auto-cpufreq)
|
||||
- [1: power_helper.py script (Snap package install only)](#1-power_helperpy-script-snap-package-install-only)
|
||||
- [2: `--force` governor override](#2---force-governor-override)
|
||||
- [3: auto-cpufreq config file](#3-auto-cpufreq-config-file)
|
||||
- [Example config file contents](#example-config-file-contents)
|
||||
- [How to run auto-cpufreq](#how-to-run-auto-cpufreq)
|
||||
- [auto-cpufreq modes and options](#auto-cpufreq-modes-and-options)
|
||||
- [monitor](#monitor)
|
||||
- [live](#live)
|
||||
- [overriding governor](#overriding-governor)
|
||||
- [Install - auto-cpufreq daemon](#install---auto-cpufreq-daemon)
|
||||
- [Update - auto-cpufreq update](#update---auto-cpufreq-update)
|
||||
- [Remove - auto-cpufreq daemon](#remove---auto-cpufreq-daemon)
|
||||
- [stats](#stats)
|
||||
- [Battery charging thresholds](#battery-charging-thresholds)
|
||||
- [Supported Devices](#supported-devices)
|
||||
- [Battery config](#battery-config)
|
||||
- [Ignoring power supplies](#Ignoring-power-supplies)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [AUR](#aur)
|
||||
- [Discussion](#discussion)
|
||||
- [Donate](#donate)
|
||||
- [Financial donation](#financial-donation)
|
||||
- [Paypal](#paypal)
|
||||
- [BitCoin](#bitcoin)
|
||||
- [Code contribution](#code-contribution)
|
||||
|
||||
## Why do I need auto-cpufreq?
|
||||
|
||||
One of the problems with Linux today on laptops is that CPU will run in unoptimized manner which will negatively reflect on battery life. For example, CPU will run using "performance" governor with turbo boost enabled regardless if it's plugged in to power or not.
|
||||
One of the problems with Linux today on laptops is that the CPU will run in an unoptimized manner which will negatively impact battery life. For example, the CPU may run using the "performance" governor with turbo boost enabled regardless of whether it's plugged into a power outlet or not.
|
||||
|
||||
Issue can be mitigated by using tools like [indicator-cpufreq](https://itsfoss.com/cpufreq-ubuntu/) or [cpufreq](https://github.com/konkor/cpufreq), but these still require manual action from your side which can be daunting and cumbersome.
|
||||
These issues can be mitigated by using tools like [indicator-cpufreq](https://itsfoss.com/cpufreq-ubuntu/) or [cpufreq](https://github.com/konkor/cpufreq), but those still require manual action from your side which can be daunting and cumbersome.
|
||||
|
||||
Using tools like [TLP](https://github.com/linrunner/TLP) can help in this situation with extending battery life (which is something I used to do for numerous years), but it also might come with its own set of problems, like losing turbo boost.
|
||||
Tools like [TLP](https://github.com/linrunner/TLP) (which I used for numerous years) can help extend battery life, but may also create their own set of problems, such as losing turbo boost.
|
||||
|
||||
With that said, I needed a simple tool which would automatically make "cpufreq" related changes, save battery like TLP, but let Linux kernel do most of the heavy lifting. That's how auto-cpufreq was born.
|
||||
Given all of the above, I needed a simple tool that would automatically make CPU frequency-related changes and save battery life, but let the Linux kernel do most of the heavy lifting. That's how auto-cpufreq was born.
|
||||
|
||||
Please note: auto-cpufreq aims to replace TLP in terms of functionality and after you install auto-cpufreq _it's recommended to remove TLP_. If both are used for same functionality, i.e: to set CPU frequencies it'll lead to unwanted results like overheating. Hence, only use [both tools in tandem](https://github.com/AdnanHodzic/auto-cpufreq/discussions/176) if you know what you're doing.
|
||||
Please note: auto-cpufreq aims to replace TLP in terms of functionality, so after you install auto-cpufreq _it's recommended to remove TLP_. Using both for the same functionality (i.e., to set CPU frequencies) will lead to unwanted results like overheating. Hence, only use [both tools in tandem](https://github.com/AdnanHodzic/auto-cpufreq/discussions/176) if you know what you're doing.
|
||||
|
||||
Tool/daemon that does not conflict with auto-cpufreq in any way and is even recommended to have running alongside is [thermald](https://wiki.debian.org/thermald).
|
||||
One tool/daemon that does not conflict with auto-cpufreq in any way, and is even recommended to have running alongside, is [thermald](https://wiki.debian.org/thermald).
|
||||
|
||||
#### Supported architectures and devices
|
||||
|
||||
Supported devices must have an Intel, AMD or ARM CPUs. This tool was developed to improve performance and battery life on laptops, but running it on desktop/servers (to lower power consumption) should also be possible.
|
||||
Only devices with an Intel, AMD, or ARM CPU are supported. This tool was developed to improve performance and battery life on laptops, but running it on desktops/servers (to lower power consumption) should also be possible.
|
||||
|
||||
## Features
|
||||
|
||||
* Monitoring
|
||||
* Basic system information
|
||||
* CPU frequency (system total & per core)
|
||||
* CPU usage (system total & per core)
|
||||
* CPU temperature (total average & per core)
|
||||
* Battery state
|
||||
* System load
|
||||
* CPU frequency scaling, governor and [turbo boost](https://en.wikipedia.org/wiki/Intel_Turbo_Boost) management based on
|
||||
* Battery state
|
||||
* CPU usage (total & per core)
|
||||
* CPU temperature in combination with CPU utilization/load (prevent overheating)
|
||||
* System load
|
||||
* Automatic CPU & power optimization (temporary and persistent)
|
||||
- Monitoring
|
||||
- Basic system information
|
||||
- CPU frequency (system total & per core)
|
||||
- CPU usage (system total & per core)
|
||||
- CPU temperature (total average & per core)
|
||||
- Battery state
|
||||
- System load
|
||||
- CPU frequency scaling, governor, and [turbo boost](https://en.wikipedia.org/wiki/Intel_Turbo_Boost) management based on
|
||||
- Battery state
|
||||
- CPU usage (total & per core)
|
||||
- CPU temperature in combination with CPU utilization/load (to prevent overheating)
|
||||
- System load
|
||||
- Automatic CPU & power optimization (temporary and persistent)
|
||||
- Settings battery charging thresholds (limited support)
|
||||
|
||||
## Installing auto-cpufreq
|
||||
|
||||
### Snap store
|
||||
|
||||
auto-cpufreq is available on [snap store](https://snapcraft.io/auto-cpufreq), or can be installed using CLI:
|
||||
|
||||
```
|
||||
sudo snap install auto-cpufreq
|
||||
```
|
||||
|
||||
**Please note:**
|
||||
* Make sure [snapd](https://snapcraft.io/docs/installing-snapd) is installed and `snap version` version is >= 2.44 for `auto-cpufreq` to fully work due to [recent snapd changes](https://github.com/snapcore/snapd/pull/8127).
|
||||
|
||||
* Fedora users will [encounter following error](https://twitter.com/killyourfm/status/1291697985236144130). Due to `cgroups v2` [being in development](https://github.com/snapcore/snapd/pull/7825). This problem can be resolved by either running `sudo snap run auto-cpufreq` after snap installation. Or using [auto-cpufreq-installer](https://github.com/AdnanHodzic/auto-cpufreq/#auto-cpufreq-installer) which doesn't have this issue.
|
||||
|
||||
### auto-cpufreq-installer
|
||||
|
||||
Get source code, run installer and follow on screen instructions:
|
||||
> As auto-cpufreq relies on git based versioning, users are advised to install `auto-cpufreq` using `git clone` method only. Downloading source code as a zip/from release will emit build error like [these](https://github.com/AdnanHodzic/auto-cpufreq/issues/623).
|
||||
|
||||
Get source code, run installer, and follow on-screen instructions:
|
||||
|
||||
```
|
||||
git clone https://github.com/AdnanHodzic/auto-cpufreq.git
|
||||
cd auto-cpufreq && sudo ./auto-cpufreq-installer
|
||||
```
|
||||
|
||||
In case you encounter any problems with `auto-cpufreq-installer`, please [submit a bug report](https://github.com/AdnanHodzic/auto-cpufreq/issues/new).
|
||||
### Snap Store
|
||||
|
||||
### AUR package (Arch/Manjaro Linux)
|
||||
*Please note: while all [auto-cpufreq >= v2.0 CLI functionality](https://www.youtube.com/watch?v=SPGpkZ0AZVU&t=295s) will work as intended, [the GUI won't be available on Snap package installs](http://foolcontrol.org/wp-content/uploads/2023/10/auto-cpufreq-v2-snap-deprecation-notice.png) due to [Snap package confinement limitations](https://forum.snapcraft.io/t/pkexec-not-found-python-gtk-gnome-app/36579). Hence, please consider installing auto-cpufreq using [auto-cpufreq-installer](#auto-cpufreq-installer)*.
|
||||
|
||||
* [Binary Package](https://aur.archlinux.org/packages/auto-cpufreq)
|
||||
(For the latest binary release on github)
|
||||
* [Git Package](https://aur.archlinux.org/packages/auto-cpufreq-git)
|
||||
(For the latest commits/changes) \
|
||||
Please note that this git package is currently unmaintained & has issues. Until someone starts maintaining it, use the [manual script installer](https://github.com/AdnanHodzic/auto-cpufreq#auto-cpufreq-installer) if you intend to have the latest changes.
|
||||
auto-cpufreq is available on the [Snap Store](https://snapcraft.io/auto-cpufreq) or via CLI:
|
||||
|
||||
After installation `auto-cpufreq` will be available as a binary and you can refer to [auto-cpufreq modes and options](https://github.com/AdnanHodzic/auto-cpufreq#auto-cpufreq-modes-and-options).
|
||||
```
|
||||
sudo snap install auto-cpufreq
|
||||
```
|
||||
|
||||
**Please note:** If you want to install auto-cpufreq daemon, do not run `auto-cpufreq --install` otherwise you'll run into an issue: [#91](https://github.com/AdnanHodzic/auto-cpufreq/issues/91), [#96](https://github.com/AdnanHodzic/auto-cpufreq/issues/96).
|
||||
**Please note:**
|
||||
- Make sure [snapd](https://snapcraft.io/docs/installing-snapd) is installed and `snap version` is >= 2.44 for `auto-cpufreq` to fully work due to [recent snapd changes](https://github.com/snapcore/snapd/pull/8127).
|
||||
|
||||
Instead run `systemctl start auto-cpufreq` to start the service. Run `systemctl status auto-cpufreq` to see the status of service, and `systemctl enable auto-cpufreq` for service to persist running across reboots.
|
||||
- Fedora users will [encounter the following error](https://twitter.com/killyourfm/status/1291697985236144130) due to `cgroups v2` [being in development](https://github.com/snapcore/snapd/pull/7825). This problem can be resolved by either running `sudo snap run auto-cpufreq` after the snap installation or by using the [auto-cpufreq-installer](#auto-cpufreq-installer) which doesn't have this issue.
|
||||
|
||||
### AUR package (Arch based distributions)
|
||||
|
||||
[](https://aur.archlinux.org/packages/auto-cpufreq)
|
||||
|
||||
The AUR [Release Package](https://aur.archlinux.org/packages/auto-cpufreq) is currently being maintained by [MusicalArtist12](https://github.com/MusicalArtist12), [liljaylj](https://github.com/liljaylj), and [parmjotsinghrobot](https://github.com/parmjotsinghrobot).
|
||||
|
||||
**Notices**
|
||||
|
||||
- The [Git Package](https://aur.archlinux.org/packages/auto-cpufreq-git) is seperately maintained and was last updated on version 1.9.6.
|
||||
- The build process links to `/usr/share/` instead of `/usr/local/share/`
|
||||
- The daemon installer provided does not work, instead start the daemon with
|
||||
|
||||
```
|
||||
# systemctl enable --now auto-cpufreq
|
||||
```
|
||||
- The GNOME Power Profiles daemon is [automatically disabled by auto-cpufreq-installer](https://github.com/AdnanHodzic/auto-cpufreq#1-power_helperpy-script-snap-package-install-only) due to it's conflict with auto-cpufreq.service. However, this doesn't happen with AUR installs, which can lead to problems (e.g., [#463](https://github.com/AdnanHodzic/auto-cpufreq/issues/463)) if not masked manually.
|
||||
- Open a terminal and run `sudo systemctl mask power-profiles-daemon.service` (then `enable` and `start` the auto-cpufreq.service if you haven't already).
|
||||
- The TuneD daemon(enabled by default with Fedora 41) is [automatically disabled by auto-cpufreq-installer](https://github.com/AdnanHodzic/auto-cpufreq#1-power_helperpy-script-snap-package-install-only) due to it's conflict with auto-cpufreq.service.
|
||||
|
||||
### Gentoo Linux (GURU Repository)
|
||||
|
||||
New versions of auto-cpufreq were recently added to GURU, Gentoo's official community-maintained ebuild repository. The [ebuild](https://github.com/gentoo-mirror/guru/tree/master/sys-power/auto-cpufreq) is maintaned by [S41G0N](https://github.com/S41G0N) and other [GURU contributors](https://bugs.gentoo.org), who can respond in case of issues.
|
||||
|
||||
In order to build auto-cpufreq, it is necessary to add & sync GURU repository first. Adding ~amd64 keyword is also needed to unmask the package.
|
||||
|
||||
```
|
||||
# echo "sys-power/auto-cpufreq ~amd64" >> /etc/portage/package.accept_keywords
|
||||
# eselect repository enable guru
|
||||
# emaint sync -r guru
|
||||
# emerge --ask auto-cpufreq
|
||||
```
|
||||
|
||||
**Notices**
|
||||
|
||||
- The build process links to `/usr/share/` instead of `/usr/local/share/`
|
||||
- The build works on both systemd/OpenRC systems (both systemd and OpenRC will have a service called auto-cpufreq which can be started automatically)
|
||||
- The daemon installer provided does work, but it is RECOMMENDED to install the daemon with:
|
||||
```
|
||||
# systemctl enable --now auto-cpufreq
|
||||
# rc-update add auto-cpufreq default && rc-service auto-cpufreq start
|
||||
```
|
||||
|
||||
### NixOS
|
||||
|
||||
<details>
|
||||
<summary>Flakes</summary>
|
||||
<br>
|
||||
|
||||
This repo contains a flake that exposes a NixOS Module that manages and offers options for auto-cpufreq. To use it, add the flake as an input to your `flake.nix` file and enable the module:
|
||||
|
||||
```nix
|
||||
# flake.nix
|
||||
|
||||
{
|
||||
|
||||
inputs = {
|
||||
# ---Snip---
|
||||
auto-cpufreq = {
|
||||
url = "github:AdnanHodzic/auto-cpufreq";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
# ---Snip---
|
||||
}
|
||||
|
||||
outputs = {nixpkgs, auto-cpufreq, ...} @ inputs: {
|
||||
nixosConfigurations.HOSTNAME = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [
|
||||
./configuration.nix
|
||||
auto-cpufreq.nixosModules.default
|
||||
];
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
Then you can enable the program in your `configuration.nix` file:
|
||||
```nix
|
||||
# configuration.nix
|
||||
|
||||
{inputs, pkgs, ...}: {
|
||||
# ---Snip---
|
||||
programs.auto-cpufreq.enable = true;
|
||||
# optionally, you can configure your auto-cpufreq settings, if you have any
|
||||
programs.auto-cpufreq.settings = {
|
||||
charger = {
|
||||
governor = "performance";
|
||||
turbo = "auto";
|
||||
};
|
||||
|
||||
battery = {
|
||||
governor = "powersave";
|
||||
turbo = "auto";
|
||||
};
|
||||
};
|
||||
# ---Snip---
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Nixpkgs</summary>
|
||||
<br>
|
||||
|
||||
There is a nixpkg available, but it is more prone to being outdated, whereas the flake pulls from the latest commit. You can install it in your `configuration.nix` and enable the system service:
|
||||
```nix
|
||||
# configuration.nix
|
||||
|
||||
# ---Snip---
|
||||
environment.systemPackages = with pkgs; [
|
||||
auto-cpufreq
|
||||
];
|
||||
|
||||
services.auto-cpufreq.enable = true;
|
||||
# ---Snip---
|
||||
```
|
||||
</details>
|
||||
|
||||
### Installation (development mode only)
|
||||
|
||||
- If you have `poetry` installed:
|
||||
```bash
|
||||
git clone https://github.com/AdnanHodzic/auto-cpufreq.git
|
||||
cd auto-cpufreq
|
||||
poetry install
|
||||
poetry run auto-cpufreq --help
|
||||
```
|
||||
|
||||
- Alternatively, we can use an editable pip install for development purposes:
|
||||
```bash
|
||||
git clone https://github.com/AdnanHodzic/auto-cpufreq.git
|
||||
cd auto-cpufreq
|
||||
# set up virtual environment (details removed for brevity)
|
||||
pip3 install -e .
|
||||
auto-cpufreq
|
||||
```
|
||||
- Regularly run `poetry update` if you get any inconsistent lock file issues.
|
||||
|
||||
## Post-installation
|
||||
|
||||
After installation, `auto-cpufreq` is available as a binary. Refer to [auto-cpufreq modes and options](https://github.com/AdnanHodzic/auto-cpufreq#auto-cpufreq-modes-and-options) for detailed information on how to run and configure `auto-cpufreq`.
|
||||
|
||||
## Configuring auto-cpufreq
|
||||
|
||||
While auto-cpufreq makes all decisions automatically based on various factors like cpu usage, temperature or system load. It's possible to perform addition configurations in 2 ways:
|
||||
auto-cpufreq makes all decisions automatically based on various factors such as CPU usage, temperature, and system load. However, it's possible to perform additional configurations:
|
||||
|
||||
### 1: power_helper.py script
|
||||
### 1: power_helper.py script (Snap package install **only**)
|
||||
|
||||
If detected as running auto-cpufreq will disable [GNOME Power profiles service](https://twitter.com/fooctrl/status/1467469508373884933), which would otherwise cause conflicts and cause problems. By default auto-cpufreq uses `balanced` mode which also works the best on various systems. However, if you're not reaching maximum frequencies your CPU is capable of with auto-cpufreq ([#361](https://github.com/AdnanHodzic/auto-cpufreq/issues/361)), you can switch to `performance` mode. Which will result in higher frequencies by default, but also higher use of energy (battery consumption).
|
||||
When installing auto-cpufreq via [auto-cpufreq-installer](#auto-cpufreq-installer), if it detects the [GNOME Power Profiles service](https://twitter.com/fooctrl/status/1467469508373884933) is running, it will automatically disable it. Otherwise, that daemon will cause conflicts and various other performance issues.
|
||||
|
||||
If you installed auto-cpufreq using [auto-cpufreq-installer](https://github.com/AdnanHodzic/auto-cpufreq/edit/master/README.md#auto-cpufreq-installer), you can switch to `performance` mode by running:
|
||||
However, when auto-cpufreq is installed as a Snap package it's running as part of a container with limited permissions, hence it's *highly recommended* to disable the GNOME Power Profiles daemon using the `power_helper.py` script.
|
||||
|
||||
`sudo auto-cpufreq --install_performance`
|
||||
**Please Note:**<br>
|
||||
The [`power_helper.py`](https://github.com/AdnanHodzic/auto-cpufreq/blob/master/auto_cpufreq/power_helper.py) script is located within the auto-cpufreq repo at `auto_cpufreq/power_helper.py`. In order to access it, first clone
|
||||
the repository:
|
||||
|
||||
Or if you installed auto-cpufreq using [Snap package](https://github.com/AdnanHodzic/auto-cpufreq/edit/master/README.md#snap-store) you can switch to `performance` mode by running:
|
||||
`git clone https://github.com/AdnanHodzic/auto-cpufreq`
|
||||
|
||||
`sudo python3 power_helper.py --gnome_power_disable performance`
|
||||
Navigate to the directory where `power_helper.py` resides:
|
||||
|
||||
Please note! In order to have access to `power_helper.py` script, first clone auto-cpufreq git repo (`git clone https://github.com/AdnanHodzic/auto-cpufreq.git`), navigate to directory where `power_helper.py` script resides by running: `cd auto-cpufreq/auto_cpufreq`
|
||||
`cd auto-cpufreq/auto_cpufreq`
|
||||
|
||||
After this step, all necessary changes will still be made automatically. However, if you wish to perform additional "manual" settings this can be done by following instructions explained in next step.
|
||||
Make sure to have `psutil` Python library installed before next step:
|
||||
|
||||
### 2: auto-cpufreq config file
|
||||
`sudo python3 -m pip install psutil`
|
||||
|
||||
You can configure profiles for battery and power supply. These profiles will let you pick which governor to use and how and when turbo boost is enabled. The possible values for turbo boost behavior are `always`, `auto` and `never`. The default behavior is `auto`, which only kicks in during high load.
|
||||
Then disable the GNOME Power Profiles daemon:
|
||||
|
||||
By default, auto-cpufreq does not use the config file! If you wish to use it, location where config needs to be placed for it to be read automatically is: `/etc/auto-cpufreq.conf`
|
||||
`sudo python3 power_helper.py --gnome_power_disable`
|
||||
|
||||
### 2: `--force` governor override
|
||||
|
||||
By default, auto-cpufreq uses `balanced` mode which works best for many systems and situations.
|
||||
|
||||
However, you can override this behaviour by switching to `performance` or `powersave` mode manually. The `performance` mode results in higher default frequencies, but also higher energy use (battery consumption) and should only be used if maximum performance is needed. The `powersave` mode does the opposite and extends battery life to its maximum.
|
||||
|
||||
See [`--force` flag](#overriding-governor) for more info.
|
||||
|
||||
### 3: auto-cpufreq config file
|
||||
|
||||
You can configure separate profiles for the battery and power supply. These profiles will let you pick which governor to use, as well as how and when turbo boost is enabled. The possible values for turbo boost behavior are `always`, `auto`, and `never`. The default behavior is `auto`, which only activates turbo during high load.
|
||||
|
||||
By default, auto-cpufreq does not use a config file. If you wish to configure auto-cpufreq statically, we look for a configuration file in the following order:
|
||||
|
||||
1. Commandline argument: `--config <FILE>` if passed as commandline argument to `auto-cpufreq`
|
||||
2. User-specific configuration: `$XDG_CONFIG_HOME/auto-cpufreq/auto-cpufreq.conf`
|
||||
3. System-wide configuration: `/etc/auto-cpufreq.conf`
|
||||
|
||||
#### Example config file contents
|
||||
```
|
||||
```python
|
||||
# settings for when connected to a power source
|
||||
[charger]
|
||||
# see available governors by running: cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
|
||||
# preferred governor.
|
||||
# preferred governor
|
||||
governor = performance
|
||||
|
||||
# EPP: see available preferences by running: cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_available_preferences
|
||||
energy_performance_preference = performance
|
||||
|
||||
# EPB (Energy Performance Bias) for the intel_pstate driver
|
||||
# see conversion info: https://www.kernel.org/doc/html/latest/admin-guide/pm/intel_epb.html
|
||||
# available EPB options include a numeric value between 0-15
|
||||
# (where 0 = maximum performance and 15 = maximum power saving),
|
||||
# or one of the following strings:
|
||||
# performance (0), balance_performance (4), default (6), balance_power (8), or power (15)
|
||||
# if the parameter is missing in the config and the hardware supports this setting, the default value will be used
|
||||
# the default value is `balance_performance` (for charger)
|
||||
# energy_perf_bias = balance_performance
|
||||
|
||||
# Platform Profiles
|
||||
# https://www.kernel.org/doc/html/latest/userspace-api/sysfs-platform_profile.html
|
||||
# See available options by running:
|
||||
# cat /sys/firmware/acpi/platform_profile_choices
|
||||
# platform_profile = performance
|
||||
|
||||
# minimum cpu frequency (in kHz)
|
||||
# example: for 800 MHz = 800000 kHz --> scaling_min_freq = 800000
|
||||
# see conversion info: https://www.rapidtables.com/convert/frequency/mhz-to-hz.html
|
||||
@ -139,6 +369,25 @@ turbo = auto
|
||||
# preferred governor
|
||||
governor = powersave
|
||||
|
||||
# EPP: see available preferences by running: cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_available_preferences
|
||||
energy_performance_preference = power
|
||||
|
||||
# EPB (Energy Performance Bias) for the intel_pstate driver
|
||||
# see conversion info: https://www.kernel.org/doc/html/latest/admin-guide/pm/intel_epb.html
|
||||
# available EPB options include a numeric value between 0-15
|
||||
# (where 0 = maximum performance and 15 = maximum power saving),
|
||||
# or one of the following strings:
|
||||
# performance (0), balance_performance (4), default (6), balance_power (8), or power (15)
|
||||
# if the parameter is missing in the config and the hardware supports this setting, the default value will be used
|
||||
# the default value is `balance_power` (for battery)
|
||||
# energy_perf_bias = balance_power
|
||||
|
||||
# Platform Profiles
|
||||
# https://www.kernel.org/doc/html/latest/userspace-api/sysfs-platform_profile.html
|
||||
# See available options by running:
|
||||
# cat /sys/firmware/acpi/platform_profile_choices
|
||||
# platform_profile = low-power
|
||||
|
||||
# minimum cpu frequency (in kHz)
|
||||
# example: for 800 MHz = 800000 kHz --> scaling_min_freq = 800000
|
||||
# see conversion info: https://www.rapidtables.com/convert/frequency/mhz-to-hz.html
|
||||
@ -151,15 +400,62 @@ governor = powersave
|
||||
# to use this feature, uncomment the following line and set the value accordingly
|
||||
# scaling_max_freq = 1000000
|
||||
|
||||
# turbo boost setting. possible values: always, auto, never
|
||||
# turbo boost setting (always, auto, or never)
|
||||
turbo = auto
|
||||
|
||||
# battery charging threshold
|
||||
# reference: https://github.com/AdnanHodzic/auto-cpufreq/#battery-charging-thresholds
|
||||
#enable_thresholds = true
|
||||
#start_threshold = 20
|
||||
#stop_threshold = 80
|
||||
```
|
||||
|
||||
## How to run auto-cpufreq
|
||||
auto-cpufreq should be run with with one of the following options:
|
||||
|
||||
auto-cpufreq can be run by simply running the `auto-cpufreq` and following on screen instructions, i.e:
|
||||
- [monitor](#monitor)
|
||||
- Monitor and see suggestions for CPU optimizations
|
||||
|
||||
`sudo auto-cpufreq`
|
||||
- [live](#live)
|
||||
- Monitor and automatically make (temporary) CPU optimizations
|
||||
|
||||
- [install](#install---auto-cpufreq-daemon) / [remove](#remove---auto-cpufreq-daemon)
|
||||
- Install/remove daemon for (permanent) automatic CPU optimizations
|
||||
|
||||
- [install (GUI)](#install---auto-cpufreq-daemon)
|
||||
- Install daemon via GUI for (permanent) automatic CPU optimizations
|
||||
|
||||
- [update](#update---auto-cpufreq-update)
|
||||
- Update auto-cpufreq to the latest release
|
||||
|
||||
- [install_performance](#1-power_helperpy-script)
|
||||
- Install daemon in "performance" mode
|
||||
|
||||
- [stats](#stats)
|
||||
- View live stats of CPU optimizations made by daemon
|
||||
|
||||
- [force=TEXT](#overriding-governor)
|
||||
- Force use of either the "powersave" or "performance" governor, or set to "reset" to go back to normal mode
|
||||
|
||||
- config=TEXT
|
||||
- Use config file at designated path
|
||||
|
||||
- debug
|
||||
- Show debug info (include when submitting bugs)
|
||||
|
||||
- version
|
||||
- Show currently installed version
|
||||
|
||||
- [donate](#financial-donation)
|
||||
- To support the project
|
||||
|
||||
- help
|
||||
- Shows all of the above options
|
||||
|
||||
- completions=TEXT
|
||||
- To support shell completions (current options are "bash", "zsh", or "fish")
|
||||
|
||||
Running `auto-cpufreq --help` will print the same list of options as above. Read [auto-cpufreq modes and options](#auto-cpufreq-modes-and-options) for more details.
|
||||
|
||||
## auto-cpufreq modes and options
|
||||
|
||||
@ -167,74 +463,227 @@ auto-cpufreq can be run by simply running the `auto-cpufreq` and following on sc
|
||||
|
||||
`sudo auto-cpufreq --monitor`
|
||||
|
||||
No changes are made to the system, and is solely made for demonstration purposes what auto-cpufreq could do differently for your system.
|
||||
No changes are made to the system. This is solely to demonstrate what auto-cpufreq could do for your system.
|
||||
|
||||
### Live
|
||||
|
||||
`sudo auto-cpufreq --live`
|
||||
|
||||
Necessary changes are temporarily made to the system which are lost with system reboot. This mode is made to evaluate what the system would behave with auto-cpufreq permanently running on the system.
|
||||
Necessary changes are temporarily made to the system over time, but this process and its changes are lost at system reboot. This mode is provided to evaluate how the system would behave with auto-cpufreq permanently running on the system.
|
||||
|
||||
### Overriding governor
|
||||
|
||||
`sudo auto-cpufreq --force=governor`
|
||||
|
||||
Force use of either the "powersave" or "performance" governor, or set to "reset" to go back to normal mode.
|
||||
Please note that any set override will persist even after reboot.
|
||||
|
||||
### Install - auto-cpufreq daemon
|
||||
|
||||
Necessary changes are made to the system for auto-cpufreq CPU optimization to persist across reboots. Daemon is deployed and then started as a systemd service. Changes are made automatically and live stats are generated for monitoring purposes.
|
||||
Necessary changes are made to the system over time and this process will continue across reboots. The daemon is deployed and started as a systemd service. Changes are made automatically and live stats are generated for monitoring purposes.
|
||||
|
||||
**Install the daemon using CLI ([after installing auto-cpufreq](#installing-auto-cpufreq)):**
|
||||
|
||||
Installing the auto-cpufreq daemon using CLI is as simple as running the following command:
|
||||
|
||||
`sudo auto-cpufreq --install`
|
||||
|
||||
After daemon is installed, `auto-cpufreq` is available as a binary and is running in the background. Its stats can be viewed by running: `auto-cpufreq --stats`
|
||||
After the daemon is installed, `auto-cpufreq` is available as a binary and runs in the background. Its stats can be viewed by running: `auto-cpufreq --stats`
|
||||
|
||||
Since daemon is running as a systemd service, its status can be seen by running:
|
||||
*Please note:* if the daemon is installed within a desktop environment, then its stats and options can be accessed via CLI or GUI. See "Install the daemon using GUI" below for more details.
|
||||
|
||||
**Install the daemon using GUI**
|
||||
|
||||
Starting with >= v2.0 [after installing auto-cpufreq](#installing-auto-cpufreq), an auto-cpufreq desktop entry (icon) is available, i.e.:
|
||||
|
||||
<img src="https://github.com/user-attachments/assets/f426d62b-00b0-4fa5-a72e-b352016ed448" width="640" alt="Example of auto-cpufreq desktop entry (icon)"/>
|
||||
|
||||
After selecting it to open the GUI, the auto-cpufreq daemon can be installed by clicking the "Install" button:
|
||||
|
||||
<img src="https://github.com/user-attachments/assets/5af47e5e-8b9e-4ff6-9ffc-e78acb623ce4" width="480" alt="The auto-cpufreq GUI's 'Install' button"/>
|
||||
|
||||
After that, the full auto-cpufreq GUI is available:
|
||||
|
||||
<img src="https://github.com/user-attachments/assets/9c7715c4-16b7-4a5c-86be-4c390276d9e8" width="640" alt="The full auto-cpufreq GUI"/>
|
||||
|
||||
*Please note:* after the daemon is installed (by any method), its stats and options are accessible via both CLI and GUI.
|
||||
|
||||
**auto-cpufreq daemon service**
|
||||
|
||||
Installing the auto-cpufreq daemon also enables the associated service (equivalent to `systemctl enable auto-cpufreq`), causing it to start on boot, and immediately starts it (equivalent to `systemctl start auto-cpufreq`).
|
||||
|
||||
Since the daemon is running as a systemd service, its status can be seen by running:
|
||||
|
||||
`systemctl status auto-cpufreq`
|
||||
|
||||
If install has been performed as part of snap package, daemon status can be verified by running:
|
||||
If installed via Snap package, daemon status can be viewed as follows:
|
||||
|
||||
`systemctl status snap.auto-cpufreq.service.service`
|
||||
|
||||
### Update - auto-cpufreq update
|
||||
|
||||
Update functionality works by cloning the auto-cpufreq repo, installing it via [auto-cpufreq-installer](#auto-cpufreq-installer), and performing a fresh [auto-cpufreq daemon install](#install---auto-cpufreq-daemon) to provide the [latest version's](https://github.com/AdnanHodzic/auto-cpufreq/releases) changes.
|
||||
|
||||
Update auto-cpufreq by running: `sudo auto-cpufreq --update`. By default, the latest revision is cloned to `/opt/auto-cpufreq/source`, thus maintaining existing directory structure.
|
||||
|
||||
Update and clone to a custom directory by running: `sudo auto-cpufreq --update=/path/to/directory`
|
||||
|
||||
### Remove - auto-cpufreq daemon
|
||||
|
||||
auto-cpufreq daemon and its systemd service, along with all its persistent changes can be removed by running:
|
||||
The auto-cpufreq daemon, its systemd service, and all its persistent changes can be removed by running:
|
||||
|
||||
`sudo auto-cpufreq --remove`
|
||||
|
||||
This does, in part, the equivalent of `systemctl stop auto-cpufreq && systemctl disable auto-cpufreq`, but the above command should be used instead of using `systemctl`.
|
||||
|
||||
*Please note:* after the daemon is removed, the auto-cpufreq GUI and desktop entry (icon) are also removed.
|
||||
|
||||
### Stats
|
||||
|
||||
If daemon has been installed, live stats of CPU/system load monitoring and optimization can be seen by running:
|
||||
If the daemon has been installed, live stats of CPU/system load monitoring and optimization can be seen by running:
|
||||
|
||||
`auto-cpufreq --stats`
|
||||
|
||||
## Battery charging thresholds
|
||||
|
||||
***Please note:** [Original implementor](https://github.com/AdnanHodzic/auto-cpufreq/pull/637) is looking for user input & testing to further improve this functionality. If you would like to help in this process, please refer to [Looking for developers and co-maintainers](https://github.com/AdnanHodzic/auto-cpufreq/#looking-for-developers-and-co-maintainers)*.
|
||||
|
||||
As of [v2.2.0](https://github.com/AdnanHodzic/auto-cpufreq/releases/tag/v2.2.0), battery charging thresholds can be set in the config file. This enforces your battery to start and stop charging at defined values.
|
||||
|
||||
### Supported devices
|
||||
|
||||
- **Lenovo ThinkPad** (thinkpad_acpi)*
|
||||
- **Lenovo IdeaPad** (ideapad_acpi)*
|
||||
|
||||
***Please note, your laptop must have an installed ACPI kernel driver specific to the manufacturer.** To check if you have the correct module installed and loaded run `lsmod [module]`
|
||||
|
||||
**To request that your device be supported, please open an [issue](https://github.com/AdnanHodzic/auto-cpufreq/issues/new). In your issue, make us aware of the driver that works with your laptop**
|
||||
|
||||
### Battery config
|
||||
Edit the config at `/etc/auto-cpufreq.conf`
|
||||
|
||||
Example config for battery ([already part of example config file](https://github.com/AdnanHodzic/auto-cpufreq/#example-config-file-contents))
|
||||
```
|
||||
[battery]
|
||||
enable_thresholds = true
|
||||
start_threshold = 20
|
||||
stop_threshold = 80
|
||||
```
|
||||
|
||||
### Lenovo_laptop conservation mode
|
||||
|
||||
this works only with `lenovo_laptop` kernel module compatable laptops.
|
||||
|
||||
add `ideapad_laptop_conservation_mode = true` to your `auto-cpufreq.conf` file
|
||||
|
||||
### Ignoring power supplies
|
||||
|
||||
you may have a controler or headphones and when ever they may be on battery they might cause auto-cpufreq
|
||||
to limit preformence to ignore them add to you config file the name of the power supply, under `[power_supply_ignore_list]`
|
||||
|
||||
the name of the power supply can be found with `ls /sys/class/power_supply/`
|
||||
|
||||
```
|
||||
[power_supply_ignore_list]
|
||||
|
||||
name1 = this
|
||||
name2 = is
|
||||
name3 = an
|
||||
name4 = example
|
||||
|
||||
# like this
|
||||
xboxctrl = {the xbox controler power supply name}
|
||||
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Q:** If after installing auto-cpufreq you're (still) experiencing:
|
||||
* high CPU temperatures
|
||||
* CPU is not scaling to minimum/maximum frequencies
|
||||
* suboptimal CPU performance
|
||||
- high CPU temperatures
|
||||
- CPU not scaling to minimum/maximum frequencies
|
||||
- suboptimal CPU performance
|
||||
- turbo mode not available
|
||||
|
||||
**A:** If you're using `intel_pstate` CPU management driver consider changing it to: `acpi-cpufreq`.
|
||||
**A:** If you're using the `intel_pstate/amd-pstate` CPU management driver, consider changing it to `acpi-cpufreq`.
|
||||
|
||||
This can be done by editing `/etc/default/grub` file and appending `intel_pstate=disable` to `GRUB_CMDLINE_LINUX_DEFAULT` line, followed by `sudo update-grub`
|
||||
This can be done by editing the `GRUB_CMDLINE_LINUX_DEFAULT` params in `/etc/default/grub`. For instance:
|
||||
|
||||
Example line change:
|
||||
```
|
||||
sudo nano /etc/default/grub
|
||||
# make sure you have nano installed, or you can use your favorite text editor
|
||||
```
|
||||
|
||||
For Intel users:
|
||||
|
||||
```
|
||||
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_pstate=disable"
|
||||
```
|
||||
|
||||
For AMD users:
|
||||
|
||||
```
|
||||
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash initcall_blacklist=amd_pstate_init amd_pstate.enable=0"
|
||||
```
|
||||
|
||||
Once you have made the necessary changes to the GRUB configuration file, you can update GRUB by running `sudo update-grub` on Debian/Ubuntu, `sudo grub-mkconfig -o /boot/grub/grub.cfg` on Arch Linux, or one of the following on Fedora:
|
||||
|
||||
```
|
||||
sudo grub2-mkconfig -o /etc/grub2.cfg
|
||||
```
|
||||
|
||||
```
|
||||
sudo grub2-mkconfig -o /etc/grub2-efi.cfg
|
||||
```
|
||||
|
||||
```
|
||||
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
|
||||
# legacy boot method
|
||||
```
|
||||
|
||||
For systemd-boot users:
|
||||
|
||||
```
|
||||
sudo nano /etc/kernel/cmdline
|
||||
# make sure you have nano installed, or you can use your favorite text editor
|
||||
```
|
||||
|
||||
For Intel users:
|
||||
|
||||
```
|
||||
quiet splash intel_pstate=disable
|
||||
```
|
||||
|
||||
For AMD users:
|
||||
|
||||
```
|
||||
quiet splash initcall_blacklist=amd_pstate_init amd_pstate.enable=0
|
||||
```
|
||||
|
||||
Once you have made the necessary changes to the `cmdline` file, you can update it by running `sudo reinstall-kernels`.
|
||||
|
||||
### AUR
|
||||
|
||||
- If the AUR installer does not work for your system, fallback to `auto-cpufreq-installer` and open an issue.
|
||||
|
||||
## Discussion:
|
||||
|
||||
* Blogpost: [auto-cpufreq - Automatic CPU speed & power optimizer for Linux](http://foolcontrol.org/?p=3124)
|
||||
- Blogpost: [auto-cpufreq - Automatic CPU speed & power optimizer for Linux](http://foolcontrol.org/?p=3124)
|
||||
|
||||
## Donate
|
||||
|
||||
Showing your support and appreciation for auto-cpufreq project can be done in two ways:
|
||||
Showing your support and appreciation for the auto-cpufreq project can be done in two ways:
|
||||
|
||||
* Financial donation
|
||||
* Code contribution
|
||||
- Financial donation
|
||||
- Code contribution
|
||||
|
||||
### Financial donation
|
||||
|
||||
If auto-cpufreq helped you out and you find it useful, show your appreciation by donating (any amount) to the project!
|
||||
|
||||
##### Become Github Sponsor
|
||||
|
||||
[Become a sponsor to Adnan Hodzic on Github](https://github.com/sponsors/AdnanHodzic) to acknowledge my efforts and help project's further open source development.
|
||||
|
||||
##### PayPal
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=7AHCP5PU95S4Y&item_name=Contribution+for+work+on+auto-cpufreq¤cy_code=EUR&source=url)
|
||||
|
||||
@ -245,6 +694,6 @@ If auto-cpufreq helped you out and you find it useful, show your appreciation by
|
||||
|
||||
### Code contribution
|
||||
|
||||
Other ways of supporting the project consists of making a code or documentation contribution. If you have an idea for a new features or want to implement some of the existing feature requests or fix some of the [bugs & issues](https://github.com/AdnanHodzic/auto-cpufreq/issues). Please make your changes and submit a [pull request](https://github.com/AdnanHodzic/auto-cpufreq/pulls) which I'll be glad to review. If your changes are accepted you'll be credited as part of [releases page](https://github.com/AdnanHodzic/auto-cpufreq/releases).
|
||||
Other ways of supporting the project consist of making a code or documentation contribution. If you have an idea for a new feature or you want to implement some of the existing feature requests or fix some of the [bugs & issues](https://github.com/AdnanHodzic/auto-cpufreq/issues), please make your changes and submit a [pull request](https://github.com/AdnanHodzic/auto-cpufreq/pulls). I'll be glad to review it and, if your changes are accepted, you'll be credited on the [releases page](https://github.com/AdnanHodzic/auto-cpufreq/releases).
|
||||
|
||||
**Please note: auto-cpufreq is looking for co-maintainers & open source developers to [help shape future of the project!](https://github.com/AdnanHodzic/auto-cpufreq/discussions/312)**
|
||||
**Please note: auto-cpufreq is looking for co-maintainers & open source developers to [help shape the future of the project!](https://github.com/AdnanHodzic/auto-cpufreq/discussions/312)**
|
||||
|
@ -1,252 +1,245 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# auto-cpufreq-installer:
|
||||
# auto-cpufreq source code based installer
|
||||
|
||||
SCRIPT_PATH=$(readlink -f "$0")
|
||||
SCRIPT_DIR=$(dirname "${SCRIPT_PATH}")
|
||||
cd "${SCRIPT_DIR}"
|
||||
cd "$(dirname "$(readlink -f "$0")")" || exit 1
|
||||
|
||||
# check if lsb_release exists on the system before using it
|
||||
if command -v lsb_release > /dev/null
|
||||
then
|
||||
distro="$(lsb_release -is)"
|
||||
release="$(lsb_release -rs)"
|
||||
codename="$(lsb_release -cs)"
|
||||
fi
|
||||
COLOUMNS="`tput cols`"
|
||||
MID="$((COLOUMNS / 2))"
|
||||
|
||||
sep="\n-------------------------------------------------------------------------------"
|
||||
APPLICATIONS_PATH="/usr/share/applications"
|
||||
VENV_PATH="/opt/auto-cpufreq"
|
||||
|
||||
# functions
|
||||
SHARE_DIR="/usr/local/share/auto-cpufreq/"
|
||||
|
||||
#separator
|
||||
function separator {
|
||||
echo -e $sep
|
||||
}
|
||||
# root check
|
||||
function root_check {
|
||||
if ((EUID != 0)); then
|
||||
separator
|
||||
echo -e "\nMust be run as root (i.e: 'sudo $0')."
|
||||
separator
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
AUTO_CPUFREQ_FILE="/usr/local/bin/auto-cpufreq"
|
||||
AUTO_CPUFREQ_GTK_FILE=$AUTO_CPUFREQ_FILE-gtk
|
||||
AUTO_CPUFREQ_GTK_DESKTOP_FILE="$(basename $AUTO_CPUFREQ_GTK_FILE).desktop"
|
||||
|
||||
# python packages install
|
||||
function setup_venv {
|
||||
venv_dir=/opt/auto-cpufreq/venv
|
||||
mkdir -p "${venv_dir}"
|
||||
python3 -m venv "${venv_dir}"
|
||||
IMG_FILE="/usr/share/pixmaps/auto-cpufreq.png"
|
||||
ORG_FILE="/usr/share/polkit-1/actions/org.auto-cpufreq.pkexec.policy"
|
||||
|
||||
source "${venv_dir}/bin/activate"
|
||||
python3 -m pip install --upgrade pip
|
||||
python3 -m pip install -r requirements.txt
|
||||
}
|
||||
|
||||
# tool install
|
||||
function install {
|
||||
python3 setup.py install --record files.txt
|
||||
mkdir -p /usr/local/share/auto-cpufreq/
|
||||
cp -r scripts/ /usr/local/share/auto-cpufreq/
|
||||
|
||||
# this is necessary since we need this script before we can run auto-cpufreq itself
|
||||
cp scripts/auto-cpufreq-venv-wrapper /usr/local/bin/auto-cpufreq
|
||||
chmod a+x /usr/local/bin/auto-cpufreq
|
||||
}
|
||||
|
||||
# First argument is the distro
|
||||
function detected_distro() {
|
||||
echo -e "\nDetected $1 distribution"
|
||||
separator
|
||||
echo -e "\nSetting up Python environment\n"
|
||||
}
|
||||
|
||||
# merged functions pip - install - complete_msg, since it repeats
|
||||
function completed () {
|
||||
echo -e "\nInstalling necessary Python packages\n"
|
||||
setup_venv
|
||||
separator
|
||||
echo -e "\ninstalling auto-cpufreq tool\n"
|
||||
install
|
||||
}
|
||||
|
||||
function complete_msg() {
|
||||
separator
|
||||
echo -e "\nauto-cpufreq tool successfully installed.\n"
|
||||
echo -e "For list of options, run:\nauto-cpufreq --help"
|
||||
separator
|
||||
}
|
||||
|
||||
function manual_install {
|
||||
echo -e "\nDidn't detect Debian or RedHat based distro.\n"
|
||||
echo -e "To complete installation, you need to:"
|
||||
echo -e "Install: python3, pip3, python3-setuptools\n"
|
||||
echo -e "Install necessary Python packages:"
|
||||
echo -e "pip3 install psutil click distro power"
|
||||
echo -e "\nRun following sequence of lines:"
|
||||
echo -e "\n-----"
|
||||
echo -e "\npython3 setup.py install --record files.txt"
|
||||
echo -e "mkdir -p /usr/local/share/auto-cpufreq/"
|
||||
echo -e "cp -r scripts/ /usr/local/share/auto-cpufreq/"
|
||||
echo -e "\n-----"
|
||||
echo -e "\nAfter which tool is installed, for full list of options run:"
|
||||
echo -e "auto-cpufreq"
|
||||
separator
|
||||
echo -e "\nConsider creating a feature request to add support for your distro:"
|
||||
echo -e "https://github.com/AdnanHodzic/auto-cpufreq/issues/new"
|
||||
echo -e "\nMake sure to include following information:\n"
|
||||
echo -e "Distribution: $distro"
|
||||
echo -e "Release: $release"
|
||||
echo -e "Codename: $codename"
|
||||
separator
|
||||
}
|
||||
|
||||
function tool_install {
|
||||
separator
|
||||
if [ -f /etc/debian_version ]; then
|
||||
detected_distro "Debian based"
|
||||
apt install python3-dev python3-pip python3-venv python3-setuptools dmidecode -y
|
||||
completed
|
||||
complete_msg
|
||||
elif [ -f /etc/redhat-release ]; then
|
||||
detected_distro "RedHat based"
|
||||
if [ -f /etc/centos-release ]; then
|
||||
yum install platform-python-devel dmidecode
|
||||
else
|
||||
yum install python-devel dmidecode
|
||||
fi
|
||||
completed
|
||||
complete_msg
|
||||
elif [ -f /etc/solus-release ]; then
|
||||
detected_distro "Solus"
|
||||
eopkg install pip python3 python3-devel dmidecode
|
||||
eopkg install -c system.devel
|
||||
completed
|
||||
complete_msg
|
||||
elif [ -f /etc/os-release ];then
|
||||
eval "$(cat /etc/os-release)"
|
||||
separator
|
||||
case $ID in
|
||||
opensuse-leap)
|
||||
detected_distro "OpenSUSE"
|
||||
zypper install -y python3 python3-pip python3-setuptools python3-devel gcc dmidecode
|
||||
completed
|
||||
;;
|
||||
opensuse)
|
||||
detected_distro "OpenSUSE"
|
||||
echo -e "\nDetected an OpenSUSE distribution\n\nSetting up Python environment\n"
|
||||
zypper install -y python38 python3-pip python3-setuptools python3-devel gcc dmidecode
|
||||
completed
|
||||
;;
|
||||
arch|manjaro|endeavouros|garuda|artix)
|
||||
detected_distro "Arch Linux based"
|
||||
pacman -S --noconfirm --needed python python-pip python-setuptools base-devel dmidecode
|
||||
completed
|
||||
;;
|
||||
void)
|
||||
detected_distro "Void Linux"
|
||||
xbps-install -Sy python3 python3-pip python3-devel python3-setuptools base-devel dmidecode
|
||||
completed
|
||||
;;
|
||||
*) #Any other distro
|
||||
manual_install
|
||||
completed
|
||||
;;
|
||||
esac
|
||||
complete_msg
|
||||
else # In case /etc/os-release doesn't exist
|
||||
manual_install
|
||||
fi
|
||||
}
|
||||
|
||||
function tool_remove {
|
||||
files="files.txt"
|
||||
share_dir="/usr/local/share/auto-cpufreq/"
|
||||
srv_install="/usr/bin/auto-cpufreq-install"
|
||||
srv_remove="/usr/bin/auto-cpufreq-remove"
|
||||
stats_file="/var/run/auto-cpufreq.stats"
|
||||
tool_proc_rm="/usr/local/bin/auto-cpufreq --remove"
|
||||
wrapper_script="/usr/local/bin/auto-cpufreq"
|
||||
unit_file="/etc/systemd/system/auto-cpufreq.service"
|
||||
venv_path="/opt/auto-cpufreq"
|
||||
cpufreqctl="/usr/bin/cpufreqctl.auto-cpufreq"
|
||||
|
||||
# stop any running auto-cpufreq argument (daemon/live/monitor)
|
||||
tool_arg_pids=($(pgrep -f "auto-cpufreq --"))
|
||||
for pid in "${tool_arg_pids[@]}"; do
|
||||
if [[ $tool_arg_pids != $$ ]]; then
|
||||
kill "$tool_arg_pids"
|
||||
fi
|
||||
done
|
||||
|
||||
# run uninstall in case of installed daemon
|
||||
if [ -f $srv_remove ]; then
|
||||
eval $tool_proc_rm
|
||||
fi
|
||||
|
||||
# remove auto-cpufreq and all its supporting files
|
||||
[ -f $files ] && cat $files | xargs sudo rm -rf && rm -f $files
|
||||
[ -d $share_dir ] && rm -rf $share_dir
|
||||
|
||||
# files cleanup
|
||||
[ -f $srv_install ] && rm $srv_install
|
||||
[ -f $srv_remove ] && rm $srv_remove
|
||||
[ -f $stats_file ] && rm $stats_file
|
||||
[ -f $unit_file ] && rm $unit_file
|
||||
[ -f $wrapper_script ] && rm $wrapper_script
|
||||
[ -f $cpufreqctl ] && rm $cpufreqctl
|
||||
|
||||
# remove python virtual environment
|
||||
rm -rf "${venv_path}"
|
||||
|
||||
separator
|
||||
echo -e "\nauto-cpufreq tool and all its supporting files successfully removed."
|
||||
separator
|
||||
function header {
|
||||
echo
|
||||
printf "%0.s─" $(seq $((MID-(${#1}/2)-2)))
|
||||
printf " $1 "
|
||||
printf "%0.s─" $(seq $((MID-(${#1}/2)-2)))
|
||||
echo; echo
|
||||
}
|
||||
|
||||
function ask_operation {
|
||||
echo -e "\n-------------------------- auto-cpufreq installer -----------------------------"
|
||||
echo -e "\nWelcome to auto-cpufreq tool installer."
|
||||
echo -e "\nOptions:\n"
|
||||
read -p \
|
||||
"[I]nstall
|
||||
[R]emove
|
||||
[Q]uit
|
||||
|
||||
Select a key: [i/r/q]: " answer
|
||||
header "auto-cpufreq installer"
|
||||
echo "Welcome to auto-cpufreq tool installer."; echo
|
||||
read -p "Select a key [I]nstall/[R]emove or press ctrl+c to quit: " answer
|
||||
}
|
||||
# End of functions
|
||||
|
||||
root_check
|
||||
function manual_install {
|
||||
if command -v lsb_release > /dev/null; then
|
||||
distro="$(lsb_release -is)"
|
||||
release="$(lsb_release -rs)"
|
||||
codename="$(lsb_release -cs)"
|
||||
fi
|
||||
|
||||
if [[ -z "${1}" ]]; then
|
||||
ask_operation
|
||||
echo "Didn't detect Debian or RedHat or Arch based distro."; echo
|
||||
echo "To complete installation, you need to:"
|
||||
echo "Install: python3, pip3, python3-setuptools, gobject-introspection, cairo (or cairo-devel), gcc, and gtk3"; echo
|
||||
echo "Install necessary Python packages:"
|
||||
echo "pip3 install psutil click distro power requests PyGObject"
|
||||
echo "Run following sequence of lines:"; echo
|
||||
echo "-----"; echo
|
||||
echo "pip3 install ."
|
||||
echo "mkdir -p $SHARE_DIR"
|
||||
echo "cp -r scripts/ $SHARE_DIR"; echo
|
||||
echo "-----"; echo
|
||||
echo "After which tool is installed, for full list of options run:";echo
|
||||
echo "auto-cpufreq --help"
|
||||
|
||||
echo; printf "%0.s─" $(seq $COLOUMNS); echo
|
||||
|
||||
echo "Consider creating a feature request to add support for your distro:"
|
||||
echo "https://github.com/AdnanHodzic/auto-cpufreq/issues/new"; echo
|
||||
echo "Make sure to include following information:"; echo
|
||||
echo "Distribution: $distro"
|
||||
echo "Release: $release"
|
||||
echo "Codename: $codename"
|
||||
echo
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
function tool_install {
|
||||
echo
|
||||
# First argument is the distro
|
||||
function detected_distro {
|
||||
header "Detected $1 distribution"
|
||||
header "Setting up Python environment"
|
||||
}
|
||||
|
||||
if [ -f /etc/debian_version ]; then
|
||||
VERSION=$(cat /etc/debian_version)
|
||||
# VERSION="CSCS"
|
||||
if [[ "$VERSION" =~ ^12(\.[0-9]+)?$ || ("$VERSION" =~ ^[0-9]+$ && "$VERSION" -lt 12) ]]; then
|
||||
LIB_GI_REPO="libgirepository1.0-dev"
|
||||
else
|
||||
LIB_GI_REPO="libgirepository-2.0-dev"
|
||||
fi
|
||||
|
||||
echo $LIB_GI_REPO needs to be installed for version $VERSION
|
||||
echo '---- '
|
||||
apt install -y python3-dev python3-pip python3-venv python3-setuptools dmidecode \
|
||||
"$LIB_GI_REPO" libcairo2-dev libgtk-3-dev gcc
|
||||
|
||||
elif [ -f /etc/redhat-release ]; then
|
||||
detected_distro "RedHat based"
|
||||
if [ -f /etc/centos-release ]; then yum install platform-python-devel
|
||||
else yum install python-devel
|
||||
fi
|
||||
yum install dmidecode gcc cairo-devel gobject-introspection-devel cairo-gobject-devel gtk3-devel
|
||||
|
||||
elif [ -f /etc/solus-release ]; then
|
||||
detected_distro "Solus"
|
||||
eopkg install pip python3 python3-devel dmidecode gobject-introspection-devel libcairo-devel gcc libgtk-3
|
||||
eopkg install -c system.devel
|
||||
|
||||
elif [ -f /etc/arch-release ]; then
|
||||
detected_distro "Arch Linux based"
|
||||
pacman -S --noconfirm --needed python python-pip python-setuptools base-devel dmidecode gobject-introspection gtk3 gcc
|
||||
|
||||
elif [ -f /etc/os-release ];then
|
||||
. /etc/os-release
|
||||
case $ID in
|
||||
opensuse-leap)
|
||||
detected_distro "OpenSUSE"
|
||||
zypper install -y python3 python3-pip python311-setuptools python3-devel gcc dmidecode gobject-introspection-devel python3-cairo-devel gtk3 gtk3-devel
|
||||
;;
|
||||
opensuse-tumbleweed)
|
||||
detected_distro "OpenSUSE"
|
||||
zypper install -y python3 python3-pip python311-setuptools python3-devel gcc dmidecode gobject-introspection-devel python3-cairo-devel gtk3 gtk3-devel
|
||||
;;
|
||||
void)
|
||||
detected_distro "Void Linux"
|
||||
xbps-install -Sy python3 python3-pip python3-devel python3-setuptools base-devel dmidecode cairo-devel gobject-introspection gcc gtk+3
|
||||
;;
|
||||
nixos)
|
||||
echo "NixOS detected"
|
||||
echo "This installer is not supported on NixOS."
|
||||
echo "Please refer to the install instructions for NixOS at https://github.com/AdnanHodzic/auto-cpufreq#nixos"
|
||||
exit 1
|
||||
;;
|
||||
*) manual_install;;
|
||||
esac
|
||||
else # In case /etc/os-release doesn't exist
|
||||
manual_install
|
||||
fi
|
||||
|
||||
header "Installing necessary Python packages"
|
||||
|
||||
venv_dir=$VENV_PATH/venv
|
||||
mkdir -p "$venv_dir"
|
||||
python3 -m venv "$venv_dir"
|
||||
|
||||
source "$venv_dir/bin/activate"
|
||||
python3 -m pip install --upgrade pip wheel
|
||||
|
||||
|
||||
# debian specific PyGObject Installation
|
||||
if [ -f /etc/debian_version ]; then
|
||||
VERSION=$(cat /etc/debian_version | cut -d'.' -f1)
|
||||
|
||||
if [[ "$VERSION" =~ ^12(\.[0-9]+)?$ ]]; then
|
||||
python3 -m pip install PyGObject==3.50.0
|
||||
fi
|
||||
fi
|
||||
python3 -m pip install PyGObject
|
||||
|
||||
header "Installing auto-cpufreq tool"
|
||||
|
||||
git config --global --add safe.directory $(pwd)
|
||||
python -m pip install .
|
||||
|
||||
mkdir -p $SHARE_DIR
|
||||
cp -r scripts/ $SHARE_DIR
|
||||
cp -r images/ $SHARE_DIR
|
||||
cp images/icon.png $IMG_FILE
|
||||
cp scripts/$(basename $ORG_FILE) $(dirname $ORG_FILE)
|
||||
|
||||
# this is necessary since we need this script before we can run auto-cpufreq itself
|
||||
cp scripts/auto-cpufreq-venv-wrapper $AUTO_CPUFREQ_FILE
|
||||
chmod a+x $AUTO_CPUFREQ_FILE
|
||||
cp scripts/start_app $AUTO_CPUFREQ_GTK_FILE
|
||||
chmod a+x $AUTO_CPUFREQ_GTK_FILE
|
||||
|
||||
desktop-file-install --dir=$APPLICATIONS_PATH scripts/$AUTO_CPUFREQ_GTK_DESKTOP_FILE
|
||||
update-desktop-database $APPLICATIONS_PATH
|
||||
|
||||
header "auto-cpufreq tool successfully installed"
|
||||
echo "For list of options, run:"
|
||||
echo "auto-cpufreq --help"; echo
|
||||
}
|
||||
|
||||
function tool_remove {
|
||||
# stop any running auto-cpufreq argument (daemon/live/monitor)
|
||||
tool_arg_pids=($(pgrep -f "auto-cpufreq --"))
|
||||
for pid in "${tool_arg_pids[@]}"; do [ $pid != $$ ] && kill "$pid"; done
|
||||
|
||||
function remove_directory {
|
||||
[ -d $1 ] && rm -rf $1
|
||||
}
|
||||
function remove_file {
|
||||
[ -f $1 ] && rm $1
|
||||
}
|
||||
|
||||
srv_remove="$AUTO_CPUFREQ_FILE-remove"
|
||||
|
||||
# run uninstall in case of installed daemon
|
||||
if [ -f $srv_remove -o -f $AUTO_CPUFREQ_FILE ]; then
|
||||
eval "$AUTO_CPUFREQ_FILE --remove"
|
||||
else
|
||||
echo; echo "Couldn't remove the auto-cpufreq daemon, $srv_remove do not exist."
|
||||
fi
|
||||
|
||||
# remove auto-cpufreq and all its supporting files
|
||||
remove_directory $SHARE_DIR
|
||||
|
||||
remove_file "$AUTO_CPUFREQ_FILE-install"
|
||||
remove_file $srv_remove
|
||||
remove_file $AUTO_CPUFREQ_FILE
|
||||
remove_file $AUTO_CPUFREQ_GTK_FILE
|
||||
remove_file $IMG_FILE
|
||||
remove_file $ORG_FILE
|
||||
remove_file "/usr/local/bin/cpufreqctl.auto-cpufreq"
|
||||
remove_file "/var/run/auto-cpufreq.stats"
|
||||
|
||||
remove_file "$APPLICATIONS_PATH/$AUTO_CPUFREQ_GTK_DESKTOP_FILE"
|
||||
update-desktop-database $APPLICATIONS_PATH
|
||||
|
||||
# remove python virtual environment
|
||||
remove_directory $venv_path
|
||||
|
||||
echo; echo "auto-cpufreq tool and all its supporting files successfully removed"; echo
|
||||
}
|
||||
|
||||
# root check
|
||||
if ((EUID != 0)); then
|
||||
echo; echo "Must be run as root (i.e: 'sudo $0')."; echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "$1" ]]; then ask_operation
|
||||
else
|
||||
case "${1}" in
|
||||
"--install")
|
||||
answer="i"
|
||||
;;
|
||||
"--remove")
|
||||
answer="r"
|
||||
;;
|
||||
*)
|
||||
answer="n"
|
||||
;;
|
||||
case "$1" in
|
||||
--install) answer="i";;
|
||||
--remove) answer="r";;
|
||||
*) ask_operation;;
|
||||
esac
|
||||
fi
|
||||
|
||||
case $answer in
|
||||
I|i)
|
||||
tool_install ;;
|
||||
R|r)
|
||||
tool_remove ;;
|
||||
Q|q)
|
||||
separator
|
||||
echo ""
|
||||
exit 0 ;;
|
||||
I|i) tool_install;;
|
||||
R|r) tool_remove;;
|
||||
*)
|
||||
separator
|
||||
echo -e "\nUnknown key, aborting ...\n"
|
||||
exit 1 ;;
|
||||
echo "Unknown key, aborting ..."; echo
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
@ -4,6 +4,25 @@
|
||||
# preferred governor.
|
||||
governor = performance
|
||||
|
||||
# EPP: see available preferences by running: cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_available_preferences
|
||||
energy_performance_preference = performance
|
||||
|
||||
# EPB (Energy Performance Bias) for the intel_pstate driver
|
||||
# see conversion info: https://www.kernel.org/doc/html/latest/admin-guide/pm/intel_epb.html
|
||||
# available EPB options include a numeric value between 0-15
|
||||
# (where 0 = maximum performance and 15 = maximum power saving),
|
||||
# or one of the following strings:
|
||||
# performance (0), balance_performance (4), default (6), balance_power (8), or power (15)
|
||||
# if the parameter is missing in the config and the hardware supports this setting, the default value will be used
|
||||
# the default value is `balance_performance` (for charger)
|
||||
# energy_perf_bias = balance_performance
|
||||
|
||||
# Platform Profiles
|
||||
# https://www.kernel.org/doc/html/latest/userspace-api/sysfs-platform_profile.html
|
||||
# See available options by running:
|
||||
# cat /sys/firmware/acpi/platform_profile_choices
|
||||
# platform_profile = performance
|
||||
|
||||
# minimum cpu frequency (in kHz)
|
||||
# example: for 800 MHz = 800000 kHz --> scaling_min_freq = 800000
|
||||
# see conversion info: https://www.rapidtables.com/convert/frequency/mhz-to-hz.html
|
||||
@ -19,12 +38,42 @@ governor = performance
|
||||
# turbo boost setting. possible values: always, auto, never
|
||||
turbo = auto
|
||||
|
||||
|
||||
# this is for ignoring controllers and other connected devices battery from affecting
|
||||
# laptop preformence
|
||||
# [power_supply_ignore_list]
|
||||
|
||||
# name1 = this
|
||||
# name2 = is
|
||||
# name3 = an
|
||||
# name4 = example
|
||||
|
||||
|
||||
# settings for when using battery power
|
||||
[battery]
|
||||
# see available governors by running: cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
|
||||
# preferred governor
|
||||
governor = powersave
|
||||
|
||||
# EPP: see available preferences by running: cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_available_preferences
|
||||
energy_performance_preference = power
|
||||
|
||||
# EPB (Energy Performance Bias) for the intel_pstate driver
|
||||
# see conversion info: https://www.kernel.org/doc/html/latest/admin-guide/pm/intel_epb.html
|
||||
# available EPB options include a numeric value between 0-15
|
||||
# (where 0 = maximum performance and 15 = maximum power saving),
|
||||
# or one of the following strings:
|
||||
# performance (0), balance_performance (4), default (6), balance_power (8), or power (15)
|
||||
# if the parameter is missing in the config and the hardware supports this setting, the default value will be used
|
||||
# the default value is `balance_power` (for battery)
|
||||
# energy_perf_bias = balance_power
|
||||
|
||||
# Platform Profiles
|
||||
# https://www.kernel.org/doc/html/latest/userspace-api/sysfs-platform_profile.html
|
||||
# See available options by running:
|
||||
# cat /sys/firmware/acpi/platform_profile_choices
|
||||
# platform_profile = low-power
|
||||
|
||||
# minimum cpu frequency (in kHz)
|
||||
# example: for 800 MHz = 800000 kHz --> scaling_min_freq = 800000
|
||||
# see conversion info: https://www.rapidtables.com/convert/frequency/mhz-to-hz.html
|
||||
@ -39,3 +88,17 @@ governor = powersave
|
||||
|
||||
# turbo boost setting. possible values: always, auto, never
|
||||
turbo = auto
|
||||
|
||||
# experimental
|
||||
|
||||
# Add battery charging threshold (currently only available to Lenovo)
|
||||
# checkout README.md for more info
|
||||
|
||||
# enable thresholds true or false
|
||||
#enable_thresholds = true
|
||||
#
|
||||
# start threshold (0 is off ) can be 0-99
|
||||
#start_threshold = 0
|
||||
#
|
||||
# stop threshold (100 is off) can be 1-100
|
||||
#stop_threshold = 100
|
||||
|
20
auto_cpufreq/battery_scripts/battery.py
Normal file
20
auto_cpufreq/battery_scripts/battery.py
Normal file
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env python3
|
||||
from subprocess import PIPE, run
|
||||
|
||||
from auto_cpufreq.battery_scripts.ideapad_acpi import ideapad_acpi_print_thresholds, ideapad_acpi_setup
|
||||
from auto_cpufreq.battery_scripts.ideapad_laptop import ideapad_laptop_print_thresholds, ideapad_laptop_setup
|
||||
from auto_cpufreq.battery_scripts.thinkpad import thinkpad_print_thresholds, thinkpad_setup
|
||||
|
||||
def lsmod(module): return module in run(['lsmod'], stdout=PIPE, stderr=PIPE, text=True, shell=True).stdout
|
||||
|
||||
def battery_get_thresholds():
|
||||
if lsmod("ideapad_acpi"): ideapad_acpi_print_thresholds()
|
||||
elif lsmod("ideapad_laptop"): ideapad_laptop_print_thresholds()
|
||||
elif lsmod("thinkpad_acpi"): thinkpad_print_thresholds()
|
||||
else: return
|
||||
|
||||
def battery_setup():
|
||||
if lsmod("ideapad_acpi"): ideapad_acpi_setup()
|
||||
elif lsmod("ideapad_laptop"): ideapad_laptop_setup()
|
||||
elif lsmod("thinkpad_acpi"): thinkpad_setup()
|
||||
else: return
|
38
auto_cpufreq/battery_scripts/ideapad_acpi.py
Normal file
38
auto_cpufreq/battery_scripts/ideapad_acpi.py
Normal file
@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
from subprocess import check_output
|
||||
|
||||
from auto_cpufreq.config.config import config
|
||||
from auto_cpufreq.globals import POWER_SUPPLY_DIR
|
||||
|
||||
def set_battery(value, mode, bat):
|
||||
path = f"{POWER_SUPPLY_DIR}{bat}/charge_{mode}_threshold"
|
||||
if os.path.isfile(path): check_output(f"echo {value} | tee {path}", shell=True, text=True)
|
||||
else: print(f"WARNING: {path} does NOT exist")
|
||||
|
||||
def get_threshold_value(mode):
|
||||
conf = config.get_config()
|
||||
return conf["battery"][f"{mode}_threshold"] if conf.has_option("battery", f"{mode}_threshold") else (0 if mode == "start" else 100)
|
||||
|
||||
def ideapad_acpi_setup():
|
||||
conf = config.get_config()
|
||||
|
||||
if not (conf.has_option("battery", "enable_thresholds") and conf["battery"]["enable_thresholds"] == "true"): return
|
||||
|
||||
if os.path.exists(POWER_SUPPLY_DIR):
|
||||
batteries = [name for name in os.listdir(POWER_SUPPLY_DIR) if name.startswith('BAT')]
|
||||
|
||||
for bat in batteries:
|
||||
set_battery(get_threshold_value("start"), "start", bat)
|
||||
set_battery(get_threshold_value("stop"), "stop", bat)
|
||||
else: print("WARNING: could NOT access", POWER_SUPPLY_DIR)
|
||||
|
||||
def ideapad_acpi_print_thresholds():
|
||||
batteries = [name for name in os.listdir(POWER_SUPPLY_DIR) if name.startswith('BAT')]
|
||||
print("\n-------------------------------- Battery Info ---------------------------------\n")
|
||||
print(f"battery count = {len(batteries)}")
|
||||
for bat in batteries:
|
||||
try:
|
||||
print(bat, "start threshold =", check_output(["cat", POWER_SUPPLY_DIR+bat+"/charge_start_threshold"]))
|
||||
print(bat, "stop threshold =", check_output(["cat", POWER_SUPPLY_DIR+bat+"/charge_stop_threshold"]))
|
||||
except Exception as e: print(f"ERROR: failed to read battery {bat} thresholds:", repr(e))
|
69
auto_cpufreq/battery_scripts/ideapad_laptop.py
Normal file
69
auto_cpufreq/battery_scripts/ideapad_laptop.py
Normal file
@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
from subprocess import check_output
|
||||
|
||||
from auto_cpufreq.config.config import config
|
||||
from auto_cpufreq.globals import CONSERVATION_MODE_FILE, POWER_SUPPLY_DIR
|
||||
|
||||
def set_battery(value, mode, bat):
|
||||
path = f"{POWER_SUPPLY_DIR}{bat}/charge_{mode}_threshold"
|
||||
if os.path.exists(path):
|
||||
check_output(f"echo {value} | tee {POWER_SUPPLY_DIR}{bat}/charge_{mode}_threshold", shell=True, text=True)
|
||||
else: print(f"WARNING: {path} does NOT exist")
|
||||
|
||||
def get_threshold_value(mode):
|
||||
conf = config.get_config()
|
||||
return conf["battery"][f"{mode}_threshold"] if conf.has_option("battery", f"{mode}_threshold") else (0 if mode == "start" else 100)
|
||||
|
||||
def conservation_mode(value):
|
||||
try:
|
||||
check_output(f"echo {value} | tee {CONSERVATION_MODE_FILE}", shell=True, text=True)
|
||||
print(f"conservation_mode is {value}")
|
||||
except: print("unable to set conservation mode")
|
||||
return
|
||||
|
||||
def check_conservation_mode():
|
||||
try:
|
||||
value = check_output(["cat", CONSERVATION_MODE_FILE], text=True).rstrip()
|
||||
if value == "1": return True
|
||||
elif value == "0": return False
|
||||
else:
|
||||
print("could not get value from conservation mode")
|
||||
return None
|
||||
except:
|
||||
print("could not get the value from conservation mode")
|
||||
return False
|
||||
|
||||
def ideapad_laptop_setup():
|
||||
conf = config.get_config()
|
||||
|
||||
if not (conf.has_option("battery", "enable_thresholds") and conf["battery"]["enable_thresholds"] == "true"): return
|
||||
|
||||
batteries = [name for name in os.listdir(POWER_SUPPLY_DIR) if name.startswith("BAT")]
|
||||
|
||||
if conf.has_option("battery", "ideapad_laptop_conservation_mode"):
|
||||
if conf["battery"]["ideapad_laptop_conservation_mode"] == "true":
|
||||
conservation_mode(1)
|
||||
return
|
||||
if conf["battery"]["ideapad_laptop_conservation_mode"] == "false": conservation_mode(0)
|
||||
|
||||
if not check_conservation_mode():
|
||||
for bat in batteries:
|
||||
set_battery(get_threshold_value("start"), "start", bat)
|
||||
set_battery(get_threshold_value("stop"), "stop", bat)
|
||||
else: print("conservation mode is enabled unable to set thresholds")
|
||||
|
||||
def ideapad_laptop_print_thresholds():
|
||||
if check_conservation_mode():
|
||||
print("conservation mode is on")
|
||||
return
|
||||
|
||||
batteries = [name for name in os.listdir(POWER_SUPPLY_DIR) if name.startswith("BAT")]
|
||||
|
||||
print("\n-------------------------------- Battery Info ---------------------------------\n")
|
||||
print(f"battery count = {len(batteries)}")
|
||||
for bat in batteries:
|
||||
try:
|
||||
print(bat, "start threshold =", check_output(["cat", POWER_SUPPLY_DIR+bat+"/charge_start_threshold"]))
|
||||
print(bat, "stop threshold =", check_output(["cat", POWER_SUPPLY_DIR+bat+"/charge_stop_threshold"]))
|
||||
except Exception as e: print(f"ERROR: failed to read battery {bat} thresholds:", repr(e))
|
39
auto_cpufreq/battery_scripts/thinkpad.py
Normal file
39
auto_cpufreq/battery_scripts/thinkpad.py
Normal file
@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
from subprocess import check_output
|
||||
|
||||
from auto_cpufreq.config.config import config
|
||||
from auto_cpufreq.globals import POWER_SUPPLY_DIR
|
||||
|
||||
def set_battery(value, mode, bat):
|
||||
path = f"{POWER_SUPPLY_DIR}{bat}/charge_{mode}_threshold"
|
||||
if os.path.isfile(path): check_output(f"echo {value} | tee {path}", shell=True, text=True)
|
||||
else: print(f"WARNING: {path} does NOT exist")
|
||||
|
||||
def get_threshold_value(mode):
|
||||
conf = config.get_config()
|
||||
return conf["battery"][f"{mode}_threshold"] if conf.has_option("battery", f"{mode}_threshold") else (0 if mode == "start" else 100)
|
||||
|
||||
def thinkpad_setup():
|
||||
conf = config.get_config()
|
||||
|
||||
if not (conf.has_option("battery", "enable_thresholds") and conf["battery"]["enable_thresholds"] == "true"): return
|
||||
|
||||
if os.path.exists(POWER_SUPPLY_DIR):
|
||||
batteries = [name for name in os.listdir(POWER_SUPPLY_DIR) if name.startswith('BAT')]
|
||||
|
||||
for bat in batteries:
|
||||
set_battery(get_threshold_value("start"), "start", bat)
|
||||
set_battery(get_threshold_value("stop"), "stop", bat)
|
||||
else: print(f"WARNING {POWER_SUPPLY_DIR} does NOT esixt")
|
||||
|
||||
|
||||
def thinkpad_print_thresholds():
|
||||
batteries = [name for name in os.listdir(POWER_SUPPLY_DIR) if name.startswith('BAT')]
|
||||
print("\n-------------------------------- Battery Info ---------------------------------\n")
|
||||
print(f"battery count = {len(batteries)}")
|
||||
for bat in batteries:
|
||||
try:
|
||||
print(bat, "start threshold =", check_output(["cat", POWER_SUPPLY_DIR+bat+"/charge_start_threshold"]))
|
||||
print(bat, "stop threshold =", check_output(["cat", POWER_SUPPLY_DIR+bat+"/charge_stop_threshold"]))
|
||||
except Exception as e: print(f"ERROR: failed to read battery {bat} thresholds:", repr(e))
|
285
auto_cpufreq/bin/auto_cpufreq.py
Executable file
285
auto_cpufreq/bin/auto_cpufreq.py
Executable file
@ -0,0 +1,285 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# auto-cpufreq - Automatic CPU speed & power optimizer for Linux
|
||||
#
|
||||
# Blog post: https://foolcontrol.org/?p=3124
|
||||
|
||||
# core import
|
||||
import sys, time
|
||||
from subprocess import run
|
||||
from shutil import rmtree
|
||||
|
||||
from auto_cpufreq.battery_scripts.battery import *
|
||||
from auto_cpufreq.config.config import config as conf, find_config_file
|
||||
from auto_cpufreq.core import *
|
||||
from auto_cpufreq.globals import GITHUB, IS_INSTALLED_WITH_AUR, IS_INSTALLED_WITH_SNAP
|
||||
from auto_cpufreq.modules.system_monitor import ViewType, SystemMonitor
|
||||
from auto_cpufreq.power_helper import *
|
||||
from threading import Thread
|
||||
|
||||
@click.command()
|
||||
@click.option("--monitor", is_flag=True, help="Monitor and see suggestions for CPU optimizations")
|
||||
@click.option("--live", is_flag=True, help="Monitor and make (temp.) suggested CPU optimizations")
|
||||
@click.option("--daemon", is_flag=True, hidden=True)
|
||||
@click.option("--install", is_flag=True, help="Install daemon for (permanent) automatic CPU optimizations")
|
||||
@click.option("--update", is_flag=False, help="Update daemon and package for (permanent) automatic CPU optimizations", flag_value="--update")
|
||||
@click.option("--remove", is_flag=True, help="Remove daemon for (permanent) automatic CPU optimizations")
|
||||
@click.option("--force", is_flag=False, help="Force use of either \"powersave\" or \"performance\" governors. Setting to \"reset\" will go back to normal mode")
|
||||
@click.option("--config", is_flag=False, required=False, help="Use config file at defined path",)
|
||||
@click.option("--stats", is_flag=True, help="View live stats of CPU optimizations made by daemon")
|
||||
@click.option("--get-state", is_flag=True, hidden=True)
|
||||
@click.option("--completions", is_flag=False, help="Enables shell completions for bash, zsh and fish.\n Possible values bash|zsh|fish")
|
||||
@click.option("--debug", is_flag=True, help="Show debug info (include when submitting bugs)")
|
||||
@click.option("--version", is_flag=True, help="Show currently installed version")
|
||||
@click.option("--donate", is_flag=True, help="Support the project")
|
||||
def main(monitor, live, daemon, install, update, remove, force, config, stats, get_state, completions, debug, version, donate):
|
||||
# display info if config file is used
|
||||
config_path = find_config_file(config)
|
||||
conf.set_path(config_path)
|
||||
def config_info_dialog():
|
||||
if conf.has_config():
|
||||
print("\nUsing settings defined in " + config_path + " file")
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
print("\n" + "-" * 32 + " auto-cpufreq " + "-" * 33 + "\n")
|
||||
print("Automatic CPU speed & power optimizer for Linux")
|
||||
|
||||
print("\nExample usage:\nauto-cpufreq --monitor")
|
||||
print("\n-----\n")
|
||||
|
||||
run(["auto-cpufreq", "--help"])
|
||||
footer()
|
||||
else:
|
||||
# set governor override unless None or invalid
|
||||
if force is not None:
|
||||
not_running_daemon_check()
|
||||
root_check() # Calling root_check before set_override as it will require sudo access
|
||||
set_override(force) # Calling set override, only if force has some values
|
||||
|
||||
if monitor:
|
||||
root_check()
|
||||
battery_setup()
|
||||
conf.notifier.start()
|
||||
if IS_INSTALLED_WITH_SNAP:
|
||||
gnome_power_detect_snap()
|
||||
tlp_service_detect_snap()
|
||||
else:
|
||||
gnome_power_detect()
|
||||
tlp_service_detect()
|
||||
|
||||
if IS_INSTALLED_WITH_SNAP or tlp_stat_exists or (systemctl_exists and not bool(gnome_power_status)):
|
||||
try:
|
||||
input("press Enter to continue or Ctrl + c to exit...")
|
||||
except KeyboardInterrupt:
|
||||
conf.notifier.stop()
|
||||
sys.exit(0)
|
||||
|
||||
monitor = SystemMonitor(suggestion=True, type=ViewType.MONITOR)
|
||||
monitor.run(on_quit=conf.notifier.stop)
|
||||
elif live:
|
||||
root_check()
|
||||
battery_setup()
|
||||
conf.notifier.start()
|
||||
if IS_INSTALLED_WITH_SNAP:
|
||||
gnome_power_detect_snap()
|
||||
tlp_service_detect_snap()
|
||||
else:
|
||||
gnome_power_detect_install()
|
||||
gnome_power_stop_live()
|
||||
tuned_stop_live()
|
||||
tlp_service_detect()
|
||||
|
||||
if IS_INSTALLED_WITH_SNAP or tlp_stat_exists or (systemctl_exists and not bool(gnome_power_status)):
|
||||
try:
|
||||
input("press Enter to continue or Ctrl + c to exit...")
|
||||
except KeyboardInterrupt:
|
||||
conf.notifier.stop()
|
||||
sys.exit(0)
|
||||
|
||||
cpufreqctl()
|
||||
def live_daemon():
|
||||
# Redirect stdout to suppress prints
|
||||
class NullWriter:
|
||||
def write(self, _): pass
|
||||
def flush(self): pass
|
||||
try:
|
||||
sys.stdout = NullWriter()
|
||||
|
||||
while True:
|
||||
time.sleep(1)
|
||||
set_autofreq()
|
||||
except:
|
||||
pass
|
||||
|
||||
def live_daemon_off():
|
||||
gnome_power_start_live()
|
||||
tuned_start_live()
|
||||
cpufreqctl_restore()
|
||||
conf.notifier.stop()
|
||||
|
||||
thread = Thread(target=live_daemon, daemon=True)
|
||||
thread.start()
|
||||
|
||||
monitor = SystemMonitor(type=ViewType.LIVE)
|
||||
monitor.run(on_quit=live_daemon_off)
|
||||
elif daemon:
|
||||
config_info_dialog()
|
||||
root_check()
|
||||
file_stats()
|
||||
if IS_INSTALLED_WITH_SNAP and SNAP_DAEMON_CHECK == "enabled":
|
||||
gnome_power_detect_snap()
|
||||
tlp_service_detect_snap()
|
||||
elif not IS_INSTALLED_WITH_SNAP:
|
||||
gnome_power_detect()
|
||||
tlp_service_detect()
|
||||
battery_setup()
|
||||
conf.notifier.start()
|
||||
while True:
|
||||
try:
|
||||
footer()
|
||||
gov_check()
|
||||
cpufreqctl()
|
||||
distro_info()
|
||||
sysinfo()
|
||||
set_autofreq()
|
||||
countdown(2)
|
||||
except KeyboardInterrupt: break
|
||||
conf.notifier.stop()
|
||||
elif install:
|
||||
root_check()
|
||||
if IS_INSTALLED_WITH_SNAP:
|
||||
running_daemon_check()
|
||||
gnome_power_detect_snap()
|
||||
tlp_service_detect_snap()
|
||||
bluetooth_notif_snap()
|
||||
gov_check()
|
||||
run("snapctl set daemon=enabled", shell=True)
|
||||
run("snapctl start --enable auto-cpufreq", shell=True)
|
||||
else:
|
||||
running_daemon_check()
|
||||
gov_check()
|
||||
deploy_daemon()
|
||||
deploy_complete_msg()
|
||||
elif update:
|
||||
root_check()
|
||||
custom_dir = "/opt/auto-cpufreq/source"
|
||||
for arg in sys.argv:
|
||||
if arg.startswith("--update="):
|
||||
custom_dir = arg.split("=")[1]
|
||||
sys.argv.remove(arg)
|
||||
|
||||
if "--update" in sys.argv:
|
||||
update = True
|
||||
sys.argv.remove("--update")
|
||||
if len(sys.argv) == 2: custom_dir = sys.argv[1]
|
||||
|
||||
if IS_INSTALLED_WITH_SNAP:
|
||||
print("Detected auto-cpufreq was installed using snap")
|
||||
# refresh snap directly using this command
|
||||
# path wont work in this case
|
||||
|
||||
print("Please update using snap package manager, i.e: `sudo snap refresh auto-cpufreq`.")
|
||||
#check for AUR
|
||||
elif IS_INSTALLED_WITH_AUR: print("Arch-based distribution with AUR support detected. Please refresh auto-cpufreq using your AUR helper.")
|
||||
else:
|
||||
is_new_update = check_for_update()
|
||||
if not is_new_update: return
|
||||
ans = input("Do you want to update auto-cpufreq to the latest release? [Y/n]: ").strip().lower()
|
||||
if not os.path.exists(custom_dir): os.makedirs(custom_dir)
|
||||
if os.path.exists(os.path.join(custom_dir, "auto-cpufreq")): rmtree(os.path.join(custom_dir, "auto-cpufreq"))
|
||||
if ans in ['', 'y', 'yes']:
|
||||
remove_daemon()
|
||||
remove_complete_msg()
|
||||
new_update(custom_dir)
|
||||
print("enabling daemon")
|
||||
run(["auto-cpufreq", "--install"])
|
||||
print("auto-cpufreq is installed with the latest version")
|
||||
run(["auto-cpufreq", "--version"])
|
||||
else: print("Aborted")
|
||||
elif remove:
|
||||
root_check()
|
||||
if IS_INSTALLED_WITH_SNAP:
|
||||
run("snapctl set daemon=disabled", shell=True)
|
||||
run("snapctl stop --disable auto-cpufreq", shell=True)
|
||||
if auto_cpufreq_stats_path.exists():
|
||||
if auto_cpufreq_stats_file is not None:
|
||||
auto_cpufreq_stats_file.close()
|
||||
|
||||
auto_cpufreq_stats_path.unlink()
|
||||
# ToDo:
|
||||
# {the following snippet also used in --update, update it there too(if required)}
|
||||
# * undo bluetooth boot disable
|
||||
gnome_power_rm_reminder_snap()
|
||||
else: remove_daemon()
|
||||
remove_complete_msg()
|
||||
elif stats:
|
||||
not_running_daemon_check()
|
||||
config_info_dialog()
|
||||
if IS_INSTALLED_WITH_SNAP:
|
||||
gnome_power_detect_snap()
|
||||
tlp_service_detect_snap()
|
||||
else:
|
||||
gnome_power_detect()
|
||||
tlp_service_detect()
|
||||
|
||||
if IS_INSTALLED_WITH_SNAP or tlp_stat_exists or (systemctl_exists and not bool(gnome_power_status)):
|
||||
try:
|
||||
input("press Enter to continue or Ctrl + c to exit...")
|
||||
except KeyboardInterrupt:
|
||||
conf.notifier.stop()
|
||||
sys.exit(0)
|
||||
|
||||
monitor = SystemMonitor(type=ViewType.STATS)
|
||||
monitor.run()
|
||||
elif get_state:
|
||||
not_running_daemon_check()
|
||||
override = get_override()
|
||||
print(override)
|
||||
elif completions:
|
||||
if completions == "bash":
|
||||
print("Run the below command in your current shell!\n")
|
||||
print("echo 'eval \"$(_AUTO_CPUFREQ_COMPLETE=bash_source auto-cpufreq)\"' >> ~/.bashrc")
|
||||
print("source ~/.bashrc")
|
||||
elif completions == "zsh":
|
||||
print("Run the below command in your current shell!\n")
|
||||
print("echo 'eval \"$(_AUTO_CPUFREQ_COMPLETE=zsh_source auto-cpufreq)\"' >> ~/.zshrc")
|
||||
print("source ~/.zshrc")
|
||||
elif completions == "fish":
|
||||
print("Run the below command in your current shell!\n")
|
||||
print("echo '_AUTO_CPUFREQ_COMPLETE=fish_source auto-cpufreq | source' > ~/.config/fish/completions/auto-cpufreq.fish")
|
||||
else: print("Invalid Option, try bash|zsh|fish as argument to --completions")
|
||||
elif debug:
|
||||
# ToDo: add status of GNOME Power Profile service status
|
||||
config_info_dialog()
|
||||
root_check()
|
||||
battery_get_thresholds()
|
||||
cpufreqctl()
|
||||
footer()
|
||||
distro_info()
|
||||
sysinfo()
|
||||
print()
|
||||
app_version()
|
||||
print()
|
||||
python_info()
|
||||
print()
|
||||
device_info()
|
||||
print(f"Battery is: {'' if charging() else 'dis'}charging")
|
||||
print()
|
||||
app_res_use()
|
||||
get_load()
|
||||
get_current_gov()
|
||||
get_turbo()
|
||||
footer()
|
||||
elif version:
|
||||
footer()
|
||||
distro_info()
|
||||
app_version()
|
||||
footer()
|
||||
elif donate:
|
||||
footer()
|
||||
print("If auto-cpufreq helped you out and you find it useful ...\n")
|
||||
print("Show your appreciation by donating!")
|
||||
print(GITHUB+"#donate")
|
||||
footer()
|
||||
|
||||
if __name__ == "__main__": main()
|
16
auto_cpufreq/bin/auto_cpufreq_gtk.py
Normal file
16
auto_cpufreq/bin/auto_cpufreq_gtk.py
Normal file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env python3
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, GLib
|
||||
|
||||
from auto_cpufreq.gui.app import ToolWindow
|
||||
|
||||
def main():
|
||||
GLib.set_prgname("auto-cpufreq")
|
||||
win = ToolWindow()
|
||||
win.connect("destroy", Gtk.main_quit)
|
||||
win.show_all()
|
||||
win.handle_update()
|
||||
Gtk.main()
|
||||
|
||||
if __name__ == "__main__": main()
|
68
auto_cpufreq/config/config.py
Normal file
68
auto_cpufreq/config/config.py
Normal file
@ -0,0 +1,68 @@
|
||||
import os, pyinotify, sys
|
||||
from configparser import ConfigParser, ParsingError
|
||||
from subprocess import run, PIPE
|
||||
|
||||
from auto_cpufreq.config.config_event_handler import ConfigEventHandler
|
||||
|
||||
def find_config_file(args_config_file) -> str:
|
||||
"""
|
||||
Find the config file to use.
|
||||
|
||||
Look for a config file in the following priorization order:
|
||||
1. Command line argument
|
||||
2. User config file
|
||||
3. System config file
|
||||
|
||||
:param args_config_file: Path to the config file provided as a command line argument
|
||||
:return: The path to the config file to use
|
||||
"""
|
||||
# Prepare paths
|
||||
|
||||
# use $SUDO_USER or $USER to get home dir since sudo can't access
|
||||
# user env vars
|
||||
home = run(["getent passwd ${SUDO_USER:-$USER} | cut -d: -f6"],
|
||||
shell=True,
|
||||
stdout=PIPE,
|
||||
universal_newlines=True
|
||||
).stdout.rstrip()
|
||||
user_config_dir = os.getenv("XDG_CONFIG_HOME", default=os.path.join(home, ".config"))
|
||||
user_config_file = os.path.join(user_config_dir, "auto-cpufreq/auto-cpufreq.conf")
|
||||
system_config_file = "/etc/auto-cpufreq.conf"
|
||||
|
||||
if args_config_file is not None: # (1) Command line argument was specified
|
||||
# Check if the config file path points to a valid file
|
||||
if os.path.isfile(args_config_file): return args_config_file
|
||||
else:
|
||||
# Not a valid file
|
||||
print(f"Config file specified with '--config {args_config_file}' not found.")
|
||||
sys.exit(1)
|
||||
elif os.path.isfile(user_config_file): return user_config_file # (2) User config file
|
||||
else: return system_config_file # (3) System config file (default if nothing else is found)
|
||||
|
||||
class _Config:
|
||||
def __init__(self) -> None:
|
||||
self.path: str = ""
|
||||
self._config: ConfigParser = ConfigParser()
|
||||
self.watch_manager: pyinotify.WatchManager = pyinotify.WatchManager()
|
||||
self.config_handler = ConfigEventHandler(self)
|
||||
|
||||
# check for file changes using threading
|
||||
self.notifier: pyinotify.ThreadedNotifier = pyinotify.ThreadedNotifier(self.watch_manager, self.config_handler)
|
||||
|
||||
def set_path(self, path: str) -> None:
|
||||
self.path = path
|
||||
mask = pyinotify.IN_CREATE | pyinotify.IN_DELETE | pyinotify.IN_MODIFY | pyinotify.IN_MOVED_FROM | pyinotify.IN_MOVED_TO
|
||||
self.watch_manager.add_watch(os.path.dirname(path), mask=mask)
|
||||
if os.path.isfile(path): self.update_config()
|
||||
|
||||
def has_config(self) -> bool: return os.path.isfile(self.path)
|
||||
|
||||
def get_config(self) -> ConfigParser: return self._config
|
||||
|
||||
def update_config(self) -> None:
|
||||
# create new ConfigParser to prevent old data from remaining
|
||||
self._config = ConfigParser()
|
||||
try: self._config.read(self.path)
|
||||
except ParsingError as e: print(f"The following error occured while parsing the config file: \n{repr(e)}")
|
||||
|
||||
config = _Config()
|
23
auto_cpufreq/config/config_event_handler.py
Normal file
23
auto_cpufreq/config/config_event_handler.py
Normal file
@ -0,0 +1,23 @@
|
||||
from pyinotify import Event, ProcessEvent
|
||||
|
||||
class ConfigEventHandler(ProcessEvent):
|
||||
def __init__(self, config) -> None:
|
||||
self.config = config
|
||||
|
||||
def _process_update(self, event: Event):
|
||||
if event.pathname.rstrip("~") == self.config.path: self.config.update_config()
|
||||
|
||||
# activates when auto-cpufreq config file is modified
|
||||
def process_IN_MODIFY(self, event: Event) -> None: self._process_update(event)
|
||||
|
||||
# activates when auto-cpufreq config file is deleted
|
||||
def process_IN_DELETE(self, event: Event) -> None: self._process_update(event)
|
||||
|
||||
# activates when auto-cpufreq config file is created
|
||||
def process_IN_CREATE(self, event: Event) -> None: self._process_update(event)
|
||||
|
||||
# activates when auto-cpufreq config file is moved from watched directory
|
||||
def process_IN_MOVED_FROM(self, event: Event) -> None: self._process_update(event)
|
||||
|
||||
# activates when auto-cpufreq config file is moved into the watched directory
|
||||
def process_IN_MOVED_TO(self, event: Event) -> None: self._process_update(event)
|
1186
auto_cpufreq/core.py
Normal file → Executable file
1186
auto_cpufreq/core.py
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
15
auto_cpufreq/globals.py
Normal file
15
auto_cpufreq/globals.py
Normal file
@ -0,0 +1,15 @@
|
||||
from os import getenv, path
|
||||
from subprocess import getoutput
|
||||
|
||||
ALL_GOVERNORS = ('performance', 'ondemand', 'conservative', 'schedutil', 'userspace', 'powersave') # from the highest performance to the lowest
|
||||
AVAILABLE_GOVERNORS = getoutput('cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors').strip().split(' ')
|
||||
AVAILABLE_GOVERNORS_SORTED = tuple(filter(lambda gov: gov in AVAILABLE_GOVERNORS, ALL_GOVERNORS))
|
||||
|
||||
CONSERVATION_MODE_FILE = "/sys/bus/platform/drivers/ideapad_acpi/VPC2004:00/conservation_mode"
|
||||
GITHUB = "https://github.com/AdnanHodzic/auto-cpufreq"
|
||||
IS_INSTALLED_WITH_AUR = path.isfile("/etc/arch-release") and bool(getoutput("pacman -Qs auto-cpufreq"))
|
||||
IS_INSTALLED_WITH_SNAP = getenv("PKG_MARKER") == "SNAP"
|
||||
POWER_SUPPLY_DIR = "/sys/class/power_supply/"
|
||||
SNAP_DAEMON_CHECK = getoutput("snapctl get daemon")
|
||||
|
||||
CPU_TEMP_SENSOR_PRIORITY = ("coretemp", "acpitz", "k10temp", "zenpower")
|
119
auto_cpufreq/gui/app.py
Normal file
119
auto_cpufreq/gui/app.py
Normal file
@ -0,0 +1,119 @@
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gdk, GdkPixbuf, Gio, GLib, Gtk
|
||||
|
||||
from contextlib import redirect_stdout
|
||||
from io import StringIO
|
||||
from subprocess import PIPE, run
|
||||
from threading import Thread
|
||||
|
||||
from auto_cpufreq.core import check_for_update, is_running
|
||||
from auto_cpufreq.globals import GITHUB, IS_INSTALLED_WITH_SNAP
|
||||
from auto_cpufreq.gui.objects import CPUFreqStatsLabel, CurrentGovernorBox, DaemonNotRunningView, DropDownMenu, RadioButtonView, SystemStatsLabel, UpdateDialog
|
||||
|
||||
if IS_INSTALLED_WITH_SNAP:
|
||||
CSS_FILE = "/snap/auto-cpufreq/current/style.css"
|
||||
ICON_FILE = "/snap/auto-cpufreq/current/icon.png"
|
||||
else:
|
||||
CSS_FILE = "/usr/local/share/auto-cpufreq/scripts/style.css"
|
||||
ICON_FILE = "/usr/local/share/auto-cpufreq/images/icon.png"
|
||||
|
||||
HBOX_PADDING = 20
|
||||
PKEXEC_ERROR = "Error executing command as another user: Not authorized\n\nThis incident has been reported.\n"
|
||||
|
||||
class ToolWindow(Gtk.Window):
|
||||
def __init__(self):
|
||||
super().__init__(title="auto-cpufreq")
|
||||
self.set_default_size(600, 480)
|
||||
self.set_border_width(10)
|
||||
self.set_resizable(False)
|
||||
self.load_css()
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(filename=ICON_FILE, width=500, height=500, preserve_aspect_ratio=True)
|
||||
self.set_icon(pixbuf)
|
||||
self.build()
|
||||
|
||||
def main(self):
|
||||
# Main HBOX
|
||||
self.hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=HBOX_PADDING)
|
||||
|
||||
self.systemstats = SystemStatsLabel()
|
||||
self.hbox.pack_start(self.systemstats, False, False, 0)
|
||||
self.add(self.hbox)
|
||||
|
||||
self.vbox_right = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=52)
|
||||
|
||||
self.menu = DropDownMenu(self)
|
||||
self.hbox.pack_end(self.menu, False, False, 0)
|
||||
|
||||
self.currentgovernor = CurrentGovernorBox()
|
||||
self.vbox_right.pack_start(self.currentgovernor, False, False, 0)
|
||||
self.vbox_right.pack_start(RadioButtonView(), False, False, 0)
|
||||
|
||||
self.cpufreqstats = CPUFreqStatsLabel()
|
||||
self.vbox_right.pack_start(self.cpufreqstats, False, False, 0)
|
||||
|
||||
self.hbox.pack_start(self.vbox_right, False, False, 0)
|
||||
|
||||
GLib.timeout_add_seconds(5, self.refresh_in_thread)
|
||||
|
||||
def snap(self):
|
||||
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, halign=Gtk.Align.CENTER, valign=Gtk.Align.CENTER)
|
||||
# reference: https://forum.snapcraft.io/t/pkexec-not-found-python-gtk-gnome-app/36579
|
||||
label = Gtk.Label(label="GUI not available due to Snap package confinement limitations.\nPlease install auto-cpufreq using auto-cpufreq-installer\nVisit the GitHub repo for more info")
|
||||
label.set_justify(Gtk.Justification.CENTER)
|
||||
button = Gtk.LinkButton.new_with_label(
|
||||
uri=GITHUB,
|
||||
label="GitHub Repo"
|
||||
)
|
||||
|
||||
box.pack_start(label, False, False, 0)
|
||||
box.pack_start(button, False, False, 0)
|
||||
self.add(box)
|
||||
|
||||
def handle_update(self):
|
||||
new_stdout = StringIO()
|
||||
with redirect_stdout(new_stdout):
|
||||
if not check_for_update(): return
|
||||
captured_output = new_stdout.getvalue().splitlines()
|
||||
dialog = UpdateDialog(self, captured_output[1], captured_output[2])
|
||||
response = dialog.run()
|
||||
dialog.destroy()
|
||||
if response != Gtk.ResponseType.YES: return
|
||||
updater = run(["pkexec", "auto-cpufreq", "--update"], input="y\n", encoding="utf-8", stderr=PIPE)
|
||||
if updater.stderr == PKEXEC_ERROR:
|
||||
error = Gtk.MessageDialog(self, 0, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, "Error updating")
|
||||
error.format_secondary_text("Authorization Failed")
|
||||
error.run()
|
||||
error.destroy()
|
||||
return
|
||||
success = Gtk.MessageDialog(self, 0, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, "Update successful")
|
||||
success.format_secondary_text("The app will now close. Please reopen to apply changes")
|
||||
success.run()
|
||||
success.destroy()
|
||||
exit(0)
|
||||
|
||||
def daemon_not_running(self):
|
||||
self.box = DaemonNotRunningView(self)
|
||||
self.add(self.box)
|
||||
|
||||
def build(self):
|
||||
if IS_INSTALLED_WITH_SNAP: self.snap()
|
||||
elif is_running("auto-cpufreq", "--daemon"): self.main()
|
||||
else: self.daemon_not_running()
|
||||
|
||||
def load_css(self):
|
||||
screen = Gdk.Screen.get_default()
|
||||
self.gtk_provider = Gtk.CssProvider()
|
||||
self.gtk_context = Gtk.StyleContext()
|
||||
self.gtk_context.add_provider_for_screen(screen, self.gtk_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
|
||||
self.gtk_provider.load_from_file(Gio.File.new_for_path(CSS_FILE))
|
||||
|
||||
def refresh_in_thread(self):
|
||||
Thread(target=self._refresh).start()
|
||||
return True
|
||||
|
||||
def _refresh(self):
|
||||
self.systemstats.refresh()
|
||||
self.currentgovernor.refresh()
|
||||
self.cpufreqstats.refresh()
|
||||
|
288
auto_cpufreq/gui/objects.py
Normal file
288
auto_cpufreq/gui/objects.py
Normal file
@ -0,0 +1,288 @@
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import GdkPixbuf, Gtk
|
||||
|
||||
import sys
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from io import StringIO
|
||||
from os.path import isfile
|
||||
from platform import python_version
|
||||
from subprocess import getoutput, PIPE, run
|
||||
|
||||
from auto_cpufreq.core import distro_info, get_formatted_version, get_override, sysinfo
|
||||
from auto_cpufreq.globals import GITHUB, IS_INSTALLED_WITH_AUR, IS_INSTALLED_WITH_SNAP
|
||||
|
||||
PKEXEC_ERROR = "Error executing command as another user: Not authorized\n\nThis incident has been reported.\n"
|
||||
|
||||
auto_cpufreq_stats_path = ("/var/snap/auto-cpufreq/current" if IS_INSTALLED_WITH_SNAP else "/var/run") + "/auto-cpufreq.stats"
|
||||
|
||||
def get_stats():
|
||||
if isfile(auto_cpufreq_stats_path):
|
||||
with open(auto_cpufreq_stats_path, "r") as file: stats = [line for line in (file.readlines() [-50:])]
|
||||
return "".join(stats)
|
||||
|
||||
def get_version():
|
||||
# snap package
|
||||
if IS_INSTALLED_WITH_SNAP: return getoutput(r"echo \(Snap\) $SNAP_VERSION")
|
||||
# aur package
|
||||
elif IS_INSTALLED_WITH_AUR: return getoutput("pacman -Qi auto-cpufreq | grep Version")
|
||||
else:
|
||||
# source code (auto-cpufreq-installer)
|
||||
try: return get_formatted_version()
|
||||
except Exception as e:
|
||||
print(repr(e))
|
||||
pass
|
||||
|
||||
class RadioButtonView(Gtk.Box):
|
||||
def __init__(self):
|
||||
super().__init__(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
|
||||
self.set_hexpand(True)
|
||||
self.hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
|
||||
self.label = Gtk.Label("Governor Override", name="bold")
|
||||
|
||||
self.default = Gtk.RadioButton.new_with_label_from_widget(None, "Default")
|
||||
self.default.connect("toggled", self.on_button_toggled, "reset")
|
||||
self.default.set_halign(Gtk.Align.END)
|
||||
self.powersave = Gtk.RadioButton.new_with_label_from_widget(self.default, "Powersave")
|
||||
self.powersave.connect("toggled", self.on_button_toggled, "powersave")
|
||||
self.powersave.set_halign(Gtk.Align.END)
|
||||
self.performance = Gtk.RadioButton.new_with_label_from_widget(self.default, "Performance")
|
||||
self.performance.connect("toggled", self.on_button_toggled, "performance")
|
||||
self.performance.set_halign(Gtk.Align.END)
|
||||
|
||||
# this keeps track of whether or not the button was toggled by the app or the user to prompt for authorization
|
||||
self.set_by_app = True
|
||||
self.set_selected()
|
||||
|
||||
self.pack_start(self.label, False, False, 0)
|
||||
self.pack_start(self.default, True, True, 0)
|
||||
self.pack_start(self.powersave, True, True, 0)
|
||||
self.pack_start(self.performance, True, True, 0)
|
||||
|
||||
def on_button_toggled(self, button, override):
|
||||
if button.get_active():
|
||||
if not self.set_by_app:
|
||||
result = run(f"pkexec auto-cpufreq --force={override}", shell=True, stdout=PIPE, stderr=PIPE)
|
||||
if result.stderr.decode() == PKEXEC_ERROR: self.set_selected()
|
||||
else: self.set_by_app = False
|
||||
|
||||
def set_selected(self):
|
||||
override = get_override()
|
||||
match override:
|
||||
case "powersave": self.powersave.set_active(True)
|
||||
case "performance": self.performance.set_active(True)
|
||||
case "default":
|
||||
# because this is the default button, it does not trigger the callback when set by the app
|
||||
if self.set_by_app: self.set_by_app = False
|
||||
self.default.set_active(True)
|
||||
|
||||
class CurrentGovernorBox(Gtk.Box):
|
||||
def __init__(self):
|
||||
super().__init__(spacing=25)
|
||||
self.static = Gtk.Label(label="Current Governor", name="bold")
|
||||
self.governor = Gtk.Label(label=getoutput("cpufreqctl.auto-cpufreq --governor").strip().split(" ")[0], halign=Gtk.Align.END)
|
||||
|
||||
self.pack_start(self.static, False, False, 0)
|
||||
self.pack_start(self.governor, False, False, 0)
|
||||
|
||||
def refresh(self):
|
||||
self.governor.set_label(getoutput("cpufreqctl.auto-cpufreq --governor").strip().split(" ")[0])
|
||||
|
||||
class SystemStatsLabel(Gtk.Label):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.refresh()
|
||||
|
||||
def refresh(self):
|
||||
# change stdout and store label text to file-like object
|
||||
old_stdout = sys.stdout
|
||||
text = StringIO()
|
||||
sys.stdout = text
|
||||
distro_info()
|
||||
sysinfo()
|
||||
self.set_label(text.getvalue())
|
||||
sys.stdout = old_stdout
|
||||
|
||||
class CPUFreqStatsLabel(Gtk.Label):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.refresh()
|
||||
|
||||
def refresh(self):
|
||||
stats = get_stats().split("\n")
|
||||
start = None
|
||||
for i, line in enumerate(stats):
|
||||
if line == ("-" * 28 + " CPU frequency scaling " + "-" * 28):
|
||||
start = i
|
||||
break
|
||||
if start is not None:
|
||||
del stats[:i]
|
||||
del stats[-4:]
|
||||
self.set_label("\n".join(stats))
|
||||
|
||||
class DropDownMenu(Gtk.MenuButton):
|
||||
def __init__(self, parent):
|
||||
super().__init__()
|
||||
self.set_halign(Gtk.Align.END)
|
||||
self.set_valign(Gtk.Align.START)
|
||||
self.image = Gtk.Image.new_from_icon_name("open-menu-symbolic", Gtk.IconSize.LARGE_TOOLBAR)
|
||||
self.add(self.image)
|
||||
self.menu = self.build_menu(parent)
|
||||
self.set_popup(self.menu)
|
||||
|
||||
def build_menu(self, parent):
|
||||
menu = Gtk.Menu()
|
||||
|
||||
daemon = Gtk.MenuItem(label="Remove Daemon")
|
||||
daemon.connect("activate", self._remove_daemon, parent)
|
||||
menu.append(daemon)
|
||||
|
||||
about = Gtk.MenuItem(label="About")
|
||||
about.connect("activate", self.about_dialog, parent)
|
||||
menu.append(about)
|
||||
|
||||
menu.show_all()
|
||||
return menu
|
||||
|
||||
def about_dialog(self, MenuItem, parent):
|
||||
dialog = AboutDialog(parent)
|
||||
response = dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
def _remove_daemon(self, MenuItem, parent):
|
||||
confirm = ConfirmDialog(parent, message="Are you sure you want to remove the daemon?")
|
||||
response = confirm.run()
|
||||
confirm.destroy()
|
||||
if response == Gtk.ResponseType.YES:
|
||||
try:
|
||||
# run in thread to prevent GUI from hanging
|
||||
with ThreadPoolExecutor() as executor:
|
||||
kwargs = {"shell": True, "stdout": PIPE, "stderr": PIPE}
|
||||
future = executor.submit(run, "pkexec auto-cpufreq --remove", **kwargs)
|
||||
result = future.result()
|
||||
assert result.stderr.decode() != PKEXEC_ERROR, Exception("Authorization was cancelled")
|
||||
dialog = Gtk.MessageDialog(
|
||||
transient_for=parent,
|
||||
message_type=Gtk.MessageType.INFO,
|
||||
buttons=Gtk.ButtonsType.OK,
|
||||
text="Daemon successfully removed"
|
||||
)
|
||||
dialog.format_secondary_text("The app will now close. Please reopen to apply changes")
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
parent.destroy()
|
||||
except Exception as e:
|
||||
dialog = Gtk.MessageDialog(
|
||||
transient_for=parent,
|
||||
message_type=Gtk.MessageType.ERROR,
|
||||
buttons=Gtk.ButtonsType.OK,
|
||||
text="Daemon removal failed"
|
||||
)
|
||||
dialog.format_secondary_text(f"The following error occured:\n{e}")
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
class AboutDialog(Gtk.Dialog):
|
||||
def __init__(self, parent):
|
||||
super().__init__(title="About", transient_for=parent)
|
||||
app_version = get_version()
|
||||
self.box = self.get_content_area()
|
||||
self.box.set_spacing(10)
|
||||
self.add_button("Close", Gtk.ResponseType.CLOSE)
|
||||
self.set_default_size(400, 350)
|
||||
img_buffer = GdkPixbuf.Pixbuf.new_from_file_at_scale(
|
||||
filename="/usr/local/share/auto-cpufreq/images/icon.png",
|
||||
width=150,
|
||||
height=150,
|
||||
preserve_aspect_ratio=True
|
||||
)
|
||||
self.image = Gtk.Image.new_from_pixbuf(img_buffer)
|
||||
self.title = Gtk.Label(label="auto-cpufreq", name="bold")
|
||||
self.version = Gtk.Label(label=app_version)
|
||||
self.python = Gtk.Label(label=f"Python {python_version()}")
|
||||
self.github = Gtk.Label(label=GITHUB)
|
||||
self.license = Gtk.Label(label="Licensed under LGPL3", name="small")
|
||||
self.love = Gtk.Label(label="Made with <3", name="small")
|
||||
|
||||
self.box.pack_start(self.image, False, False, 0)
|
||||
self.box.pack_start(self.title, False, False, 0)
|
||||
self.box.pack_start(self.version, False, False, 0)
|
||||
self.box.pack_start(self.python, False, False, 0)
|
||||
self.box.pack_start(self.github, False, False, 0)
|
||||
self.box.pack_start(self.license, False, False, 0)
|
||||
self.box.pack_start(self.love, False, False, 0)
|
||||
self.show_all()
|
||||
|
||||
class UpdateDialog(Gtk.Dialog):
|
||||
def __init__(self, parent, current_version: str, latest_version: str):
|
||||
super().__init__(title="Update Available", transient_for=parent)
|
||||
self.box = self.get_content_area()
|
||||
self.set_default_size(400, 100)
|
||||
self.add_buttons("Update", Gtk.ResponseType.YES, "Cancel", Gtk.ResponseType.NO)
|
||||
self.label = Gtk.Label(label="An update is available\n")
|
||||
self.current_version = Gtk.Label(label=current_version + "\n")
|
||||
self.latest_version = Gtk.Label(label=latest_version + "\n")
|
||||
|
||||
self.box.pack_start(self.label, True, False, 0)
|
||||
self.box.pack_start(self.current_version, True, False, 0)
|
||||
self.box.pack_start(self.latest_version, True, False, 0)
|
||||
|
||||
self.show_all()
|
||||
|
||||
class ConfirmDialog(Gtk.Dialog):
|
||||
def __init__(self, parent, message: str):
|
||||
super().__init__(title="Confirmation", transient_for=parent)
|
||||
self.box = self.get_content_area()
|
||||
self.set_default_size(400, 100)
|
||||
self.add_buttons("Yes", Gtk.ResponseType.YES, "No", Gtk.ResponseType.NO)
|
||||
self.label = Gtk.Label(label=message)
|
||||
|
||||
self.box.pack_start(self.label, True, False, 0)
|
||||
|
||||
self.show_all()
|
||||
|
||||
class DaemonNotRunningView(Gtk.Box):
|
||||
def __init__(self, parent):
|
||||
super().__init__(orientation=Gtk.Orientation.VERTICAL, spacing=10, halign=Gtk.Align.CENTER, valign=Gtk.Align.CENTER)
|
||||
|
||||
self.label = Gtk.Label(label="auto-cpufreq daemon is not running. Please click the install button")
|
||||
self.install_button = Gtk.Button.new_with_label("Install")
|
||||
|
||||
self.install_button.connect("clicked", self.install_daemon, parent)
|
||||
|
||||
self.pack_start(self.label, False, False, 0)
|
||||
self.pack_start(self.install_button, False, False, 0)
|
||||
|
||||
def install_daemon(self, button, parent):
|
||||
try:
|
||||
# run in thread to prevent GUI from hanging
|
||||
with ThreadPoolExecutor() as executor:
|
||||
kwargs = {"shell": True, "stdout": PIPE, "stderr": PIPE}
|
||||
future = executor.submit(run, "pkexec auto-cpufreq --install", **kwargs)
|
||||
result = future.result()
|
||||
assert result.stderr.decode() != PKEXEC_ERROR, Exception("Authorization was cancelled")
|
||||
# enable for debug. causes issues if kept
|
||||
# elif result.stderr is not None:
|
||||
# raise Exception(result.stderr.decode())
|
||||
dialog = Gtk.MessageDialog(
|
||||
transient_for=parent,
|
||||
message_type=Gtk.MessageType.INFO,
|
||||
buttons=Gtk.ButtonsType.OK,
|
||||
text="Daemon successfully installed"
|
||||
)
|
||||
dialog.format_secondary_text("The app will now close. Please reopen to apply changes")
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
parent.destroy()
|
||||
except Exception as e:
|
||||
dialog = Gtk.MessageDialog(
|
||||
transient_for=parent,
|
||||
message_type=Gtk.MessageType.ERROR,
|
||||
buttons=Gtk.ButtonsType.OK,
|
||||
text="Daemon install failed"
|
||||
)
|
||||
dialog.format_secondary_text(f"The following error occured:\n{e}")
|
||||
dialog.run()
|
||||
dialog.destroy()
|
28
auto_cpufreq/gui/tray.py
Normal file
28
auto_cpufreq/gui/tray.py
Normal file
@ -0,0 +1,28 @@
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, AppIndicator3 as appindicator
|
||||
|
||||
from subprocess import run
|
||||
|
||||
def main():
|
||||
indicator = appindicator.Indicator.new("auto-cpufreq-tray", "network-idle-symbolic", appindicator.IndicatorCategory.APPLICATION_STATUS)
|
||||
indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
|
||||
indicator.set_menu(build_menu())
|
||||
Gtk.main()
|
||||
|
||||
def build_menu():
|
||||
menu = Gtk.Menu()
|
||||
|
||||
program = Gtk.MenuItem("auto-cpufreq")
|
||||
program.connect("activate", open_app)
|
||||
menu.append(program)
|
||||
|
||||
_quit = Gtk.MenuItem("Quit")
|
||||
_quit.connect("activate", Gtk.main_quit)
|
||||
menu.append(_quit)
|
||||
menu.show_all()
|
||||
return menu
|
||||
|
||||
def open_app(MenuItem): run("sudo -E python app.py", shell=True)
|
||||
|
||||
if __name__ == "__main__": main()
|
337
auto_cpufreq/modules/system_info.py
Normal file
337
auto_cpufreq/modules/system_info.py
Normal file
@ -0,0 +1,337 @@
|
||||
from dataclasses import dataclass
|
||||
import os
|
||||
from pathlib import Path
|
||||
import platform
|
||||
from subprocess import getoutput
|
||||
from typing import Tuple, List
|
||||
import psutil
|
||||
import distro
|
||||
from pathlib import Path
|
||||
from auto_cpufreq.config.config import config
|
||||
from auto_cpufreq.core import get_power_supply_ignore_list
|
||||
from auto_cpufreq.globals import (
|
||||
AVAILABLE_GOVERNORS_SORTED,
|
||||
CPU_TEMP_SENSOR_PRIORITY,
|
||||
IS_INSTALLED_WITH_SNAP,
|
||||
POWER_SUPPLY_DIR,
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class CoreInfo:
|
||||
id: int
|
||||
usage: float
|
||||
temperature: float
|
||||
frequency: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class BatteryInfo:
|
||||
is_charging: bool | None
|
||||
is_ac_plugged: bool | None
|
||||
charging_start_threshold: int | None
|
||||
charging_stop_threshold: int | None
|
||||
battery_level: int | None
|
||||
power_consumption: float | None
|
||||
|
||||
def __repr__(self) -> str:
|
||||
if self.is_charging:
|
||||
return "charging"
|
||||
elif not self.is_ac_plugged:
|
||||
return f"discharging {('(' + '{:.2f}'.format(self.power_consumption) + ' W)') if self.power_consumption != None else ''}"
|
||||
return "Not Charging"
|
||||
|
||||
|
||||
@dataclass
|
||||
class SystemReport:
|
||||
distro_name: str
|
||||
distro_ver: str
|
||||
arch: str
|
||||
processor_model: str
|
||||
total_core: int | None
|
||||
kernel_version: str
|
||||
current_gov: str | None
|
||||
current_epp: str | None
|
||||
current_epb: str | None
|
||||
cpu_driver: str
|
||||
cpu_fan_speed: int | None
|
||||
cpu_usage: float
|
||||
cpu_max_freq: float | None
|
||||
cpu_min_freq: float | None
|
||||
load: float
|
||||
avg_load: Tuple[float, float, float] | None
|
||||
cores_info: list[CoreInfo]
|
||||
battery_info: BatteryInfo
|
||||
is_turbo_on: Tuple[bool | None, bool | None]
|
||||
|
||||
|
||||
class SystemInfo:
|
||||
"""
|
||||
Provides system information related to CPU, distribution, and performance metrics.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.distro_name: str = (
|
||||
distro.name(pretty=True) if not IS_INSTALLED_WITH_SNAP else "UNKNOWN"
|
||||
)
|
||||
self.distro_version: str = (
|
||||
distro.version() if not IS_INSTALLED_WITH_SNAP else "UNKNOWN"
|
||||
)
|
||||
self.architecture: str = platform.machine()
|
||||
self.processor_model: str = (
|
||||
getoutput("grep -E 'model name' /proc/cpuinfo -m 1").split(":")[-1].strip()
|
||||
)
|
||||
self.total_cores: int | None = psutil.cpu_count(logical=True)
|
||||
self.cpu_driver: str = getoutput(
|
||||
"cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver"
|
||||
).strip()
|
||||
self.kernel_version: str = platform.release()
|
||||
|
||||
@staticmethod
|
||||
def cpu_min_freq() -> float | None:
|
||||
freqs = psutil.cpu_freq(percpu=True)
|
||||
return min((freq.min for freq in freqs), default=None)
|
||||
|
||||
@staticmethod
|
||||
def cpu_max_freq() -> float | None:
|
||||
freqs = psutil.cpu_freq(percpu=True)
|
||||
return max((freq.max for freq in freqs), default=None)
|
||||
|
||||
@staticmethod
|
||||
def get_cpu_info() -> List[CoreInfo]:
|
||||
"""Returns detailed CPU information for each core."""
|
||||
cpu_usage = psutil.cpu_percent(percpu=True)
|
||||
cpu_freqs = psutil.cpu_freq(percpu=True)
|
||||
|
||||
try:
|
||||
temps = psutil.sensors_temperatures()
|
||||
temp_sensor = []
|
||||
for sensor in CPU_TEMP_SENSOR_PRIORITY:
|
||||
temp_sensor = temps.get(sensor, [])
|
||||
if temp_sensor != []:
|
||||
break
|
||||
|
||||
core_temps = [temp.current for temp in temp_sensor]
|
||||
except AttributeError:
|
||||
core_temps = []
|
||||
|
||||
avg_temp = sum(core_temps) / len(core_temps) if core_temps else 0.0
|
||||
|
||||
return [
|
||||
CoreInfo(
|
||||
id=i,
|
||||
usage=cpu_usage[i],
|
||||
temperature=core_temps[i] if i < len(core_temps) else avg_temp,
|
||||
frequency=cpu_freqs[i].current,
|
||||
)
|
||||
for i in range(len(cpu_usage))
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def cpu_fan_speed() -> int | None:
|
||||
fans = psutil.sensors_fans()
|
||||
return next((fan[0].current for fan in fans.values() if fan), None)
|
||||
|
||||
@staticmethod
|
||||
def current_gov() -> str | None:
|
||||
try:
|
||||
with open(
|
||||
"/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", "r"
|
||||
) as f:
|
||||
return f.read().strip()
|
||||
except:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def current_epp() -> str | None:
|
||||
epp_path = "/sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference"
|
||||
if not Path(epp_path).exists():
|
||||
return None
|
||||
return config.get_config().get(
|
||||
"battery", "energy_performance_preference", fallback="balance_power"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def current_epb() -> str | None:
|
||||
epb_path = "/sys/devices/system/cpu/intel_pstate"
|
||||
if not Path(epb_path).exists():
|
||||
return None
|
||||
return config.get_config().get(
|
||||
"battery", "energy_perf_bias", fallback="balance_power"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def cpu_usage() -> float:
|
||||
return psutil.cpu_percent(
|
||||
interval=0.5
|
||||
) # Reduced interval for better responsiveness
|
||||
|
||||
@staticmethod
|
||||
def system_load() -> float:
|
||||
return os.getloadavg()[0]
|
||||
|
||||
@staticmethod
|
||||
def avg_load() -> Tuple[float, float, float]:
|
||||
return os.getloadavg()
|
||||
|
||||
@staticmethod
|
||||
def avg_temp() -> int:
|
||||
temps: List[float] = [i.temperature for i in SystemInfo.get_cpu_info()]
|
||||
return int(sum(temps) / len(temps))
|
||||
|
||||
@staticmethod
|
||||
def turbo_on() -> Tuple[bool | None, bool | None]:
|
||||
"""Get CPU turbo mode status.
|
||||
|
||||
Returns: Tuple[bool | None, bool | None]:
|
||||
|
||||
The first value indicates whether turbo mode is enabled, None if unknown
|
||||
|
||||
The second value indicates whether auto mode is enabled (amd_pstate only), None if unknown
|
||||
"""
|
||||
intel_pstate = Path("/sys/devices/system/cpu/intel_pstate/no_turbo")
|
||||
cpu_freq = Path("/sys/devices/system/cpu/cpufreq/boost")
|
||||
amd_pstate = Path("/sys/devices/system/cpu/amd_pstate/status")
|
||||
|
||||
if intel_pstate.exists():
|
||||
control_file: Path = intel_pstate
|
||||
inverse_logic = True
|
||||
elif cpu_freq.exists():
|
||||
control_file = cpu_freq
|
||||
inverse_logic = False
|
||||
elif amd_pstate.exists():
|
||||
amd_status: str = amd_pstate.read_text().strip()
|
||||
if amd_status == "active":
|
||||
return None, True
|
||||
return None, False
|
||||
else:
|
||||
return None, None
|
||||
|
||||
try:
|
||||
current_value = int(control_file.read_text().strip())
|
||||
return bool(current_value) ^ inverse_logic, False
|
||||
except Exception as e:
|
||||
return None, None
|
||||
|
||||
@staticmethod
|
||||
def battery_info() -> BatteryInfo:
|
||||
def read_file(path: str) -> str | None:
|
||||
try:
|
||||
with open(path, "r") as f:
|
||||
return f.read().strip()
|
||||
except FileNotFoundError:
|
||||
return None
|
||||
|
||||
power_supplies: List[str] = sorted(os.listdir(POWER_SUPPLY_DIR))
|
||||
|
||||
if not power_supplies:
|
||||
return BatteryInfo(
|
||||
is_charging=None,
|
||||
is_ac_plugged=True,
|
||||
charging_start_threshold=None,
|
||||
charging_stop_threshold=None,
|
||||
battery_level=None,
|
||||
power_consumption=None,
|
||||
)
|
||||
|
||||
is_ac_plugged = None
|
||||
is_charging = None
|
||||
battery_level = None
|
||||
power_consumption = None
|
||||
charging_start_threshold = None
|
||||
charging_stop_threshold = None
|
||||
|
||||
for supply in power_supplies:
|
||||
if any(item in supply for item in get_power_supply_ignore_list()):
|
||||
continue
|
||||
|
||||
supply_type: str | None = read_file(f"{POWER_SUPPLY_DIR}{supply}/type")
|
||||
|
||||
if supply_type == "Mains":
|
||||
power_supply_online: str | None = read_file(
|
||||
f"{POWER_SUPPLY_DIR}{supply}/online"
|
||||
)
|
||||
is_ac_plugged = power_supply_online == "1"
|
||||
|
||||
elif supply_type == "Battery":
|
||||
battery_status: str | None = read_file(
|
||||
f"{POWER_SUPPLY_DIR}{supply}/status"
|
||||
)
|
||||
battery_percentage: str | None = read_file(
|
||||
f"{POWER_SUPPLY_DIR}{supply}/capacity"
|
||||
)
|
||||
energy_rate: str | None = read_file(
|
||||
f"{POWER_SUPPLY_DIR}{supply}/power_now"
|
||||
)
|
||||
charge_start_threshold: str | None = read_file(
|
||||
f"{POWER_SUPPLY_DIR}{supply}/charge_start_threshold"
|
||||
)
|
||||
charge_stop_threshold: str | None = read_file(
|
||||
f"{POWER_SUPPLY_DIR}{supply}/charge_stop_threshold"
|
||||
)
|
||||
|
||||
is_charging: bool | None = (
|
||||
battery_status.lower() == "charging" if battery_status else None
|
||||
)
|
||||
battery_level: int | None = (
|
||||
int(battery_percentage) if battery_percentage else None
|
||||
)
|
||||
power_consumption: float | None = (
|
||||
float(energy_rate) / 1_000_000 if energy_rate else None
|
||||
)
|
||||
charging_start_threshold: int | None = (
|
||||
int(charge_start_threshold) if charge_start_threshold else None
|
||||
)
|
||||
charging_stop_threshold: int | None = (
|
||||
int(charge_stop_threshold) if charge_stop_threshold else None
|
||||
)
|
||||
|
||||
return BatteryInfo(
|
||||
is_charging=is_charging,
|
||||
is_ac_plugged=is_ac_plugged,
|
||||
charging_start_threshold=charging_start_threshold,
|
||||
charging_stop_threshold=charging_stop_threshold,
|
||||
battery_level=battery_level,
|
||||
power_consumption=power_consumption,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def turbo_on_suggestion() -> bool:
|
||||
usage = SystemInfo.cpu_usage()
|
||||
if usage >= 20.0:
|
||||
return True
|
||||
elif usage <= 25 and SystemInfo.avg_temp() >= 70:
|
||||
return False
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def governor_suggestion() -> str:
|
||||
if SystemInfo.battery_info().is_ac_plugged:
|
||||
return AVAILABLE_GOVERNORS_SORTED[0]
|
||||
return AVAILABLE_GOVERNORS_SORTED[-1]
|
||||
|
||||
def generate_system_report(self) -> SystemReport:
|
||||
return SystemReport(
|
||||
distro_name=self.distro_name,
|
||||
distro_ver=self.distro_version,
|
||||
arch=self.architecture,
|
||||
processor_model=self.processor_model,
|
||||
total_core=self.total_cores,
|
||||
cpu_driver=self.cpu_driver,
|
||||
kernel_version=self.kernel_version,
|
||||
current_gov=self.current_gov(),
|
||||
current_epp=self.current_epp(),
|
||||
current_epb=self.current_epb(),
|
||||
cpu_fan_speed=self.cpu_fan_speed(),
|
||||
cpu_usage=self.cpu_usage(),
|
||||
cpu_max_freq=self.cpu_max_freq(),
|
||||
cpu_min_freq=self.cpu_min_freq(),
|
||||
load=self.system_load(),
|
||||
avg_load=self.avg_load(),
|
||||
cores_info=self.get_cpu_info(),
|
||||
is_turbo_on=self.turbo_on(),
|
||||
battery_info=self.battery_info(),
|
||||
)
|
||||
|
||||
|
||||
system_info = SystemInfo()
|
301
auto_cpufreq/modules/system_monitor.py
Normal file
301
auto_cpufreq/modules/system_monitor.py
Normal file
@ -0,0 +1,301 @@
|
||||
import sys
|
||||
from typing import Callable
|
||||
import urwid
|
||||
import time
|
||||
from .system_info import SystemReport, system_info
|
||||
from auto_cpufreq.config.config import config
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class ViewType(str, Enum):
|
||||
STATS = "Stats"
|
||||
MONITOR = "Monitor"
|
||||
LIVE = "Live"
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.value
|
||||
|
||||
|
||||
class SystemMonitor:
|
||||
def __init__(self, type: ViewType, suggestion: bool = False):
|
||||
self.type: ViewType = type
|
||||
self.title_header = urwid.Text(f"{type} Mode", align="center")
|
||||
self.header = urwid.Columns(
|
||||
[
|
||||
self.title_header,
|
||||
]
|
||||
)
|
||||
|
||||
# Create separate content walkers for left and right columns
|
||||
self.left_content = urwid.SimpleListWalker([])
|
||||
self.right_content = urwid.SimpleListWalker([])
|
||||
|
||||
# Create listboxes for both columns
|
||||
self.left_listbox = urwid.ListBox(self.left_content)
|
||||
self.right_listbox = urwid.ListBox(self.right_content)
|
||||
|
||||
# Create a columns widget with a vertical line (using box drawing character)
|
||||
self.columns = urwid.Columns(
|
||||
[
|
||||
("weight", 1, self.left_listbox),
|
||||
(
|
||||
"fixed",
|
||||
1,
|
||||
urwid.AttrMap(urwid.SolidFill("│"), "divider"),
|
||||
), # Vertical line # type: ignore
|
||||
("weight", 1, self.right_listbox),
|
||||
],
|
||||
dividechars=0,
|
||||
)
|
||||
|
||||
self.footer = urwid.AttrMap(
|
||||
urwid.Text(
|
||||
"Press Q or Ctrl+C to quit | Use ↑↓ or PageUp/PageDown to scroll",
|
||||
align="center",
|
||||
),
|
||||
"footer",
|
||||
)
|
||||
|
||||
self.frame = urwid.Frame(
|
||||
body=self.columns,
|
||||
header=urwid.AttrMap(self.header, "header"),
|
||||
footer=self.footer,
|
||||
)
|
||||
|
||||
palette = [
|
||||
("header", "white", "dark blue"),
|
||||
("footer", "white", "dark green"),
|
||||
("body", "white", "default"),
|
||||
("divider", "light gray", "default"), # Style for the vertical line
|
||||
]
|
||||
|
||||
if suggestion:
|
||||
palette.append(("suggestion", "yellow", "default"))
|
||||
|
||||
self.loop = urwid.MainLoop(
|
||||
self.frame, palette=palette, unhandled_input=self.handle_input
|
||||
)
|
||||
|
||||
self.last_focus_left = 0
|
||||
self.last_focus_right = 0
|
||||
self.on_quit: Callable[[], None] | None = None
|
||||
self.suggestion = suggestion
|
||||
|
||||
def update(self, loop: urwid.MainLoop, user_data: dict) -> None:
|
||||
# Store current focus positions
|
||||
if len(self.left_content) > 0:
|
||||
_, self.last_focus_left = self.left_listbox.get_focus()
|
||||
if self.last_focus_left is None:
|
||||
self.last_focus_left = 0
|
||||
if len(self.right_content) > 0:
|
||||
_, self.last_focus_right = self.right_listbox.get_focus()
|
||||
if self.last_focus_right is None:
|
||||
self.last_focus_right = 0
|
||||
|
||||
current_time = time.strftime("%H:%M:%S")
|
||||
self.title_header.set_text(f"{self.type} Mode - {current_time}")
|
||||
|
||||
report: SystemReport = system_info.generate_system_report()
|
||||
self.format_system_info(report)
|
||||
|
||||
# Restore focus positions
|
||||
if len(self.left_content) > 0:
|
||||
self.left_listbox.set_focus(min(self.last_focus_left, len(self.left_content) - 1)) # type: ignore
|
||||
if len(self.right_content) > 0:
|
||||
self.right_listbox.set_focus(min(self.last_focus_right, len(self.right_content) - 1)) # type: ignore
|
||||
|
||||
self.loop.set_alarm_in(2, self.update) # type: ignore
|
||||
|
||||
def handle_input(self, key):
|
||||
if key in ("q", "Q"):
|
||||
if self.on_quit:
|
||||
self.on_quit()
|
||||
raise urwid.ExitMainLoop()
|
||||
|
||||
def format_system_info(self, report: SystemReport):
|
||||
self.left_content.clear()
|
||||
self.right_content.clear()
|
||||
|
||||
# Helper function to create centered text
|
||||
def aligned_text(text: str) -> urwid.Text:
|
||||
return urwid.Text(text, align="left")
|
||||
|
||||
# Left Column - System Info and CPU Stats
|
||||
self.left_content.extend(
|
||||
[
|
||||
urwid.AttrMap(aligned_text("System Information"), "header"),
|
||||
aligned_text(""),
|
||||
aligned_text(f"Linux distro: {report.distro_name} {report.distro_ver}"),
|
||||
aligned_text(f"Linux kernel: {report.kernel_version}"),
|
||||
aligned_text(f"Processor: {report.processor_model}"),
|
||||
aligned_text(f"Cores: {report.total_core}"),
|
||||
aligned_text(f"Architecture: {report.arch}"),
|
||||
aligned_text(f"Driver: {report.cpu_driver}"),
|
||||
aligned_text(""),
|
||||
]
|
||||
)
|
||||
|
||||
if config.has_config():
|
||||
self.left_content.append(
|
||||
aligned_text(f"Using settings defined in {config.path} file")
|
||||
)
|
||||
self.left_content.append(aligned_text(""))
|
||||
|
||||
# CPU Stats
|
||||
self.left_content.extend(
|
||||
[
|
||||
urwid.AttrMap(aligned_text("Current CPU Stats"), "header"),
|
||||
aligned_text(""),
|
||||
aligned_text(f"CPU max frequency: {report.cpu_max_freq} MHz"),
|
||||
aligned_text(f"CPU min frequency: {report.cpu_min_freq} MHz"),
|
||||
aligned_text(""),
|
||||
aligned_text("Core Usage Temperature Frequency"),
|
||||
]
|
||||
)
|
||||
|
||||
for core in report.cores_info:
|
||||
self.left_content.append(
|
||||
aligned_text(
|
||||
f"CPU{core.id:<2} {core.usage:>4.1f}% {core.temperature:>6.0f} °C {core.frequency:>6.0f} MHz"
|
||||
)
|
||||
)
|
||||
|
||||
if report.cpu_fan_speed:
|
||||
self.left_content.append(aligned_text(""))
|
||||
self.left_content.append(
|
||||
aligned_text(f"CPU fan speed: {report.cpu_fan_speed} RPM")
|
||||
)
|
||||
|
||||
# Right Column - Battery, Frequency Scaling, and System Stats
|
||||
if report.battery_info != None:
|
||||
self.right_content.extend(
|
||||
[
|
||||
urwid.AttrMap(aligned_text("Battery Stats"), "header"),
|
||||
aligned_text(""),
|
||||
aligned_text(f"Battery status: {str(report.battery_info)}"),
|
||||
aligned_text(
|
||||
f"Battery precentage: {(str(report.battery_info.battery_level) + '%') if report.battery_info.battery_level != None else 'Unknown'}"
|
||||
),
|
||||
aligned_text(
|
||||
f'AC plugged: {("Yes" if report.battery_info.is_ac_plugged else "No") if report.battery_info.is_ac_plugged != None else "Unknown"}'
|
||||
),
|
||||
aligned_text(
|
||||
f'Charging start threshold: {report.battery_info.charging_start_threshold if report.battery_info.is_ac_plugged != None else "Unknown"}'
|
||||
),
|
||||
aligned_text(
|
||||
f'Charging stop threshold: {report.battery_info.charging_stop_threshold if report.battery_info.is_ac_plugged != None else "Unknown"}'
|
||||
),
|
||||
aligned_text(""),
|
||||
]
|
||||
)
|
||||
|
||||
# CPU Frequency Scaling
|
||||
self.right_content.extend(
|
||||
[
|
||||
urwid.AttrMap(aligned_text("CPU Frequency Scaling"), "header"),
|
||||
aligned_text(""),
|
||||
aligned_text(
|
||||
f'Setting to use: "{report.current_gov if report.current_gov != None else "Unknown"}" governor'
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
if (
|
||||
self.suggestion
|
||||
and report.current_gov != None
|
||||
and system_info.governor_suggestion() != report.current_gov
|
||||
):
|
||||
self.right_content.append(
|
||||
urwid.AttrMap(
|
||||
aligned_text(
|
||||
f'Suggesting use of: "{system_info.governor_suggestion()}" governor'
|
||||
),
|
||||
"suggestion",
|
||||
)
|
||||
)
|
||||
|
||||
if report.current_epp:
|
||||
self.right_content.append(
|
||||
aligned_text(f"EPP setting: {report.current_epp}")
|
||||
)
|
||||
else:
|
||||
self.right_content.append(
|
||||
aligned_text("Not setting EPP (not supported by system)")
|
||||
)
|
||||
|
||||
if report.current_epb:
|
||||
self.right_content.append(
|
||||
aligned_text(f'Setting to use: "{report.current_epb}" EPB')
|
||||
)
|
||||
|
||||
self.right_content.append(aligned_text(""))
|
||||
|
||||
# System Statistics
|
||||
self.right_content.extend(
|
||||
[
|
||||
urwid.AttrMap(aligned_text("System Statistics"), "header"),
|
||||
aligned_text(""),
|
||||
aligned_text(f"Total CPU usage: {report.cpu_usage:.1f} %"),
|
||||
aligned_text(f"Total system load: {report.load:.2f}"),
|
||||
]
|
||||
)
|
||||
|
||||
if report.cores_info:
|
||||
avg_temp = sum(core.temperature for core in report.cores_info) / len(
|
||||
report.cores_info
|
||||
)
|
||||
self.right_content.append(
|
||||
aligned_text(f"Average temp. of all cores: {avg_temp:.2f} °C")
|
||||
)
|
||||
|
||||
if report.avg_load:
|
||||
load_status = "Load optimal" if report.load < 1.0 else "Load high"
|
||||
self.right_content.append(
|
||||
aligned_text(
|
||||
f"{load_status} (load average: {report.avg_load[0]:.2f}, {report.avg_load[1]:.2f}, {report.avg_load[2]:.2f})"
|
||||
)
|
||||
)
|
||||
|
||||
if report.cores_info:
|
||||
usage_status = "Optimal" if report.cpu_usage < 70 else "High"
|
||||
temp_status = "high" if avg_temp > 75 else "normal" # type: ignore
|
||||
self.right_content.append(
|
||||
aligned_text(
|
||||
f"{usage_status} total CPU usage: {report.cpu_usage:.1f}%, {temp_status} average core temp: {avg_temp:.1f}°C" # type: ignore
|
||||
)
|
||||
)
|
||||
|
||||
turbo_status: str
|
||||
if report.is_turbo_on[0] != None:
|
||||
turbo_status = "On" if report.is_turbo_on[0] else "Off"
|
||||
elif report.is_turbo_on[1] != None:
|
||||
turbo_status = (
|
||||
f"Auto mode {'enabled' if report.is_turbo_on[1] else 'disabled'}"
|
||||
)
|
||||
else:
|
||||
turbo_status = "Unknown"
|
||||
self.right_content.append(aligned_text(f"Setting turbo boost: {turbo_status}"))
|
||||
if (
|
||||
self.suggestion
|
||||
and report.is_turbo_on[0] != None
|
||||
and system_info.turbo_on_suggestion() != report.is_turbo_on[0]
|
||||
):
|
||||
self.right_content.append(
|
||||
urwid.AttrMap(
|
||||
aligned_text(
|
||||
f'Suggesting to set turbo boost: {"on" if system_info.turbo_on_suggestion() else "off"}'
|
||||
),
|
||||
"suggestion",
|
||||
)
|
||||
)
|
||||
|
||||
def run(self, on_quit: Callable[[], None] | None = None):
|
||||
try:
|
||||
if on_quit:
|
||||
self.on_quit = on_quit
|
||||
self.loop.set_alarm_in(0, self.update) # type: ignore
|
||||
self.loop.run()
|
||||
except KeyboardInterrupt:
|
||||
if on_quit:
|
||||
on_quit()
|
||||
sys.exit(0)
|
@ -1,50 +1,40 @@
|
||||
# * add status as one of the available options
|
||||
# * alert user on snap if detected and how to remove first time live/stats message starts
|
||||
# * if daemon is disabled and auto-cpufreq is removed (snap) remind user to enable it back
|
||||
from logging import root
|
||||
import os, sys, click, subprocess
|
||||
from subprocess import getoutput, call, run, check_output, DEVNULL
|
||||
import click
|
||||
from shutil import which
|
||||
from subprocess import call, DEVNULL, getoutput, STDOUT
|
||||
from sys import argv
|
||||
|
||||
sys.path.append("../")
|
||||
from auto_cpufreq.core import *
|
||||
from auto_cpufreq.globals import GITHUB, IS_INSTALLED_WITH_SNAP
|
||||
from auto_cpufreq.tlp_stat_parser import TLPStatusParser
|
||||
|
||||
# app_name var
|
||||
if sys.argv[0] == "power_helper.py":
|
||||
app_name = "python3 power_helper.py"
|
||||
else:
|
||||
app_name = "auto-cpufreq"
|
||||
app_name = "python3 power_helper.py" if argv[0] == "power_helper.py" else "auto-cpufreq"
|
||||
|
||||
def header(): print("\n------------------------- auto-cpufreq: Power helper -------------------------\n")
|
||||
def warning(): print("\n----------------------------------- Warning -----------------------------------\n")
|
||||
|
||||
def header():
|
||||
print("\n------------------------- auto-cpufreq: Power helper -------------------------\n")
|
||||
|
||||
|
||||
def helper_opts():
|
||||
print("\nFor full list of options run: python3 power_helper.py --help")
|
||||
|
||||
def helper_opts(): print("\nFor full list of options run: python3 power_helper.py --help")
|
||||
|
||||
# used to check if binary exists on the system
|
||||
def does_command_exists(cmd):
|
||||
return which(cmd) is not None
|
||||
def does_command_exists(cmd): return which(cmd) is not None
|
||||
|
||||
|
||||
systemctl_exists = does_command_exists("systemctl")
|
||||
bluetoothctl_exists = does_command_exists("bluetoothctl")
|
||||
tlp_stat_exists = does_command_exists("tlp-stat")
|
||||
powerprofilesctl_exists = does_command_exists("powerprofilesctl")
|
||||
systemctl_exists = does_command_exists("systemctl")
|
||||
tlp_stat_exists = does_command_exists("tlp-stat")
|
||||
tuned_stat_exists = does_command_exists("tuned")
|
||||
|
||||
# detect if gnome power profile service is running
|
||||
if os.getenv("PKG_MARKER") != "SNAP":
|
||||
if not IS_INSTALLED_WITH_SNAP:
|
||||
if systemctl_exists:
|
||||
try:
|
||||
gnome_power_status = call(
|
||||
["systemctl", "is-active", "--quiet", "power-profiles-daemon"]
|
||||
)
|
||||
try: gnome_power_status = call(["systemctl", "is-active", "--quiet", "power-profiles-daemon"])
|
||||
except:
|
||||
print("\nUnable to determine init system")
|
||||
print("If this causes any problems, please submit an issue:")
|
||||
print("https://github.com/AdnanHodzic/auto-cpufreq/issues")
|
||||
print(GITHUB+"/issues")
|
||||
|
||||
# alert in case TLP service is running
|
||||
def tlp_service_detect():
|
||||
@ -52,93 +42,99 @@ def tlp_service_detect():
|
||||
status_output = getoutput("tlp-stat -s")
|
||||
tlp_status = TLPStatusParser(status_output)
|
||||
if tlp_status.is_enabled():
|
||||
print(
|
||||
"\n----------------------------------- Warning -----------------------------------\n"
|
||||
)
|
||||
warning()
|
||||
print("Detected you are running a TLP service!")
|
||||
print(
|
||||
"This daemon might interfere with auto-cpufreq which can lead to unexpected results."
|
||||
)
|
||||
print(
|
||||
"We strongly encourage you to remove TLP unless you really know what you are doing."
|
||||
)
|
||||
|
||||
print("This daemon might interfere with auto-cpufreq which can lead to unexpected results.")
|
||||
print("We strongly encourage you to remove TLP unless you really know what you are doing.")
|
||||
|
||||
# alert about TLP when using snap
|
||||
def tlp_service_detect_snap():
|
||||
print("\n----------------------------------- Warning -----------------------------------\n")
|
||||
warning()
|
||||
print("Unable to detect if you are using a TLP service!")
|
||||
print("This daemon might interfere with auto-cpufreq which can lead to unexpected results.")
|
||||
print("We strongly encourage you not to use TLP unless you really know what you are doing.")
|
||||
|
||||
|
||||
# alert in case gnome power profile service is running
|
||||
def gnome_power_detect():
|
||||
if systemctl_exists:
|
||||
if gnome_power_status == 0:
|
||||
print(
|
||||
"\n----------------------------------- Warning -----------------------------------\n"
|
||||
)
|
||||
print("Detected running GNOME Power Profiles daemon service!")
|
||||
print("This daemon might interfere with auto-cpufreq and should be disabled.")
|
||||
print("\nSteps to perform this action using auto-cpufreq: power_helper script:")
|
||||
print("git clone https://github.com/AdnanHodzic/auto-cpufreq.git")
|
||||
print("cd auto-cpufreq/auto_cpufreq")
|
||||
print("python3 power_helper.py --gnome_power_disable")
|
||||
print("\nReference: https://github.com/AdnanHodzic/auto-cpufreq#configuring-auto-cpufreq")
|
||||
|
||||
if systemctl_exists and not bool(gnome_power_status):
|
||||
warning()
|
||||
print("Detected running GNOME Power Profiles daemon service!")
|
||||
print("\nThis daemon might interfere with auto-cpufreq and will be automatically")
|
||||
print("disabled when auto-cpufreq daemon is installed and")
|
||||
print("it will be re-enabled after auto-cpufreq is removed.")
|
||||
|
||||
print("\nOnly necessary to be manually done on Snap package installs!")
|
||||
print("Steps to perform this action using auto-cpufreq: power_helper script:")
|
||||
print(f"git clone {GITHUB}.git")
|
||||
print("cd auto-cpufreq/auto_cpufreq")
|
||||
print("python3 power_helper.py --gnome_power_disable")
|
||||
print(f"\nReference: {GITHUB}#configuring-auto-cpufreq")
|
||||
|
||||
# automatically disable gnome power profile service in case it's running during install
|
||||
def gnome_power_detect_install():
|
||||
if systemctl_exists:
|
||||
if gnome_power_status == 0:
|
||||
print(
|
||||
"\n----------------------------------- Warning -----------------------------------\n"
|
||||
)
|
||||
print("Detected running GNOME Power Profiles daemon service!")
|
||||
print("This daemon might interfere with auto-cpufreq and has been disabled.\n")
|
||||
print('This daemon is not automatically disabled in "monitor" mode and')
|
||||
print("will be enabled after auto-cpufreq is removed.\n")
|
||||
if systemctl_exists and not bool(gnome_power_status):
|
||||
warning()
|
||||
print("Detected running GNOME Power Profiles daemon service!")
|
||||
print("\nThis daemon might interfere with auto-cpufreq and has been disabled.\n")
|
||||
print('This daemon is not automatically disabled in "monitor" mode and')
|
||||
print("will be enabled after auto-cpufreq daemon is removed.")
|
||||
|
||||
|
||||
# notification on snap
|
||||
def gnome_power_detect_snap():
|
||||
print("\n----------------------------------- Warning -----------------------------------\n")
|
||||
warning()
|
||||
print("Due to Snap package confinement limitations please consider installing auto-cpufreq using")
|
||||
print(f"auto-cpufreq-installer: {GITHUB}#auto-cpufreq-installer")
|
||||
print()
|
||||
print("Unable to detect state of GNOME Power Profiles daemon service!")
|
||||
print("This daemon might interfere with auto-cpufreq and should be disabled.")
|
||||
print("This daemon might interfere with auto-cpufreq and should be disabled!")
|
||||
print("\nSteps to perform this action using auto-cpufreq: power_helper script:")
|
||||
print("git clone https://github.com/AdnanHodzic/auto-cpufreq.git")
|
||||
print(f"git clone {GITHUB}.git")
|
||||
print("cd auto-cpufreq/auto_cpufreq")
|
||||
print("python3 power_helper.py --gnome_power_disable")
|
||||
print("\nReference: https://github.com/AdnanHodzic/auto-cpufreq#configuring-auto-cpufreq")
|
||||
|
||||
print(f"\nReference: {GITHUB}#configuring-auto-cpufreq")
|
||||
|
||||
# stops gnome >= 40 power profiles (live)
|
||||
def gnome_power_stop_live():
|
||||
if systemctl_exists:
|
||||
if gnome_power_status == 0 and powerprofilesctl_exists:
|
||||
call(["powerprofilesctl", "set", "balanced"])
|
||||
call(["systemctl", "stop", "power-profiles-daemon"])
|
||||
if systemctl_exists and not bool(gnome_power_status) and powerprofilesctl_exists:
|
||||
call(["powerprofilesctl", "set", "balanced"])
|
||||
call(["systemctl", "stop", "power-profiles-daemon"])
|
||||
|
||||
# stops tuned (live)
|
||||
def tuned_stop_live():
|
||||
if systemctl_exists and tuned_stat_exists:
|
||||
call(["systemctl", "stop", "tuned"])
|
||||
|
||||
# starts gnome >= 40 power profiles (live)
|
||||
def gnome_power_start_live():
|
||||
if systemctl_exists:
|
||||
call(["systemctl", "start", "power-profiles-daemon"])
|
||||
if systemctl_exists: call(["systemctl", "start", "power-profiles-daemon"])
|
||||
|
||||
def tuned_start_live():
|
||||
if systemctl_exists and tuned_stat_exists:
|
||||
call(["systemctl", "start", "tuned"])
|
||||
|
||||
# enable gnome >= 40 power profiles (uninstall)
|
||||
def gnome_power_svc_enable():
|
||||
if systemctl_exists:
|
||||
try:
|
||||
print("\n* Enabling GNOME power profiles")
|
||||
print("* Enabling GNOME power profiles\n")
|
||||
call(["systemctl", "unmask", "power-profiles-daemon"])
|
||||
call(["systemctl", "start", "power-profiles-daemon"])
|
||||
call(["systemctl", "enable", "power-profiles-daemon"])
|
||||
call(["systemctl", "daemon-reload"])
|
||||
call(["systemctl", "enable", "--now", "power-profiles-daemon"])
|
||||
except:
|
||||
print("\nUnable to enable GNOME power profiles")
|
||||
print("If this causes any problems, please submit an issue:")
|
||||
print("https://github.com/AdnanHodzic/auto-cpufreq/issues")
|
||||
print(GITHUB+"/issues")
|
||||
|
||||
def tuned_svc_enable():
|
||||
if systemctl_exists and tuned_stat_exists:
|
||||
try:
|
||||
print("* Enabling TuneD\n")
|
||||
call(["systemctl", "unmask", "tuned"])
|
||||
call(["systemctl", "enable", "--now", "tuned"])
|
||||
except:
|
||||
print("\nUnable to enable TuneD daemon")
|
||||
print("If this causes any problems, please submit an issue:")
|
||||
print(GITHUB+"/issues")
|
||||
|
||||
# gnome power profiles current status
|
||||
def gnome_power_svc_status():
|
||||
@ -149,15 +145,13 @@ def gnome_power_svc_status():
|
||||
except:
|
||||
print("\nUnable to see GNOME power profiles status")
|
||||
print("If this causes any problems, please submit an issue:")
|
||||
print("https://github.com/AdnanHodzic/auto-cpufreq/issues")
|
||||
|
||||
print(GITHUB+"/issues")
|
||||
|
||||
# disable bluetooth on boot
|
||||
def bluetooth_disable():
|
||||
if os.getenv("PKG_MARKER") == "SNAP":
|
||||
bluetooth_notif_snap()
|
||||
if IS_INSTALLED_WITH_SNAP: bluetooth_notif_snap()
|
||||
elif bluetoothctl_exists:
|
||||
print("* Turn off bluetooth on boot")
|
||||
print("* Turn off bluetooth on boot (can be turned on any time later on!)")
|
||||
btconf = Path("/etc/bluetooth/main.conf")
|
||||
try:
|
||||
orig_set = "AutoEnable=true"
|
||||
@ -167,18 +161,12 @@ def bluetooth_disable():
|
||||
f.seek(0)
|
||||
f.truncate()
|
||||
f.write(content.replace(orig_set, change_set))
|
||||
except Exception as e:
|
||||
print(f"\nERROR:\nWas unable to turn off bluetooth on boot\n{repr(e)}")
|
||||
else:
|
||||
print(
|
||||
"* Turn off bluetooth on boot [skipping] (package providing bluetooth access is not present)"
|
||||
)
|
||||
|
||||
except Exception as e: print(f"\nERROR:\nWas unable to turn off bluetooth on boot\n{repr(e)}")
|
||||
else: print("* Turn off bluetooth on boot [skipping] (package providing bluetooth access is not present)")
|
||||
|
||||
# enable bluetooth on boot
|
||||
def bluetooth_enable():
|
||||
if os.getenv("PKG_MARKER") == "SNAP":
|
||||
bluetooth_on_notif_snap()
|
||||
if IS_INSTALLED_WITH_SNAP: bluetooth_on_notif_snap()
|
||||
if bluetoothctl_exists:
|
||||
print("* Turn on bluetooth on boot")
|
||||
btconf = "/etc/bluetooth/main.conf"
|
||||
@ -190,13 +178,8 @@ def bluetooth_enable():
|
||||
f.seek(0)
|
||||
f.truncate()
|
||||
f.write(content.replace(change_set, orig_set))
|
||||
except Exception as e:
|
||||
print(f"\nERROR:\nWas unable to turn on bluetooth on boot\n{repr(e)}")
|
||||
else:
|
||||
print(
|
||||
"* Turn on bluetooth on boot [skipping] (package providing bluetooth access is not present)"
|
||||
)
|
||||
|
||||
except Exception as e: print(f"\nERROR:\nWas unable to turn on bluetooth on boot\n{repr(e)}")
|
||||
else: print("* Turn on bluetooth on boot [skipping] (package providing bluetooth access is not present)")
|
||||
|
||||
# turn off bluetooth on snap message
|
||||
def bluetooth_notif_snap():
|
||||
@ -204,201 +187,126 @@ def bluetooth_notif_snap():
|
||||
print("\nSteps to perform this action using auto-cpufreq: power_helper script:")
|
||||
print("python3 power_helper.py --bluetooth_boot_off")
|
||||
|
||||
|
||||
# turn off bluetooth on snap message
|
||||
def bluetooth_on_notif_snap():
|
||||
print("\n* Unable to turn on bluetooth on boot due to Snap package restrictions!")
|
||||
print("\nSteps to perform this action using auto-cpufreq: power_helper script:")
|
||||
print("python3 power_helper.py --bluetooth_boot_on")
|
||||
|
||||
|
||||
# gnome power removal reminder
|
||||
def gnome_power_rm_reminder():
|
||||
if systemctl_exists:
|
||||
if gnome_power_status != 0:
|
||||
print(
|
||||
"\n----------------------------------- Warning -----------------------------------\n"
|
||||
)
|
||||
print("Detected GNOME Power Profiles daemon service is stopped!")
|
||||
print("This service will now be enabled and started again.")
|
||||
if systemctl_exists and bool(gnome_power_status):
|
||||
warning()
|
||||
print("Detected GNOME Power Profiles daemon service is stopped!")
|
||||
print("This service will now be enabled and started again.\n")
|
||||
|
||||
|
||||
def gnome_power_rm_reminder_snap():
|
||||
print("\n----------------------------------- Warning -----------------------------------\n")
|
||||
warning()
|
||||
print("Unable to detect state of GNOME Power Profiles daemon service!")
|
||||
print("Now it's recommended to enable this service.")
|
||||
print("\nSteps to perform this action using auto-cpufreq: power_helper script:")
|
||||
print("git clone https://github.com/AdnanHodzic/auto-cpufreq.git")
|
||||
print(f"git clone {GITHUB}.git")
|
||||
print("cd auto-cpufreq/auto_cpufreq")
|
||||
print("python3 power_helper.py --gnome_power_enable")
|
||||
print("\nReference: https://github.com/AdnanHodzic/auto-cpufreq#configuring-auto-cpufreq")
|
||||
|
||||
|
||||
print(f"\nReference: {GITHUB}#configuring-auto-cpufreq")
|
||||
|
||||
def valid_options():
|
||||
print("--gnome_power_enable\t\tEnable GNOME Power Profiles daemon")
|
||||
print("--gnome_power_disable\t\tDisable GNOME Power Profiles daemon\n")
|
||||
|
||||
|
||||
def disable_power_profiles_daemon():
|
||||
# always disable power-profiles-daemon
|
||||
try:
|
||||
print("\n* Disabling GNOME power profiles")
|
||||
call(["systemctl", "stop", "power-profiles-daemon"])
|
||||
call(["systemctl", "disable", "power-profiles-daemon"])
|
||||
call(["systemctl", "disable", "--now", "power-profiles-daemon"])
|
||||
call(["systemctl", "mask", "power-profiles-daemon"])
|
||||
call(["systemctl", "daemon-reload"])
|
||||
except:
|
||||
print("\nUnable to disable GNOME power profiles")
|
||||
print("If this causes any problems, please submit an issue:")
|
||||
print("https://github.com/AdnanHodzic/auto-cpufreq/issues")
|
||||
print(GITHUB+"/issues")
|
||||
|
||||
def disable_tuned_daemon():
|
||||
# always disable TuneD daemon
|
||||
try:
|
||||
print("\n* Disabling TuneD daemon")
|
||||
call(["systemctl", "disable", "--now", "tuned"])
|
||||
call(["systemctl", "mask", "tuned"])
|
||||
except:
|
||||
print("\nUnable to disable TuneD daemon")
|
||||
print("If this causes any problems, please submit an issue:")
|
||||
print(GITHUB+"/issues")
|
||||
|
||||
# default gnome_power_svc_disable func (balanced)
|
||||
def gnome_power_svc_disable():
|
||||
snap_pkg_check = 0
|
||||
if systemctl_exists:
|
||||
# set balanced profile if its running before disabling it
|
||||
if gnome_power_status == 0 and powerprofilesctl_exists:
|
||||
print("Using profile: ", "balanced")
|
||||
call(["powerprofilesctl", "set", "balanced"])
|
||||
if bool(gnome_power_status):
|
||||
try:
|
||||
# check if snap package installed
|
||||
snap_pkg_check = call(['snap', 'list', '|', 'grep', 'auto-cpufreq'],
|
||||
stdout=DEVNULL,
|
||||
stderr=STDOUT)
|
||||
# check if snapd is present and if snap package is installed | 0 is success
|
||||
if not bool(snap_pkg_check):
|
||||
print("GNOME Power Profiles Daemon is already disabled, it can be re-enabled by running:\n"
|
||||
"sudo python3 power_helper.py --gnome_power_enable\n"
|
||||
)
|
||||
elif snap_pkg_check == 1:
|
||||
print("auto-cpufreq snap package not installed\nGNOME Power Profiles Daemon should be enabled. run:\n\n"
|
||||
"sudo python3 power_helper.py --gnome_power_enable"
|
||||
)
|
||||
except:
|
||||
# snapd not found on the system
|
||||
print("There was a problem, couldn't determine GNOME Power Profiles Daemon")
|
||||
snap_pkg_check = 0
|
||||
|
||||
disable_power_profiles_daemon()
|
||||
if not bool(gnome_power_status) and powerprofilesctl_exists:
|
||||
if snap_pkg_check == 1:
|
||||
print("auto-cpufreq snap package not installed.\nGNOME Power Profiles Daemon should be enabled, run:\n\n"
|
||||
"sudo python3 power_helper.py --gnome_power_enable"
|
||||
)
|
||||
else:
|
||||
print("auto-cpufreq snap package installed, GNOME Power Profiles Daemon should be disabled.\n")
|
||||
print("Using profile: ", "balanced")
|
||||
call(["powerprofilesctl", "set", "balanced"])
|
||||
|
||||
# default gnome_power_svc_disable func (performance)
|
||||
def gnome_power_svc_disable_performance():
|
||||
if systemctl_exists:
|
||||
# set performance profile if its running before disabling it
|
||||
if gnome_power_status == 0 and powerprofilesctl_exists:
|
||||
print("Using profile: ", "performance")
|
||||
call(["powerprofilesctl", "set", "performance"])
|
||||
|
||||
disable_power_profiles_daemon()
|
||||
disable_power_profiles_daemon()
|
||||
|
||||
def tuned_svc_disable():
|
||||
if systemctl_exists and tuned_stat_exists:
|
||||
disable_tuned_daemon()
|
||||
|
||||
# cli
|
||||
@click.pass_context
|
||||
# external gnome power srevice disable function
|
||||
def gnome_power_svc_disable_ext(ctx, power_selection):
|
||||
raw_power_disable = ctx.params["gnome_power_disable"]
|
||||
gnome_power_disable = str(raw_power_disable).replace('[','').replace(']','').replace(",", "").replace("(","").replace(")","").replace("'","")
|
||||
|
||||
if systemctl_exists:
|
||||
# 0 is active
|
||||
if gnome_power_status != 0:
|
||||
|
||||
try:
|
||||
snap_pkg_check = call(['snap', 'list', '|', 'grep', 'auto-cpufreq'],
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.STDOUT)
|
||||
|
||||
# check if snapd is present and if snap package is installed | 0 is success
|
||||
if snap_pkg_check == 0:
|
||||
print("Power Profiles Daemon is already disabled, re-enable by running:\n"
|
||||
"sudo python3 power_helper.py --gnome_power_enable\n"
|
||||
"\nfollowed by running:\n"
|
||||
"sudo python3 power_helper.py --gnome_power_disable"
|
||||
)
|
||||
else:
|
||||
# snapd present, snap package not installed
|
||||
print("Power Profiles Daemon is already disabled, first remove auto-cpufreq:\n"
|
||||
"sudo auto-cpufreq --remove\n"
|
||||
"\nfollowed by installing auto-cpufreq in performance mode:\n"
|
||||
"sudo auto-cpufreq --install_performance"
|
||||
)
|
||||
|
||||
except FileNotFoundError:
|
||||
# snapd not found on the system
|
||||
print("Power Profiles Daemon is already disabled, first remove auto-cpufreq:\n"
|
||||
"sudo auto-cpufreq --remove\n"
|
||||
"\nfollowed by installing auto-cpufreq in performance mode:\n"
|
||||
"sudo auto-cpufreq --install_performance"
|
||||
)
|
||||
|
||||
# set balanced profile if its running before disabling it
|
||||
if gnome_power_status == 0 and powerprofilesctl_exists:
|
||||
# 0 is success (snap package is installed)
|
||||
|
||||
try:
|
||||
snap_pkg_check = call(['snap', 'list', '|', 'grep', 'auto-cpufreq'],
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.STDOUT)
|
||||
|
||||
if snap_pkg_check == 0:
|
||||
#if snap_exist == 0 and snap_pkg_install == 0:
|
||||
print("Using profile: ", gnome_power_disable)
|
||||
call(["powerprofilesctl", "set", gnome_power_disable])
|
||||
|
||||
disable_power_profiles_daemon()
|
||||
else:
|
||||
print("Install auto-cpufreq in performance mode by running:\n"
|
||||
"sudo auto-cpufreq --install_performance\n"
|
||||
)
|
||||
|
||||
except FileNotFoundError:
|
||||
print("Install auto-cpufreq in performance mode by running:\n"
|
||||
"sudo auto-cpufreq --install_performance\n"
|
||||
)
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option("--gnome_power_disable", help="Disable GNOME Power profiles service (default: balanced), reference:\n https://bit.ly/3bjVZW1", type=click.Choice(['balanced', 'performance'], case_sensitive=False))
|
||||
#@click.option("--gnome_power_disable", help="Disable GNOME Power profiles service (default: balanced), reference:\n https://bit.ly/3bjVZW1", type=click.Choice(['balanced', 'performance'], case_sensitive=False))
|
||||
@click.option("--gnome_power_disable", is_flag=True, help="Disable GNOME Power profiles service")
|
||||
# ToDo:
|
||||
# * update readme/docs
|
||||
@click.option("--power_selection", hidden=True)
|
||||
@click.option("--gnome_power_enable", is_flag=True, help="Enable GNOME Power profiles service")
|
||||
|
||||
@click.option("--gnome_power_status", is_flag=True, help="Get status of GNOME Power profiles service"
|
||||
)
|
||||
@click.option("--gnome_power_status", is_flag=True, help="Get status of GNOME Power profiles service")
|
||||
@click.option("--bluetooth_boot_on", is_flag=True, help="Turn on Bluetooth on boot")
|
||||
@click.option("--bluetooth_boot_off", is_flag=True, help="Turn off Bluetooth on boot")
|
||||
def main(
|
||||
power_selection,
|
||||
gnome_power_enable,
|
||||
gnome_power_disable,
|
||||
gnome_power_status,
|
||||
bluetooth_boot_off,
|
||||
bluetooth_boot_on,
|
||||
):
|
||||
|
||||
root_check()
|
||||
if len(sys.argv) == 1:
|
||||
header()
|
||||
print(
|
||||
'Unrecognized option!\n\nRun: "' + app_name + ' --help" for list of available options.'
|
||||
)
|
||||
footer()
|
||||
header()
|
||||
|
||||
if len(argv) == 1: print('Unrecognized option!\n\nRun: "' + app_name + ' --help" for list of available options.')
|
||||
else:
|
||||
if gnome_power_enable:
|
||||
header()
|
||||
root_check()
|
||||
gnome_power_svc_enable()
|
||||
helper_opts()
|
||||
footer()
|
||||
elif gnome_power_disable:
|
||||
header()
|
||||
root_check()
|
||||
gnome_power_svc_disable_ext(power_selection)
|
||||
helper_opts()
|
||||
footer()
|
||||
elif gnome_power_status:
|
||||
header()
|
||||
root_check()
|
||||
gnome_power_svc_status()
|
||||
helper_opts()
|
||||
footer()
|
||||
elif bluetooth_boot_off:
|
||||
header()
|
||||
root_check()
|
||||
bluetooth_disable()
|
||||
helper_opts()
|
||||
footer()
|
||||
elif bluetooth_boot_on:
|
||||
header()
|
||||
root_check()
|
||||
bluetooth_enable()
|
||||
helper_opts()
|
||||
footer()
|
||||
if gnome_power_enable: gnome_power_svc_enable()
|
||||
elif gnome_power_disable: gnome_power_svc_disable()
|
||||
elif gnome_power_status: gnome_power_svc_status()
|
||||
elif bluetooth_boot_off: bluetooth_disable()
|
||||
elif bluetooth_boot_on: bluetooth_enable()
|
||||
helper_opts()
|
||||
|
||||
footer()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
if __name__ == "__main__": main()
|
@ -6,14 +6,8 @@ class TLPStatusParser:
|
||||
def _parse(self, data):
|
||||
for line in data.split("\n"):
|
||||
key_val = line.split("=", 1)
|
||||
if len(key_val) > 1:
|
||||
self.data[key_val[0].strip().lower()] = key_val[1].strip()
|
||||
if len(key_val) > 1: self.data[key_val[0].strip().lower()] = key_val[1].strip()
|
||||
|
||||
def _get_key(self, key):
|
||||
if key in self.data:
|
||||
return self.data[key]
|
||||
else:
|
||||
return ""
|
||||
def _get_key(self, key): return self.data[key] if key in self.data else ""
|
||||
|
||||
def is_enabled(self):
|
||||
return self._get_key("state") == "enabled"
|
||||
def is_enabled(self): return self._get_key("state") == "enabled"
|
||||
|
226
bin/auto-cpufreq
226
bin/auto-cpufreq
@ -1,226 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# auto-cpufreq - Automatic CPU speed & power optimizer for Linux
|
||||
#
|
||||
# Blog post: https://foolcontrol.org/?p=3124
|
||||
|
||||
# core import
|
||||
import sys
|
||||
import time
|
||||
import click
|
||||
from subprocess import call, run
|
||||
|
||||
sys.path.append("../")
|
||||
from auto_cpufreq.core import *
|
||||
from auto_cpufreq.power_helper import *
|
||||
|
||||
# cli
|
||||
@click.command()
|
||||
@click.option("--monitor", is_flag=True, help="Monitor and see suggestions for CPU optimizations")
|
||||
@click.option("--live", is_flag=True, help="Monitor and make (temp.) suggested CPU optimizations")
|
||||
@click.option(
|
||||
"--install/--remove",
|
||||
default=True,
|
||||
help="Install/remove daemon for (permanent) automatic CPU optimizations",
|
||||
)
|
||||
@click.option("--install_performance", is_flag=True, help="Install daemon in \"performance\" mode, reference:\n https://bit.ly/3bjVZW1")
|
||||
@click.option("--stats", is_flag=True, help="View live stats of CPU optimizations made by daemon")
|
||||
@click.option(
|
||||
"--config",
|
||||
is_flag=False,
|
||||
default="/etc/auto-cpufreq.conf",
|
||||
help="Use config file at defined path",
|
||||
)
|
||||
@click.option("--debug", is_flag=True, help="Show debug info (include when submitting bugs)")
|
||||
@click.option("--version", is_flag=True, help="Show currently installed version")
|
||||
@click.option("--donate", is_flag=True, help="Support the project")
|
||||
@click.option("--log", is_flag=True, hidden=True)
|
||||
@click.option("--daemon", is_flag=True, hidden=True)
|
||||
def main(config, daemon, debug, install, install_performance, live, log, monitor, stats, version, donate):
|
||||
|
||||
# display info if config file is used
|
||||
def config_info_dialog():
|
||||
if get_config(config) and hasattr(get_config, "using_cfg_file"):
|
||||
print("\nUsing settings defined in " + config + " file")
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
print("\n" + "-" * 32 + " auto-cpufreq " + "-" * 33 + "\n")
|
||||
print("Automatic CPU speed & power optimizer for Linux")
|
||||
print("\nExample usage:\nauto-cpufreq --monitor")
|
||||
print("\n-----\n")
|
||||
|
||||
run(["auto-cpufreq", "--help"])
|
||||
footer()
|
||||
else:
|
||||
if daemon:
|
||||
config_info_dialog()
|
||||
root_check()
|
||||
file_stats()
|
||||
if os.getenv("PKG_MARKER") == "SNAP" and dcheck == "enabled":
|
||||
gnome_power_detect_snap()
|
||||
tlp_service_detect_snap()
|
||||
while True:
|
||||
footer()
|
||||
gov_check()
|
||||
cpufreqctl()
|
||||
distro_info()
|
||||
sysinfo()
|
||||
set_autofreq()
|
||||
countdown(2)
|
||||
elif os.getenv("PKG_MARKER") != "SNAP":
|
||||
gnome_power_detect()
|
||||
tlp_service_detect()
|
||||
while True:
|
||||
footer()
|
||||
gov_check()
|
||||
cpufreqctl()
|
||||
distro_info()
|
||||
sysinfo()
|
||||
set_autofreq()
|
||||
countdown(2)
|
||||
else:
|
||||
daemon_not_found()
|
||||
elif monitor:
|
||||
config_info_dialog()
|
||||
root_check()
|
||||
print('\nNote: You can quit monitor mode by pressing "ctrl+c"')
|
||||
if os.getenv("PKG_MARKER") == "SNAP":
|
||||
gnome_power_detect_snap()
|
||||
tlp_service_detect_snap()
|
||||
else:
|
||||
gnome_power_detect()
|
||||
tlp_service_detect()
|
||||
while True:
|
||||
time.sleep(1)
|
||||
running_daemon()
|
||||
footer()
|
||||
gov_check()
|
||||
cpufreqctl()
|
||||
distro_info()
|
||||
sysinfo()
|
||||
mon_autofreq()
|
||||
countdown(2)
|
||||
elif live:
|
||||
root_check()
|
||||
config_info_dialog()
|
||||
print('\nNote: You can quit live mode by pressing "ctrl+c"')
|
||||
time.sleep(1)
|
||||
if os.getenv("PKG_MARKER") == "SNAP":
|
||||
gnome_power_detect_snap()
|
||||
tlp_service_detect_snap()
|
||||
else:
|
||||
gnome_power_detect_install()
|
||||
gnome_power_stop_live()
|
||||
tlp_service_detect()
|
||||
while True:
|
||||
try:
|
||||
running_daemon()
|
||||
footer()
|
||||
gov_check()
|
||||
cpufreqctl()
|
||||
distro_info()
|
||||
sysinfo()
|
||||
set_autofreq()
|
||||
countdown(2)
|
||||
except KeyboardInterrupt:
|
||||
gnome_power_start_live()
|
||||
print("")
|
||||
sys.exit()
|
||||
elif stats:
|
||||
config_info_dialog()
|
||||
print('\nNote: You can quit stats mode by pressing "ctrl+c"')
|
||||
if os.getenv("PKG_MARKER") == "SNAP":
|
||||
gnome_power_detect_snap()
|
||||
tlp_service_detect_snap()
|
||||
else:
|
||||
gnome_power_detect()
|
||||
tlp_service_detect()
|
||||
read_stats()
|
||||
elif log:
|
||||
deprecated_log_msg()
|
||||
elif debug:
|
||||
# ToDo: add status of GNOME Power Profile service status
|
||||
config_info_dialog()
|
||||
root_check()
|
||||
cpufreqctl()
|
||||
footer()
|
||||
distro_info()
|
||||
sysinfo()
|
||||
print("")
|
||||
app_version()
|
||||
print("")
|
||||
python_info()
|
||||
print("")
|
||||
device_info()
|
||||
if charging():
|
||||
print("Battery is: charging")
|
||||
else:
|
||||
print("Battery is: discharging")
|
||||
print("")
|
||||
app_res_use()
|
||||
display_load()
|
||||
get_current_gov()
|
||||
get_turbo()
|
||||
footer()
|
||||
elif version:
|
||||
footer()
|
||||
distro_info()
|
||||
app_version()
|
||||
footer()
|
||||
elif donate:
|
||||
footer()
|
||||
print("If auto-cpufreq helped you out and you find it useful ...\n")
|
||||
print("Show your appreciation by donating!")
|
||||
print("https://github.com/AdnanHodzic/auto-cpufreq/#donate")
|
||||
footer()
|
||||
elif install_performance:
|
||||
if os.getenv("PKG_MARKER") == "SNAP":
|
||||
root_check()
|
||||
print("\nThis option is only available on non Snap installs.\n\n"
|
||||
"Please refer to auto-cpufreq power_helper.py script for more info\n"
|
||||
"Reference: https://github.com/AdnanHodzic/auto-cpufreq#configuring-auto-cpufreq\n")
|
||||
else:
|
||||
root_check()
|
||||
running_daemon()
|
||||
gov_check()
|
||||
deploy_daemon_performance()
|
||||
deploy_complete_msg()
|
||||
elif install:
|
||||
if os.getenv("PKG_MARKER") == "SNAP":
|
||||
root_check()
|
||||
running_daemon()
|
||||
gnome_power_detect_snap()
|
||||
tlp_service_detect_snap()
|
||||
bluetooth_notif_snap()
|
||||
gov_check()
|
||||
run("snapctl set daemon=enabled", shell=True)
|
||||
run("snapctl start --enable auto-cpufreq", shell=True)
|
||||
deploy_complete_msg()
|
||||
else:
|
||||
root_check()
|
||||
running_daemon()
|
||||
gov_check()
|
||||
deploy_daemon()
|
||||
deploy_complete_msg()
|
||||
elif remove:
|
||||
if os.getenv("PKG_MARKER") == "SNAP":
|
||||
root_check()
|
||||
run("snapctl set daemon=disabled", shell=True)
|
||||
run("snapctl stop --disable auto-cpufreq", shell=True)
|
||||
if auto_cpufreq_stats_path.exists():
|
||||
if auto_cpufreq_stats_file is not None:
|
||||
auto_cpufreq_stats_file.close()
|
||||
|
||||
auto_cpufreq_stats_path.unlink()
|
||||
# ToDo:
|
||||
# * undo bluetooth boot disable
|
||||
gnome_power_rm_reminder_snap()
|
||||
remove_complete_msg()
|
||||
else:
|
||||
root_check()
|
||||
remove()
|
||||
remove_complete_msg()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
27
flake.lock
generated
Normal file
27
flake.lock
generated
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1740547748,
|
||||
"narHash": "sha256-Ly2fBL1LscV+KyCqPRufUBuiw+zmWrlJzpWOWbahplg=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "3a05eebede89661660945da1f151959900903b6a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
24
flake.nix
Normal file
24
flake.nix
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
};
|
||||
|
||||
outputs = {nixpkgs, ...} @ inputs: let
|
||||
forAllSystems = nixpkgs.lib.genAttrs ["x86_64-linux" "i686-linux" "aarch64-linux"];
|
||||
pkgsForEach = nixpkgs.legacyPackages;
|
||||
in {
|
||||
packages = forAllSystems (system: {
|
||||
default = pkgsForEach.${system}.callPackage ./nix/default.nix {};
|
||||
});
|
||||
|
||||
devShells = forAllSystems (system: {
|
||||
default = pkgsForEach.${system}.callPackage ./nix/shell.nix {};
|
||||
});
|
||||
|
||||
overlays.default = final: _: {
|
||||
auto-cpufreq = final.callPackage ./nix/default.nix {};
|
||||
};
|
||||
|
||||
nixosModules.default = import ./nix/module.nix inputs;
|
||||
};
|
||||
}
|
BIN
images/icon.png
Normal file
BIN
images/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
82
nix/default.nix
Normal file
82
nix/default.nix
Normal file
@ -0,0 +1,82 @@
|
||||
{
|
||||
lib,
|
||||
python3Packages,
|
||||
pkgs,
|
||||
fetchFromGitHub,
|
||||
fetchPypi,
|
||||
}:
|
||||
let
|
||||
|
||||
pyinotify = python3Packages.pyinotify.overrideAttrs (oldAttrs: {
|
||||
src = fetchFromGitHub {
|
||||
owner = "shadeyg56";
|
||||
repo = "pyinotify-3.12";
|
||||
rev = "923cebec3a2a84c7e38c9e68171eb93f5d07ce5d";
|
||||
hash = "sha256-714CximEK4YhIqDmvqJYOUGs39gvDkWGrkNrXwxT8iM=";
|
||||
};
|
||||
patches = [];
|
||||
});
|
||||
|
||||
in
|
||||
python3Packages.buildPythonPackage {
|
||||
# use pyproject.toml instead of setup.py
|
||||
format = "pyproject";
|
||||
|
||||
pname = "auto-cpufreq";
|
||||
version = "2.5.0";
|
||||
src = ../.;
|
||||
|
||||
nativeBuildInputs = with pkgs; [wrapGAppsHook gobject-introspection];
|
||||
|
||||
buildInputs = with pkgs; [gtk3 python3Packages.poetry-core];
|
||||
|
||||
propagatedBuildInputs = with python3Packages; [requests pygobject3 click distro psutil setuptools poetry-dynamic-versioning pyinotify urwid pyasyncore pkgs.getent];
|
||||
|
||||
doCheck = false;
|
||||
pythonImportsCheck = ["auto_cpufreq"];
|
||||
|
||||
patches = [
|
||||
# patch to prevent script copying and to disable install
|
||||
./patches/prevent-install-and-copy.patch
|
||||
];
|
||||
|
||||
postPatch = ''
|
||||
substituteInPlace auto_cpufreq/core.py --replace-fail '/opt/auto-cpufreq/override.pickle' /var/run/override.pickle
|
||||
substituteInPlace scripts/org.auto-cpufreq.pkexec.policy --replace-fail "/opt/auto-cpufreq/venv/bin/auto-cpufreq" $out/bin/auto-cpufreq
|
||||
|
||||
substituteInPlace auto_cpufreq/gui/app.py auto_cpufreq/gui/objects.py --replace-fail "/usr/local/share/auto-cpufreq/images/icon.png" $out/share/pixmaps/auto-cpufreq.png
|
||||
substituteInPlace auto_cpufreq/gui/app.py --replace-fail "/usr/local/share/auto-cpufreq/scripts/style.css" $out/share/auto-cpufreq/scripts/style.css
|
||||
'';
|
||||
|
||||
postInstall = ''
|
||||
# copy script manually
|
||||
cp scripts/cpufreqctl.sh $out/bin/cpufreqctl.auto-cpufreq
|
||||
|
||||
# move the css to the right place
|
||||
mkdir -p $out/share/auto-cpufreq/scripts
|
||||
cp scripts/style.css $out/share/auto-cpufreq/scripts/style.css
|
||||
|
||||
# systemd service
|
||||
mkdir -p $out/lib/systemd/system
|
||||
cp scripts/auto-cpufreq.service $out/lib/systemd/system
|
||||
|
||||
# desktop icon
|
||||
mkdir -p $out/share/applications
|
||||
mkdir $out/share/pixmaps
|
||||
cp scripts/auto-cpufreq-gtk.desktop $out/share/applications
|
||||
cp images/icon.png $out/share/pixmaps/auto-cpufreq.png
|
||||
|
||||
# polkit policy
|
||||
mkdir -p $out/share/polkit-1/actions
|
||||
cp scripts/org.auto-cpufreq.pkexec.policy $out/share/polkit-1/actions
|
||||
'';
|
||||
|
||||
meta = {
|
||||
homepage = "https://github.com/AdnanHodzic/auto-cpufreq";
|
||||
description = "Automatic CPU speed & power optimizer for Linux";
|
||||
license = lib.licenses.lgpl3Plus;
|
||||
platforms = lib.platforms.linux;
|
||||
maintainers = with lib.maintainers; [Technical27];
|
||||
mainProgram = "auto-cpufreq";
|
||||
};
|
||||
}
|
64
nix/module.nix
Normal file
64
nix/module.nix
Normal file
@ -0,0 +1,64 @@
|
||||
inputs: {
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.auto-cpufreq;
|
||||
inherit (pkgs.stdenv.hostPlatform) system;
|
||||
defaultPackage = inputs.self.packages.${system}.default;
|
||||
cfgFilename = "auto-cpufreq.conf";
|
||||
cfgFile = format.generate cfgFilename cfg.settings;
|
||||
|
||||
inherit (lib) types;
|
||||
inherit (lib.modules) mkIf mkForce;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
|
||||
format = pkgs.formats.ini {};
|
||||
in {
|
||||
options.programs.auto-cpufreq = {
|
||||
enable = mkEnableOption "Automatic CPU speed & power optimizer for Linux";
|
||||
|
||||
settings = mkOption {
|
||||
description = ''
|
||||
Configuration for `auto-cpufreq`.
|
||||
|
||||
See its [example configuration file] for supported settings.
|
||||
[example configuration file]: https://github.com/AdnanHodzic/auto-cpufreq/blob/master/auto-cpufreq.conf-example
|
||||
'';
|
||||
|
||||
default = {};
|
||||
type = types.submodule {freeformType = format.type;};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [ defaultPackage ];
|
||||
|
||||
systemd = {
|
||||
packages = [ defaultPackage ];
|
||||
services.auto-cpufreq = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = with pkgs; [ bash coreutils ];
|
||||
overrideStrategy = "asDropin";
|
||||
|
||||
serviceConfig.WorkingDirectory = "";
|
||||
serviceConfig.ExecStart = mkForce [
|
||||
""
|
||||
"${defaultPackage}/bin/auto-cpufreq --daemon --config ${cfgFile}"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion = !config.services.power-profiles-daemon.enable;
|
||||
message = ''
|
||||
You have set services.power-profiles-daemon.enable = true;
|
||||
which conflicts with auto-cpufreq
|
||||
'';
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
101
nix/patches/prevent-install-and-copy.patch
Normal file
101
nix/patches/prevent-install-and-copy.patch
Normal file
@ -0,0 +1,101 @@
|
||||
diff --git a/auto_cpufreq/core.py b/auto_cpufreq/core.py
|
||||
index f03e7de..2dff5fb 100755
|
||||
--- a/auto_cpufreq/core.py
|
||||
+++ b/auto_cpufreq/core.py
|
||||
@@ -277,19 +277,12 @@ def get_current_gov():
|
||||
)
|
||||
|
||||
def cpufreqctl():
|
||||
- """
|
||||
- deploy cpufreqctl.auto-cpufreq script
|
||||
- """
|
||||
- if not (IS_INSTALLED_WITH_SNAP or os.path.isfile("/usr/local/bin/cpufreqctl.auto-cpufreq")):
|
||||
- copy(SCRIPTS_DIR / "cpufreqctl.sh", "/usr/local/bin/cpufreqctl.auto-cpufreq")
|
||||
- call(["chmod", "a+x", "/usr/local/bin/cpufreqctl.auto-cpufreq"])
|
||||
+ # scripts are already in the correct place
|
||||
+ pass
|
||||
|
||||
def cpufreqctl_restore():
|
||||
- """
|
||||
- remove cpufreqctl.auto-cpufreq script
|
||||
- """
|
||||
- if not IS_INSTALLED_WITH_SNAP and os.path.isfile("/usr/local/bin/cpufreqctl.auto-cpufreq"):
|
||||
- os.remove("/usr/local/bin/cpufreqctl.auto-cpufreq")
|
||||
+ #no need to restore
|
||||
+ pass
|
||||
|
||||
def footer(l=79): print("\n" + "-" * l + "\n")
|
||||
|
||||
@@ -307,31 +300,8 @@ def remove_complete_msg():
|
||||
footer()
|
||||
|
||||
def deploy_daemon():
|
||||
- print("\n" + "-" * 21 + " Deploying auto-cpufreq as a daemon " + "-" * 22 + "\n")
|
||||
-
|
||||
- cpufreqctl() # deploy cpufreqctl script func call
|
||||
-
|
||||
- bluetooth_disable() # turn off bluetooth on boot
|
||||
-
|
||||
- auto_cpufreq_stats_path.touch(exist_ok=True)
|
||||
-
|
||||
- print("\n* Deploy auto-cpufreq install script")
|
||||
- copy(SCRIPTS_DIR / "auto-cpufreq-install.sh", "/usr/local/bin/auto-cpufreq-install")
|
||||
- call(["chmod", "a+x", "/usr/local/bin/auto-cpufreq-install"])
|
||||
-
|
||||
- print("\n* Deploy auto-cpufreq remove script")
|
||||
- copy(SCRIPTS_DIR / "auto-cpufreq-remove.sh", "/usr/local/bin/auto-cpufreq-remove")
|
||||
- call(["chmod", "a+x", "/usr/local/bin/auto-cpufreq-remove"])
|
||||
-
|
||||
- # output warning if gnome power profile is running
|
||||
- gnome_power_detect_install()
|
||||
- gnome_power_svc_disable()
|
||||
-
|
||||
- tuned_svc_disable()
|
||||
-
|
||||
- tlp_service_detect() # output warning if TLP service is detected
|
||||
-
|
||||
- call("/usr/local/bin/auto-cpufreq-install", shell=True)
|
||||
+ # prevent needless copying and system changes
|
||||
+ pass
|
||||
|
||||
def deploy_daemon_performance():
|
||||
print("\n" + "-" * 21 + " Deploying auto-cpufreq as a daemon (performance) " + "-" * 22 + "\n")
|
||||
@@ -363,37 +333,7 @@ def deploy_daemon_performance():
|
||||
|
||||
call("/usr/local/bin/auto-cpufreq-install", shell=True)
|
||||
|
||||
-def remove_daemon():
|
||||
- # check if auto-cpufreq is installed
|
||||
- if not os.path.exists("/usr/local/bin/auto-cpufreq-remove"):
|
||||
- print("\nauto-cpufreq daemon is not installed.\n")
|
||||
- sys.exit(1)
|
||||
-
|
||||
- print("\n" + "-" * 21 + " Removing auto-cpufreq daemon " + "-" * 22 + "\n")
|
||||
-
|
||||
- bluetooth_enable() # turn on bluetooth on boot
|
||||
-
|
||||
- # output warning if gnome power profile is stopped
|
||||
- gnome_power_rm_reminder()
|
||||
- gnome_power_svc_enable()
|
||||
-
|
||||
- tuned_svc_enable()
|
||||
-
|
||||
- # run auto-cpufreq daemon remove script
|
||||
- call("/usr/local/bin/auto-cpufreq-remove", shell=True)
|
||||
-
|
||||
- # remove auto-cpufreq-remove
|
||||
- os.remove("/usr/local/bin/auto-cpufreq-remove")
|
||||
-
|
||||
- # delete override pickle if it exists
|
||||
- if os.path.exists(governor_override_state): os.remove(governor_override_state)
|
||||
-
|
||||
- # delete stats file
|
||||
- if auto_cpufreq_stats_path.exists():
|
||||
- if auto_cpufreq_stats_file is not None: auto_cpufreq_stats_file.close()
|
||||
- auto_cpufreq_stats_path.unlink()
|
||||
-
|
||||
- cpufreqctl_restore() # restore original cpufrectl script
|
||||
+def remove_daemon(): pass
|
||||
|
||||
def gov_check():
|
||||
for gov in AVAILABLE_GOVERNORS:
|
15
nix/shell.nix
Normal file
15
nix/shell.nix
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
python3Packages,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
mainPkg = python3Packages.callPackage ./default.nix {};
|
||||
in
|
||||
mainPkg.overrideAttrs (oa: {
|
||||
nativeBuildInputs =
|
||||
[
|
||||
python3Packages.pip
|
||||
pkgs.poetry
|
||||
]
|
||||
++ (oa.nativeBuildInputs or []);
|
||||
})
|
1332
poetry.lock
generated
Normal file
1332
poetry.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
52
pyproject.toml
Normal file
52
pyproject.toml
Normal file
@ -0,0 +1,52 @@
|
||||
[tool.poetry]
|
||||
name = "auto-cpufreq"
|
||||
version = "2.5.0"
|
||||
description = "Automatic CPU speed & power optimizer for Linux"
|
||||
authors = ["Adnan Hodzic <adnan@hodzic.org>"]
|
||||
license = "GPL-3.0-or-later"
|
||||
readme = "README.md"
|
||||
classifiers=[
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Intended Audience :: Developers",
|
||||
"Operating System :: POSIX :: Linux",
|
||||
"Environment :: Console",
|
||||
"Natural Language :: English"
|
||||
]
|
||||
keywords=["linux", "cpu", "speed", "power", "frequency", "turbo", "optimzier", "auto", "cpufreq"]
|
||||
repository = "https://github.com/AdnanHodzic/auto-cpufreq"
|
||||
documentation = "https://github.com/AdnanHodzic/auto-cpufreq#readme"
|
||||
packages = [
|
||||
{ include = "./auto_cpufreq" },
|
||||
{ include = "./auto_cpufreq/gui" },
|
||||
]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.9, <4.0"
|
||||
psutil = ">=6.0.0,<8.0.0"
|
||||
click = "^8.1.0"
|
||||
distro = "^1.8.0"
|
||||
requests = "^2.32.3"
|
||||
PyGObject = {version="3.50.0", optional=true}
|
||||
urwid = "^2.6.16"
|
||||
pyinotify = {git = "https://github.com/shadeyg56/pyinotify-3.12"}
|
||||
pyasyncore = "^1.0.4"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
poetry = "^1.6.1"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning>=1.0.0,<2.0.0"]
|
||||
build-backend = "poetry_dynamic_versioning.backend"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
auto-cpufreq = "auto_cpufreq.bin.auto_cpufreq:main"
|
||||
auto-cpufreq-gtk = "auto_cpufreq.bin.auto_cpufreq_gtk:main"
|
||||
|
||||
# https://github.com/mtkennerly/poetry-dynamic-versioning
|
||||
[tool.poetry-dynamic-versioning]
|
||||
enable = true
|
||||
vcs = "git"
|
||||
format = "v{base}+{commit}"
|
||||
|
||||
# SideNote
|
||||
# Regarding zip_safe = https://setuptools.pypa.io/en/latest/deprecated/zip_safe.html
|
@ -1,4 +0,0 @@
|
||||
setuptools
|
||||
psutil
|
||||
click
|
||||
distro
|
3
scripts/auto-cpufreq-dinit
Normal file
3
scripts/auto-cpufreq-dinit
Normal file
@ -0,0 +1,3 @@
|
||||
type = scripted
|
||||
command = /usr/local/bin/auto-cpufreq --daemon
|
||||
run-as = root
|
8
scripts/auto-cpufreq-gtk.desktop
Normal file
8
scripts/auto-cpufreq-gtk.desktop
Normal file
@ -0,0 +1,8 @@
|
||||
[Desktop Entry]
|
||||
Name=auto-cpufreq
|
||||
Exec=auto-cpufreq-gtk
|
||||
Type=Application
|
||||
Terminal=false
|
||||
Icon=auto-cpufreq
|
||||
StartupWMClass=app.py
|
||||
Categories=System;
|
@ -1,95 +1,96 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# auto-cpufreq daemon install script
|
||||
# reference: https://github.com/AdnanHodzic/auto-cpufreq
|
||||
# Thanks to https://github.com/errornonamer for openrc fix
|
||||
echo -e "\n------------------ Running auto-cpufreq daemon install script ------------------"
|
||||
|
||||
if [[ $EUID != 0 ]];
|
||||
then
|
||||
echo -e "\nERROR\nMust be run as root (i.e: 'sudo $0')\n"
|
||||
exit 1
|
||||
MID="$((`tput cols` / 2))"
|
||||
|
||||
echo
|
||||
printf "%0.s─" $(seq $(( (MID-(${#1}/2)-2) / 2 )))
|
||||
printf " Running auto-cpufreq daemon install script "
|
||||
printf "%0.s─" $(seq $(( (MID-(${#1}/2)-2) / 2 )))
|
||||
echo; echo
|
||||
|
||||
# root check
|
||||
if ((EUID != 0)); then
|
||||
echo; echo "Must be run as root (i.e: 'sudo $0')."; echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# First argument is the "sv" path, second argument is the "service" path this
|
||||
# only exist because the path between distros may vary
|
||||
runit_ln() {
|
||||
echo -e "\n* Deploy auto-cpufreq runit unit file"
|
||||
mkdir "$1"/sv/auto-cpufreq
|
||||
cp /usr/local/share/auto-cpufreq/scripts/auto-cpufreq-runit "$1"/sv/auto-cpufreq/run
|
||||
chmod +x "$1"/sv/auto-cpufreq/run
|
||||
|
||||
echo -e "\n* Creating symbolic link ($2/service/auto-cpufreq -> $1/sv/auto-cpufreq)"
|
||||
ln -s "$1"/sv/auto-cpufreq "$2"/service
|
||||
# First argument is the init name, second argument is the start command, third argument is the enable command
|
||||
function auto_cpufreq_install {
|
||||
echo -e "\n* Starting auto-cpufreq daemon ($1) service"
|
||||
$2
|
||||
echo -e "\n* Enabling auto-cpufreq daemon ($1) at boot"
|
||||
$3
|
||||
}
|
||||
|
||||
# sv commands
|
||||
sv_cmd() {
|
||||
echo -e "\n* Stopping auto-cpufreq daemon (runit) service"
|
||||
sv stop auto-cpufreq
|
||||
echo -e "\n* Starting auto-cpufreq daemon (runit) service"
|
||||
sv start auto-cpufreq
|
||||
sv up auto-cpufreq
|
||||
}
|
||||
case "$(ps h -o comm 1)" in
|
||||
dinit)
|
||||
echo -e "\n* Deploying auto-cpufreq (dinit) unit file"
|
||||
cp /usr/local/share/auto-cpufreq/scripts/auto-cpufreq-dinit /etc/dinit.d/auto-cpufreq
|
||||
|
||||
# Installation for runit, we still look for the distro because of the path may
|
||||
# vary.
|
||||
if [ "$(ps h -o comm 1)" = "runit" ];then
|
||||
if [ -f /etc/os-release ];then
|
||||
eval "$(cat /etc/os-release)"
|
||||
case $ID in
|
||||
void)
|
||||
runit_ln /etc /var
|
||||
sv_cmd
|
||||
;;
|
||||
artix)
|
||||
# Note: Artix supports other inits than runnit
|
||||
runit_ln /etc/runit /run/runit
|
||||
sv_cmd
|
||||
;;
|
||||
*)
|
||||
echo -e "\n* Runit init detected but your distro is not supported\n"
|
||||
echo -e "\n* Please open an issue on https://github.com/AdnanHodzic/auto-cpufreq\n"
|
||||
esac
|
||||
fi
|
||||
# Install script for systemd
|
||||
elif [ "$(ps h -o comm 1)" = "systemd" ];then
|
||||
echo -e "\n* Deploy auto-cpufreq systemd unit file"
|
||||
auto_cpufreq_install "dinit" "dinitctl start auto-cpufreq" "dinitctl enable auto-cpufreq"
|
||||
;;
|
||||
init)
|
||||
echo -e "\n* Deploying auto-cpufreq openrc unit file"
|
||||
cp /usr/local/share/auto-cpufreq/scripts/auto-cpufreq-openrc /etc/init.d/auto-cpufreq
|
||||
chmod +x /etc/init.d/auto-cpufreq
|
||||
|
||||
auto_cpufreq_install "openrc" "rc-service auto-cpufreq start" "rc-update add auto-cpufreq"
|
||||
;;
|
||||
runit)
|
||||
# First argument is the "sv" path, second argument is the "service" path
|
||||
runit_ln() {
|
||||
echo -e "\n* Deploying auto-cpufreq (runit) unit file"
|
||||
mkdir "$1"/sv/auto-cpufreq
|
||||
cp /usr/local/share/auto-cpufreq/scripts/auto-cpufreq-runit "$1"/sv/auto-cpufreq/run
|
||||
chmod +x "$1"/sv/auto-cpufreq/run
|
||||
|
||||
echo -e "\n* Creating symbolic link ($2/service/auto-cpufreq -> $1/sv/auto-cpufreq)"
|
||||
ln -s "$1"/sv/auto-cpufreq "$2"/service
|
||||
|
||||
auto_cpufreq_install "runit"
|
||||
|
||||
sv start auto-cpufreq
|
||||
sv up auto-cpufreq
|
||||
}
|
||||
|
||||
if [ -f /etc/os-release ];then
|
||||
eval "$(cat /etc/os-release)"
|
||||
case $ID in
|
||||
void) runit_ln /etc /var;;
|
||||
artix) runit_ln /etc/runit /run/runit;;
|
||||
*)
|
||||
echo -e "\n* Runit init detected but your distro is not supported\n"
|
||||
echo -e "\n* Please open an issue on https://github.com/AdnanHodzic/auto-cpufreq\n"
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
systemd)
|
||||
echo -e "Deploying auto-cpufreq systemd unit file"
|
||||
cp /usr/local/share/auto-cpufreq/scripts/auto-cpufreq.service /etc/systemd/system/auto-cpufreq.service
|
||||
|
||||
echo -e "\n* Reloading systemd manager configuration"
|
||||
systemctl daemon-reload
|
||||
|
||||
echo -e "\n* Stopping auto-cpufreq daemon (systemd) service"
|
||||
systemctl stop auto-cpufreq
|
||||
|
||||
echo -e "\n* Starting auto-cpufreq daemon (systemd) service"
|
||||
systemctl start auto-cpufreq
|
||||
|
||||
echo -e "\n* Enabling auto-cpufreq daemon (systemd) service at boot"
|
||||
systemctl enable auto-cpufreq
|
||||
# Install script for openrc
|
||||
elif [ "$(ps h -o comm 1)" = "init" ];then
|
||||
echo -e "\n* Deploying auto-cpufreq openrc unit file"
|
||||
cp /usr/local/share/auto-cpufreq/scripts/auto-cpufreq-openrc /etc/init.d/auto-cpufreq
|
||||
chmod +x /etc/init.d/auto-cpufreq
|
||||
|
||||
echo -e "Starting auto-cpufreq daemon (openrc) service"
|
||||
rc-service auto-cpufreq start
|
||||
|
||||
echo -e "\n* Enabling auto-cpufreq daemon (openrc) service at boot"
|
||||
rc-update add auto-cpufreq
|
||||
# Install script for s6
|
||||
elif [ "$(ps h -o comm 1)" = "s6-svscan" ];then
|
||||
echo -e "\n* Deploying auto-cpufreq s6 unit file"
|
||||
auto_cpufreq_install "systemd" "systemctl start auto-cpufreq" "systemctl enable auto-cpufreq"
|
||||
;;
|
||||
s6-svscan)
|
||||
echo -e "\n* Deploying auto-cpufreq (s6) unit file"
|
||||
cp -r /usr/local/share/auto-cpufreq/scripts/auto-cpufreq-s6 /etc/s6/sv/auto-cpufreq
|
||||
|
||||
echo -e "\n* Add auto-cpufreq service (s6) to default bundle"
|
||||
s6-service add default auto-cpufreq
|
||||
echo -e "Starting auto-cpufreq daemon (s6) service"
|
||||
s6-rc -u change auto-cpufreq default
|
||||
|
||||
auto_cpufreq_install "s6" "s6-rc -u change auto-cpufreq default"
|
||||
|
||||
echo -e "\n* Update daemon service bundle (s6)"
|
||||
s6-db-reload
|
||||
else
|
||||
echo -e "\n* Unsupported init system detected, could not install the daemon\n"
|
||||
echo -e "\n* Please open an issue on https://github.com/AdnanHodzic/auto-cpufreq\n"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo -e "\n* Unsupported init system detected, could not install the daemon\n"
|
||||
echo -e "\n* Please open an issue on https://github.com/AdnanHodzic/auto-cpufreq\n"
|
||||
;;
|
||||
esac
|
||||
|
@ -4,72 +4,68 @@
|
||||
# reference: https://github.com/AdnanHodzic/auto-cpufreq
|
||||
# Thanks to https://github.com/errornonamer for openrc fix
|
||||
|
||||
echo -e "\n------------------ Running auto-cpufreq daemon removal script ------------------"
|
||||
MID="$((`tput cols` / 2))"
|
||||
|
||||
if [[ $EUID != 0 ]]; then
|
||||
echo -e "\nERROR\nMust be run as root (i.e: 'sudo $0')\n"
|
||||
exit 1
|
||||
echo
|
||||
printf "%0.s─" $(seq $(( (MID-(${#1}/2)-2) / 2 )))
|
||||
printf " Running auto-cpufreq daemon removal script "
|
||||
printf "%0.s─" $(seq $(( (MID-(${#1}/2)-2) / 2 )))
|
||||
echo; echo
|
||||
|
||||
# root check
|
||||
if ((EUID != 0)); then
|
||||
echo; echo "Must be run as root (i.e: 'sudo $0')."; echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# First argument is the "sv" path, second argument is the "service" path
|
||||
rm_sv() {
|
||||
echo -e "\n* Stopping auto-cpufreq daemon (runit) service"
|
||||
sv stop auto-cpufreq
|
||||
|
||||
echo -e "\n* Removing auto-cpufreq daemon (runit) unit files"
|
||||
rm -rf "$1"/sv/auto-cpufreq
|
||||
rm -rf "$2"/service/auto-cpufreq
|
||||
# First argument is the init name, second argument is the stop command, third argument is the disable command and the fourth is the "service" path
|
||||
function auto_cpufreq_remove {
|
||||
echo -e "\n* Stopping auto-cpufreq daemon ($1) service"
|
||||
$2
|
||||
echo -e "\n* Disabling auto-cpufreq daemon ($1) at boot"
|
||||
$3
|
||||
echo -e "\n* Removing auto-cpufreq daemon ($1) unit file"
|
||||
rm $4
|
||||
}
|
||||
|
||||
# Remove service for runit
|
||||
if [ "$(ps h -o comm 1)" = "runit" ];then
|
||||
if [ -f /etc/os-release ];then
|
||||
eval "$(cat /etc/os-release)"
|
||||
case $ID in
|
||||
void)
|
||||
rm_sv /etc /var ;;
|
||||
artix)
|
||||
rm_sv /etc/runit /run/runit ;;
|
||||
*)
|
||||
echo -e "\n* Runit init detected but your distro is not supported\n"
|
||||
echo -e "\n* Please open an issue on https://github.com/AdnanHodzic/auto-cpufreq\n"
|
||||
case "$(ps h -o comm 1)" in
|
||||
dinit) auto_cpufreq_remove "dinit" "dinitctl stop auto-cpufreq" "dinitctl disable auto-cpufreq" "/etc/dinit.d/auto-cpufreq";;
|
||||
init) auto_cpufreq_remove "openrc" "rc-service auto-cpufreq stop" "rc-update del auto-cpufreq" "/etc/init.d/auto-cpufreq";;
|
||||
runit)
|
||||
# First argument is the "sv" path, second argument is the "service" path
|
||||
rm_sv() {
|
||||
auto_cpufreq_remove "runit" "sv stop auto-cpufreq" "" "-rf $1/sv/auto-cpufreq $2/service/auto-cpufreq"
|
||||
}
|
||||
|
||||
esac
|
||||
fi
|
||||
# Remove service for systemd
|
||||
elif [ "$(ps h -o comm 1)" = "systemd" ];then
|
||||
echo -e "\n* Stopping auto-cpufreq daemon (systemd) service"
|
||||
systemctl stop auto-cpufreq
|
||||
|
||||
echo -e "\n* Disabling auto-cpufreq daemon (systemd) at boot"
|
||||
systemctl disable auto-cpufreq
|
||||
|
||||
echo -e "\n* Removing auto-cpufreq daemon (systemd) unit file"
|
||||
rm /etc/systemd/system/auto-cpufreq.service
|
||||
if [ -f /etc/os-release ]; then
|
||||
. /etc/os-release
|
||||
case $ID in
|
||||
void) rm_sv /etc /var;;
|
||||
artix) rm_sv /etc/runit /run/runit;;
|
||||
*)
|
||||
echo -e "\n* Runit init detected but your distro is not supported\n"
|
||||
echo -e "\n* Please open an issue on https://github.com/AdnanHodzic/auto-cpufreq\n"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
systemd)
|
||||
auto_cpufreq_remove "systemd" "systemctl stop auto-cpufreq" "systemctl disable auto-cpufreq" "/etc/systemd/system/auto-cpufreq.service"
|
||||
|
||||
echo -e "\n* Reloading systemd manager configuration"
|
||||
systemctl daemon-reload
|
||||
|
||||
echo -e "reset failed"
|
||||
echo "reset failed"
|
||||
systemctl reset-failed
|
||||
elif [ "$(ps h -o comm 1)" = "init" ];then
|
||||
echo -e "\n* Stopping auto-cpufreq daemon (openrc) service"
|
||||
rc-service auto-cpufreq stop
|
||||
|
||||
echo -e "\n* Disabling auto-cpufreq daemon (openrc) at boot"
|
||||
rc-update del auto-cpufreq
|
||||
|
||||
echo -e "\n* Removing auto-cpufreq daemon (openrc) unit file"
|
||||
rm /etc/init.d/auto-cpufreq
|
||||
# Remove service for s6
|
||||
elif [ "$(ps h -o comm 1)" = "s6-svscan" ];then
|
||||
echo -e "\n* Disabling auto-cpufreq daemon (s6) at boot"
|
||||
s6-service delete default auto-cpufreq
|
||||
echo -e "\n* Removing auto-cpufreq daemon (s6) unit file"
|
||||
rm -rf /etc/s6/sv/auto-cpufreq
|
||||
;;
|
||||
s6-svscan)
|
||||
auto_cpufreq_remove "s6" "" "s6-service delete default auto-cpufreq" "-rf /etc/s6/sv/auto-cpufreq"
|
||||
|
||||
echo -e "\n* Update daemon service bundle (s6)"
|
||||
s6-db-reload
|
||||
else
|
||||
echo -e "\n* Unsupported init system detected, could not remove the daemon\n"
|
||||
echo -e "\n* Please open an issue on https://github.com/AdnanHodzic/auto-cpufreq\n"
|
||||
fi
|
||||
s6-db-reload
|
||||
;;
|
||||
*)
|
||||
echo -e "\n* Unsupported init system detected, could not remove the daemon"
|
||||
echo -e "\n* Please open an issue on https://github.com/AdnanHodzic/auto-cpufreq\n"
|
||||
;;
|
||||
esac
|
||||
|
@ -1,2 +1,3 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
export PATH="$PATH:/usr/local/bin"
|
||||
exec /usr/local/bin/auto-cpufreq --daemon
|
||||
|
@ -1,34 +1,17 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
# Wrapper script around auto-cpufreq using the python virtual environment
|
||||
|
||||
set -eu
|
||||
|
||||
# get script name
|
||||
PROGNAME=$(basename "${0}")
|
||||
|
||||
# bailout function
|
||||
err_exit()
|
||||
{
|
||||
echo "${PROGNAME}: ${1:-wrong invocation. try --help for help.}" 1>&2
|
||||
exit 1
|
||||
err_exit() {
|
||||
echo "$(basename $0): ${1:-wrong invocation. try --help for help.}" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# invocation handling
|
||||
#
|
||||
param=""
|
||||
if [ "${#}" -ne 1 ];
|
||||
then
|
||||
err_exit
|
||||
else
|
||||
param="${1}"
|
||||
fi
|
||||
|
||||
# load python virtual environment
|
||||
venv_dir=/opt/auto-cpufreq/venv
|
||||
. "${venv_dir}/bin/activate"
|
||||
opt_path=/opt/auto-cpufreq
|
||||
venv_bin_dir=$opt_path/venv/bin
|
||||
. "$venv_bin_dir/activate"
|
||||
|
||||
# run python code with venv loaded
|
||||
PYTHONPATH=/opt/auto-cpufreq \
|
||||
/opt/auto-cpufreq/venv/bin/python \
|
||||
/opt/auto-cpufreq/venv/bin/auto-cpufreq \
|
||||
"${param}"
|
||||
PYTHONPATH=$opt_path $venv_bin_dir/python $venv_bin_dir/auto-cpufreq "$@"
|
||||
|
@ -1,6 +1,5 @@
|
||||
[Unit]
|
||||
Description=auto-cpufreq - Automatic CPU speed & power optimizer for Linux
|
||||
After=network.target network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
|
@ -1,105 +1,104 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
VERSION='20'
|
||||
cpucount=`cat /proc/cpuinfo|grep processor|wc -l`
|
||||
cpucount=`cat /proc/cpuinfo | grep processor | wc -l`
|
||||
FLROOT=/sys/devices/system/cpu
|
||||
FWROOT=/sys/firmware
|
||||
DRIVER=auto
|
||||
VERBOSE=0
|
||||
|
||||
## parse special options
|
||||
for i in "$@"
|
||||
do
|
||||
case $i in
|
||||
-v|--verbose)
|
||||
VERBOSE=1
|
||||
shift
|
||||
;;
|
||||
--set=*)
|
||||
VALUE="${i#*=}"
|
||||
shift
|
||||
;;
|
||||
-c=*|--core=*)
|
||||
CORE="${i#*=}"
|
||||
shift
|
||||
;;
|
||||
--available)
|
||||
AVAILABLE=1
|
||||
shift
|
||||
;;
|
||||
-*)
|
||||
OPTION=$i
|
||||
shift
|
||||
;;
|
||||
*) # unknown
|
||||
;;
|
||||
esac
|
||||
for i in "$@"; do
|
||||
case $i in
|
||||
-v|--verbose)
|
||||
VERBOSE=1
|
||||
shift
|
||||
;;
|
||||
-s=*|--set=*)
|
||||
VALUE="${i#*=}"
|
||||
shift
|
||||
;;
|
||||
-c=*|--core=*)
|
||||
CORE="${i#*=}"
|
||||
shift
|
||||
;;
|
||||
-a|--available)
|
||||
AVAILABLE=1
|
||||
shift
|
||||
;;
|
||||
-*)
|
||||
OPTION=$i
|
||||
shift
|
||||
;;
|
||||
*) exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
function help () {
|
||||
echo "Package version: "$VERSION
|
||||
echo "Usage:"
|
||||
echo " cpufreqctl [OPTION[=VALUE]...]"
|
||||
echo ""
|
||||
echo " --help Show help options"
|
||||
echo " --version Package version"
|
||||
echo " --verbose, -v Verbose output"
|
||||
echo ""
|
||||
echo " --set=VALUE Set VALUE for selected option"
|
||||
echo " --core=NUMBER Apply selected option just for the core NUMBER (0 ~ N - 1)"
|
||||
echo " --available Get available values instand of default: current"
|
||||
echo ""
|
||||
echo " --driver Current processor driver"
|
||||
echo " --governor Scaling governor's options"
|
||||
echo " --epp Governor's energy_performance_preference options"
|
||||
echo " --frequency Frequency options"
|
||||
echo " --on Turn on --core=NUMBER"
|
||||
echo " --off Turn off --core=NUMBER"
|
||||
echo " --frequency-min Minimal frequency options"
|
||||
echo " --frequency-max Maximum frequency options"
|
||||
echo " --frequency-min-limit Get minimal frequency limit"
|
||||
echo " --frequency-max-limit Get maximum frequency limit"
|
||||
echo " --boost Current cpu boost value"
|
||||
echo ""
|
||||
echo "Usage: cpufreqctl [OPTION[=VALUE]...]"
|
||||
echo
|
||||
echo " -h, --help Show help options"
|
||||
echo " --version Package version"
|
||||
echo " -v, --verbose Verbose output"
|
||||
echo
|
||||
echo " -s, --set =VALUE Set VALUE for selected option"
|
||||
echo " -c, --core =NUMBER Apply selected option just for the core NUMBER (0 ~ N - 1)"
|
||||
echo " -a, --available Get available values instand of default: current"
|
||||
echo
|
||||
echo " -d, --driver Current processor driver"
|
||||
echo " -g, --governor Scaling governor's options"
|
||||
echo " -e, --epp Governor's energy_performance_preference options"
|
||||
echo " -f, --frequency Frequency options"
|
||||
echo " --on Turn on --core=NUMBER"
|
||||
echo " --off Turn off --core=NUMBER"
|
||||
echo " --frequency-min Minimal frequency options"
|
||||
echo " --frequency-max Maximum frequency options"
|
||||
echo " --frequency-min-limit Get minimal frequency limit"
|
||||
echo " --frequency-max-limit Get maximum frequency limit"
|
||||
echo " -b, --boost Current cpu boost value"
|
||||
echo
|
||||
echo "intel_pstate options"
|
||||
echo " --no-turbo Current no_turbo value"
|
||||
echo " --min-perf Current min_perf_pct options"
|
||||
echo " --max-perf Current max_perf_pct options"
|
||||
echo ""
|
||||
echo " --no-turbo Current no_turbo value"
|
||||
echo " --min-perf Current min_perf_pct options"
|
||||
echo " --max-perf Current max_perf_pct options"
|
||||
echo
|
||||
echo "Events options"
|
||||
echo " --throttle Get thermal throttle counter"
|
||||
echo " --throttle-event Get kernel thermal throttle events counter"
|
||||
echo " --irqbalance Get irqbalance presence"
|
||||
echo " --throttle Get thermal throttle counter"
|
||||
echo " --throttle-event Get kernel thermal throttle events counter"
|
||||
echo " --irqbalance Get irqbalance presence"
|
||||
}
|
||||
|
||||
function info () {
|
||||
echo "CPU driver: "`driver`
|
||||
echo "Governors: "`cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors`
|
||||
echo "Frequencies: "`cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies`
|
||||
echo ""
|
||||
echo "Governors: "`cat $FLROOT/cpu0/cpufreq/scaling_available_governors`
|
||||
echo "Frequencies: "`cat $FLROOT/cpu0/cpufreq/scaling_available_frequencies`
|
||||
echo
|
||||
echo "Usage:"
|
||||
echo "## list scaling governors:"
|
||||
echo "cpufreqctl --governor"
|
||||
echo ""
|
||||
echo
|
||||
echo "## Set all active cpu cores to the 'performance' scaling governor:"
|
||||
echo "cpufreqctl --governor --set=performance"
|
||||
echo ""
|
||||
echo
|
||||
echo "## Set 'performance' scaling governor for the selected core:"
|
||||
echo "cpufreqctl --governor --set=performance --core=0"
|
||||
echo ""
|
||||
echo
|
||||
echo "Use --help argument to see available options"
|
||||
}
|
||||
|
||||
verbose () {
|
||||
if [ $VERBOSE = 1 ]
|
||||
then
|
||||
echo $1
|
||||
fi
|
||||
if [ $VERBOSE = 1 ]; then echo $1; fi
|
||||
}
|
||||
|
||||
function driver () {
|
||||
cat $FLROOT/cpu0/cpufreq/scaling_driver
|
||||
}
|
||||
|
||||
function write_value () {
|
||||
if [ -w $FLNM ]; then echo $VALUE > $FLNM; fi
|
||||
}
|
||||
|
||||
function set_driver () {
|
||||
DRIVER=`driver`
|
||||
case $DRIVER in
|
||||
@ -113,376 +112,339 @@ function get_governor () {
|
||||
then
|
||||
i=0
|
||||
ag=''
|
||||
while [ $i -ne $cpucount ]
|
||||
do
|
||||
if [ $i = 0 ]
|
||||
then
|
||||
ag=`cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor`
|
||||
else
|
||||
ag=$ag' '`cat /sys/devices/system/cpu/cpu$i/cpufreq/scaling_governor`
|
||||
while [ $i -ne $cpucount ]; do
|
||||
if [ $i = 0 ]; then ag=`cat $FLROOT/cpu0/cpufreq/scaling_governor`
|
||||
else ag=$ag' '`cat $FLROOT/cpu$i/cpufreq/scaling_governor`
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
echo $ag
|
||||
else
|
||||
cat /sys/devices/system/cpu/cpu$CORE/cpufreq/scaling_governor
|
||||
else cat $FLROOT/cpu$CORE/cpufreq/scaling_governor
|
||||
fi
|
||||
}
|
||||
|
||||
function set_governor () {
|
||||
if [ -z $CORE ]
|
||||
then
|
||||
if [ -z $CORE ]; then
|
||||
i=0
|
||||
while [ $i -ne $cpucount ]
|
||||
do
|
||||
while [ $i -ne $cpucount ]; do
|
||||
FLNM="$FLROOT/cpu"$i"/cpufreq/scaling_governor"
|
||||
echo $VALUE > $FLNM
|
||||
write_value
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
else
|
||||
echo $VALUE > /sys/devices/system/cpu/cpu$CORE/cpufreq/scaling_governor
|
||||
else echo $VALUE > $FLROOT/cpu$CORE/cpufreq/scaling_governor
|
||||
fi
|
||||
}
|
||||
|
||||
function get_frequency () {
|
||||
if [ -z $CORE ]
|
||||
then
|
||||
if [ -z $CORE ]; then
|
||||
i=0
|
||||
V=0
|
||||
M=$(cat "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq")
|
||||
while [ $i -ne $cpucount ]
|
||||
do
|
||||
V=$(cat "/sys/devices/system/cpu/cpu"$i"/cpufreq/scaling_cur_freq")
|
||||
if [[ $V > $M ]]
|
||||
then
|
||||
M=$V
|
||||
fi
|
||||
M=$(cat "$FLROOT/cpu0/cpufreq/scaling_cur_freq")
|
||||
while [ $i -ne $cpucount ]; do
|
||||
V=$(cat "$FLROOT/cpu"$i"/cpufreq/scaling_cur_freq")
|
||||
if [[ $V > $M ]]; then M=$V; fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
echo "$M"
|
||||
else
|
||||
cat /sys/devices/system/cpu/cpu$CORE/cpufreq/scaling_cur_freq
|
||||
else cat $FLROOT/cpu$CORE/cpufreq/scaling_cur_freq
|
||||
fi
|
||||
}
|
||||
|
||||
function set_frequency () {
|
||||
set_driver
|
||||
if [ $DRIVER = 'pstate']
|
||||
then
|
||||
if [ $DRIVER = 'pstate' ]; then
|
||||
echo "Unavailable function for intel_pstate"
|
||||
return
|
||||
fi
|
||||
if [ -z $CORE ]
|
||||
then
|
||||
if [ -z $CORE ]; then
|
||||
i=0
|
||||
while [ $i -ne $cpucount ]
|
||||
do
|
||||
while [ $i -ne $cpucount ]; do
|
||||
FLNM="$FLROOT/cpu"$i"/cpufreq/scaling_setspeed"
|
||||
echo $VALUE > $FLNM
|
||||
write_value
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
else
|
||||
echo $VALUE > /sys/devices/system/cpu/cpu$CORE/cpufreq/scaling_setspeed
|
||||
else echo $VALUE > $FLROOT/cpu$CORE/cpufreq/scaling_setspeed
|
||||
fi
|
||||
}
|
||||
|
||||
function get_frequency_min () {
|
||||
if [ -z $CORE ]
|
||||
then
|
||||
CORE=0
|
||||
fi
|
||||
cat /sys/devices/system/cpu/cpu$CORE/cpufreq/scaling_min_freq
|
||||
if [ -z $CORE ]; then CORE=0; fi
|
||||
cat $FLROOT/cpu$CORE/cpufreq/scaling_min_freq
|
||||
}
|
||||
|
||||
function set_frequency_min () {
|
||||
if [ -z $CORE ]
|
||||
then
|
||||
if [ -z $CORE ]; then
|
||||
i=0
|
||||
while [ $i -ne $cpucount ]
|
||||
do
|
||||
while [ $i -ne $cpucount ]; do
|
||||
FLNM="$FLROOT/cpu"$i"/cpufreq/scaling_min_freq"
|
||||
echo $VALUE > $FLNM
|
||||
write_value
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
else
|
||||
echo $VALUE > /sys/devices/system/cpu/cpu$CORE/cpufreq/scaling_min_freq
|
||||
else echo $VALUE > $FLROOT/cpu$CORE/cpufreq/scaling_min_freq
|
||||
fi
|
||||
}
|
||||
|
||||
function get_frequency_max () {
|
||||
if [ -z $CORE ]
|
||||
then
|
||||
CORE=0
|
||||
fi
|
||||
cat /sys/devices/system/cpu/cpu$CORE/cpufreq/scaling_max_freq
|
||||
if [ -z $CORE ]; then CORE=0; fi
|
||||
cat $FLROOT/cpu$CORE/cpufreq/scaling_max_freq
|
||||
}
|
||||
|
||||
function set_frequency_max () {
|
||||
if [ -z $CORE ]
|
||||
then
|
||||
if [ -z $CORE ]; then
|
||||
i=0
|
||||
while [ $i -ne $cpucount ]
|
||||
do
|
||||
while [ $i -ne $cpucount ]; do
|
||||
FLNM="$FLROOT/cpu"$i"/cpufreq/scaling_max_freq"
|
||||
echo $VALUE > $FLNM
|
||||
write_value
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
else
|
||||
echo $VALUE > /sys/devices/system/cpu/cpu$CORE/cpufreq/scaling_max_freq
|
||||
else echo $VALUE > $FLROOT/cpu$CORE/cpufreq/scaling_max_freq
|
||||
fi
|
||||
}
|
||||
|
||||
function get_frequency_min_limit () {
|
||||
if [ -z $CORE ]
|
||||
then
|
||||
CORE=0
|
||||
fi
|
||||
cat /sys/devices/system/cpu/cpu$CORE/cpufreq/cpuinfo_min_freq
|
||||
if [ -z $CORE ]; then CORE=0; fi
|
||||
cat $FLROOT/cpu$CORE/cpufreq/cpuinfo_min_freq
|
||||
}
|
||||
|
||||
function get_frequency_max_limit () {
|
||||
if [ -z $CORE ]
|
||||
then
|
||||
CORE=0
|
||||
fi
|
||||
cat /sys/devices/system/cpu/cpu$CORE/cpufreq/cpuinfo_max_freq
|
||||
if [ -z $CORE ]; then CORE=0; fi
|
||||
cat $FLROOT/cpu$CORE/cpufreq/cpuinfo_max_freq
|
||||
}
|
||||
|
||||
function get_energy_performance_preference () {
|
||||
if [ -z $CORE ]
|
||||
then
|
||||
if [ -z $CORE ]; then
|
||||
i=0
|
||||
ag=''
|
||||
while [ $i -ne $cpucount ]
|
||||
do
|
||||
if [ $i = 0 ]
|
||||
then
|
||||
ag=`cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference`
|
||||
while [ $i -ne $cpucount ]; do
|
||||
if [ $i = 0 ]; then
|
||||
ag=`cat $FLROOT/cpu0/cpufreq/energy_performance_preference`
|
||||
else
|
||||
ag=$ag' '`cat /sys/devices/system/cpu/cpu$i/cpufreq/energy_performance_preference`
|
||||
ag=$ag' '`cat $FLROOT/cpu$i/cpufreq/energy_performance_preference`
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
echo $ag
|
||||
else
|
||||
cat /sys/devices/system/cpu/cpu$CORE/cpufreq/energy_performance_preference
|
||||
else cat $FLROOT/cpu$CORE/cpufreq/energy_performance_preference
|
||||
fi
|
||||
}
|
||||
|
||||
function set_energy_performance_preference () {
|
||||
if [ -z $CORE ]
|
||||
then
|
||||
if [ -z $CORE ]; then
|
||||
i=0
|
||||
while [ $i -ne $cpucount ]
|
||||
do
|
||||
while [ $i -ne $cpucount ]; do
|
||||
FLNM="$FLROOT/cpu"$i"/cpufreq/energy_performance_preference"
|
||||
echo $VALUE > $FLNM
|
||||
write_value
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
else
|
||||
echo $VALUE > /sys/devices/system/cpu/cpu$CORE/cpufreq/energy_performance_preference
|
||||
else echo $VALUE > $FLROOT/cpu$CORE/cpufreq/energy_performance_preference
|
||||
fi
|
||||
}
|
||||
|
||||
if [ -z $OPTION ] # No options
|
||||
then
|
||||
info
|
||||
exit
|
||||
fi
|
||||
if [ $OPTION = "--help" ]
|
||||
then
|
||||
help
|
||||
exit
|
||||
fi
|
||||
if [ $OPTION = "--version" ]
|
||||
then
|
||||
echo $VERSION
|
||||
exit
|
||||
fi
|
||||
if [ $OPTION = "--driver" ]
|
||||
then
|
||||
driver
|
||||
exit
|
||||
fi
|
||||
if [ $OPTION = "--governor" ]
|
||||
then
|
||||
if [ ! -z $AVAILABLE ]
|
||||
then
|
||||
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
|
||||
exit
|
||||
|
||||
function get_energy_performance_bias () {
|
||||
if [ -z $CORE ]; then
|
||||
i=0
|
||||
ag=''
|
||||
while [ $i -ne $cpucount ]; do
|
||||
if [ $i = 0 ]; then
|
||||
ag=`cat $FLROOT/cpu0/power/energy_perf_bias`
|
||||
else
|
||||
ag=$ag' '`cat $FLROOT/cpu$i/power/energy_perf_bias`
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
echo $ag
|
||||
else cat $FLROOT/cpu$CORE/power/energy_perf_bias
|
||||
fi
|
||||
if [ -z $VALUE ]
|
||||
then
|
||||
verbose "Getting CPU"$CORE" governors"
|
||||
get_governor
|
||||
}
|
||||
|
||||
function set_energy_performance_bias () {
|
||||
if [ `driver` != 'intel_pstate' ]; then
|
||||
verbose "EPB is not supported by a driver other than intel_pstate"
|
||||
return
|
||||
fi
|
||||
local EPB_VALUE=6 # default value
|
||||
if [[ "$VALUE" =~ ^[0-9]+$ && $VALUE -ge 0 && $VALUE -le 15 ]]; then
|
||||
EPB_VALUE=$VALUE
|
||||
else
|
||||
verbose "Setting CPU"$CORE" governors to "$VALUE
|
||||
set_governor
|
||||
case $VALUE in
|
||||
performance) EPB_VALUE=0;;
|
||||
balance_performance) EPB_VALUE=4;;
|
||||
default) EPB_VALUE=6;;
|
||||
balance_power) EPB_VALUE=8;;
|
||||
power) EPB_VALUE=15;;
|
||||
*)
|
||||
verbose "Invalid value provided for EPB"
|
||||
verbose "Acceptable values: performance|balance-power|default|balance-power|power or a number in the range [0-15]"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
if [ $OPTION = "--epp" ]
|
||||
then
|
||||
if [ ! -z $AVAILABLE ]
|
||||
then
|
||||
cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_available_preferences
|
||||
exit
|
||||
|
||||
if [ -z $CORE ]; then
|
||||
i=0
|
||||
while [ $i -ne $cpucount ]; do
|
||||
FLNM="$FLROOT/cpu"$i"/power/energy_perf_bias"
|
||||
if [ -w $FLNM ]; then echo $EPB_VALUE > $FLNM; fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
else echo $EPB_VALUE > $FLROOT/cpu$CORE/power/energy_perf_bias
|
||||
fi
|
||||
if [ -z $VALUE ]
|
||||
then
|
||||
verbose "Getting CPU"$CORE" EPPs"
|
||||
get_energy_performance_preference
|
||||
else
|
||||
verbose "Setting CPU"$CORE" EPPs to "$VALUE
|
||||
set_energy_performance_preference
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
if [ $OPTION = "--frequency" ]
|
||||
then
|
||||
if [ ! -z $AVAILABLE ]
|
||||
then
|
||||
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
|
||||
exit
|
||||
fi
|
||||
if [ -z $VALUE ]
|
||||
then
|
||||
verbose "Getting CPU"$CORE" frequency"
|
||||
get_frequency
|
||||
else
|
||||
verbose "Setting CPU"$CORE" frequency to "$VALUE
|
||||
set_frequency
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
if [ $OPTION = "--no-turbo" ]
|
||||
then
|
||||
if [ -z $VALUE ]
|
||||
then
|
||||
verbose "Getting no_turbo value"
|
||||
cat /sys/devices/system/cpu/intel_pstate/no_turbo
|
||||
else
|
||||
verbose "Setting no_turbo value "$VALUE
|
||||
echo $VALUE > /sys/devices/system/cpu/intel_pstate/no_turbo
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
if [ $OPTION = "--boost" ]
|
||||
then
|
||||
if [ -z $VALUE ]
|
||||
then
|
||||
verbose "Getting boost value"
|
||||
cat /sys/devices/system/cpu/cpufreq/boost
|
||||
else
|
||||
verbose "Setting boost value "$VALUE
|
||||
echo $VALUE > /sys/devices/system/cpu/cpufreq/boost
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
if [ $OPTION = "--frequency-min" ]
|
||||
then
|
||||
if [ -z $VALUE ]
|
||||
then
|
||||
verbose "Getting CPU"$CORE" minimal frequency"
|
||||
get_frequency_min
|
||||
else
|
||||
verbose "Setting CPU"$CORE" minimal frequency to "$VALUE
|
||||
set_frequency_min
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
if [ $OPTION = "--frequency-max" ]
|
||||
then
|
||||
if [ -z $VALUE ]
|
||||
then
|
||||
verbose "Getting CPU"$CORE" maximal frequency"
|
||||
get_frequency_max
|
||||
else
|
||||
verbose "Setting CPU"$CORE" maximal frequency to "$VALUE
|
||||
set_frequency_max
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
if [ $OPTION = "--frequency-min-limit" ]
|
||||
then
|
||||
}
|
||||
|
||||
case $OPTION in
|
||||
-h|--help) help;;
|
||||
--version) echo $VERSION;;
|
||||
-d|--driver) driver;;
|
||||
-g|--governor)
|
||||
if [ ! -z $AVAILABLE ]; then cat $FLROOT/cpu0/cpufreq/scaling_available_governors
|
||||
elif [ -z $VALUE ]; then
|
||||
verbose "Getting CPU"$CORE" governors"
|
||||
get_governor
|
||||
else
|
||||
verbose "Setting CPU"$CORE" governors to "$VALUE
|
||||
set_governor
|
||||
fi
|
||||
;;
|
||||
-e|--epp)
|
||||
if [ ! -z $AVAILABLE ]; then cat $FLROOT/cpu0/cpufreq/energy_performance_available_preferences
|
||||
elif [ -z $VALUE ]; then
|
||||
verbose "Getting CPU"$CORE" EPPs"
|
||||
get_energy_performance_preference
|
||||
else
|
||||
verbose "Setting CPU"$CORE" EPPs to "$VALUE
|
||||
set_energy_performance_preference
|
||||
fi
|
||||
;;
|
||||
--epb)
|
||||
if [ ! -z $AVAILABLE ]; then cat $FLROOT/cpu0/power/energy_perf_bias
|
||||
elif [ -z $VALUE ]; then
|
||||
verbose "Getting CPU"$CORE" EPBs"
|
||||
get_energy_performance_bias
|
||||
else
|
||||
verbose "Setting CPU"$CORE" EPBs to "$VALUE
|
||||
set_energy_performance_bias
|
||||
fi
|
||||
;;
|
||||
-p|--pp)
|
||||
if [ ! -z $AVAILABLE ]; then cat $FWROOT/acpi/platform_profile_choices
|
||||
elif [ -z $VALUE ]; then
|
||||
verbose "Getting Platform Profile"
|
||||
cat $FWROOT/acpi/platform_profile
|
||||
else
|
||||
verbose "Getting Platform Profile to "$VALUE
|
||||
echo $VALUE > $FWROOT/acpi/platform_profile
|
||||
fi
|
||||
;;
|
||||
-f|--frequency)
|
||||
if [ ! -z $AVAILABLE ]; then cat $FLROOT/cpu0/cpufreq/scaling_available_frequencies
|
||||
elif [ -z $VALUE ]; then
|
||||
verbose "Getting CPU"$CORE" frequency"
|
||||
get_frequency
|
||||
else
|
||||
verbose "Setting CPU"$CORE" frequency to "$VALUE
|
||||
set_frequency
|
||||
fi
|
||||
;;
|
||||
--no-turbo)
|
||||
if [ -z $VALUE ]; then
|
||||
verbose "Getting no_turbo value"
|
||||
cat $FLROOT/intel_pstate/no_turbo
|
||||
else
|
||||
verbose "Setting no_turbo value "$VALUE
|
||||
echo $VALUE > $FLROOT/intel_pstate/no_turbo
|
||||
fi
|
||||
;;
|
||||
-b|--boost)
|
||||
if [ -z $VALUE ]; then
|
||||
verbose "Getting boost value"
|
||||
cat $FLROOT/cpufreq/boost
|
||||
else
|
||||
verbose "Setting boost value "$VALUE
|
||||
echo $VALUE > $FLROOT/cpufreq/boost
|
||||
fi
|
||||
;;
|
||||
--frequency-min)
|
||||
if [ -z $VALUE ]; then
|
||||
verbose "Getting CPU"$CORE" minimal frequency"
|
||||
get_frequency_min
|
||||
else
|
||||
verbose "Setting CPU"$CORE" minimal frequency to "$VALUE
|
||||
set_frequency_min
|
||||
fi
|
||||
;;
|
||||
--frequency-max)
|
||||
if [ -z $VALUE ]; then
|
||||
verbose "Getting CPU"$CORE" maximal frequency"
|
||||
get_frequency_max
|
||||
else
|
||||
verbose "Setting CPU"$CORE" maximal frequency to "$VALUE
|
||||
set_frequency_max
|
||||
fi
|
||||
;;
|
||||
--frequency-min-limit)
|
||||
verbose "Getting CPU"$CORE" minimal frequency limit"
|
||||
get_frequency_min_limit
|
||||
fi
|
||||
if [ $OPTION = "--frequency-max-limit" ]
|
||||
then
|
||||
;;
|
||||
--frequency-max-limit)
|
||||
verbose "Getting CPU"$CORE" maximum frequency limit"
|
||||
get_frequency_max_limit
|
||||
fi
|
||||
if [ $OPTION = "--min-perf" ]
|
||||
then
|
||||
if [ -z $VALUE ]
|
||||
then
|
||||
verbose "Getting min_perf_pct value"
|
||||
cat /sys/devices/system/cpu/intel_pstate/min_perf_pct
|
||||
else
|
||||
verbose "Setting min_perf_pct value "$VALUE
|
||||
echo $VALUE > /sys/devices/system/cpu/intel_pstate/min_perf_pct
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
if [ $OPTION = "--max-perf" ]
|
||||
then
|
||||
if [ -z $VALUE ]
|
||||
then
|
||||
verbose "Getting max_perf_pct value"
|
||||
cat /sys/devices/system/cpu/intel_pstate/max_perf_pct
|
||||
else
|
||||
verbose "Setting max_perf_pct value "$VALUE
|
||||
echo $VALUE > /sys/devices/system/cpu/intel_pstate/max_perf_pct
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
if [ $OPTION = "--on" ]
|
||||
then
|
||||
if [ -z $CORE ]
|
||||
then
|
||||
verbose "Should be specify --core=NUMBER"
|
||||
else
|
||||
verbose "Power on CPU Core"$CORE
|
||||
echo "1" > $FLROOT/cpu"$CORE"/online
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
if [ $OPTION = "--off" ]
|
||||
then
|
||||
if [ -z $CORE ]
|
||||
then
|
||||
verbose "Should be specify --core=NUMBER"
|
||||
else
|
||||
verbose "Power off CPU Core"$CORE
|
||||
echo "0" > $FLROOT/cpu"$CORE"/online
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
;;
|
||||
--min-perf)
|
||||
if [ -z $VALUE ]; then
|
||||
verbose "Getting min_perf_pct value"
|
||||
cat $FLROOT/intel_pstate/min_perf_pct
|
||||
else
|
||||
verbose "Setting min_perf_pct value "$VALUE
|
||||
echo $VALUE > $FLROOT/intel_pstate/min_perf_pct
|
||||
fi
|
||||
;;
|
||||
--max-perf)
|
||||
if [ -z $VALUE ]; then
|
||||
verbose "Getting max_perf_pct value"
|
||||
cat $FLROOT/intel_pstate/max_perf_pct
|
||||
else
|
||||
verbose "Setting max_perf_pct value "$VALUE
|
||||
echo $VALUE > $FLROOT/intel_pstate/max_perf_pct
|
||||
fi
|
||||
;;
|
||||
--on)
|
||||
if [ -z $CORE ]; then verbose "Should be specify --core=NUMBER"
|
||||
else
|
||||
verbose "Power on CPU Core"$CORE
|
||||
echo "1" > $FLROOT/cpu"$CORE"/online
|
||||
fi
|
||||
;;
|
||||
--off)
|
||||
if [ -z $CORE ]; then verbose "Should be specify --core=NUMBER"
|
||||
else
|
||||
verbose "Power off CPU Core$CORE"
|
||||
echo "0" > $FLROOT/cpu"$CORE"/online
|
||||
fi
|
||||
;;
|
||||
--throttle)
|
||||
i=1
|
||||
V=0
|
||||
M=$(cat "$FLROOT/cpu0/thermal_throttle/core_throttle_count")
|
||||
while [ $i -ne $cpucount ]; do
|
||||
V=$(cat "$FLROOT/cpu$i/thermal_throttle/core_throttle_count")
|
||||
M=`expr $M + $V`
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
echo "$M"
|
||||
;;
|
||||
--throttle-events)
|
||||
M=$(journalctl --dmesg --boot --since=yesterday | grep "cpu clock throttled" | wc -l)
|
||||
echo "$M"
|
||||
;;
|
||||
--irqbalance)
|
||||
M=$(ps -A | grep irqbalance)
|
||||
echo "$M"
|
||||
;;
|
||||
*)
|
||||
info
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $OPTION = "--throttle" ]
|
||||
then
|
||||
i=1
|
||||
V=0
|
||||
M=$(cat "/sys/devices/system/cpu/cpu0/thermal_throttle/core_throttle_count")
|
||||
while [ $i -ne $cpucount ]
|
||||
do
|
||||
V=$(cat "/sys/devices/system/cpu/cpu"$i"/thermal_throttle/core_throttle_count")
|
||||
M=`expr $M + $V`
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
echo "$M"
|
||||
exit
|
||||
fi
|
||||
if [ $OPTION = "--throttle-events" ]
|
||||
then
|
||||
M=$(journalctl --dmesg --boot --since=yesterday | grep "cpu clock throttled" | wc -l)
|
||||
echo "$M"
|
||||
exit
|
||||
fi
|
||||
if [ $OPTION = "--irqbalance" ]
|
||||
then
|
||||
M=$(ps -A |grep irqbalance)
|
||||
echo "$M"
|
||||
exit
|
||||
fi
|
||||
exit 0
|
||||
|
19
scripts/org.auto-cpufreq.pkexec.policy
Normal file
19
scripts/org.auto-cpufreq.pkexec.policy
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE policyconfig PUBLIC
|
||||
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
|
||||
<policyconfig>
|
||||
<action id="org.auto-cpufreq.pkexec">
|
||||
<description>Run auto-cpufreq command</description>
|
||||
<message>Authentication is required to run auto-cpufreq</message>
|
||||
<icon_name>auto-cpufreq</icon_name>
|
||||
<defaults>
|
||||
<allow_any>auth_admin</allow_any>
|
||||
<allow_inactive>auth_admin</allow_inactive>
|
||||
<allow_active>auth_admin</allow_active>
|
||||
</defaults>
|
||||
<annotate key="org.freedesktop.policykit.exec.path">/opt/auto-cpufreq/venv/bin/auto-cpufreq</annotate>
|
||||
<!-- <annotate key="org.freedesktop.policykit.exec.argv1">/opt/auto-cpufreq/venv/bin/auto-cpufreq</annotate> -->
|
||||
<!-- <annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate> -->
|
||||
</action>
|
||||
</policyconfig>
|
@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# workaround for running Daemon without polluting syslog (#53, #82)
|
||||
$SNAP/bin/auto-cpufreq --daemon 2>&1 >> $SNAP_DATA/auto-cpufreq.stats
|
||||
|
18
scripts/start_app
Normal file
18
scripts/start_app
Normal file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/sh
|
||||
|
||||
# load python virtual environment
|
||||
venv_dir=/opt/auto-cpufreq/venv
|
||||
. "$venv_dir/bin/activate"
|
||||
python_command="$venv_dir/bin/auto-cpufreq-gtk"
|
||||
|
||||
# if [ "$XDG_SESSION_TYPE" = "wayland" ] ; then
|
||||
# # necessary for running on wayland
|
||||
# xhost +SI:localuser:root
|
||||
# pkexec $python_command
|
||||
# xhost -SI:localuser:root
|
||||
# xhost
|
||||
# else
|
||||
# pkexec $python_command
|
||||
# fi
|
||||
|
||||
$python_command
|
8
scripts/style.css
Normal file
8
scripts/style.css
Normal file
@ -0,0 +1,8 @@
|
||||
label {
|
||||
/*font-family: Noto Sans;*/
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
#bold { font-weight: bold; }
|
||||
|
||||
#small { font-size: 12px; }
|
44
setup.py
44
setup.py
@ -1,44 +0,0 @@
|
||||
import os
|
||||
|
||||
from setuptools import setup
|
||||
|
||||
with open("README.md") as readme_file:
|
||||
readme = readme_file.read()
|
||||
|
||||
this = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
|
||||
def read(name):
|
||||
with open(os.path.join(this, name)) as f:
|
||||
return f.read()
|
||||
|
||||
# Used for the tar.gz/snap releases
|
||||
VERSION = "1.9.6"
|
||||
|
||||
setup(
|
||||
name="auto-cpufreq",
|
||||
setuptools_git_versioning={
|
||||
"starting_version": VERSION,
|
||||
"template": "{tag}+{sha}",
|
||||
"dev_template": "{tag}+{sha}",
|
||||
"dirty_template": "{tag}+{sha}.post{ccount}.dirty"
|
||||
},
|
||||
setup_requires=["setuptools-git-versioning"],
|
||||
description="Automatic CPU speed & power optimizer for Linux",
|
||||
long_description=readme,
|
||||
author="Adnan Hodzic",
|
||||
author_email="adnan@hodzic.org",
|
||||
url="https://github.com/AdnanHodzic/auto-cpufreq",
|
||||
packages=["auto_cpufreq"],
|
||||
install_requires=read("requirements.txt"),
|
||||
include_package_data=True,
|
||||
zip_safe=True,
|
||||
license="GPLv3",
|
||||
keywords="linux cpu speed power frequency turbo optimzier auto cpufreq",
|
||||
classifiers=[
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Intended Audience :: Developers",
|
||||
"Operating System :: POSIX :: Linux" "Environment :: Console" "Natural Language :: English",
|
||||
],
|
||||
scripts=["bin/auto-cpufreq"],
|
||||
)
|
BIN
snap/gui/auto-cpufreq.png
Normal file
BIN
snap/gui/auto-cpufreq.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
10
snap/gui/auto-cpufreq_auto-cpufreq.desktop
Normal file
10
snap/gui/auto-cpufreq_auto-cpufreq.desktop
Normal file
@ -0,0 +1,10 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Encoding=UTF-8
|
||||
Name=auto-cpufreq
|
||||
Comment=Automatic CPU speed & power optimizer for Linux
|
||||
Exec=auto-cpufreq.auto-cpufreq-gtk
|
||||
StartupWMClass=app.py
|
||||
Terminal=false
|
||||
Icon=${SNAP}/meta/gui/auto-cpufreq.png
|
||||
Categories=System;
|
@ -14,22 +14,30 @@ adopt-info: auto-cpufreq
|
||||
|
||||
compression: lzo
|
||||
|
||||
architectures:
|
||||
- build-on: [amd64]
|
||||
build-for: [amd64]
|
||||
- build-on: [amd64]
|
||||
build-for: [arm64]
|
||||
|
||||
parts:
|
||||
auto-cpufreq:
|
||||
plugin: python
|
||||
python-packages:
|
||||
- setuptools
|
||||
- wheel
|
||||
- requests
|
||||
build-packages:
|
||||
- gcc
|
||||
- python3-dev
|
||||
stage-packages:
|
||||
- coreutils
|
||||
- dmidecode
|
||||
- pkexec
|
||||
source: .
|
||||
override-pull: |
|
||||
snapcraftctl pull
|
||||
snapcraftctl set-version `grep ^VERSION $SNAPCRAFT_PART_SRC/setup.py | sed 's/.*"\(.*\)"/\1/'`
|
||||
snapcraftctl set-version `grep ^version $SNAPCRAFT_PART_SRC/pyproject.toml | sed 's/.*"\(.*\)"/\1/'`
|
||||
|
||||
deploy-scripts:
|
||||
plugin: dump
|
||||
@ -38,6 +46,10 @@ parts:
|
||||
cpufreqctl.sh: usr/bin/cpufreqctl.auto-cpufreq
|
||||
snapdaemon.sh: usr/bin/snapdaemon
|
||||
|
||||
copy-image:
|
||||
plugin: dump
|
||||
source: images
|
||||
|
||||
plugs:
|
||||
etc-auto-cpufreq-conf:
|
||||
interface: system-files
|
||||
@ -58,13 +70,28 @@ apps:
|
||||
- hardware-observe
|
||||
- etc-auto-cpufreq-conf
|
||||
|
||||
auto-cpufreq-gtk:
|
||||
command: bin/auto-cpufreq-gtk
|
||||
extensions: [gnome]
|
||||
environment:
|
||||
PYTHONPATH: $SNAP/usr/lib/python3/site-packages:$SNAP/usr/lib/python3/dist-packages:$PYTHONPATH
|
||||
LC_ALL: C.UTF-8
|
||||
LANG: C.UTF-8
|
||||
PKG_MARKER: SNAP
|
||||
plugs:
|
||||
- cpu-control
|
||||
- system-observe
|
||||
- hardware-observe
|
||||
- desktop
|
||||
- desktop-legacy
|
||||
- wayland
|
||||
- x11
|
||||
service:
|
||||
command: usr/bin/snapdaemon
|
||||
plugs:
|
||||
- cpu-control
|
||||
- system-observe
|
||||
- hardware-observe
|
||||
- etc-auto-cpufreq-conf
|
||||
environment:
|
||||
LC_ALL: C.UTF-8
|
||||
LANG: C.UTF-8
|
||||
|
Loading…
x
Reference in New Issue
Block a user