├── ftw.rules ├── etc-conf.d └── ftw ├── README.md └── ftw /ftw.rules: -------------------------------------------------------------------------------- 1 | SUBSYSTEM=="power_supply", ATTR{online}=="1", RUN+="/usr/bin/ftw adp" 2 | SUBSYSTEM=="power_supply", ATTR{online}=="0", RUN+="/usr/bin/ftw bat" 3 | SUBSYSTEM=="block", ENV{POWER_SUPPLY_ONLINE}=="1", ENV{UDISKS_DISABLE_POLLING}="0" 4 | SUBSYSTEM=="block", ENV{POWER_SUPPLY_ONLINE}=="0", ENV{UDISKS_DISABLE_POLLING}="1" 5 | -------------------------------------------------------------------------------- /etc-conf.d/ftw: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Comment out options to disable them. 4 | 5 | # File to which the current profile name will be written after the profile is 6 | # called. 7 | PROFILE_FILE=/tmp/ftw.profile 8 | 9 | # Array of modules to be removed when offline and inserted when online. 10 | MODULES=(uvcvideo videodev) 11 | 12 | # Device partitions affected by REMOUNT_OPTIONS. 13 | PARTITIONS=/dev/sd* 14 | 15 | # Devices affected by BLOCKDEV_READAHEAD, HD_POWER_MANAGEMENT, 16 | # and HD_SPINDOWN_TIMEOUT. 17 | DEVICES=/dev/sd? 18 | 19 | bat() { 20 | # CPU power scheme governor. 21 | CPUFREQ_GOVERNOR=ondemand 22 | 23 | # Execute periodic NMI interrupts to monitor CPU lock ups? 24 | NMI_WATCHDOG=0 25 | 26 | # Control everything in /sys/bus/*/devices/*. 27 | # on = device should be resumed and autosuspend is not allowed 28 | # auto = device is allowed to autosuspend and autoresume 29 | BUS_CONTROL=auto 30 | 31 | # How long to wait before suspending USB devices. 32 | USB_AUTOSUSPEND_TIMEOUT=5 33 | 34 | # PCI Express Active State Power Management. 35 | # Will probably require pcie_aspm=force kernel boot parameter. 36 | PCIE_ASPM_POLICY=powersave 37 | 38 | # Attempt to maximize the amount of time disks spend in a low power state 39 | # by submitting all future pending disk IO when performing an IO operaiton? 40 | LAPTOP_MODE=5 41 | 42 | # Maximum percentage of memory dirty pages can occupy before processes are 43 | # forced to write dirty buffers themselves. 44 | DIRTY_RATIO=90 45 | 46 | # Maximum percentage of memory dirty pages can occupy before pdflush begins 47 | # to write them. 48 | DIRTY_BACKGROUND_RATIO=1 49 | 50 | # How long data can be in the page cache before it expires, signifying it 51 | # must be written at the next opportunity. 52 | DIRTY_EXPIRE_CENTISECS=600 53 | 54 | # How often pdflush wakes up to write data to disk. 55 | DIRTY_WRITEBACK_CENTISECS=6000 56 | 57 | # Policy for SCSI host adapters. 58 | SCSI_HOST_POLICY=min_power 59 | 60 | # Comma-separated list (option1,option2,etc) of mount options to be applied 61 | # when remounting devices. 62 | REMOUNT_OPTIONS=noatime 63 | 64 | # Block device readahead in kilobytes. 65 | BLOCKDEV_READAHEAD=4096 66 | 67 | # Hard drive Advanced Power Management. 68 | # See hdparm(8) (-B flag section) for more information. 69 | HD_POWER_MANAGEMENT=1 70 | 71 | # How long to wait after disk activity stops before turning off hard 72 | # drive's spindle motor. 73 | # See hdparm(8) (-S flag section) for more information. 74 | HD_SPINDOWN_TIMEOUT=24 75 | 76 | # Enable Intel HDA audio chipset power saving? 77 | SND_INTEL_POWER_SAVE=1 78 | 79 | # Enable AC97 audio chipset power saving? 80 | SND_AC97_POWER_SAVE=1 81 | 82 | # Enable wireless adapter power saving? 83 | WIRELESS_POWER_SAVE=on 84 | 85 | # Dim backlight to save power? For max value (min is 0), check 86 | # /sys/class/backlight/acpi_video*/max_brightness. 87 | BACKLIGHT_BRIGHTNESS=10 88 | 89 | # Add custom commands to be executed when profile is called. 90 | 91 | if [[ $MODULES ]]; then 92 | for i in $MODULES; do 93 | modprobe -r $i &> /dev/null 94 | done 95 | fi 96 | } 97 | 98 | adp() { 99 | CPUFREQ_GOVERNOR=ondemand 100 | NMI_WATCHDOG=1 101 | BUS_CONTROL=on 102 | #USB_AUTOSUSPEND_TIMEOUT=60 103 | PCIE_ASPM_POLICY=default 104 | LAPTOP_MODE=0 105 | DIRTY_RATIO=30 106 | DIRTY_BACKGROUND_RATIO=10 107 | DIRTY_EXPIRE_CENTISECS=300 108 | DIRTY_WRITEBACK_CENTISECS=3000 109 | SCSI_HOST_POLICY=max_performance 110 | REMOUNT_OPTIONS=relatime 111 | BLOCKDEV_READAHEAD=256 112 | HD_POWER_MANAGEMENT=254 113 | HD_SPINDOWN_TIMEOUT=253 114 | SND_INTEL_POWER_SAVE=0 115 | SND_AC97_POWER_SAVE=0 116 | WIRELESS_POWER_SAVE=off 117 | BACKLIGHT_BRIGHTNESS=15 118 | 119 | if [[ $MODULES ]]; then 120 | for i in $MODULES; do 121 | modprobe $i &> /dev/null 122 | done 123 | fi 124 | } 125 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # for the watts 2 | 3 | ## dependencies 4 | 5 | * bash 6 | * udev 7 | * hdparm 8 | * iw 9 | 10 | ## configuration 11 | 12 | The config file is located at `/etc/conf.d/ftw`. 13 | 14 | ### universal options 15 | 16 | **PROFILE_FILE** 17 | 18 | * File to which the current profile name will be written after the profile is 19 | called. 20 | 21 | **MODULES** 22 | 23 | * Array of modules to be removed when offline and inserted when online. 24 | 25 | **PARTITIONS** 26 | 27 | * Device partitions affected by `REMOUNT_OPTIONS`. 28 | 29 | **DEVICES** 30 | 31 | * Devices affected by `BLOCKDEV_READAHEAD`, `HD_POWER_MANAGEMENT`, and 32 | `HD_SPINDOWN_TIMEOUT`. 33 | 34 | ### state-dependent options 35 | 36 | **CPUFREQ_GOVERNOR** 37 | 38 | * CPU power scheme governor. 39 | 40 | **NMI_WATCHDOG** 41 | 42 | * Execute periodic NMI interrupts to monitor CPU lock ups? 43 | 44 | **BUS_CONTROL** 45 | 46 | * Control everything in `/sys/bus/*/devices/*`. 47 | * `on` means device should be resumed and autosuspend is not allowed. 48 | * `auto` means device is allowed to autosuspend and autoresume. 49 | 50 | **USB_AUTOSUSPEND_TIMEOUT** 51 | 52 | * How long to wait before suspending USB devices. 53 | 54 | **PCIE_ASPM_POLICY** 55 | 56 | * PCI Express Active State Power Management. 57 | * Will probably require `pcie_aspm=force` kernel boot parameter. 58 | 59 | **LAPTOP_MODE** 60 | 61 | * Attempt to maximize the amount of time disks spend in a low power state by 62 | submitting all future pending disk IO when performing an IO operation? 63 | 64 | **DIRTY_RATIO** 65 | 66 | * Maximum percentage of memory dirty pages can occupy before processes are 67 | forced to write dirty buffers themselves. 68 | 69 | **DIRTY_BACKGROUND_RATIO** 70 | 71 | * Maximum percentage of memory dirty pages can occupy before pdflush begins to 72 | write them. 73 | 74 | **DIRTY_EXPIRE_CENTISECS** 75 | 76 | * How long data can be in the page cache before it expires, signifying it must 77 | be written at the next opportunity. 78 | 79 | **DIRTY_WRITEBACK_CENTISECS** 80 | 81 | * How often pdflush wakes up to write data to disk. 82 | 83 | **SCSI_HOST_POLICY** 84 | 85 | * Policy for SCSI host adapters. 86 | 87 | **REMOUNT_OPTIONS** 88 | 89 | * Comma-separated list (`option1,option2,etc`) of mount options to be applied 90 | when remounting devices. 91 | 92 | **BLOCKDEV_READAHEAD** 93 | 94 | * Block device readahead in kilobytes. 95 | 96 | **HD_POWER_MANAGEMENT** 97 | 98 | * Hard drive Advanced Power Management. 99 | * See `hdparm(8)` (-B flag section) for more information. 100 | 101 | **HD_SPINDOWN_TIMEOUT** 102 | 103 | * How long to wait after disk activity stops before turning off hard drive's 104 | spindle motor. 105 | * See `hdparm(8)` (-S flag section) for more information. 106 | 107 | **SND_INTEL_POWER_SAVE** 108 | 109 | * Enable Intel HDA audio chipset power saving? 110 | 111 | **SND_AC97_POWER_SAVE** 112 | 113 | * Enable AC97 audio chipset power saving? 114 | 115 | **WIRELESS_POWER_SAVE** 116 | 117 | * Enable wireless adapter power saving? 118 | 119 | **BACKLIGHT_BRIGHTNESS** 120 | 121 | * Dim backlight to save power? 122 | * For max value (min is `0`), check 123 | `/sys/class/backlight/acpi_video*/max_brightness`. 124 | 125 | ### custom profiles 126 | 127 | Custom profiles added to the config file can be called with `ftw profile`. 128 | 129 | ### custom commands 130 | 131 | Custom commands added to profile definitions will be executed when the profile 132 | is called. 133 | 134 | #### examples 135 | 136 | Disable Wake-on-LAN on battery with 137 | [ethtool](https://www.kernel.org/pub/software/network/ethtool/): 138 | 139 | bat() { 140 | ethtool -s eth0 wol d 141 | } 142 | 143 | adp() { 144 | ethtool -s eth0 wol g 145 | } 146 | 147 | Manage backlight brightness per profile using 148 | [relight](http://xyne.archlinux.ca/projects/relight/): 149 | 150 | bat() { 151 | if [[ -f $PROFILE_FILE && $(< $PROFILE_FILE) == 'adp' ]]; then 152 | relight save adp 153 | relight restore bat 154 | fi 155 | } 156 | 157 | adp() { 158 | if [[ -f $PROFILE_FILE && $(< $PROFILE_FILE) == 'bat' ]]; then 159 | relight save bat 160 | relight restore adp 161 | fi 162 | } 163 | -------------------------------------------------------------------------------- /ftw: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | _defaults() { 4 | PROFILE_FILE=/tmp/ftw.profile 5 | MODULES=(uvcvideo videodev) 6 | adp() { 7 | CPUFREQ_GOVERNOR=ondemand 8 | NMI_WATCHDOG=1 9 | BUS_CONTROL=on 10 | PCIE_ASPM_POLICY=default 11 | LAPTOP_MODE=0 12 | DIRTY_RATIO=30 13 | DIRTY_BACKGROUND_RATIO=10 14 | DIRTY_EXPIRE_CENTISECS=300 15 | DIRTY_WRITEBACK_CENTISECS=3000 16 | SCSI_HOST_POLICY=max_performance 17 | REMOUNT_OPTIONS=relatime 18 | BLOCKDEV_READAHEAD=256 19 | HD_POWER_MANAGEMENT=254 20 | HD_SPINDOWN_TIMEOUT=253 21 | SND_INTEL_POWER_SAVE=0 22 | SND_AC97_POWER_SAVE=0 23 | WIRELESS_POWER_SAVE=off 24 | BACKLIGHT_BRIGHTNESS=15 25 | if [[ $MODULES ]]; then 26 | for i in $MODULES; do 27 | modprobe $i &> /dev/null 28 | done 29 | fi 30 | } 31 | bat() { 32 | CPUFREQ_GOVERNOR=ondemand 33 | NMI_WATCHDOG=0 34 | BUS_CONTROL=auto 35 | USB_AUTOSUSPEND_TIMEOUT=5 36 | PCIE_ASPM_POLICY=powersave 37 | LAPTOP_MODE=5 38 | DIRTY_RATIO=90 39 | DIRTY_BACKGROUND_RATIO=1 40 | DIRTY_EXPIRE_CENTISECS=600 41 | DIRTY_WRITEBACK_CENTISECS=6000 42 | SCSI_HOST_POLICY=min_power 43 | REMOUNT_OPTIONS=noatime 44 | BLOCKDEV_READAHEAD=4096 45 | HD_POWER_MANAGEMENT=1 46 | HD_SPINDOWN_TIMEOUT=24 47 | SND_INTEL_POWER_SAVE=1 48 | SND_AC97_POWER_SAVE=1 49 | WIRELESS_POWER_SAVE=on 50 | BACKLIGHT_BRIGHTNESS=10 51 | if [[ $MODULES ]]; then 52 | for i in $MODULES; do 53 | modprobe -r $i &> /dev/null 54 | done 55 | fi 56 | } 57 | } 58 | 59 | _common() { 60 | opt() { [[ -f $1 ]] && echo $2 > $1 2> /dev/null; } 61 | 62 | if [[ $CPUFREQ_GOVERNOR ]]; then 63 | modprobe cpufreq_$CPUFREQ_GOVERNOR &> /dev/null 64 | for i in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do 65 | opt $i $CPUFREQ_GOVERNOR 66 | done 67 | fi 68 | 69 | if [[ $NMI_WATCHDOG ]]; then 70 | opt /proc/sys/kernel/nmi_watchdog $NMI_WATCHDOG 71 | fi 72 | 73 | if [[ $BUS_CONTROL ]]; then 74 | for i in /sys/bus/*/devices/*/power/control; do 75 | opt $i $BUS_CONTROL 76 | done 77 | fi 78 | 79 | if [[ $USB_AUTOSUSPEND_TIMEOUT ]]; then 80 | for i in /sys/bus/usb/devices/*/power/autosuspend; do 81 | opt $i $USB_AUTOSUSPEND_TIMEOUT 82 | done 83 | fi 84 | 85 | if [[ $PCIE_ASPM_POLICY ]]; then 86 | opt /sys/module/pcie_aspm/parameters/policy $PCIE_ASPM_POLICY 87 | fi 88 | 89 | if [[ $LAPTOP_MODE ]]; then 90 | opt /proc/sys/vm/laptop_mode $LAPTOP_MODE 91 | fi 92 | 93 | if [[ $DIRTY_RATIO ]]; then 94 | opt /proc/sys/vm/dirty_ratio $DIRTY_RATIO 95 | fi 96 | 97 | if [[ $DIRTY_BACKGROUND_RATIO ]]; then 98 | opt /proc/sys/vm/dirty_background_ratio $DIRTY_BACKGROUND_RATIO 99 | fi 100 | 101 | if [[ $DIRTY_EXPIRE_CENTISECS ]]; then 102 | opt /proc/sys/vm/dirty_expire_centisecs $DIRTY_EXPIRE_CENTISECS 103 | fi 104 | 105 | if [[ $DIRTY_WRITEBACK_CENTISECS ]]; then 106 | opt /proc/sys/vm/dirty_writeback_centisecs $DIRTY_WRITEBACK_CENTISECS 107 | fi 108 | 109 | if [[ $SCSI_HOST_POLICY ]]; then 110 | for i in /sys/class/scsi_host/host*/link_power_management_policy; do 111 | opt $i $SCSI_HOST_POLICY 112 | done 113 | fi 114 | 115 | if [[ $REMOUNT_OPTIONS ]]; then 116 | local p=${PARTITIONS:-/dev/sd*} 117 | for i in $(awk "/^${p//\//\\/}/ {print \$1}" /etc/mtab); do 118 | mount -o remount,$REMOUNT_OPTIONS $i 119 | done 120 | fi 121 | 122 | for i in ${DEVICES:-/dev/sd?}; do 123 | [[ $BLOCKDEV_READAHEAD ]] && blockdev --setra $BLOCKDEV_READAHEAD $i 124 | [[ $HD_POWER_MANAGEMENT ]] && hdparm -q -B $HD_POWER_MANAGEMENT $i 125 | [[ $HD_SPINDOWN_TIMEOUT ]] && hdparm -q -S $HD_SPINDOWN_TIMEOUT $i 126 | done 127 | 128 | if [[ $SND_INTEL_POWER_SAVE ]]; then 129 | local dir=/sys/module/snd_hda_intel/parameters yn 130 | [[ $SND_INTEL_POWER_SAVE -eq 1 ]] && yn=Y || yn=N 131 | opt $dir/power_save_controller $yn 132 | opt $dir/power_save $SND_INTEL_POWER_SAVE 133 | fi 134 | 135 | if [[ $SND_AC97_POWER_SAVE ]]; then 136 | local dir=/sys/module/snd_ac97_codec/parameters 137 | opt $dir/power_save $SND_AC97_POWER_SAVE 138 | fi 139 | 140 | if [[ $WIRELESS_POWER_SAVE ]]; then 141 | for i in $(iw dev | grep Interface | cut -d ' ' -f 2); do 142 | iw dev $i set power_save $WIRELESS_POWER_SAVE 143 | done 144 | fi 145 | 146 | if [[ $BACKLIGHT_BRIGHTNESS ]]; then 147 | for i in /sys/class/backlight/acpi_video*/brightness; do 148 | opt $i $BACKLIGHT_BRIGHTNESS 149 | done 150 | fi 151 | } 152 | 153 | if [[ $1 && $(expr match "$1" '-') -eq 0 ]]; then 154 | profile=$1 155 | config=/etc/conf.d/ftw 156 | [[ -f $config ]] && source $config || _defaults 157 | 158 | if declare -f $profile > /dev/null; then 159 | if [[ $EUID -ne 0 ]]; then 160 | echo 'requires root privileges' 161 | exit 1 162 | fi 163 | 164 | lock=/tmp/ftw.lock 165 | [[ -f $lock ]] && exit 2 166 | : > $lock 167 | trap "rm -f $lock" EXIT 168 | 169 | $profile 170 | _common 171 | [[ $PROFILE_FILE ]] && echo $profile > $PROFILE_FILE 172 | else 173 | echo "profile '$profile' does not exist in $config" 174 | exit 1 175 | fi 176 | else 177 | echo 'usage: ftw [profile]' 178 | exit 1 179 | fi 180 | --------------------------------------------------------------------------------