Customizable LCD Status screen for Debian on Cobalt hardware


This is a handy framework to monitor several system parameters on Cobalt hardware running Debian GNU/Linux.

No button input is handled yet, but so far this script is much less of a cpu-hog than paneld. Especially when choosing a large update interval, of course. ;)

Adding monitors (called display format fuctions in the script) is quite easy, just add a bash function to define the monitor and the script will display its output, and that of the other monitors, in sequence on the LCD of the Qube or Raq.

The only Cobalt hardware in my home running Debian is an old 2700, so your milage may vary on other models.

The script should be self-explanatory: ;)


#!/bin/bash

# Cobalt LCD status screen updater
# Hessel Schut, hessel@isquared.nl, 2007-01-31

# This script uses the putlcd(8) command provided by cobalt-panel-utils.

# VARIABLES

lcdv_sleep=5			# time between updates
lcdv_tfmt="%a %d %b %R"		# timestamp format, see strftime(3)

# Display format definitions follow below, each format should be written
# as a function with a unique identifier starting with lcdf_, so valid
# identifiers would be lcdf_foo and lcdf_bar or even lcdf_3_baz73.

# A display format function may return one or two lines, if one line is
# returned, the first line of the display will be used to display the 
# time of day using the lcdv_tfmt variable.

# Display definitions will be displayed in alphabetical order.

## DISPLAY DEFINITIONS ################################################

function lcdf_load {
	# display 1m loadavg:
	echo Load: $(cut -d\  -f1 /proc/loadavg)
}

function lcdf_host_version {
	# display hostname + kernel version
	echo Host: $(hostname)
	echo "("$(uname -r)")"
}

function lcdf_mem_free {
	# display free real memory (excl. swap)
	local m=$(free -k | awk '
		/^Mem/ {
			printf("%.2f kB", ($4)/1024);
		}
	')
	echo Free: $m
}

function lcdf_users {
	# display count of logged in users
	local t=0 i=0
	who | cut -d\  -f1 | sort | uniq -c | {
        	while read l
        	do
                	((t+=${l/ *}))	# sum user session counts
			((i++))		# sum unique users
        	done
        	echo $i users 
		echo $t total
	}
}

#######################################################################

# debug flag
_lcd_dbg=0

# get all display function definitions
# list is formatted as: numfunc func-1 func-2 ... func-n
_lcd_funclist=$(declare -f | awk '
		BEGIN { i=0 }
		/^lcdf_/ { 
			dfuncs=dfuncs" "$1;
			i++;
		} 
		END { print i dfuncs }
	' )

# strip numfunc from funclist
_lcd_numfuncs=${_lcd_funclist/ *}	# car 
_lcd_funclist=${_lcd_funclist#* }	# cdr ;)

# (infinite) main loop
while [ == ]
do
	# iterate over all defined display definitions
	for func in ${_lcd_funclist}
	do
		# update timestamp
		_lcd_timestamp=$(date +"${lcdv_tfmt}")
	
		# (re-)initialize display array
		_lcd[1]=''; _lcd[2]=''
		${func} | {
			# get display function output for at most two lines
			while read line && [ -z "${_lcd[2]}" ] 
			do
				[ -z "${_lcd[1]}" ] && _lcd[1]=${line} || _lcd[2]=${line}
			done
			# swap top and bottom when bottom is empty and use timestamp as top
			if [ -z "${_lcd[2]}" ]
			then
				_lcd[2]=${_lcd[1]}
				_lcd[1]=${_lcd_timestamp} 
			fi

			[ ${_lcd_dbg} == 0 ] && /usr/sbin/putlcd 				"${_lcd[1]}" 				"${_lcd[2]}"
			[ ${_lcd_dbg} == 1 ] && (
				echo "${_lcd[1]}"; 
				echo "${_lcd[2]}" )
		}
		# nap for lcdv_sleep seconds
		sleep ${lcdv_sleep}
	done
done