You are not logged in.

#1 2013-09-08 17:12:02

cris9288
Member
Registered: 2013-01-07
Posts: 348

[SOLVED] suspending with battery using acpid

Hi everyone,

I'm trying to get acpid to suspend my laptop when it gets to a certain percentage. I know I've gotten this to work before, but for some reason my script doesn't seem to be working. I'm not very skilled with bash, but here is what I'm using

#!/bin/bash

if [ $(acpi -b | grep "Discharging, 8%") ]; then
    systemctl suspend
else
    acpi -b
fi

when I run it in the terminal i get

/usr/bin/lobatt: line 3: [: too many arguments
Battery 0: Discharging, 7%, 00:19:27 remaining

this is when my battery is at the threshold. If it is above or below the else clause executes fine.

this is the relevant section of handler.sh

battery)
        case "$2" in
            BAT0)
                case "$4" in
                    00000000)
                        logger 'Battery online'
                        ;;
                    00000001)
                        logger 'Battery offline'
                        ;;
                esac
                ;;
            CPU0)
                ;;
            *)  logger "ACPI action undefined: $2" ;;
        esac
        lobatt
        ;;

I'm not sure what I'm doing wrong with the bash script. I've executed scripts like that several times, but I'm sure there is some small detail i'm missing in the syntax. Thanks for any help!

Last edited by cris9288 (2013-09-08 21:37:02)

Offline

#2 2013-09-08 18:19:05

cookies
Member
Registered: 2013-01-17
Posts: 253

Re: [SOLVED] suspending with battery using acpid

a little change to your lobatt script might do it:

!/bin/bash

text=`acpi -b | grep "Discharging, 8%"`

if [ -n $text ]; then
    systemctl suspend
else
    acpi -b
fi

Edit: does not work!

Last edited by cookies (2013-09-08 21:48:03)

Offline

#3 2013-09-08 18:52:42

Raynman
Member
Registered: 2011-10-22
Posts: 1,539

Re: [SOLVED] suspending with battery using acpid

That might do it, but it is unnecessary.

The if uses the return status of the command to pick one of the branches. [ (or test) is a special command that evaluates conditional expressions. The original script feeds grep's output to [, but that output is not a conditional expression. (When your battery is above or below the threshold you have an empty expression and that is acceptable.) Checking grep's output with -n is better, but it is easier to use grep's return status (suppressing output with -q):

if acpi -b | grep -q "Discharging, 8%"; then
    systemctl suspend
else
    acpi -b
fi

The else clause is probably only useful for testing, or does acpid log this stuff?

Offline

#4 2013-09-08 19:04:45

WonderWoofy
Member
From: Los Gatos, CA
Registered: 2012-05-19
Posts: 8,414

Re: [SOLVED] suspending with battery using acpid

Typically, if you want acpid to handle something, there have to be events being given to udev.  For example, when you open and close the lid, it sends lid events, or when you push the power button, it sends button events.

So on most (if not all) systems, there is no event that is sent on each percentage decrease of the battery.  You can test this by using either udevadm monitor or by using acpi_listen (from the acpid package).  But I have yet to come across a machine that actually reports these things.

So instead, I think what you are probably going to want to do is create something like a cron job that runs every few minutes and check to see if the level is below a certain threshold.  If it is, then it should issue a suspend command.  That is probably the most sane way to do it without resorting to more third party software like xfce4-power-manager or the gnome-power-manager.

Otherwise, you could create a systemd service that runs a script for you.  In the script you would have a loop that simply does the same thing as the cron job above.  That is, check the battery level, sleep a while, then check again.  The check should be in some kind of an if statement that will suspend if that level has been reached.  But this is really just repeating the functionality of a daemon that already runs on most systems (cron).

The other thing you could do is to set up a systemd.timer event that runs a oneshot systemd.service that checks this.  But again, this is probably making things more complex that is necessary.

The way you are going about it now, I don't think is going to work.  Good luck though!

Offline

#5 2013-09-08 19:13:15

cris9288
Member
Registered: 2013-01-07
Posts: 348

Re: [SOLVED] suspending with battery using acpid

Raynman wrote:

That might do it, but it is unnecessary.

The if uses the return status of the command to pick one of the branches. [ (or test) is a special command that evaluates conditional expressions. The original script feeds grep's output to [, but that output is not a conditional expression. (When your battery is above or below the threshold you have an empty expression and that is acceptable.) Checking grep's output with -n is better, but it is easier to use grep's return status (suppressing output with -q):

if acpi -b | grep -q "Discharging, 8%"; then
    systemctl suspend
else
    acpi -b
fi

The else clause is probably only useful for testing, or does acpid log this stuff?


That seems to work. Thanks! cookie's suggestion seemed to always suspend no matter what the condition was.

The echo was just for testing purposes. Thanks for the replies everyone.

EDIT for WonderWoofy:

Luckily enough, by laptop actually does report battery events to acpid and I've been able to use this kind of a script to suspend/hibernate on low battery before. Correct syntax in if/else clauses in bash has always eluded me, though.

Last edited by cris9288 (2013-09-08 19:17:14)

Offline

#6 2013-09-08 21:47:26

cookies
Member
Registered: 2013-01-17
Posts: 253

Re: [SOLVED] suspending with battery using acpid

cris9288 wrote:

cookie's suggestion seemed to always suspend no matter what the condition was.

Damn! It really does. Sorry!

Offline

Board footer

Powered by FluxBB