Battery notification bash script

HI All.. I'm new to the community & new to bash scripting. Over the past week or so I have been trying to create a simple bash script that will notify me whenever my battery is fully charged & display a window created with yad if my battery drops to 22% or below. I'm completly new to bash scripting & so far haven't been able to get anything working. I was hoping that someone here with more skill or knowledge might be able to help me get it working :? Below is my code in it's current state & many thanks in advanced for commenting & or helping....

#!/usr/bin/env bash

battery=$(/sys/class/power_supply/BAT0/capacity)
if [[ $battery -eq 100 ]]; then
  export DISPLAY=:0.0
  notify-send -i "/usr/share/icons/Arc-X-P/panel/22/battery-full-charged.svg" "Battery Charged" "Level: ${battery_percent}% "
elif [[ $battery -lt 22 ]]; then
  export DISPLAY=:0.0
  yad --no-buttons --center --borders=22 --timeout=8 --title="BATTERY LOW. PLEASE PLUG IN CHARGER...." --image /home/furycd001/Terminal/Selena\ Gomez/batterylow.jpg
fi

I have rewrote the script above using the code below.. The notification for 100% charged works just fine now, but the 22% or lower part still does nothing.. If anyone can get either working I'll be forever grateful....

#!/usr/bin/env bash
while true
do
    export DISPLAY=:0.0
    battery_percent=$(acpi -b | grep -P -o '[0-9]+(?=%)')
    if on_ac_power; then
        if [ "$battery_percent" -eq 100 ]; then
            notify-send -i "/usr/share/icons/Arc/panel/22/battery-full.svg" "Battery Charged" "Level: ${battery_percent}% "
          elif [[ $battery -lt 22 ]]; then
            yad --no-buttons --center --borders=22 --timeout=8 --title="BATTERY LOW. PLEASE PLUG IN CHARGER...." --image /home/furycd001/Terminal/Selena\ Gomez/batterylow.jpg
          fi
        fi
    fi
    sleep 300 # (5 minutes)
done

Where does this variable get set in your script?

Woops that was a typo.. Should be as follows. Thanks for pointing that out....

#!/usr/bin/env bash
while true
do
    export DISPLAY=:0.0
    battery=$(acpi -b | grep -P -o '[0-9]+(?=%)')
    if on_ac_power; then
        if [ "$battery" -eq 100 ]; then
            notify-send -i "/usr/share/icons/Arc/panel/22/battery-full.svg" "Battery Charged" "Level: ${battery}% "
          elif [[ "$battery" -lt 22 ]]; then
            yad --no-buttons --center --borders=22 --timeout=8 --title="BATTERY LOW. PLEASE PLUG IN CHARGER...." --image /home/furycd001/Terminal/Selena\ Gomez/batterylow.jpg
          fi
        fi
    fi
    sleep 300 # (5 minutes)
done

Okay so even after correcting that typo, the script still doesn't work. I thought that the first part was working correctly, but after checking it appears that it's not. I may be writing the script totally incorrectly, but I'm not sure because I've only just started to learn bash scripting. I should get a notification whenever my battery reach 100% charge & a window created with yad whenever my battery reaches 22% or lower. Again any help is appreciated....

What is the OS you are using?

Xubuntu-core 18.04 on one machine & Fedora 32 with xfce on the other. Script works on neither....

What happens when you put an echo statement (to print to the screen your battery variable) after you set your battery variable?

