#!/usr/bin/wish -f # -*- Tcl -*- # usage: # xbatmon-simple-tray # [WISH-OPTIONS... [-- TRAY-EMBED-OPTIONS... [-- XBATMON-SIMPLE-OPTIONS...]]] source subproc.tcl source utils.tcl source args.tcl proc cmdline {id orientation} { global argv return [concat [list xacpi-simple -into $id] $argv] } #----- tooltip generation ----- proc tt-invisible {} { tt-noafter applet::tooltip-set {} } proc tt-noafter {} { global ttafter catch { after cancel $ttafter } catch { unset ttafter } } proc tt-show {} { global ttafter tt-noafter set ttafter [after 500 tt-show] applet::tooltip-set [tt-string] } proc append-energies {av energy power eunit punit fmt} { upvar 1 o o upvar 1 $av a append o [format " ${fmt}%s / ${fmt}%s / ${fmt}%s ${fmt}%s" \ [expr { $a(${energy}_NOW) * 1e-6 }] $eunit \ [expr { $a(${energy}_FULL) * 1e-6 }] $eunit \ [expr { $a(${energy}_FULL_DESIGN) * 1e-6 }] $eunit \ [expr { $a(${power}_NOW) * 1e-6 }] $punit] } proc append-percents {qv} { upvar 1 o o upvar 1 $qv q append o [format " %.0f%% (%.0f%%/%.0f%%)" \ [expr { $q(energy_NOW) * 100.0 / $q(energy_FULL_DESIGN) }] \ [expr { $q(energy_NOW) * 100.0 / $q(energy_FULL) }] \ [expr { $q(energy_FULL) * 100.0 / $q(energy_FULL_DESIGN) }]] if {$q(power_NOW) < -1} { set endpoint 0 } elseif {$q(power_NOW) > -1} { set endpoint $q(energy_FULL) } if {[info exists endpoint]} { set until [expr {($endpoint - $q(energy_NOW)) * 60.0/ $q(power_NOW)}] if {$until < 72*60} { append o [format " %.fmins" $until] } } } proc tt-string {} { global errorInfo set lines {} if {[catch { set dir /sys/class/power_supply foreach f [glob -nocomplain -tails -directory $dir *] { debug::debug "TT-INFO $f" if {[catch { set chan [open $dir/$f/uevent] tt-info $chan } info]} { set info "error: $info" debug::debug "$f $errorInfo" } lappend lines "$f: $info" catch { close $chan } catch { unset chan } } } emsg]} { lappend lines "error scanning: $emsg" debug::debug "scanning $errorInfo" } if {$nbatts} { set o "Total: $nbatts present " append o [join [lsort [array names states]] /] append-energies tot energy power Wh W %.1f append-percents tot lappend lines $o } if {![llength $lines]} { lappend lines "no power information" } return [join $lines "\n"] } proc compute {power energy factor punit eunit sign fmt} { upvar 1 a a upvar 1 q q upvar 1 tot tot upvar 1 o o debug::debug "COMPUTE $power $energy $factor" set energy_sign 1 set power_sign $sign set entl {{energy NOW} {energy FULL} {energy FULL_DESIGN} {power NOW}} foreach ent $entl { manyset $ent pe k set kq "${pe}_${k}" set kv "[set $pe]_$k" if {![info exists a($kv)]} { return 0 } set a($kv) [expr {$a($kv) * [set "${pe}_sign"]}] set q($kq) [expr {$a($kv) * $factor}] } debug::debug "COMPUTE OK [array names q]" foreach ent $entl { manyset $ent pe k set kq "${pe}_${k}" if {![info exists tot($kq)]} { set tot($kq) 0 } set tot($kq) [expr {$tot($kq) + $q($kq)}] } append-energies a $energy $power $eunit $punit $fmt append-percents q return 1 } proc tt-info {chan} { upvar 1 tot tot upvar 1 nbatts nbatts upvar 1 states states while {[gets $chan l] >= 0} { if {[regexp {^POWER_SUPPLY_([A-Z0-9_]+)=(.*)$} $l dummy k v]} { debug::debug " uevent ok $l" set a($k) $v } else { debug::debug " uevent unk $l" } } debug::debug "GOT [array names a]" if {![info exists a(TYPE)]} { set op {} foreach k {ONLINE PRESENT} { append op [info exists a($k)] } switch -exact $op { 10 { set a(TYPE) Mains } 01 { set a(TYPE) Battery } default { error "no type and bad op $op" } } debug::debug " guessed type $a(TYPE) from ONLINE PRESENT $op" } set o "$a(TYPE)" set nbatts 0 switch -exact -- $a(TYPE) { Mains { switch -exact -- $a(ONLINE) { 0 { append o " Offline" } 1 { append o " Online" } default { append o " ?$o" } } } Battery { switch -exact -- $a(PRESENT) { 0 { append o " Absent"; return $o } 1 { append o " Present" } default { apend o " ?$o" } } set sign 1 append o " " switch -exact -- $a(STATUS) { Charging { } Discharging { set sign -1 } default { append o "Status=" } } set states($a(STATUS)) 1 append o $a(STATUS) foreach power {POWER CURRENT} energy {ENERGY CHARGE} \ punit {W A} eunit {Wh Ah} fmt {%.1f %.2f} { switch -exact $power { POWER { set factor 1.0 } CURRENT { set factor [expr {$a(VOLTAGE_NOW) * 1e-6}] } } if {![compute $power $energy $factor \ $punit $eunit $sign $fmt]} continue incr nbatts } } } return $o } #----- modes ----- proc mode/normal {} { uplevel #0 source applet.tcl applet::setup-subproc cmdline applet::setup-tooltip tt-show tt-invisible } proc mode/-tooltip-string {} { puts [tt-string] exit 0 } #----- command line parsing ----- set mode normal while {[args::next_special arg]} { switch -exact -- $arg { -- { break } -tooltip-string { set mode $arg } default { args::badoption } } } mode/$mode