# [SCRIPTS]: Power profiles for laptops

## optilude

UPDATE 2003-12-22: The power profile system is now integrated into the more general and flexible hprofile system. This makes it possible to switch configuration files along with profiles, and is more powerful than the scripts presented below. I'll leave these scripts here for those who just want the simpler power-profile scripts.

Hello,

I wanted an integrated power management solution that would scale by CPU back, adjust my backlight (and maybe do other things), both when I told it to, and automatically when I plugged in/out the AC adapter on my laptop.

The power-profile and select-power-profile scripts are general can can be applied to any installation. I'm also going to give examples of power-profile scripts and ACPI events (which require acpid to be running!) that work on my machine. Some of these may not apply to you. In particular, note that I have an ASUS-built notebook with ASUS ACPI extensions built into the kernel, and I use speedfreq on a 2.6 kernel to throttle CPU. It should be no problem to use ACPI throttling and dimming, or any form of power management techniques.

Changelog:

2003-12-16: 

 o New configuration file /etc/power-profile lets you specify profile directories and a default "boot" profile.

 o New option -b loads this boot profile

 o power-profile now remembers which profile it's currently in, and the previous profile. Use the -c option to print the current profile, and the -r option to revert to the previous profile. If you apply a new profile twice, the -r option still reverts to the previous "different" profile.

 o Note that you (probably) need root access to allow the current previous profiles to be stored in their default location (/var/run/power-profile/). I use "sudo" and allow members of the wheel group to execute power-profile without a password in /etc/sudoers.

1. The power profile system

The following simple script should go in /usr/local/power-profile. It will allow you to change the power profile by executing

```

$ power-profile <profilename>

```

The <profilename> is the name of a script in /etc/power-profile.d (which you must create!); this directory should contain executable scripts that configure the machine according to the desired power profile. See examples in section 2 below.

/usr/local/bin/power-profile (Updated 2003-12-16)

```

#!/bin/bash

CONFIGFILE="/etc/power-profile"

# Default options - override these in CONFIGFILE

PROFILEDIR="/etc/power-profile.d"

BOOTPROFILE="unknown"

CURRENTSTATE="/var/run/power-profile/current"

PREVSTATE="/var/run/power-profile/previous"

source "${CONFIGFILE}" 2>/dev/null

select_profile () {

   local profile="${1}"

            

   test -x ${PROFILEDIR}/${profile} -a -f ${PROFILEDIR}/${profile} || 

      (echo "Profile ${profile} not found." >&2 ; return 1)

   

   # Run the profile script

   ${PROFILEDIR}/${profile} || 

      (echo "Profile script ${profile} failed." >&2 ; return 2)

   # If we have a "current" state already, make this the "previous" unless

   # we didn't make a change. Only allow the same "current" and "previous"

   # if there was no "previous" already.

   

   if test -f "${CURRENTSTATE}" ; then

      local cur=$(cat "${CURRENTSTATE}")

      test ! -f "${PREVSTATE}" -o "${cur}" != "${profile}" &&

         mv "${CURRENTSTATE}" "${PREVSTATE}"

   fi

               

   echo "${profile}" > "${CURRENTSTATE}"

   return 0

}

get_profiles () {

   find "${PROFILEDIR}" -maxdepth 1 -type f -perm +111 -printf "%f\n" | sort

}

print_profiles () {

   for p in `get_profiles` ; do

      echo "${p}"

   done

}

print_current_profile () {

   test -f "${CURRENTSTATE}" || 

      (echo "State file ${CURRENTSTATE} not found." >&2 ; return 1)

   cat "${CURRENTSTATE}"

   return 0

}

select_previous_profile () {

   test -f "${PREVSTATE}" || 

      (echo "State file ${PREVSTATE} not found." >&2 ; return 1)

   local state=$(cat "${PREVSTATE}")

   select_profile "${state}"

   return $?

}

print_help () {

   echo "Usage: power-profile [-p] [-h] [-b] [-c] [-r] [profile]"

   echo 

   echo "         -p  Print a list of profiles"

   echo "         -b  Select boot profile"

   echo "         -c  Print current profile"

   echo "         -r  Revert to previous profile"

   echo "         -h  Print this help message"

   echo

   echo "Argument 'profile' must be an executable files in ${PROFILEDIR}."

   echo "Boot profile and profile directory can be configured in ${CONFIGFILE}."

}

while getopts "pbcrh" opt ; do

   case "${opt}" in

      p)

         print_profiles

         exit 0

         ;;

      b)

         if select_profile "${BOOTPROFILE}" ; then

            exit 0

         else

            echo "Boot profile specified in ${BOOTPROFILE} not found." >&2

            exit 1

         fi

         ;;

      c)

         if print_current_profile ; then

            exit 0

         else

            echo "Unable to determine current profile." >&2

            exit 1

         fi

         ;;

      r)

         if select_previous_profile ; then

            exit 0

         else

            echo "Unable to revert to previous profile." >&2

            exit 1

         fi

         ;;

      h)

         print_help

         exit 0

         ;;

      *)

         print_help

         exit 1

         ;;

   esac

done

if test -z ${1} ; then

   print_help

   exit 1

else

   if select_profile $1 ; then

      exit 0

   else

      exit 1

   fi

fi

```

