Sunday 24 July 2011

Adding a battery monitor to the taskbar

Sadly, xfce's battery monitor won't work, for the simple reason
it depends on either APM, or APCI. Both require that there be
kernel support for them, and this kernel support is missing in
this particular debian image. However, there is a way to fix this
problem. This method will probably not provide as accurate results
as does APCI, but it is good enough to inform the user of general
trends.

The key is that the battery state is still reported in various
files in the directory /sys/class/power_supply/battery. The files
we are interested in are called capacity, present, and status.
'capacity' shows the charge in the battery. I believe, the numbers are
supposed to be between 0 and 100. On my tablet, the maximum is 91,
but I would not get a full battery on android either. This is why
I think that the maximum is supposed to be 100, but I might very well
be wrong. The file 'present' reports the battery voltage in mV, while
the file 'status' tells us whether the tablet is connected to the
power supply ("Charging"), or it is running on battery ("Not charging").

Having figured out which files are relevant, we need a means of
displaying our findings. For this, we will use the generic monitor
applet. It is not installed by default, so you will have to issue
the command

sudo apt-get install xfce4-genmon-plugin

This is a quite handy application, which takes a string, and
displays its content. What is wonderful is that, if the string
points to an image, then this image will be shown, and if the
string contains a number between 0, and 100, a bar will be
displayed. The bar's length is, of course, proportional to the
magnitude of this number.

Once apt-get has installed the applet, you should right-click on
the taskbar, and say "Add new", and choose "General monitor applet".
In the "Properties" section of the applet, set "/usr/bin/battery.sh"
and set the period to whatever suits your need or your taste.

At this point, we are done with the applet, and we only need to set
up the script that produces the argument to the applet. Copy the
following to /usr/bin/battery.sh, and do not forget to make it
executable (chmod a+x battery.sh)!

 #!/bin/sh

img_batpath="/usr/share/icons/gnome/16x16/status/"
tmp_battery="/dev/shm/battery.tmp"
if [ ! -e "$tmp_battery" ]
then
echo "ac" > "$tmp_battery"
fi

charge=$( cat /sys/class/power_supply/battery/capacity )
voltage=$( cat /sys/class/power_supply/battery/present )
# The potential is given in mV, so we convert it to V
voltage_int=$((voltage/1000))
voltage_frac=$((voltage%1000))
voltage_int=`echo "$voltage" | cut -b 1`
voltage_frac=`echo "$voltage" | cut -b 2-4`
status=$( cat /sys/class/power_supply/battery/status )
old_status=$( cat "$tmp_battery" )

echo "<bar>"$charge"</bar>"
echo "<txt>"$charge"%</txt>"
if [ "$status" = "Not charging" ]
then
if [ "$old_status" = "ac" ]
then
echo "battery" > "$tmp_battery"
./brightness.sh half
fi

if [ "$charge" -gt 90 ]
then
echo "<img>"$img_batpath"battery-full.png</img>"
elif [ "$charge" -gt 30 ]
then
echo "<img>"$img_batpath"battery-good.png</img>"
elif [ "$charge" -gt 10 ]
then
echo "<img>"$img_batpath"battery-low.png</img>"
else
echo "<img>"$img_batpath"battery-caution.png</img>"
fi
else
echo "<img>"$img_batpath"battery-charging.png</img>"
if [ "$old_status" = "battery" ]
then
echo "ac" > "$tmp_battery"
./brightness.sh max
fi
fi
echo "<tool>Voltage: "$voltage_int"."$voltage_frac" V</tool>"

You should now have a bar, an image, and a number at the place
of your genmon applet. (You might have to set the font size to
7 pt, otherwise, the image and the text will overlap.) In addition,
if you hover with your mouse over the applet, you should also see the
present potential of the battery.

You can also combine the backlight dimmer with the battery monitor, and
make the script automatically dim the backlight, if the adapter is
unplugged. To this end, we have to check whether someone has tampered
with the plug. We do this by comparing the present connectedness to
that at the time of the last reading. Obviously, we have to keep the
old connectedness somewhere. We, therefore, always write the value to
a file in /dev/shm, and compare the value stored there to the value
that we read out now. By writing the file to /dev/shm, we actually
save it in memory, so the flash remains untouched. I don't know whether
this is really necessary, but it certainly does not hurt. However, when
we log out, and re-start the computer, this file will be gone (this was
the purpose, after all), so we have to make sure that it does exist when
we want to read from it. This is why we check its existence, and in case
of failure, we simply create the file. If you unplug your device now, it
should become dimmer when battery.sh is run next, and the opposite should
happen, when you plug in the power cord.

A screenshot is below. When it was taken, the tablet was running on AC. 


The next screenshot shows how you can read off the battery voltage.

4 comments:

  1. The work you are bringing here is amazing! I'm very impressed.

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Hmm... OK I got it to load but the icon is a red X as thought it doesn't exist.

    ReplyDelete
  4. Nevermind. Fixed.

    ReplyDelete