2021-11-28 14:49:14 +01:00
# * add status as one of the available options
# * alert user on snap if detected and how to remove first time live/stats message starts
2021-11-28 14:06:46 +01:00
# * if daemon is disabled and auto-cpufreq is removed (snap) remind user to enable it back
2022-02-06 16:54:56 +01:00
from logging import root
2021-11-28 14:06:46 +01:00
import os , sys , click
from subprocess import getoutput , call , run , check_output , DEVNULL
2021-12-22 08:28:08 +01:00
sys . path . append ( " ../ " )
2021-11-28 14:06:46 +01:00
from auto_cpufreq . core import *
2021-12-11 11:59:41 +01:00
from auto_cpufreq . tlp_stat_parser import TLPStatusParser
2021-11-28 14:06:46 +01:00
# app_name var
2021-12-04 15:40:03 +01:00
if sys . argv [ 0 ] == " power_helper.py " :
2021-12-22 08:28:08 +01:00
app_name = " python3 power_helper.py "
2021-11-28 14:06:46 +01:00
else :
2021-12-22 08:28:08 +01:00
app_name = " auto-cpufreq "
2021-11-28 14:06:46 +01:00
2021-12-04 18:32:50 +01:00
def header ( ) :
print ( " \n ------------------------- auto-cpufreq: Power helper ------------------------- \n " )
2021-12-22 08:28:08 +01:00
2021-12-04 18:32:50 +01:00
def helper_opts ( ) :
print ( " \n For full list of options run: python3 power_helper.py --help " )
2021-12-22 08:28:08 +01:00
2021-12-11 11:59:41 +01:00
# used to check if binary exists on the system
def does_command_exists ( cmd ) :
return which ( cmd ) is not None
2021-12-22 08:28:08 +01:00
2021-12-11 11:59:41 +01:00
systemctl_exists = does_command_exists ( " systemctl " )
bluetoothctl_exists = does_command_exists ( " bluetoothctl " )
tlp_stat_exists = does_command_exists ( " tlp-stat " )
2022-01-08 13:05:50 +01:00
powerprofilesctl_exists = does_command_exists ( " powerprofilesctl " )
2021-12-11 11:59:41 +01:00
2021-11-28 14:06:46 +01:00
# detect if gnome power profile service is running
2021-12-22 08:28:08 +01:00
if os . getenv ( " PKG_MARKER " ) != " SNAP " :
2021-12-11 11:59:41 +01:00
if systemctl_exists :
2021-12-07 08:28:58 +01:00
try :
2021-12-22 08:28:08 +01:00
gnome_power_status = call (
[ " systemctl " , " is-active " , " --quiet " , " power-profiles-daemon " ]
)
2021-12-07 08:28:58 +01:00
except :
print ( " \n Unable to determine init system " )
print ( " If this causes any problems, please submit an issue: " )
print ( " https://github.com/AdnanHodzic/auto-cpufreq/issues " )
2021-11-28 14:06:46 +01:00
2021-12-11 11:59:41 +01:00
# 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 ( ) :
2021-12-22 08:28:08 +01:00
print (
" \n ----------------------------------- Warning ----------------------------------- \n "
)
2021-12-11 11:59:41 +01:00
print ( " Detected you are running a TLP service! " )
2021-12-22 08:28:08 +01:00
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. "
)
2021-12-11 11:59:41 +01:00
# alert about TLP when using snap
def tlp_service_detect_snap ( ) :
print ( " \n ----------------------------------- Warning ----------------------------------- \n " )
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. " )
2021-12-22 08:28:08 +01:00
2021-11-28 14:06:46 +01:00
# alert in case gnome power profile service is running
def gnome_power_detect ( ) :
2021-12-11 11:59:41 +01:00
if systemctl_exists :
if gnome_power_status == 0 :
2021-12-22 08:28:08 +01:00
print (
" \n ----------------------------------- Warning ----------------------------------- \n "
)
2021-12-07 08:28:58 +01:00
print ( " Detected running GNOME Power Profiles daemon service! " )
print ( " This daemon might interfere with auto-cpufreq and should be disabled. " )
print ( " \n Steps 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 " )
2021-12-05 10:39:00 +01:00
2021-12-04 10:02:19 +01:00
2021-12-04 20:56:50 +01:00
# automatically disable gnome power profile service in case it's running during install
def gnome_power_detect_install ( ) :
2021-12-11 11:59:41 +01:00
if systemctl_exists :
if gnome_power_status == 0 :
2021-12-22 08:28:08 +01:00
print (
" \n ----------------------------------- Warning ----------------------------------- \n "
)
2021-12-07 08:28:58 +01:00
print ( " Detected running GNOME Power Profiles daemon service! " )
print ( " This daemon might interfere with auto-cpufreq and has been disabled. \n " )
2022-01-08 13:05:50 +01:00
print ( ' This daemon is not automatically disabled in " monitor " mode and ' )
2021-12-07 08:28:58 +01:00
print ( " will be enabled after auto-cpufreq is removed. " )
2021-11-28 14:06:46 +01:00
2021-12-22 08:28:08 +01:00
2021-12-02 21:33:02 +01:00
# notification on snap
def gnome_power_detect_snap ( ) :
2021-12-22 08:28:08 +01:00
print ( " \n ----------------------------------- Warning ----------------------------------- \n " )
print ( " Unable to detect state of GNOME Power Profiles daemon service! " )
print ( " This daemon might interfere with auto-cpufreq and should be disabled. " )
print ( " \n Steps 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 " )
2021-12-02 21:33:02 +01:00
2021-12-04 10:02:19 +01:00
2022-01-08 13:05:50 +01:00
# 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 " ] )
# starts gnome >= 40 power profiles (live)
def gnome_power_start_live ( ) :
if systemctl_exists :
call ( [ " systemctl " , " start " , " power-profiles-daemon " ] )
2021-11-28 14:06:46 +01:00
# enable gnome >= 40 power profiles (uninstall)
2021-12-04 15:40:03 +01:00
def gnome_power_svc_enable ( ) :
2021-12-11 11:59:41 +01:00
if systemctl_exists :
2021-12-07 08:28:58 +01:00
try :
print ( " \n * Enabling GNOME power profiles " )
call ( [ " systemctl " , " unmask " , " power-profiles-daemon " ] )
call ( [ " systemctl " , " start " , " power-profiles-daemon " ] )
call ( [ " systemctl " , " enable " , " power-profiles-daemon " ] )
call ( [ " systemctl " , " daemon-reload " ] )
except :
print ( " \n Unable to enable GNOME power profiles " )
print ( " If this causes any problems, please submit an issue: " )
print ( " https://github.com/AdnanHodzic/auto-cpufreq/issues " )
2021-12-04 18:32:50 +01:00
2021-12-04 10:02:19 +01:00
# gnome power profiles current status
2021-12-04 15:40:03 +01:00
def gnome_power_svc_status ( ) :
2021-12-11 11:59:41 +01:00
if systemctl_exists :
2021-12-07 08:28:58 +01:00
try :
print ( " * GNOME power profiles status " )
call ( [ " systemctl " , " status " , " power-profiles-daemon " ] )
except :
print ( " \n Unable to see GNOME power profiles status " )
print ( " If this causes any problems, please submit an issue: " )
print ( " https://github.com/AdnanHodzic/auto-cpufreq/issues " )
2021-12-22 08:28:08 +01:00
2021-12-04 18:32:50 +01:00
# disable bluetooth on boot
def bluetooth_disable ( ) :
if os . getenv ( " PKG_MARKER " ) == " SNAP " :
bluetooth_notif_snap ( )
2021-12-11 11:59:41 +01:00
elif bluetoothctl_exists :
2021-12-04 18:32:50 +01:00
print ( " * Turn off bluetooth on boot " )
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 " \n ERROR: \n Was unable to turn off bluetooth on boot \n { repr ( e ) } " )
else :
2021-12-22 08:28:08 +01:00
print (
" * Turn off bluetooth on boot [skipping] (package providing bluetooth access is not present) "
)
2021-12-04 18:32:50 +01:00
# enable bluetooth on boot
def bluetooth_enable ( ) :
if os . getenv ( " PKG_MARKER " ) == " SNAP " :
bluetooth_on_notif_snap ( )
2021-12-11 11:59:41 +01:00
if bluetoothctl_exists :
2021-12-04 18:32:50 +01:00
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 " \n ERROR: \n Was unable to turn on bluetooth on boot \n { repr ( e ) } " )
else :
2021-12-22 08:28:08 +01:00
print (
" * Turn on bluetooth on boot [skipping] (package providing bluetooth access is not present) "
)
2021-12-04 18:32:50 +01:00
# 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 ( " \n Steps to perform this action using auto-cpufreq: power_helper script: " )
print ( " python3 power_helper.py --bluetooth_boot_off " )
2021-12-22 08:28:08 +01:00
2021-12-04 18:32:50 +01:00
# 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 ( " \n Steps to perform this action using auto-cpufreq: power_helper script: " )
print ( " python3 power_helper.py --bluetooth_boot_on " )
2021-12-22 08:28:08 +01:00
2021-12-04 10:02:19 +01:00
# gnome power removal reminder
def gnome_power_rm_reminder ( ) :
2021-12-11 11:59:41 +01:00
if systemctl_exists :
if gnome_power_status != 0 :
2021-12-22 08:28:08 +01:00
print (
" \n ----------------------------------- Warning ----------------------------------- \n "
)
2021-12-07 08:28:58 +01:00
print ( " Detected GNOME Power Profiles daemon service is stopped! " )
print ( " This service will now be enabled and started again. " )
2021-12-04 18:32:50 +01:00
2021-12-22 08:28:08 +01:00
2021-12-04 10:02:19 +01:00
def gnome_power_rm_reminder_snap ( ) :
2021-12-22 08:28:08 +01:00
print ( " \n ----------------------------------- Warning ----------------------------------- \n " )
print ( " Unable to detect state of GNOME Power Profiles daemon service! " )
print ( " Now it ' s recommended to enable this service. " )
print ( " \n Steps 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_enable " )
2021-11-28 14:06:46 +01:00
2021-12-04 18:32:50 +01:00
2021-11-28 14:06:46 +01:00
def valid_options ( ) :
2021-12-05 10:39:00 +01:00
print ( " --gnome_power_enable \t \t Enable GNOME Power Profiles daemon " )
print ( " --gnome_power_disable \t \t Disable GNOME Power Profiles daemon \n " )
2021-11-28 14:06:46 +01:00
2021-12-04 10:02:19 +01:00
2022-02-07 18:40:14 +01:00
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 " , " mask " , " power-profiles-daemon " ] )
call ( [ " systemctl " , " daemon-reload " ] )
except :
print ( " \n Unable to disable GNOME power profiles " )
print ( " If this causes any problems, please submit an issue: " )
print ( " https://github.com/AdnanHodzic/auto-cpufreq/issues " )
2022-02-07 20:30:35 +01:00
# default gnome_power_svc_disable func (balanced)
2022-02-07 18:40:14 +01:00
def gnome_power_svc_disable ( ) :
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 " ] )
disable_power_profiles_daemon ( )
2021-11-28 14:06:46 +01:00
# cli
2022-02-06 16:54:56 +01:00
@click.pass_context
2022-02-07 18:40:14 +01:00
# external gnome power srevice disable function
def gnome_power_svc_disable_ext ( ctx , power_selection ) :
2022-02-07 20:30:35 +01:00
raw_power_disable = ctx . params [ " gnome_power_disable " ]
gnome_power_disable = str ( raw_power_disable ) . replace ( ' [ ' , ' ' ) . replace ( ' ] ' , ' ' ) . replace ( " , " , " " ) . replace ( " ( " , " " ) . replace ( " ) " , " " ) . replace ( " ' " , " " )
2022-02-06 16:54:56 +01:00
if systemctl_exists :
2022-02-07 20:30:35 +01:00
# 0 is active
if gnome_power_status != 0 :
print ( " Power Profiles Daemon is already disabled, re-enable by running: \n "
" sudo python3 power_helper.py --gnome_power_enable \n "
" \n followed by running: \n "
" sudo python3 power_helper.py --gnome_power_disable "
)
2022-02-06 16:54:56 +01:00
# set balanced profile if its running before disabling it
2022-02-07 20:30:35 +01:00
elif gnome_power_status == 0 and powerprofilesctl_exists :
2022-02-06 17:07:18 +01:00
print ( " Using profile: " , gnome_power_disable )
call ( [ " powerprofilesctl " , " set " , gnome_power_disable ] )
2022-02-06 16:54:56 +01:00
2022-02-07 18:40:14 +01:00
disable_power_profiles_daemon ( )
2022-02-06 16:54:56 +01:00
2021-11-28 14:06:46 +01:00
@click.command ( )
2022-02-06 17:07:18 +01:00
@click.option ( " --gnome_power_disable " , help = " Disable GNOME Power profiles service (default: balanced) " , type = click . Choice ( [ ' balanced ' , ' performance ' ] , case_sensitive = False ) )
# ToDo:
# * update readme/docs
@click.option ( " --power_selection " , hidden = True )
2021-12-04 15:40:03 +01:00
@click.option ( " --gnome_power_enable " , is_flag = True , help = " Enable GNOME Power profiles service " )
2022-02-06 17:07:18 +01:00
2022-02-06 16:54:56 +01:00
@click.option ( " --gnome_power_status " , is_flag = True , help = " Get status of GNOME Power profiles service "
2021-12-22 08:28:08 +01:00
)
2021-12-04 18:32:50 +01:00
@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 " )
2021-12-22 08:28:08 +01:00
def main (
2022-02-06 17:07:18 +01:00
power_selection ,
2021-12-22 08:28:08 +01:00
gnome_power_enable ,
gnome_power_disable ,
gnome_power_status ,
bluetooth_boot_off ,
bluetooth_boot_on ,
) :
2021-11-28 14:06:46 +01:00
root_check ( )
if len ( sys . argv ) == 1 :
2021-12-04 18:32:50 +01:00
header ( )
2021-12-22 08:28:08 +01:00
print (
' Unrecognized option! \n \n Run: " ' + app_name + ' --help " for list of available options. '
)
2021-11-28 14:06:46 +01:00
footer ( )
else :
2021-12-04 15:40:03 +01:00
if gnome_power_enable :
2021-12-04 18:32:50 +01:00
header ( )
2021-11-28 14:06:46 +01:00
root_check ( )
2021-12-04 15:40:03 +01:00
gnome_power_svc_enable ( )
2021-12-04 18:32:50 +01:00
helper_opts ( )
2021-12-04 10:02:19 +01:00
footer ( )
2021-12-04 15:40:03 +01:00
elif gnome_power_disable :
2021-12-04 18:32:50 +01:00
header ( )
2021-12-02 21:33:02 +01:00
root_check ( )
2022-02-07 18:40:14 +01:00
gnome_power_svc_disable_ext ( power_selection )
2021-12-04 18:32:50 +01:00
helper_opts ( )
2021-12-04 10:02:19 +01:00
footer ( )
2021-12-04 15:40:03 +01:00
elif gnome_power_status :
2021-12-04 18:32:50 +01:00
header ( )
2021-12-04 10:02:19 +01:00
root_check ( )
2021-12-04 15:40:03 +01:00
gnome_power_svc_status ( )
2021-12-04 18:32:50 +01:00
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 ( )
2021-12-04 10:02:19 +01:00
footer ( )
2021-11-28 14:06:46 +01:00
2021-12-22 08:28:08 +01:00
if __name__ == " __main__ " :
2021-11-28 14:06:46 +01:00
main ( )