Run "power-profile -h" for help (not that much is needed).

Next, here is a script that uses zenity (which can be found in the ebuild gnome-extra/zenity) to display a pretty GTK2 dialogue letting you select the power profile you want. 

/usr/local/bin/select-power-profile (Updated 2003-12-16)

```

#!/bin/bash

display_zenity_menu () {

   items=""

   for p in $@ ; do

      items="${items} FALSE ${p}"

   done

            

   zenity  --title "Select power profile" --list --radiolist \

               --height 210 \

               --column "" --column "Profile" ${items}

}

profiles=`power-profile -p`

selected=`display_zenity_menu ${profiles}`

test "${selected}" != "" && sudo power-profile ${selected}

```

I'm sure something similar would be possible in KDE, but I don't know what the equivalent program to zenity would be...

New:You now also need a configuration file in /etc called power-profile.

/etc/power-profile (New 2003-12-16)

```

# Configuration options for power-profile

# Profile selected when power-profile -b is run

BOOTPROFILE="AC"

# File holding current state

CURRENTSTATE="/var/run/power-profile/current" 

# File holding previous state

PREVSTATE="/var/run/power-profile/previous"

# Directory holding power profiles

PROFILEDIR="/etc/power-profile.d"

```

Note that the above file really just contains bash variables, so no spaces between the = signs and the variable names or values, and use double quotes if you've got spaces. Comments begin with # and extend to the end of the line as usual.

2. Example power profiles

I have the following scripts in /etc/power-profile.d. Note that the /proc/acpi/asus/brn comes courtesy of ASUS ACPI extensions. Other scripts on these forums seem to have success with the "xgamma" command, but I could never get this to work on my macine; Also note that to be able to change speedfreq policies as a non-root user, you should set SPEEDFREQ_USERS="yes" in/etc/conf.d/speedfreq. However, at the time of writing, the speedfreq init script does not seem to honour this flag. Please see Bug #33714 for a fixed /etc/init.d/speedfreq.

Really, you can be as creative as you want with these scripts. You can even have profiles that don't change power management at all!  :Smile: 

/etc/power-profile.d/AC

```

#!/bin/bash

speedfreq -p performance

echo "15" > /proc/acpi/asus/brn

```

/etc/power-profile.d/Battery

```

#!/bin/bash

speedfreq -p powersave

echo "6" > /proc/acpi/asus/brn

```

/etc/power-profile.d/Dynamic

```

#!/bin/bash

speedfreq -p dynamic

```

/etc/power-profile.d/Medium

```

#!/bin/bash

speedfreq -p 1000

echo "11" > /proc/acpi/asus/brn

```

3. Setting the power profile at startup

So far, we're able to select power profiles by entering "power-profile AC" or "power-profile Battery" etc., and we can select this using a GTK2 dialogue box using "select-power-profile". Now, to select power profiles at startup, I use the following init script. This checks /proc/acpi/ac_adapter/AC0/state to find out if the AC adapter is unplugged or plugged in and selects the AC or Battery profiles accordingly. Again, you may need to edit this to your tastes if you have different names for your profiles (i.e. the scripts in /etc/power-profile.d). Also, note the dependency on speedfreq - this is to ensure speedfreqd is run before power-profile is started. If you depend on another service (such as acpid), you should put this in the depend() function.

