#!/usr/bin/tclsh

# v1.0  3/30/99  by Jon Duncan
# Run this on a box and it will connect to an LCDproc server to
# display # of users on, and cpu loads.
#
# Usage:  lcd_users_load.tcl <system name> [server:port] &
#
#    <system name> is needed, and must be different from any other lcd_users_load
#      client connected to your server.  My lan uses host for this.
#      Its main use is for multiple clients over multiple machines.
#
#    If [server:port] is omitted,   localhost:13666  is assumed.
#
################################################################################

set sysname [lindex $argv 0]
if {"$sysname" == ""} {
	puts stdout "ERROR: Usage: $argv0 <system name> \[server:port\] &"
	return 1
}
set tmp [lindex $argv 1]
if {"$tmp" == ""} {
	set lcdproc_host	"localhost"
	set lcdproc_port	"13666"
} else {
	set lcdproc_host	"[lindex [split $tmp ":"] 0]"
	set lcdproc_port	"[lindex [split $tmp ":"] 1]"
	if {"$lcdproc_port" == ""} { set lcdproc_port 13666 }
}


# Returns :  {<users> <load 1> <load 5> <load 15>}
proc get_uptime {} {
	set line "[exec "/usr/bin/uptime"]"
	set tmp [lsearch $line "users,"]
	if {$tmp == -1} {
		set tmp [lsearch $line "user,"]
		if {$tmp == -1} {
			set users "?"
		} else {
			set users "[lindex $line [expr $tmp - 1 ]]"
		}
	} else {
		set users "[lindex $line [expr $tmp - 1 ]]"
	}
	set tmp [lsearch $line "average:"]
	if {$tmp == -1} {
		set la "?.??" ; set lb "?.??" ; set lc "?.??"
	} else {
		set la [string trimright [lindex $line [expr $tmp + 1 ]] ","]
		set lb [string trimright [lindex $line [expr $tmp + 2 ]] ","]
		set lc [string trimright [lindex $line [expr $tmp + 3 ]] ","]
	}
	return "$users $la $lb $lc"
}


proc main {} {
	global sock sysname lcdproc_host lcdproc_port

### Attempt to open socket, abort if failed.

	if {[catch {set sock [socket $lcdproc_host $lcdproc_port]}]} {
		puts stdout "Error connecting to $lcdproc_host $lcdproc_port" ; return 0
	}

### Setup event handlers.

	fconfigure $sock -blocking 0
	fileevent $sock readable event_in

### Get data ready for first screen

	set data [get_uptime]
	set users "[lindex $data 0]"
	set loads "[lrange $data 1 3]"

### TCP connection opened..  sending INIT stuffs.

	puts $sock "hello"
	flush $sock
	gets $sock infoline

	puts $sock "client_set name up-$sysname"
	puts $sock "screen_add screen"

	puts $sock "widget_add screen title title"
	puts $sock "widget_add screen label-u string"
	puts $sock "widget_add screen label-l string"
	puts $sock "widget_add screen data-u string"
	puts $sock "widget_add screen data-l string"

	puts $sock "widget_set screen title \{Sys: $sysname\}"

	puts $sock "widget_set screen label-u 1 2 Users:"
	puts $sock "widget_set screen label-l 1 3 \{System Load\}"

	puts $sock "widget_set screen data-u 9 2 $users"
	puts $sock "widget_set screen data-l 3 4 \{$loads\}"

	flush $sock

### Enter loop

	after 10000 event_time
	vwait done	

### Loop exited, close sock and exit

}


# This proc is called once every 10 seconds.
proc event_time {} {
	global listen
	if {$listen == 1} {update_lcd}
	after 10000 event_time
}


# This proc is called when data is send from server to us.
proc event_in {} {
	global sock listen done

	gets $sock line
	set cmd [lindex $line 0]

	switch $cmd {
		"listen" { set listen 1 ; update_lcd }
		"ignore" { set listen 0 }
		"bye" { set listen 0 ; set done 1 }
	}
}

# this proc send updated screen info to lcd
proc update_lcd {} {
	global sock

	set data [get_uptime]

	puts $sock "widget_set screen data-u 9 2 [lindex $data 0]"
	puts $sock "widget_set screen data-l 3 4 \{[lrange $data 1 3]\}"
	flush $sock


}





set sock "" ; set done 1 ; set listen 1
main
