Laptop battery high/low alarm

My laptop battery didn't last half as long as I had hoped and it is an internal one. That is, it is very inconvenient to replace. I would like my replacement battery to last as long as possible, and after reading up on it, it looks like the best way to do that is to allow it to charge and discharge on a regular basis. So I looked for a program or app in the Ubuntu software center that could remind me to unplug or plug in and found nothing, and the default battery indicator is insufficient because it doesn't care about battery health.

So, is there any app that does this? If not, is there an API I can take advantage of so I can write my own?

Edit: A simple google search revealed I could look up battery information using the command upower -i /org/freedesktop/UPower/devices/battery_BAT0. It would be nice to have a status indicator do this for me (and possibly keep a tally of charge/discharge cycles).


Solution 1:

You can try to use this script.

It raise a notification and play sound (with pulseaudio) when battery level reach selected value. It doesn't keep track of charge/discharge cycles, but with some edit you can add this feature.

#! /bin/bash

# read battery percentage value
OUT=`upower -i /org/freedesktop/UPower/devices/battery_BAT0 | grep percentage`

# select only the int value
IFS=':' read -ra P <<< "$OUT"
PERCENTAGE="%"
BATTERY_VALUE=${P[1]%$PERCENTAGE}

# send a notification and play sound if battery level is under 10%
if (( $BATTERY_VALUE  < "10")); then
  notify-send "Battery Low level! You need to plug your PC!"

# command to play sound - you can select your preferred sound if this doesn't work
  paplay /usr/share/sounds/freedesktop/stereo/complete.oga
fi

# send a notification and play sound if battery level is equal to 100%
if (( $BATTERY_VALUE  >= "100")); then
  notify-send "Battery charged! You can now unplug your PC!"
  paplay /usr/share/sounds/freedesktop/stereo/complete.oga
fi

Copy this script into a bash file and move it into local bin folder:

sudo mv <script_file> /usr/local/bin/

Where script_file is the name (or path) of your script. Then you can use cron daemon to run it every 5 minutes to check battery level. So edit cron:

crontab -e

Select preferred editor and add at the end of file this line:

*/5 * * * * /usr/local/bin/<script_file>

Change script_file with your script name.

Now it should work. Check it after a system reboot.

I hope to be useful.

Solution 2:

You can use this script as I was stuck today on the same problem.

You can think of this script as an upgrade to the script given by @Danibix. The script below uses systemd service as to restart itself even if the process is killed.

#!/bin/bash

# Run this script as a cronjob every 5 minutes or so, to get notifications when
# battery percentage goes below 30% or above 80%. Also you can create a systemd service.
# Cronjob line example:
# */5 * * * * /bin/bash /path/to/battery_health_notifications.sh

export $(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME gnome-session | head -n 1)/environ | tr '\0' '\n')
export XDG_RUNTIME_DIR="/run/user/1000"

while ((1)) ; do
    BATTERY_PATH=$(upower -e | grep battery)
    LINE_POWER_PATH=$(upower -e | grep line_power)
    BATTERY_PERCENTAGE=$(upower -i $BATTERY_PATH | grep 'percentage:' | awk '{ print $2 }' | sed 's/%//')
    CABLE_PLUGGED=$(upower -i $LINE_POWER_PATH | grep -A2 'line-power' | grep online | awk '{ print $2 }')

    if [[ $CABLE_PLUGGED == 'yes' ]]; then

        if [[ $BATTERY_PERCENTAGE -gt 75 ]]; then
        notify-send --hint=int:transient:1 --urgency=critical "Battery optimization" "Battery reached 75%, unplug the power cable to optimize battery life."

        #Using my own alarm file. You can choose your desired alarm file.
        /bin/paplay /home/ali/.local/alarm.wav
        fi

    else

        if [[ $BATTERY_PERCENTAGE -lt 30 ]]; then
        notify-send --hint=int:transient:1 --urgency=critical "Battery optimization" "Battery is below 30%, plug in the power cable to optimize battery life."

        #Using my own alarm file. You can choose your desired alarm file.
        /bin/paplay /home/ali/.local/alarm.wav
        fi

    fi
    sleep 2
done

Put the above script anywhere in your home folder as battery_health_notifications.sh

After that create a service file as battery_alarm.service and copy the text below in it. Make sure you read the comments in the service file below to configure it according to your system.

[Unit]
#just what it does
Description= Battery alarm notifies the user about charge and discharge cycle of battery

[Service]
#not run by root, but by me. Change User to your username
User=ali
#we assume the full service as active one the script was started
Type=simple
#where to find the executable 
ExecStart=/home/ali/.local/battery_health_notifications.sh
#what you want: make sure it always is running
Restart=always

[Install]
#which service wants this to run - default.target is just it is loaded by default
WantedBy=default.target

Open the terminal where your battery_alarm.service is located and copy the commands below onto your terminal.

sudo mv battery_alarm.service /etc/systemd/system/
systemctl enable battery_alarm.service
systemctl start battery_alarm.service

Your battery alarm setup is complete. To check if its running or not type the below command onto your terminal.

systemctl status battery_alarm.service 

You would get something like this.

● battery_alarm.service - Battery alarm notifies user about charge discharge cycle of battery
     Loaded: loaded (/etc/systemd/system/battery_alarm.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2020-05-16 20:26:34 PKT; 23min ago
   Main PID: 166450 (battery_health_)
      Tasks: 2 (limit: 12979)
     Memory: 2.6M
     CGroup: /system.slice/battery_alarm.service
             ├─166450 /bin/bash /home/ali/.local/battery_health_notifications.sh
             └─183382 sleep 2

May 16 20:26:34 pop-os systemd[1]: Started Battery alarm notifies the user about charge-discharge cycle of the battery.