/etc/init.d/power-profile

```

#!/sbin/runscript

# Copyright 1999-2003 Gentoo Technologies, Inc.

# Distributed under the terms of the GNU General Public License v2

# $Header: /home/cvsroot/gentoo-x86/sys-apps/speedfreq/files/speedfreq.rc,v 1.1 2003/08/21 02:31:55 vapier Exp $

depend() {

   need modules logger

   use speedfreq

}

check_acpi() {

   POWER_PROFILE="AC"

   [ ! -f /proc/acpi/ac_adapter/AC0/state ] && return 0

   local status="`echo $(</proc/acpi/ac_adapter/AC0/state)`"

   case "${status}" in

      *on-line)  POWER_PROFILE=AC;;

      *off-line) POWER_PROFILE=Battery;

   esac

}

start() {

   check_acpi

   ebegin "Selecting power profile ${POWER_PROFILE}"

   /usr/local/bin/power-profile ${POWER_PROFILE}

   eend $?

}

```

Now run "rc-update add power-profile boot" and the power profile should be set automatically at startup to "Battery" or "AC" depending on whether or not the AC adapter is plugged in.

4. Responding to ACPI events

Finally, I use these scripts to automatically set the power profile to "Battery" when the AC adapter is unplugged and to "AC" when it's plugged back in. These require acpid to be running. Note that there are lots of ways to configure /etc/acpi. I choose to have individual config files for each type of event in /etc/acpi/events and corresponding action scripts in /etc/acpi/actions. 

/etc/acpi/events/ac_in

```

event=ac_adapter.AC..00000080.00000001

action=/etc/acpi/actions/ac_in

```

/etc/acpi/events/ac_out

```

event=ac_adapter.AC..00000080.00000000

action=/etc/acpi/actions/ac_out

```

/etc/acpi/actions/ac_in (should be executable)

```

#!/bin/bash

power-profile AC

```

/etc/acpi/actions/ac_out (should be executable)

```

#!/bin/bash

power-profile Battery

```

That's it! If you do use these scripts, post your /etc/power-profile.d scripts here so that others can make use of them!

Best wishes,

Martin Aspeli

----------

## hulk2nd

hei wow, looks great! gonna give it a try immediatly after i get my laptop working again. Big thanks for that!

----------

## optilude

No problem!  :Smile: 

It would be good if you post your /etc/power-profile.d scripts here so we can build up a repository of scripts for various configurations. Also, if you use speedfreq to change your CPU speed(e.g. on a centrino machine, though I think it handles standard ACPI throttling, too) and you use Gnome or XFCE , have a look for the LTSpeedfreqMon desklet on gdesklets.gnomedesktop.org; I wrote that to show my current CPU speed and it looks very cool.  :Smile: 

Martin

P.S.

Are you at the university in Freiburg? One of my best mates is doing a year abroad there; I hear the beer is good!

----------

## hulk2nd

 *Quote:*   

> P.S.
> 
> Are you at the university in Freiburg? One of my best mates is doing a year abroad there; I hear the beer is good!

 

hehe cool!!!! yes indeed, i am at the university of freiburg! i really like it there cause it is very modern. wlan is nearly everywhere and you can download the lessons as video/audio file if you missed one. and guess what i'm doing right now ... drinking beer  :Razz:  :Razz:  greets to you and your friend!!!

hulk

----------

## Kalin

I was just wondering the other week how to manage the power on my Toshiba SS/S5 notebook and saw this thread on today's GWN :-)

Will give it a try and report success (I hope)  here later.

----------

## optilude

Wahey! That's the second time I've been mentioned on GWN!  :Smile: 

/me is humbled.

Hopefully this means more people will use (read: crash test) the scripts. As I said before, it'd be great if people could post their /etc/power-profile.d scripts here so we could build up a repository of what works for people.

----------

## NiXZe

Anyone else got none working AC events i'm runing 2.6.0-test10 and everything works great that's supposed to work ecept when i pull the plug there is no events for it (buttons generates events) this comp is a compaq armada m700.

----------

## optilude

