312 lines
13 KiB
Python
312 lines
13 KiB
Python
# * 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
|
|
import click
|
|
from shutil import which
|
|
from subprocess import call, DEVNULL, getoutput, STDOUT
|
|
from sys import argv
|
|
|
|
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
|
|
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 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
|
|
|
|
bluetoothctl_exists = does_command_exists("bluetoothctl")
|
|
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 not IS_INSTALLED_WITH_SNAP:
|
|
if systemctl_exists:
|
|
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(GITHUB+"/issues")
|
|
|
|
# alert in case TLP service is running
|
|
def tlp_service_detect():
|
|
if tlp_stat_exists:
|
|
status_output = getoutput("tlp-stat -s")
|
|
tlp_status = TLPStatusParser(status_output)
|
|
if tlp_status.is_enabled():
|
|
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.")
|
|
|
|
# alert about TLP when using snap
|
|
def tlp_service_detect_snap():
|
|
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 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 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():
|
|
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("\nSteps 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")
|
|
|
|
# stops gnome >= 40 power profiles (live)
|
|
def gnome_power_stop_live():
|
|
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"])
|
|
|
|
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("* Enabling GNOME power profiles\n")
|
|
call(["systemctl", "unmask", "power-profiles-daemon"])
|
|
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(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():
|
|
if systemctl_exists:
|
|
try:
|
|
print("* GNOME power profiles status")
|
|
call(["systemctl", "status", "power-profiles-daemon"])
|
|
except:
|
|
print("\nUnable to see GNOME power profiles status")
|
|
print("If this causes any problems, please submit an issue:")
|
|
print(GITHUB+"/issues")
|
|
|
|
# disable bluetooth on boot
|
|
def bluetooth_disable():
|
|
if IS_INSTALLED_WITH_SNAP: bluetooth_notif_snap()
|
|
elif bluetoothctl_exists:
|
|
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"
|
|
change_set = "AutoEnable=false"
|
|
with btconf.open(mode="r+") as f:
|
|
content = f.read()
|
|
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)")
|
|
|
|
# enable bluetooth on boot
|
|
def bluetooth_enable():
|
|
if IS_INSTALLED_WITH_SNAP: bluetooth_on_notif_snap()
|
|
if bluetoothctl_exists:
|
|
print("* Turn on bluetooth on boot")
|
|
btconf = "/etc/bluetooth/main.conf"
|
|
try:
|
|
orig_set = "AutoEnable=true"
|
|
change_set = "AutoEnable=false"
|
|
with open(btconf, "r+") as f:
|
|
content = f.read()
|
|
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)")
|
|
|
|
# turn off bluetooth on snap message
|
|
def bluetooth_notif_snap():
|
|
print("\n* Unable to turn off 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_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 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():
|
|
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(f"git clone {GITHUB}.git")
|
|
print("cd auto-cpufreq/auto_cpufreq")
|
|
print("python3 power_helper.py --gnome_power_enable")
|
|
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", "disable", "--now", "power-profiles-daemon"])
|
|
call(["systemctl", "mask", "power-profiles-daemon"])
|
|
except:
|
|
print("\nUnable to disable GNOME power profiles")
|
|
print("If this causes any problems, please submit an issue:")
|
|
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:
|
|
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
|
|
|
|
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"])
|
|
|
|
disable_power_profiles_daemon()
|
|
|
|
def tuned_svc_disable():
|
|
if systemctl_exists and tuned_stat_exists:
|
|
disable_tuned_daemon()
|
|
|
|
# cli
|
|
@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", is_flag=True, help="Disable GNOME Power profiles service")
|
|
# ToDo:
|
|
# * update readme/docs
|
|
@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("--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(
|
|
gnome_power_enable,
|
|
gnome_power_disable,
|
|
gnome_power_status,
|
|
bluetooth_boot_off,
|
|
bluetooth_boot_on,
|
|
):
|
|
root_check()
|
|
header()
|
|
|
|
if len(argv) == 1: print('Unrecognized option!\n\nRun: "' + app_name + ' --help" for list of available options.')
|
|
else:
|
|
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() |