diff --git a/README.md b/README.md index 1f24483..6ac5c9e 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,31 @@ In case you encounter any problems with `auto-cpufreq-installer`, please [submit 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 accross reboots. +## Configuring auto-cpufreq + +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. + +### Example config +``` +# 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. +governor = performance + +# turbo boost setting. possible values: always, auto, never +turbo = auto + +# 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 + +# turbo boost setting. possible values: always, auto, never +turbo = auto +``` + ## How to run auto-cpufreq auto-cpufreq can be run by simply running the `auto-cpufreq` and following on screen instructions, i.e: diff --git a/auto-cpufreq.conf-example b/auto-cpufreq.conf-example new file mode 100644 index 0000000..994dfe5 --- /dev/null +++ b/auto-cpufreq.conf-example @@ -0,0 +1,20 @@ +# configuration file for auto-cpufreq +# located in /etc/auto-cpufreq.conf + +# 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. +governor = performance + +# turbo boost setting. possible values: always, auto, never +turbo = auto + +#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 + +# turbo boost setting. possible values: always, auto, never +turbo = auto diff --git a/auto_cpufreq/core.py b/auto_cpufreq/core.py index 83d0d64..b297eb0 100644 --- a/auto_cpufreq/core.py +++ b/auto_cpufreq/core.py @@ -11,6 +11,7 @@ import distro import time import click import warnings +import configparser from math import isclose from pathlib import Path from subprocess import getoutput, call, run, check_output, DEVNULL @@ -61,6 +62,17 @@ def file_stats(): auto_cpufreq_stats_file = open(auto_cpufreq_stats_path, "w") sys.stdout = auto_cpufreq_stats_file +def get_config(config_file=''): + if not hasattr(get_config, 'dict'): + get_config.dict = dict() + + config = configparser.ConfigParser() + config.read(config_file) + + for section in config.sections(): + get_config.dict[section] = dict(config.items(section)) + + return get_config.dict # get distro name dist_name = distro.id() @@ -415,8 +427,14 @@ def display_load(): # set powersave and enable turbo def set_powersave(): - print(f'Setting to use: "{get_avail_powersave()}" governor') - run(f"cpufreqctl.auto-cpufreq --governor --set={get_avail_powersave()}", shell=True) + gov = get_config() + if "battery" in gov: + if "governor" in gov["battery"]: + gov = gov["battery"]["governor"] + else: + gov = get_avail_powersave() + print(f'Setting to use: "{gov}" governor') + run(f"cpufreqctl.auto-cpufreq --governor --set={gov}", shell=True) if ( Path( "/sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference" @@ -438,76 +456,92 @@ def set_powersave(): print("Average temp. of all cores:", avg_all_core_temp, "°C") # conditions for setting turbo in powersave - if psutil.cpu_percent(percpu=False, interval=0.01) >= 30.0 or isclose( - max(psutil.cpu_percent(percpu=True, interval=0.01)), 100 - ): - print("\nHigh CPU load") - - # high cpu usage trigger - if cpuload >= 20: - print("setting turbo boost: on") - turbo(True) - - # set turbo state based on average of all core temperatures - elif cpuload <= 20 and avg_all_core_temp >= 70: - print( - "Optimal total CPU usage:", - cpuload, - "%, high average core temp:", - avg_all_core_temp, - "°C", - ) - print("setting turbo boost: off") - turbo(False) - else: - print("setting turbo boost: off") - turbo(False) - - elif load1m > powersave_load_threshold: - print("\nHigh system load") - - # high cpu usage trigger - if cpuload >= 20: - print("setting turbo boost: on") - turbo(True) - - # set turbo state based on average of all core temperatures - elif cpuload <= 20 and avg_all_core_temp >= 65: - print( - "Optimal total CPU usage:", - cpuload, - "%, high average core temp:", - avg_all_core_temp, - "°C", - ) - print("setting turbo boost: off") - turbo(False) - else: - print("setting turbo boost: off") - turbo(False) - + auto = get_config() + if "battery" in auto: + if "turbo" in auto["battery"]: + auto = auto["battery"]["turbo"] else: - print("\nLoad optimal") + auto = "auto" - # high cpu usage trigger - if cpuload >= 20: - print("setting turbo boost: on") - turbo(True) + if auto == "always": + print("Configuration file enforces turbo boost") + print("setting turbo boost: on") + turbo(True) + elif auto == "never": + print("Configuration file disables turbo boost") + print("setting turbo boost: off") + turbo(True) + else: + if psutil.cpu_percent(percpu=False, interval=0.01) >= 30.0 or isclose( + max(psutil.cpu_percent(percpu=True, interval=0.01)), 100 + ): + print("\nHigh CPU load") + + # high cpu usage trigger + if cpuload >= 20: + print("setting turbo boost: on") + turbo(True) + + # set turbo state based on average of all core temperatures + elif cpuload <= 20 and avg_all_core_temp >= 70: + print( + "Optimal total CPU usage:", + cpuload, + "%, high average core temp:", + avg_all_core_temp, + "°C", + ) + print("setting turbo boost: off") + turbo(False) + else: + print("setting turbo boost: off") + turbo(False) + + elif load1m > powersave_load_threshold: + print("\nHigh system load") + + # high cpu usage trigger + if cpuload >= 20: + print("setting turbo boost: on") + turbo(True) + + # set turbo state based on average of all core temperatures + elif cpuload <= 20 and avg_all_core_temp >= 65: + print( + "Optimal total CPU usage:", + cpuload, + "%, high average core temp:", + avg_all_core_temp, + "°C", + ) + print("setting turbo boost: off") + turbo(False) + else: + print("setting turbo boost: off") + turbo(False) - # set turbo state based on average of all core temperatures - elif cpuload <= 20 and avg_all_core_temp >= 60: - print( - "Optimal total CPU usage:", - cpuload, - "%, high average core temp:", - avg_all_core_temp, - "°C", - ) - print("setting turbo boost: off") - turbo(False) else: - print("setting turbo boost: off") - turbo(False) + print("\nLoad optimal") + + # high cpu usage trigger + if cpuload >= 20: + print("setting turbo boost: on") + turbo(True) + + # set turbo state based on average of all core temperatures + elif cpuload <= 20 and avg_all_core_temp >= 60: + print( + "Optimal total CPU usage:", + cpuload, + "%, high average core temp:", + avg_all_core_temp, + "°C", + ) + print("setting turbo boost: off") + turbo(False) + else: + print("setting turbo boost: off") + turbo(False) footer() @@ -601,10 +635,16 @@ def mon_powersave(): # set performance and enable turbo def set_performance(): + gov = get_config() + if "charger" in gov: + if "governor" in gov["charger"]: + gov = gov["charger"]["governor"] + else: + gov = get_avail_performance() - print(f'Setting to use: "{get_avail_performance()}" governor') + print(f'Setting to use: "{gov}" governor') run( - f"cpufreqctl.auto-cpufreq --governor --set={get_avail_performance()}", + f"cpufreqctl.auto-cpufreq --governor --set={gov}", shell=True, ) if ( @@ -627,77 +667,93 @@ def set_performance(): print("Total system load:", load1m) print("Average temp. of all cores:", avg_all_core_temp, "°C") - if ( - psutil.cpu_percent(percpu=False, interval=0.01) >= 20.0 - or max(psutil.cpu_percent(percpu=True, interval=0.01)) >= 75 - ): - print("\nHigh CPU load") - - # high cpu usage trigger - if cpuload >= 20: - print("setting turbo boost: on") - turbo(True) - - # set turbo state based on average of all core temperatures - elif cpuload <= 25 and avg_all_core_temp >= 70: - print( - "Optimal total CPU usage:", - cpuload, - "%, high average core temp:", - avg_all_core_temp, - "°C", - ) - print("setting turbo boost: off") - turbo(False) - else: - print("setting turbo boost: on") - turbo(True) - - elif load1m >= performance_load_threshold: - print("\nHigh system load") - - # high cpu usage trigger - if cpuload >= 20: - print("setting turbo boost: on") - turbo(True) - - # set turbo state based on average of all core temperatures - elif cpuload <= 25 and avg_all_core_temp >= 65: - print( - "Optimal total CPU usage:", - cpuload, - "%, high average core temp:", - avg_all_core_temp, - "°C", - ) - print("setting turbo boost: off") - turbo(False) - else: - print("setting turbo boost: on") - turbo(True) - + auto = get_config() + if "charger" in auto: + if "turbo" in auto["charger"]: + auto = auto["charger"]["turbo"] else: - print("\nLoad optimal") + auto = "auto" - # high cpu usage trigger - if cpuload >= 20: - print("setting turbo boost: on") - turbo(True) + if auto == "always": + print("Configuration file enforces turbo boost") + print("setting turbo boost: on") + turbo(True) + elif auto == "never": + print("Configuration file disables turbo boost") + print("setting turbo boost: off") + turbo(True) + else: + if ( + psutil.cpu_percent(percpu=False, interval=0.01) >= 20.0 + or max(psutil.cpu_percent(percpu=True, interval=0.01)) >= 75 + ): + print("\nHigh CPU load") + + # high cpu usage trigger + if cpuload >= 20: + print("setting turbo boost: on") + turbo(True) + + # set turbo state based on average of all core temperatures + elif cpuload <= 25 and avg_all_core_temp >= 70: + print( + "Optimal total CPU usage:", + cpuload, + "%, high average core temp:", + avg_all_core_temp, + "°C", + ) + print("setting turbo boost: off") + turbo(False) + else: + print("setting turbo boost: on") + turbo(True) + + elif load1m >= performance_load_threshold: + print("\nHigh system load") + + # high cpu usage trigger + if cpuload >= 20: + print("setting turbo boost: on") + turbo(True) + + # set turbo state based on average of all core temperatures + elif cpuload <= 25 and avg_all_core_temp >= 65: + print( + "Optimal total CPU usage:", + cpuload, + "%, high average core temp:", + avg_all_core_temp, + "°C", + ) + print("setting turbo boost: off") + turbo(False) + else: + print("setting turbo boost: on") + turbo(True) - # set turbo state based on average of all core temperatures - elif cpuload <= 25 and avg_all_core_temp >= 60: - print( - "Optimal total CPU usage:", - cpuload, - "%, high average core temp:", - avg_all_core_temp, - "°C", - ) - print("setting turbo boost: off") - turbo(False) else: - print("setting turbo boost: off") - turbo(False) + print("\nLoad optimal") + + # high cpu usage trigger + if cpuload >= 20: + print("setting turbo boost: on") + turbo(True) + + # set turbo state based on average of all core temperatures + elif cpuload <= 25 and avg_all_core_temp >= 60: + print( + "Optimal total CPU usage:", + cpuload, + "%, high average core temp:", + avg_all_core_temp, + "°C", + ) + print("setting turbo boost: off") + turbo(False) + else: + print("setting turbo boost: off") + turbo(False) footer() diff --git a/bin/auto-cpufreq b/bin/auto-cpufreq index 804aa7a..6395e32 100755 --- a/bin/auto-cpufreq +++ b/bin/auto-cpufreq @@ -15,6 +15,7 @@ from auto_cpufreq.core import * # cli @click.command() +@click.option("--config", is_flag=False, default="/etc/auto-cpufreq.conf", help="Use config file at defined path") @click.option("--daemon", is_flag=True, hidden=True) @click.option("--debug", is_flag=True, help="Show debug info (include when submitting bugs)") @click.option("--install/--remove", default=True, help="Install/remove daemon for (permanent) automatic CPU optimizations") @@ -23,7 +24,7 @@ from auto_cpufreq.core import * @click.option("--monitor", is_flag=True, help="Monitor and see suggestions for CPU optimizations") @click.option("--stats", is_flag=True, help="View live stats of CPU optimizations made by daemon") @click.option("--version", is_flag=True, help="Show currently installed version") -def main(daemon, debug, install, live, log, monitor, stats, version): +def main(config, daemon, debug, install, live, log, monitor, stats, version): if len(sys.argv) == 1: print("\n" + "-" * 32 + " auto-cpufreq " + "-" * 33 + "\n") print("Automatic CPU speed & power optimizer for Linux") @@ -33,6 +34,8 @@ def main(daemon, debug, install, live, log, monitor, stats, version): run(["auto-cpufreq", "--help"]) footer() else: + if bool(get_config(config)): + print("\nUsing settings defined in " + config + " file") # Important: order does matter if daemon: file_stats()