Have you got the "ac" module loaded/compiled in (that's the ACPI AC adapter stuff)? Is acpid running? Look at /var/log/acpid (as root) - do you get any activity when the you pull the AC adapter out/plug it back in? If so, note the event string and see how this matches the regular expression in /etc/acpid/events/ac_in (provided you use my conventions for acpid configuration).

Best wishes,

Martin

----------

## NiXZe

yepp everything works (lid switch, sleep etc) all the modules are there and i can get the info from /proc/acpi/..... but when i pull the plug there is no event... i enabled debug in the acpi section of the kernel and then i got a

[ACPI Debug] _L09 : Enter

[ACPI Debug] _L09 : Exit

after this i played around in the source and got some debug info when i do a

 cat /proc/acpi/ac_adapter/C105/state

or similar. however still no events

*scratches head* i also have a problem with my fan i can turn it on but not turn it off and not change the speed as a result i sometimes got a laptop that is way to hot.. also tryed to remove the fan support under acpi as some one else did and hopped that the comp itself would control the fan as it did before i started to use ACPI but no luck  :Sad: 

i can live with it as it is but it would be nice to solve the problems or at least hear that i'm not the only one  :Wink: 

----------

## optilude

All I can suggest is look for a BIOS update from your manufacturer. It does sound like a compliance issue with its ACPI implementation. Sorry I can't be more help.

Martin

----------

## de4d

for my fsc lifebook E4010 ive added:

```

lid)    

  let "decdir = 0x$4" # direction in decimal (hex doesnt work)

  if [ `expr $decdir % 2` -eq 0 ]; then

    # logger "opened";

    su $USER -c "/usr/X11R6/bin/xset dpms force on -display $DISPLAY"

  else

    # logger "closed";

    su $USER -c "/usr/bin/xlock -display $DISPLAY -mode blank"

    su $USER -c "/usr/X11R6/bin/xset dpms force off -display $DISPLAY"

  fi

;;

```

somewhere into /etc/acpi/default.sh

for some reason i think that dpms off AND backlight off (hardware) saves more battery. iam not sure though.

DISPLAY is ":0" and USER the user who is using the x server.

ive hardcoded this, but if someone knows howto 'find out' that would be cool.

----------

## optilude

(This is off course somewhat O/T because de4d's code has nothing to do with the power profile scripts, but it could be useful nonetheless...)

 *de4d wrote:*   

> for my fsc lifebook E4010 ive added:
> 
> ```
> 
> <snip>
> ...

 

What does the $decdir variable do? It's the "direction" - of what? The lid? 

If you wanted to make this a little more transparent, you could of course add another script called something like "lid-closed" in /etc/power-profile.d that would set your screen off and map the ACPI lid closed event as in your configuration to this. You'd put the DPMS off stuff in there - it may also be wise to turn on other power saving options (hparm stuff to turn off your disks, perhaps).

You could then map the ACPI opened event to another script that would reset the changes.

Also note: I worry that your script may not work so well if linux was booted with the lid closed!  :Smile: 

Martin

----------

## MooktaKiNG

I have a sony vaio laptop and i don't seem to get any events for ac in or ac out. I just don't understand it. I recompiled the kernel with debug on, for acpi, and it does detect ac in and out.

But acpid for some reason doesn't show it  in /var/log/acpid, anyway, i'll try the script above tonight and see if that works.

----------

## optilude

 *MooktaKiNG wrote:*   

> I have a sony vaio laptop and i don't seem to get any events for ac in or ac out. I just don't understand it. I recompiled the kernel with debug on, for acpi, and it does detect ac in and out.
> 
> But acpid for some reason doesn't show it  in /var/log/acpid, anyway, i'll try the script above tonight and see if that works.

 

I used to have a VAIO (FX108k) and could never get ACPI to work properly... sad, but true. Hope you have better luck! If you compiled the ACPI stuff as modules, make sure you've loaded them (modprobe ac) - also, I had more luck with ACPI on this 2.6 kernel than on the 2.4 series.

Martin

----------

## MooktaKiNG

I'm using the 2.6.0 mm Test 9 kernel. But it still doesn't seem to work.

I'm not sure if the problem is with acpi, or acpid itself. Becuase when i compile in verbose into the kernel and run it acpi does mension that my AC cable is out, and in.

However acpid doesn't cause an event. I need to get this working so that i can use cpufreq, to slow my CPU down when its using the battery.

I do get events for the lid being closed and opened, and the power button.

I'm thinking, does acpid just cause events for buttons only? (lid and power is a button).

By the way i got Suspend to Disk working fairly well, it works nearly the same way as hibernation in windows.

Maybe i should try the latest acpid (unstable), however my internet has been cut from my room, i live in university campus, for downloading too much. Therefore using portage is a pain right now  :Sad:  :Sad:  :Sad: 

----------

## MooktaKiNG

Another weird thing is when i close my lid, the back light does not go off.

However i used acpid to run 'cat' on the state file of lid inside /proc, then it turns the backlight off.

This is really weird. I don't really know how special the cat command is, but this seems to have solved my problem for lid.  :Smile:  :Smile:  :Smile:  :Smile: 

----------

## de4d

 *optilude wrote:*   

> 
> 
> What does the $decdir variable do? It's the "direction" - of what? The lid? 
> 
> 

 

yes. direction of lid. but to be more accurate its the event counter ($4) in decimal (to make the % operator work). ive seen the same lines without the decimal conversion somewhere, but these only work 'sometimes'.

 *optilude wrote:*   

> 
> 
> Also note: I worry that your script may not work so well if linux was booted with the lid closed! :-)
> 
> 

 

you got me. :|

.. okay OT again, but at least there might be a power-save use for this.

----------

## federico

I'm using an Acer Travelmate 291lmi, centrino processor.

My default action is to pass everything to default.sh

default.sh

```

#!/bin/sh

# Default acpi script that takes an entry for all actions

set $*

group=${1/\/*/}

action=${1/*\//}

case "$group" in

        button)

                case "$action" in

                        power)  /sbin/init 0

                        ;;

                        lid)

                        azione="`cat /proc/acpi/battery/BAT1/state | grep charging | cut -c 26-`"

                        case $azione in

                                charging)       

                                        /usr/local/bin/power-profile AC

                                        logger "A/C adapter plugged in"

                                        ;;

                                discharging)    

                                        lidstate="`cat /proc/acpi/button/lid/LID/state | cut -c 13-`"

                                        case $lidstate in

                                                closed)  /usr/local/bin/power-profile Battery

                                                        logger "Schermo Chiuso"

                                                        ;;

                                                open)   /usr/local/bin/power-profile Dynamic

                                                        logger "A/C adapter plugged out"

                                                        ;;

                                        esac

                                        ;;        

                                unknown) /usr/local/bin/power-profile AC

                                        logger "A/C adapter plugged in"

                                        ;;

                        esac

                        ;;

                        *)      logger "ACPI action $action is not defined"

                                ;;

                esac

                ;;

        # Battery acpi script that set different speedfreq modes depending on AC adapter

        # Can only handle one battery at the time, will add support for more when I get time

        battery)

                if [ $4 -eq 00000001 ] && [ -f /proc/acpi/battery/BAT1/state ] ; then

                        action="`cat /proc/acpi/battery/BAT1/state | grep charging | cut -c 26-`"

                        case $action in

                                charging)       /usr/local/bin/power-profile AC

                                                logger "A/C adapter plugged in"

                                                ;;

                                discharging)    /usr/local/bin/power-profile Dynamic

                                                logger "A/C adapter plugged out"

                                                ;;

                                unknown)        /usr/local/bin/power-profile AC

                                                logger "A/C adapter plugged in"

                                                ;;

                        esac

                fi

        ;;

        *)

                logger "ACPI group $group / action $action is not defined"

                ;;

esac

```

And well...

Pressing the power butto the pc shoutdown.

If the AC cable is connected we use max processor, if now we use the dynamic mode.

If the AC cable is not connected ad we close the screen the PC goes to battery mode.

Thanks for the script!

Fede

----------

## NiXZe

Ok got a new laptop now IBM ThinkPad T40p that old Compaq Armada M700 i don't want to see again  :Wink:  well posting a link to my present /etc/acpi/default.sh *link removed*

and yeha i like runing seti but i don't want to do it when it's on battery  :Wink: 

----------

