Sometimes while working on my laptop, when not connected to the AC power source, I get notified when power is critically low. I wrote this script which notifies me for every steps of 10% change in power level (for more details, please refer to the script code). For notification I preferred using zenity
to notify-send
as I frequently miss out to check such toast notifications while busy.
Script name: /home/username/bin/notification_battery_discharge.sh
;
Contents:
#!/bin/bash
notification_battery_discharge.sh (v0.1)
Configuration options:
declare -i __DISPLAY_CHARGING_NOTIFICATIONS=1 ## where, 1=true, 0=false
declare __FILENAME="/sys/class/power_supply/BAT1/uevent"
declare -ri __TIME_SLEEP_SECONDS=60
declare __CURR_POWER_SUPPLY_STATUS=""
declare -i __CURR_BATTERY_PERCENTAGE_LEVEL=0
declare -i __LOWER_LEVEL=0
declare -i __UPPER_LEVEL=0
declare -A __LEVEL
__LEVEL["90-100"]=0 ## where, 1=true; 0=false
__LEVEL["80-90"]=0
__LEVEL["70-80"]=0
__LEVEL["60-70"]=0
__LEVEL["50-60"]=0
__LEVEL["40-50"]=0
__LEVEL["30-40"]=0
__LEVEL["20-30"]=0
__LEVEL["10-20"]=0
__LEVEL["0-10"]=0
declare -A __LEVEL_MSG_DISPLAYED
__LEVEL_MSG_DISPLAYED["90-100"]=0 ## where, 1=true; 0=false
__LEVEL_MSG_DISPLAYED["80-90"]=0
__LEVEL_MSG_DISPLAYED["70-80"]=0
__LEVEL_MSG_DISPLAYED["60-70"]=0
__LEVEL_MSG_DISPLAYED["50-60"]=0
__LEVEL_MSG_DISPLAYED["40-50"]=0
__LEVEL_MSG_DISPLAYED["30-40"]=0
__LEVEL_MSG_DISPLAYED["20-30"]=0
__LEVEL_MSG_DISPLAYED["10-20"]=0
__LEVEL_MSG_DISPLAYED["0-10"]=0
function checkLevel() {
declare myLevel="${1}" ## $1 is required to be level string e.g. "80-90"
if [[ ${__LEVEL[${myLevel}]} -eq 1 && ${__LEVEL_MSG_DISPLAYED[${myLevel}]} -eq 0 ]] ; then
if [[ "${__CURR_POWER_SUPPLY_STATUS}" != "Discharging" ]] ; then
if [[ ${__DISPLAY_CHARGING_NOTIFICATIONS} -eq 1 ]] ; then
zenity --info --title="Battery Status: ${__CURR_POWER_SUPPLY_STATUS} ($(date +%Y-%m-%d' '%H:%M))" --text="The power supply is currently ${__CURR_POWER_SUPPLY_STATUS} at level ${__CURR_BATTERY_PERCENTAGE_LEVEL}%." &
fi
else
zenity --error --title="Battery Status: ${__CURR_POWER_SUPPLY_STATUS} ($(date +%Y-%m-%d' '%H:%M))" --text="The power supply is currently ${__CURR_POWER_SUPPLY_STATUS} at level ${__CURR_BATTERY_PERCENTAGE_LEVEL}%." &
fi
__LEVEL_MSG_DISPLAYED[${myLevel}]=1
fi
if [[ ${__LEVEL[${myLevel}]} -eq 0 && ${__LEVEL_MSG_DISPLAYED[${myLevel}]} -eq 1 ]] ; then
__LEVEL_MSG_DISPLAYED[${myLevel}]=0
fi
}
while : ; do
while read ; do
if [[ "${REPLY}" =~ ^POWER_SUPPLY_STATUS=(.*)$ ]] ; then
__CURR_POWER_SUPPLY_STATUS=${BASH_REMATCH[1]}
fi
if [[ "${REPLY}" =~ ^POWER_SUPPLY_CAPACITY=(.*)$ ]] ; then
__CURR_BATTERY_PERCENTAGE_LEVEL=${BASH_REMATCH[1]}
fi
done < "${__FILENAME}"
__LOWER_LEVEL=90
__UPPER_LEVEL=100
if [[ ${__CURR_BATTERY_PERCENTAGE_LEVEL} -ge ${__LOWER_LEVEL} && ${__CURR_BATTERY_PERCENTAGE_LEVEL} -lt ${__UPPER_LEVEL} ]] ; then
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=1
else
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=0
fi
__LOWER_LEVEL=80
__UPPER_LEVEL=90
if [[ ${__CURR_BATTERY_PERCENTAGE_LEVEL} -ge ${__LOWER_LEVEL} && ${__CURR_BATTERY_PERCENTAGE_LEVEL} -lt ${__UPPER_LEVEL} ]] ; then
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=1
else
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=0
fi
__LOWER_LEVEL=70
__UPPER_LEVEL=80
if [[ ${__CURR_BATTERY_PERCENTAGE_LEVEL} -ge ${__LOWER_LEVEL} && ${__CURR_BATTERY_PERCENTAGE_LEVEL} -lt ${__UPPER_LEVEL} ]] ; then
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=1
else
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=0
fi
__LOWER_LEVEL=60
__UPPER_LEVEL=70
if [[ ${__CURR_BATTERY_PERCENTAGE_LEVEL} -ge ${__LOWER_LEVEL} && ${__CURR_BATTERY_PERCENTAGE_LEVEL} -lt ${__UPPER_LEVEL} ]] ; then
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=1
else
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=0
fi
__LOWER_LEVEL=50
__UPPER_LEVEL=60
if [[ ${__CURR_BATTERY_PERCENTAGE_LEVEL} -ge ${__LOWER_LEVEL} && ${__CURR_BATTERY_PERCENTAGE_LEVEL} -lt ${__UPPER_LEVEL} ]] ; then
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=1
else
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=0
fi
__LOWER_LEVEL=40
__UPPER_LEVEL=50
if [[ ${__CURR_BATTERY_PERCENTAGE_LEVEL} -ge ${__LOWER_LEVEL} && ${__CURR_BATTERY_PERCENTAGE_LEVEL} -lt ${__UPPER_LEVEL} ]] ; then
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=1
else
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=0
fi
__LOWER_LEVEL=30
__UPPER_LEVEL=40
if [[ ${__CURR_BATTERY_PERCENTAGE_LEVEL} -ge ${__LOWER_LEVEL} && ${__CURR_BATTERY_PERCENTAGE_LEVEL} -lt ${__UPPER_LEVEL} ]] ; then
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=1
else
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=0
fi
__LOWER_LEVEL=20
__UPPER_LEVEL=30
if [[ ${__CURR_BATTERY_PERCENTAGE_LEVEL} -ge ${__LOWER_LEVEL} && ${__CURR_BATTERY_PERCENTAGE_LEVEL} -lt ${__UPPER_LEVEL} ]] ; then
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=1
else
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=0
fi
__LOWER_LEVEL=10
__UPPER_LEVEL=20
if [[ ${__CURR_BATTERY_PERCENTAGE_LEVEL} -ge ${__LOWER_LEVEL} && ${__CURR_BATTERY_PERCENTAGE_LEVEL} -lt ${__UPPER_LEVEL} ]] ; then
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=1
else
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=0
fi
__LOWER_LEVEL=0
__UPPER_LEVEL=10
if [[ ${__CURR_BATTERY_PERCENTAGE_LEVEL} -ge ${__LOWER_LEVEL} && ${__CURR_BATTERY_PERCENTAGE_LEVEL} -lt ${__UPPER_LEVEL} ]] ; then
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=1
else
__LEVEL["${__LOWER_LEVEL}-${__UPPER_LEVEL}"]=0
fi
checkLevel "90-100"
checkLevel "80-90"
checkLevel "70-80"
checkLevel "60-70"
checkLevel "50-60"
checkLevel "40-50"
checkLevel "30-40"
checkLevel "20-30"
checkLevel "10-20"
checkLevel "0-10"
sleep ${__TIME_SLEEP_SECONDS}s
done
End of script.
Configuration: Appropriately fix the __FILENAME variable to point to /sys/class/power_supply/BAT0/uevent
or /sys/class/power_supply/BAT1/uevent
or something else as needed. If you don't want the notification during charging use __DISPLAY_CHARGING_NOTIFICATIONS=0
.
The script can be started manually by running bash /home/username/bin/notification_battery_discharge.sh
.
Setup:
For automatic startup, create a .desktop
file in $HOME/.config/autostart
e.g. /home/username/.config/autostart/notification_battery_discharge.desktop
with the following content:
[Desktop Entry]
Name=Notification of Battery Discharge
Exec="/home/username/bin/notification_battery_discharge.sh"
Type=Application
If required run chmod +x /home/username/.config/autostart/notification_battery_discharge.desktop
. Then log out, and log back in, the script should start its notification process.
Alternatively, for automatic start up using systemd
, create a .service
file in $HOME/.config/systemd/user/
directory e.g. $HOME/.config/systemd/user/notification_battery_discharge.service
with the following content:
[Unit]
Description=Display notification at different levels of battery discharging/charging.
After=graphical-session.target
[Service]
Type=oneshot
ExecStart=-/bin/bash -c '/home/username/bin/notification_battery_discharge.sh'
[Install]
WantedBy=graphical-session.target
Then use the command systemctl --user enable notification_battery_discharge.service
then log out, and log back in. The notification process should start.