# auto suspend when battery goes below a defined limit?

## ChojinDSL

I've got suspend to disk working on my laptop using swsusp in the gentoo-kernel.

It all works fine, I can suspend and resume properly. But how can I specify that my laptop automatically goes into suspend-to-disk mode once the battery goes below a certain limit?

Im using gnome by the way. Is there perhaps a gnome applet which will take care of this, or maybe a simple script that runs in the background?

----------

## pianosaurus

If you post a command that outputs battery level (give a sample of the output) and one that suspends, I can write you a bash script you can run in the background. It's only a couple of lines of code.

----------

## ChojinDSL

```
cat /proc/acpi/battery/BAT0/state
```

will give me a readout of my laptop battery. In this case, its fully charged and the output is:

```
present:                 yes

capacity state:          ok

charging state:          charged

present rate:            0 mW

remaining capacity:      1258 mWh

present voltage:         16809 mV

```

The value to check is "remaining capacity"

Currently its at maximum, but when I unplug it, that value will drop.

So if your script checks for something it should check for that.

Perhaps if "remaining capacity" drops below 150 mWh or something. Thats when it should suspend. 

On my system, the command for suspend to disk is:

```
 echo 4 > /proc/acpi/sleep
```

----------

## pianosaurus

Save this to a file and make it executable, edit variables as needed and then launch:

```
#!/bin/bash

LIMIT="150" ## Suspend if battery level drops below this (in mWh):

SLEEP="60"  ## Seconds between each battery level check:

while [ true ]; do

  BATTERY=$(/bin/sed -ne "/remaining capacity:/{s/^remaining capacity:[ ]*\([0-9]*\) mWh$/\1/p;q}" /proc/acpi/battery/BAT0/state)

  if [ "$BATTERY" -lt "$LIMIT" ]; then

    ## Comment out the following line if you don't

    ## want to log the event to system log:

    logger "Battery at ${BATTERY} mWh. Suspending to disk."

    echo "Battery at ${BATTERY} mWh. Suspending to disk."

    ## Suspend:

    echo 4 > /proc/acpi/sleep

  fi

  sleep ${SLEEP}s

done
```

I'm not able to test this out (I don't use suspend), so get back to me if it doesn't work, and we'll work it out.

Edit 1: Fixed BATTERY= line (was cut at the end)

Edit 2: Changed from % to mWh in logger and echo.

Edit 3: Removed useless code line. Darn, there's always something...

Addendum: Use tuxlovers updated version below instead. It doesn't suspend when the computer's plugged in.

----------

## tuxlover

I make the script supplied by Cuber in start /etc/conf.d/local.start (which gets loaded by /etc/init.d/local on every startup):

```
/usr/local/bin/suspend-when-bat-low.sh &
```

Also on my machine the battery capacity is given in "mAh" (not mWh) so this needed to be changed. I also don't have BAT0 (but BAT1).

After making these changes this script worked wonderfully, thank you  :Smile: 

If you use suspend2, you should change

```
echo 4 > /proc/acpi/sleep
```

to

```
/usr/local/sbin/hibernate
```

(Actually you can call any suspend mechanism - even suspend to RAM - with the hibernate script, which is much better than simply telling the kernel to suspend.)

----------

## pianosaurus

NP, tuxlover.

Hmm. I had forgotten about this thread. Did it work for you too, ChojinDSL? If it did, you should add [SOLVED] to the subject of your first post.

----------

## tuxlover

After actually really trying the script, I noticed that it suspends even though I had already plugged in my a/c. So I made some 

changes:

check if battery is actually there

make hibernation script configurable

only suspend if we are actually discharging the battery

handle mAh and mWh

make path to battery configurable

call hibernate script (emerge hibernate-script)

