#! /bin/sh
# Request apm battery charging percentage.
# To be invoked by Cron, e.g. about every 3 minutes. 
# Calls 'powermesg' to wall warnings to all open tty and pts.
# If there exists any X-session, invoke an xterm also.
# Note: the $xuser - detection depends on kdm here !!
# If battery is critical launch 'powerlog' which logs in short intervals
# the actual state to devices PTS for xterm and TTY for textconsole. 
# Note: cron must not invoke this if on ac power !
# Make the job in /etc/crontab like:
# */3  *  ***   root   on_ac_power || powermon
PATH=$PATH:/usr/bin/X11:/usr/local/bin
# -----------This values change with battery aging ------------------
CUT=18			# 'cutoff' apm % when the machine powerfails
U=72			# how many seconds lasts 1 apm %
LOW=15			# Value = remainig minutes until power off
CRITICAL=5		# Include the cronjob frequence here !
# -------------------------------------------------------------------
INTERVAL=30 		# Critical-logging frequence in seconds.
TTY=/dev/tty8 		# first log device (textconsole)
TTY_ALT=/dev/tty7	# where to log instead if not on X at all
PTS=/dev/console 	# second log device (xterm -C)
GEOMETRY="84x32"	# xterm-window size (chars)
TITLE="Battery power warning:" # xterm-window title
LOCK=/tmp/powermon.lock # internal lockfile

# ===== parameter preparations 

# Get actual powerstate by apm (percentage value):
actual=`cat /proc/apm | cut -d " " -f 7 | tr --delete "%"`;

# XXX DEBUG
#clear;
#echo -n "$LOCK: .........."; cat $LOCK;
#echo -n "
#Simulate power: "; read actual
# XXX DEBUG

# guess remaining minutes
# this formular expression may be different for your battery !
rmain=$((($actual-$CUT)*$U/60))

# Translate actual powerstate into categories
power=high
[ $rmain -le $LOW ] && power=low;
[ $rmain -le $CRITICAL ] && power=critical;

# Get previous locked status. 
if [ -f $LOCK ]; then lastlock=`cat $LOCK`;
else lastlock=null; fi

# What to do if battery is recharged after hibernation ? --> Clean up ... 
# Indicated by power now higher than lastlock.
# Remove stale lockfile and kill logging process.
if [ $lastlock = low ] && [ $power = high ]; then hibernation=true;
elif [ $lastlock = critical ] && [ $power != critical ]; then hibernation=true;
else hibernation=false;
fi

if $hibernation; then
    rm -f $LOCK;
    lastlock=null;
    powerlog off;
fi;

# XXX DEBUG
#m="\n powermon debug message:" 
#m=$m"\n actual: "$actual
#m=$m"\n rmain: "$rmain
#m=$m"\n power: "$power
#m=$m"\n Lockfile: "`[ -f $LOCK ] && echo $LOCK`
#m=$m"\n lastlock: "$lastlock
#m=$m"\n hibernated: "$hibernation
#echo -e "\n`date` $m" > $TTY
# XXX DEBUG


# If power is high --> nothing more to do.
if [ $power = high ]; then exit 0; fi

# ===== MAIN

# ===== Condition handler: xterm window

# Power's either low or critical. 
# If powerlog is already running, nothing to do:
[ $power = critical ] && [ $lastlock = critical ] && exit 0
# If power's low but message is already done, don't repeat message:
[ $power = low ] && [ $lastlock = low ] && exit 0

# So power state has declined to either low or critical.
# First launch a new xterm-console for a new message... but only if:
# 1) there's an Xsession at all, and 2) no 'xterm -C' already.

case `ps ux | grep ' -:0$'` in
    
    "") PTS="" 		# No xsession
	TTY=$TTY_ALT 	# --> log on TTY_ALT only ....
    ;;

    *)  xterm_pid=`ps ax | grep 'xterm -C' | grep -v grep | cut -d" " -f2`;
	if [ ! $xterm_pid ]; then  
	# First get username and X-key.   
    	    xuser=`cat /etc/kde2/kdm/kdmsts | tail -n1 | cut -d"=" -f2`;      
	    xauth merge /home/$xuser/.Xauthority;
	# Provided: Only display 0.0 is open. -C connects the xterm to /dev/console.
	    xterm -C -fg blue -title "$TITLE" -geometry $GEOMETRY -b 30 -display :0.0 &
	    sleep 1; # let xterm settle down
	fi;
    ;;

esac;

# XXX DEBUG
#m="\n TTY: "$TTY
#m=$m"\n PTS: "$PTS
#m=$m"\n xuser: "$xuser
#m=$m"\n xterm_pid: "$xterm_pid
#echo -e "\n`date` $m" > $TTY
# XXX DEBUG

# ===== Wall a powermessage
powermesg $power $rmain $TTY $PTS
# ===== Set lockfile to recent powerstate
echo $power > $LOCK
# ===== Condition handler: Launch logging ?
if [ $power = critical ];
 then powerlog $INTERVAL $TTY $PTS &
fi

exit 0