... also try adding set -x right after the shebang line (#!/usr/bin/env bash).
Run the script and see what the script is executing....

1 Like

If I add "echo $battery" & then run the script from a terminal I get the battery level showing. Oh thanks for the tip. I'll try that now....

1 Like

Okay so here is what it shows with "set-x" added....

furycd001 > ./battery.sh 
    + true
    + export DISPLAY=:0.0
    + DISPLAY=:0.0
    ++ acpi -b
    ++ grep -P -o '[0-9]+(?=%)'
    + battery=79
    + echo 79
    79
    + on_ac_power
    + '[' 79 -eq 100 ']'
    + [[ 79 -lt 22 ]]
    + sleep 300
1 Like

looks like it's doing what it's supposed to do...
I'd lower/adjust your "thresholds" and see what happens when you hit your conditions...

1 Like

I've already tried changing the battery levels from 100% to 88% & 22% to both 15% & 30%. Also with my original code posted at the very top I get the following output with "set -x".

furycd001 > ./batterylow.sh 
++ /sys/class/power_supply/BAT0/capacity
./batterylow.sh: line 3: /sys/class/power_supply/BAT0/capacity: Permission denied
+ battery=
+ echo
+ [[ '' -eq 100 ]]
+ [[ '' -lt 22 ]]
+ export DISPLAY=:0.0
+ DISPLAY=:0.0
+ yad --no-buttons --center --borders=22 --timeout=8 '--title=BATTERY LOW. PLEASE PLUG IN CHARGER....' --image '/home/furycd001/Terminal/Selena Gomez/batterylow.jpg'

Should also note that when I run the original code from the terminal the window created with yad appears, but with the new code it does not appear....

looks like a "Permission" issue...
Either way... you'll need to fix issues very tediously and iteratively - no need to rush...

I'm probably going to use the second version of the script anyway, but I can "cat /sys/class/power_supply/BAT0/capacity" in a terminal & get an output returned. I'll try rebooting my system to see if anything happens to change....

You do not need to reboot.

Just analyze your permissions

Okay so I just changed "battery=$(/sys/class/power_supply/BAT0/capacity)" to be "battery=$(acpi -b | grep -P -o '[0-9]+(?=%)')" because I didn't want to mess around with permissions. I get no errors appearing in the terminal now & the yad window doesn't open automatically. Let's see if it works now....

Since you've already been helped, I just thought I'd drop a similar script.
I use this script to retrieve the battery status on my laptop, to show it to me via the WM called 'Awesome' (lua).

#!/usr/bin/bash
# Simple script to get either time or percentage remaining of battery
# Includes a warning to the user if percentage is below 10.
# Requires acpi & awesome-wm (for the warning of powerloss/drain)
# Images from: 'batterymon-themer.sh' from an icon pack.
#
#	Variables
#
	[ -z "$1" ] && echo "Usage: bat.sh percent|time|image" && exit 1
	OUT=""
	IMAGE="battery"
	DATA_RAW=$(LC_ALL=C acpi)
	mode=$(echo "$DATA_RAW" | awk -v IFS="," '{print $3}' | tr -d ',')
	[ -z "${mode/Charging}" ] && prefix="+" || prefix="-"
#
#	Time
#
	[ "$1" = "time" ] && echo "$DATA_RAW" | awk -v PRE=$prefix -v IFS="," '{print PRE$5}' | tr -d ',' && exit 0
#
#	Percent
#
	OUT=$(echo "$DATA_RAW" | awk -v IFS="," '{print $4}' | tr -d ',')
	if [ "$1" = "percent" ]
	then	if [ ${OUT/\%} -lt 10 ]
		then	echo "msgbox(\"Connect Power Cord!\")" | awesome-client
		fi
		echo "${prefix/-}$OUT"
		exit 0
	fi
#
# 	Image
#
	OUT="${OUT/\%}"
	[ "$mode" = "Charging" ] && IMAGE+="_${mode,,}"
	if [ $OUT -lt 20 ]
	then	N=1
	elif [ $OUT -lt 40 ]
	then	N=2
	elif [ $OUT -lt 60 ]
	then	N=3
	elif [ $OUT -lt 80 ]
	then	N=4
	elif [ $OUT -lt 100 ]
	then	N=5
	elif echo "$DATA_RAW" | grep -q "discharging at zero rate"
	then	N="full"
	fi
	IMAGE+="_$N.png"
	echo "$IMAGE"
	exit 0

Saying, where you see the pipe to 'awesome-client, you would need to change that line to use 'yad'.
Other than that, you may have a look at the if-else-block to 'define' the image that I'll use to display.

Hope this helps

2 Likes

Thank you for this comment. It's super helpful & awesome. I'm going to look at that script right now....

1 Like

I think you meant -v FS=','.
IFS is shell's InputFieldSeparator - awk has its own (FS/OFS).
Just nit-picking - sowwy....

1 Like