You are not logged in.
According to this article we should be keeping our batteries between 40 and 80% capacity.
I've written a script to remind the user via notifications when it is time to plug in/unplug the laptop.
It has the strange dependency of pulseaudio at the moment, but if anyone can see a better way of discovering all DBUS instances I'd love to know.
It can be found in the AUR at batterylife
Last edited by parchd (2014-07-01 18:00:49)
Offline
Link to source? AUR page?
Offline
Sorry jasonwryan, I needed a url to add it to the AUR and so I ended up posting this before it was there. I tried to get it in before anyone noticed the post.
Offline
Modern laptops (or at least Dell, Lenovo, Fujitsu, Apple, Asus that I can confirm for certain) all do this themselves. Leave one on for a few days (on charge), you'll see it lets the battery discharge to as low as 90% on its own before the charger tops it up to 100 again.
The power consumption of a (genuine/original... not £5 ebay) charger for the above brands when plugged in, but not actually charging, is next to nothing. Unmeasurable by my power meter, which reads as low as 5watts before it says zero
Last edited by stevenhoneyman (2014-07-01 18:13:35)
My: [ GitHub | AUR Packages ]
Offline
Maybe it is unnecessary, I'm not that knowledgeable about battery technology, but what you're describing only seems to prevent continuing to charge after reaching 100%, whereas the article I linked to says that stopping at 80% and not discharging past 40% provides a significant extension to the batteries overall lifespan. With batteries in smaller laptops (and tablets) not being easily replaceable nowadays, making them last as long as possible seems like a good idea.
Offline
I take the opinion of "by the time the battery needs replacing, it'll be time to buy a new device anyway"
I've never had a lithium ion go bad in any device - usually replace devices on around the 3 year mark.
My: [ GitHub | AUR Packages ]
Offline
We differ there then . I'm still using a laptop I bought more than 7 years ago*, and although my partner's previous laptop was a couple of years younger the battery life ended up being just 2 minutes.
The motivation behind this script was mostly the fact that her new laptop's battery isn't (supposed to be) end-user replaceable, and she is terrified of ending up with a battery life of 2 minutes again.
*and I don't intend to replace it any time soon, although I might supplement it with a tablet at some point.
Offline
Thanks!
My version (removed the systemd timer, i think this way is simpler, because there is no need for temporary files)
I use kde, so i grep for plasma-desktop... i wonder if there is another way to get the dbus session address...
#! /bin/bash
MIN=40
MAX=80
ALERTLO=0
ALERTHI=0
notify-send-all(){
for p in $(pgrep "plasma-desktop"); do
dbus=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$p/environ | sed 's/DBUS_SESSION_BUS_ADDRESS=//')
user=$(grep -m 1 -z USER /proc/$p/environ | sed 's/USER=//')
dply=$(grep -z DISPLAY /proc/$p/environ | sed 's/DISPLAY=//')
sudo -u $user sh -c "DBUS_SESSION_BUS_ADDRESS=\"$dbus\" DISPLAY=\"$dply\" notify-send -i battery $1"
done
}
sleep 60 #delay startup by 1 minute
while true ; do
unplugged=$(cat /sys/bus/acpi/drivers/battery/*/power_supply/BAT?/status|grep -i discharging)
acpiout=$(acpi)
if [ "$(echo $acpiout|grep -Po "[0-9]+(?=%)")" -le $MIN ]; then #Battery under low limit
ALERTHI="0"
if [ ! "$unplugged" == "" ]; then #unplugged
if [ "$ALERTLO" == "0" ]; then
notify-send-all "\"BatteryLife\" \"Battery under $MIN%\n\nBetter to plug the ac\""
ALERTLO="1"
fi
fi
elif [ "$(echo $acpiout|grep -Po "[0-9]+(?=%)")" -ge $MAX ]; then #Battery over high limit
ALERTLO="0"
if [ "$unplugged" == "" ]; then #plugged
if [ "$ALERTHI" == "0" ]; then
notify-send-all "\"BatteryLife\" \"Battery over $MAX%\n\nBetter to UNplug the ac\""
ALERTHI="1"
fi
fi
fi
sleep 60 #Repeat every minute
done
-EDIT it wasn't working
Last edited by kokoko3k (2014-07-10 12:09:57)
Help me to improve ssh-rdp !
Retroarch User? Try my koko-aio shader !
Offline
Batterylife: 40 80 percent bash script for connecting and disconnecting laptop charger:
I think the notify-send-all function can be removed from the script. Further I don't see the use of ALERTLO and ALERTHI. So I have removed the ALERTHI, ALERTLO and edited the bash script. The delay startup can also be removed. The new script is as follows and works fine. Thank you parchd and kokoko3k for the script.
#! /bin/bash
MIN=40
MAX=80
while true ; do
unplugged=$(cat /sys/bus/acpi/drivers/battery/*/power_supply/BAT?/status|grep -i discharging)
acpiout=$(acpi)
if [ "$(echo $acpiout|grep -Po "[0-9]+(?=%)")" -le $MIN ]; then #Battery under low limit
if [ ! "$unplugged" == "" ]; then #unplugged
notify-send "Battery under $MIN. Please plug in the adapter"
fi
elif [ "$(echo $acpiout|grep -Po "[0-9]+(?=%)")" -ge $MAX ]; then #Battery over high limit
if [ "$unplugged" == "" ]; then #plugged
notify-send "Battery above $MAX. Please remove the adapter"
fi
fi
sleep 10 #Repeat every 10 seconds
done
Offline
FWIW, there is a useless use of cat to grep, and a use of grep to a variable to check if it is empty, all of which can be replaced by a proper use of `grep -q`. You could also grab the battery level directly from /sys/class rather than grepping acpi output. On top of this, given that bash is explicitly specified, you should use bash's built in '[[' rather than the separate binary '['.:
#! /bin/bash
MIN=40
MAX=80
while true; do
for bat in /sys/class/power_supply/BAT*; do
level=$(< $bat/capacity)
if [[ $level -le $MIN ]]; then
grep -q discharging ${bat}/status && notify-send "Battery under $MIN. Please plug in the adapter"
elif [[ $level -gt $MAX ]]; then
grep -q charging ${bat}/status && notify-send "Battery above $MAX. Please remove the adapter"
fi
done
sleep 10
done
I also added an internal loop to handle more than one battery. If you know there is only one battery, then remove the inner loop and specify BAT0 explicitly. The BAT? regex is problematic without a loop though as it only serves to handle more than one battery but will fail in the absence of a loop treating the two /sys/ paths separately.
You could also get rid of the if block if you wanted:
for bat in /sys/class/power_supply/BAT*; do
level=$(< $bat/capacity)
[[ $level -le $MIN ]] && grep -q discharging ${bat}/status && notify-send "Battery under $MIN. Please plug in the adapter"
[[ $level -gt $MAX ]] && grep -q charging ${bat}/status && notify-send "Battery above $MAX. Please remove the adapter"
done
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
This post was extremely useful
Just to mention that the "i" option should be added to grep, since some distros report the status of "Charging" or "Discharging" with capital letters. Something like:
for bat in /sys/class/power_supply/BAT*; do
level=$(< $bat/capacity)
[[ $level -le $MIN ]] && grep -iq discharging ${bat}/status && notify-send "Battery under $MIN. Please plug in the adapter"
[[ $level -gt $MAX ]] && grep -iq charging ${bat}/status && notify-send "Battery above $MAX. Please remove the adapter"
done
Offline