```
#!/bin/bash

LIMIT="200" ## Suspend if battery level drops below this (in mAh/mWh):

SLEEP="60"  ## Seconds between each battery level check:

BAT="BAT1" ## Part of path: /proc/acpi/battery/BAT/

HIBERNATE="/usr/local/sbin/hibernate" ## command used to suspend

#HIBERNATE="echo 4 > /proc/acpi/sleep"

while [ true ]; do

  if [ -e "/proc/acpi/battery/$BAT/state" ]; then

     PRESENT=$(/bin/sed -ne "/present:/{s/^present:[ ]*\([a-z]*\)$/\1/p;q}" /proc/acpi/battery/$BAT/state)

     echo $PRESENT

     if [ "$PRESENT" = "yes" ]; then

        STATE=$(/bin/sed -ne "/charging state:/{s/^charging state:[ ]*\([a-zA-Z]*\)$/\1/p;q}" /proc/acpi/battery/$BAT/state)

        BATTERY=$(/bin/sed -ne "/remaining capacity:/{s/^remaining capacity:[ ]*\([0-9]*\) m[WA]h$/\1/p;q}" /proc/acpi/battery/$BAT/state)

        echo $BATTERY

        echo $STATE

        if [ "$BATTERY" -lt "$LIMIT" ] && [ "$STATE" = "discharging" ]; then

           ## Comment out the following line if you don't

           ## want to log the event to system log:

           logger "Battery at ${BATTERY} mWh. Suspending to disk."

           #echo "Battery at ${BATTERY} mWh. Suspending to disk."

           ## Suspend:

           exec "$HIBERNATE"

       fi

     fi

  fi

  sleep ${SLEEP}s

done
```

Last edited by tuxlover on Fri May 20, 2005 11:48 am; edited 1 time in total

----------

## pianosaurus

Looking good. As I said, I never got to try it out, so I expected bugs. Why don't you make the hibernate command configurable too. Seems people do it several different ways.

----------

## tuxlover

Some more changes to the script above. I noticed that the script complains when my battery is not in the computer:

check if battery is actually there

make hibernation script configurable

----------

## Tsuna

interesting, im gonna try to set up some suspend to disk method (swsup or suspend2, dunno which one yet)

any advice as to which one is better?

----------

## tuxlover

Tsuna, take a look at http://gentoo-wiki.com/HOWTO_Software_Suspend_v2

I believe that swsusp v2 is much better than v1, and hopefully soon included in the vanilla kernel as well.

----------

## Tsuna

thats interesting

im reading and following the howto

it seems that installing their unofficial ebuild (sys-kernel/suspend2-sources) doesn't actually patch you current kernel sources but rather install new ones... does it differe from gentoo-sources only by the fact that suspend2 is patched in the kernel or is it actually based on a normal 2.6.11.9 kernel (which makes us loose benefit of the patches applied to the 2.6.11 by gentoo-sources)

```
/usr/src # ll

total 20K

lrwxrwxrwx   1 root root   22 May 20 11:03 linux -> linux-2.6.11-gentoo-r9

drwxr-xr-x  18 root root 4.0K May 20 11:45 linux-2.6.11-gentoo-r6

drwxr-xr-x  19 root root 4.0K May 20 11:49 linux-2.6.11-gentoo-r9

drwxr-xr-x  18 root root 4.0K May 21 02:51 linux-2.6.11.9-suspend2

```

----------

## Tsuna

im going to try to use the patch given on suspend2 website

```
/usr/src/linux # /tmp/software-suspend-2.1.8-for-2.6.11/apply /tmp/software-suspend-2.1.8-for-2.6.11/

Applying 101-kdb-v4.4-2.6.11-rc3-common-1 ...

101-kdb-v4.4-2.6.11-rc3-common-1 will not apply cleanly. Reverse applied patches [Yn]? 

Reversing patches...

Done.

```

is this normal?

I hope this patch will be enough to benefit from the splash compatibility and other stuff patched by suspend2-sources

edit: damn, I dont see Software Suspend 2 in make menuconfig! dunno what to do, any idea please?

----------

## tuxlover

For help regarding suspend2 please go to this thread - it's the thread that started the howto in the gentoo wiki.

I answered your question (or maybe not  :Smile:  ) there.

----------

