6

My laptop battery sucks, and lasts up to 5minutes without charging. Sometimes the charger falls out without me knowing, making the computer shut off unexpectedly.

Is there a way to get a notification the moment my charger falls out? not when battery needs to be charged like Ubuntu is used to do(Because that doesn't work for my laptop, and I've given up that idea)

Braiam
  • 67,791
  • 32
  • 179
  • 269
Jeggy
  • 3,062

2 Answers2

6

Simple linear command:

[[ $(acpi -b | grep -o "Discharging") ]] && notify-send "Alert" "Battery is not charging.\n Please plug your AC adapter!"

From man acpi we have:

NAME
       acpi - Shows battery status and other ACPI information    
SYNOPSIS
       acpi [options]    
DESCRIPTION
       acpi Shows information from the /proc or the /sys filesystem, such as battery status or thermal information.    
OPTIONS
       -b | --battery
                 show battery information

If you run acpi -b and you battery is charging mode, you will get this result of that:

Battery 0: Charging, 88%, 00:38:17 until charged

And if your battery isn't charging then the result would be like this:

Battery 0: Discharging, 87%, 03:46:06 remaining

Then We are looking "Discharging" in the result with this command:

acpi -b | grep -o "Discharging"

If battery was not in charging the result will "Discharging".

And finally we send an alert to notification if we got "Discharging" from above command:

[[ $(acpi -b | grep -o "Discharging") ]] && notify-send "Alert" "Battery is not charging.\n Please plug your AC adapter!"

Note: [[ Something ]] always true and [[ ! Something ]] always false.

Now it's easiest way that we run it in the background, inside a while loop. Then I put the command into a while loop and I check the battery status between X interval of time. Like this:

while true
 do
    # Our command
    sleep [number of seconds] # check the status every [number of seconds] seconds
 done

And if you want to run the script on startup and every 5 minutes, so the construction would be:

  • Save the script(I named it ChkCharge.sh in my home directory)
  • Add a line in /etc/rc.local to call your script (your ChkCharge.sh) + "&" to make it exit. like bash /home/USERNAME/ChkCharge.sh &.

Final Script

#!/bin/bash
while true
do
    [[ $(acpi -b | grep -o "Discharging") ]] && notify-send "Alert" "Battery is not charging.\n Please plug your AC adapter!"
    sleep 300 # 300 seconds or 5 minutes
done

Finish. Reboot and see the magic ;)

αғsнιη
  • 35,660
  • It's so great to see different ways to achieve the same goal :) – Eliezer Oct 04 '14 at 17:08
  • The script works great, but the startup thingy doesn't work for me :/ http://khp.randompoop.net/uploads/Screenshot%20from%202014-10-04%2020:45:47.png does that look right? – Jeggy Oct 04 '14 at 18:48
  • @Jeggy run directly the script sh /home/jeggy/.startup/ChkCharge.sh and see if runs without any errors. – αғsнιη Oct 04 '14 at 20:40
  • 1
    /home/jeggy/.startup/ChkCharge.sh: 4: /home/jeggy/.startup/ChkCharge.sh: [[: not found – Jeggy Oct 04 '14 at 20:46
  • 1
    @Jeggy use bash instead of sh at the begging and run again – αғsнιη Oct 04 '14 at 20:56
  • I changed the code to this: http://paste.ubuntu.com/8495663/ as it didn't say charging when it was charging with 100% and thanks bash did work instead of sh :D – Jeggy Oct 04 '14 at 21:41
  • tested, but the startup thingy still doesn't work :/ I changed it to 3seconds for testing purposes. bash /home/jeggy/.startup/ChkCharge.sh works – Jeggy Oct 04 '14 at 21:53
  • @Jeggy I have updated answer. yes may be your /etc/rc.local don't want to start. try this command to force start it sudo /etc/rc.local start and check if that runs the script. if worked then you have to open new question to solve your problem that your rc.local doesn't run your script at startup ;) – αғsнιη Oct 04 '14 at 22:02
  • 1
    alright, thanks. That did work, so I'll just open a new question. I have accepted your answer :) – Jeggy Oct 04 '14 at 22:07
4

This looks pretty simple, I'm not a bash script expert, but maybe could be useful for you

# sh script.sh

The script.sh content:

#! /bin/bash

power=$(cat /sys/class/power_supply/BAT1/status)

while true; do
  actual=$(cat /sys/class/power_supply/BAT1/status)

  if [ $actual != $power ]; then
     power=$actual
     notify-send $actual
  fi
done

Basically, I'm reading a file at sysfs that has information about your battery, there are more information in there that could be interesting. The file status contains a flag indicating if your device is actually Charging or Discharging. Hope that helps you.

Eliezer
  • 141
  • You don't need to store last status power=$(cat /sys/class/power_supply/BAT1/status). just compare $temp !="Charging". You are good ;) – αғsнιη Oct 04 '14 at 17:08
  • But this way I can get notifications when power supply is connected and when it's disconnected. – Eliezer Oct 04 '14 at 17:10
  • 1
    This line actual=$(cat /sys/class/power_supply/BAT1/status) checks if power supply is connected("Charging") or dis(Discharging), and the goal is "if battery not charging", then you need only check the actual=$(cat /sys/class/power_supply/BAT1/status) and compare it with "Charging", if they are not equal then we will know that, the battery is not charging. both ways are correct. and one more thing, replace $temp to $actual – αғsнιη Oct 04 '14 at 17:28
  • 1
    Also it could be a problem to hardcode it to look at BAT1... On my system for example the battery is located at BAT0. So I think the other answer using the acpi command might be more elegant/universal – Daniel W. Oct 04 '14 at 18:49